JavaScript class 中的变量始终未定义

JavaScript variable inside class is always undefined

我有一个 JavaScript class 这样的:

Dog = (function() {
    var name;

    function setName(_name) {
        name = _name;
    }

    return {
        setName: setName,
        name: name
    };
})();

当我运行:

Dog.setName('Hero');

Dog.name 始终未定义。

我当然遗漏了一些关于 JS 作用域的东西,但是什么?

这可能是更适合您的模式。您正在使用非常古老的 ES3 样式构造函数。

(function(exports) {

  function Dog(name) {
    this.name = name;
  }

  Dog.prototype.speak = function() {
    return "woof";
  };

  // other functions ...

  exports.Dog = Dog;
})(window);

var d = new Dog('Hero');
console.log(d.name); // "Hero"

您可能也想研究一下 ES6 类

class Dog {
  constructor(name) {
    this.name = name;
  }
}

let d = new Dog('Hero'); 
console.log(d.name); // "Hero"

您正在返回一个对象,其中 name 属性 在 那个时间点 的值为 name (未定义) .当更新 IIFE 中的 name 变量时,返回对象的 name 属性 不会以某种方式动态更新。

有很多方法可以处理您似乎想做的事情。这是一个:

Dog = (function() {
    var name;

    function setName(_name) {
        name = _name;
    }

    return Object.defineProperties({}, {
      setName: { value: setName },
      name:    { get: function() { return name; } }
    });

})();

这将 name 保留为私有变量,只能通过 setName 设置,但提供 getter 属性 来获取其值。

另一个答案中提出的替代方案是等效的,只是一种不同的写法:

return {
  setName:  function(n) { name = n; },
  get name: function() { return name; }
};

次要点,但在这个特定的上下文中,您不需要在 IIFE 周围加上括号:

Dog = function() { }();

会很好用。

使用 'this' 关键字。

Dog = (function() {
    var name;

    function setName(_name) {
        this.name = _name;
    }

    return {
        setName: setName,
        name: name
    };
})();
Dog.setName('Hero');
alert(Dog.name);

发生这种情况是因为您假设对象中的设置 name 保留了对原始 name 变量的引用。相反,您想将其分配给当前对象(您不妨完全忽略私有变量)。

Dog = {
  name: '',
  setName: function(n) {
    this.name = n;
  }
};

但是,如果您想将 name 设为私有,则可以为其创建一个 getter。

var Dog = (function() {
  var name;

  return {
    setName: function(n) {
      name = n;
    },
    get name: function() {
      return name;
    }
  };
})();

解决此问题的简单方法是:

Dog = (function() {

var dog = {
    setName: setName,
    name: name
};

function setName(_name) {
    dog.name = _name;
}

return dog;
}

在您的代码中,您设置了错误的 name 变量。

变量名称;

function setName(_name) {
    name = _name;
}

在此函数中,setName 设置内部变量 name 而不是 属性 name。在 JavaScript 中,字符串是不可变的,因此当您更改它时,它会创建一个新字符串,并且不会更新现有字符串。

听起来你想做一个构造函数...检查这个示例:

function Dog(prop) {
        this.name = prop.name;
        this.color = prop.color;
    }
    var myDog = new Dog({
        name:'Sam',
        color: 'brown'
    });
    alert()
    console.log('my dog\'s name is: '+myDog.name);
    console.log('my dog\'s color is: '+myDog.color);

你可以在这里试试:http://jsfiddle.net/leojavier/ahs16jos/

希望对大家有所帮助...