我想出了下面的情况:
function Dog () {
"use strict";
this.age = 1;
var name = "Fido";
this.getName = function () { return name; }
}
现在我正在创建一个“Dog”类的新实例并打印变量的值。
var d = new Dog;
document.write('<strong>Dog age:</strong> ' +d.age); \\Outputs "1" as expected
document.write('<br/>');
document.write('<strong>Dog name:</strong> ' +d.name); \\Outputs "undefined" as expected, 'cause it's a private variable.
document.write('<br/>');
document.write('<strong>Get Dog name:</strong> ' +d.getName()); \\Outputs "Fido", as expected.
但是我要说我想改变狗的名字,就像这样:
d.name = "Stinky";
document.write('<br/>');
document.write('<strong>Dog name Again:</strong> ' +d.name);
document.write('<br/>');
document.write('<strong>Get Dog name Again:</strong> ' +d.getName());
基于此,我提出了几个问题:
有什么想法吗?
这是一个让事情变得更轻松的小事。
答案 0 :(得分:6)
d.name = "Stinky";
正在向d
对象添加一个新的(公共)属性,这是一个instanceOf Dog
。
getter仍然引用值为Fido
的(private)变量。
如果您想允许消费者更改私有变量,您还需要一个setter:
function Dog () {
"use strict";
this.age = 1;
var name = "Fido";
this.getName = function () { return name; }
this.setName = function (value) { name = value; }
}
var d = new Dog();
d.name; // undefined because there is no name public property
d.getName() // returns the internal private, "Fido"
d.setName('Stinky'); // the internal private is now "Stinky"
答案 1 :(得分:1)
您将局部变量与实例属性混淆。这些是完全分开的。
1)你设置d.name
,一个实例属性,这就是你要调用的,而不是私有变量。
2)Fido是私有var的valeu,这是你的方法返回的,而不是实例属性,所以该方法总是会说Fido。
您的原始代码可能如下所示:
function Dog () {
"use strict";
this.age = 1;
this.name = "Fido";
}
Dog.prototype.getName = function() { return this.name; }
注意我将方法添加到原型中,而不是将其显式添加到每个实例中。这样,实例继承了它。这是更好的做法;可重复使用的代码应该在原型上,并且它比每次添加到每个实例都要好。
答案 2 :(得分:1)
var name
和someObj.name
永远不会是同一个东西。 2个不同的值,可以设置为2个不同的东西。相反,你需要一个像你的getter一样工作的setter函数:
this.setName = function(newName) { name = newName; };
设置与私有变量同名的属性时无法引发错误。它们是两个完全不同的东西,当你设置一个甚至可以拦截的属性时,没有回调。