意外设置Javascript对象实例属性
我有以下代码:意外设置Javascript对象实例属性,javascript,prototypal-inheritance,function-constructor,Javascript,Prototypal Inheritance,Function Constructor,我有以下代码: function Foo() { Foo.prototype.test = 0; } Foo.prototype.incTest = function() { Foo.prototype.test++; }; Foo.prototype.getTest = function(name) { console.log(name +" this: " + this.test + " proto: " + Foo.prototype.test); }; va
function Foo() {
Foo.prototype.test = 0;
}
Foo.prototype.incTest = function() {
Foo.prototype.test++;
};
Foo.prototype.getTest = function(name) {
console.log(name +" this: " + this.test + " proto: " + Foo.prototype.test);
};
var bar = new Foo();
var baz = new Foo();
bar.getTest('bar');
bar.incTest();
bar.getTest('bar');
baz.incTest();
bar.getTest('bar');
baz.getTest('baz');
可预测的结果是:
bar this: 0 proto: 0
bar this: 1 proto: 1
bar this: 2 proto: 2
baz this: 2 proto: 2
现在,我尝试利用这个
查找原型链,并将incTest
更改为:
Foo.prototype.incTest = function() {
this.test++;
};
这给了我完全不同的输出
bar this: 0 proto: 0
bar this: 1 proto: 0
bar this: 1 proto: 0
baz this: 1 proto: 0
this.test不应该引用Foo-prototype属性吗?这到底是怎么回事
编辑:
此外,将行更改为Foo.prototype.test=this.test++
还生成第二个输出,我不知道为什么
编辑2:
第一次编辑的解决方案是后缀和前缀。前缀增量产生第一个输出。该将引用函数的当前实例,而不是原型。第一种情况:
您只增加了prototype变量,该变量将由prototype对象的所有实例共享
这里需要注意的重要一点是,当您使用this.test
访问test
时,在第一种情况下,JavaScript尝试在this
中查找test
(当前对象)。它找不到它,在原型链中向上爬。它在Foo.prototype
中查找test
,并返回该值。这就是为什么this.test
和Foo.prototype.test
得到相同的值
第二种情况:
您正在增加此测试的this.test++
可以这样理解
this.test = this.test + 1
Foo.prototype.deleteTest = function () {
delete this.test;
}
...
...
bar.deleteTest();
bar.getTest('bar');
现在,它从pototype链中获取test
的值(Foo.prototype.test
将被使用,它是0),向其中添加1,并将结果存储在当前对象的test
成员中。因此,您正在中创建一个名为test
的新成员。这就是为什么它的值不同于Foo.prototype.test
您可以通过再添加一个方法来确认这一点,如下所示
this.test = this.test + 1
Foo.prototype.deleteTest = function () {
delete this.test;
}
...
...
bar.deleteTest();
bar.getTest('bar');
现在bar.getTest
将打印0
,因为我们使用deletetetest()
从中删除了test
。因此,它将在Foo.prototype
中找到test
,即0。正确。但是如果当前实例没有属性test
,它不应该解析为原型的test
?否则,this.test
将是undefined
,递增undefined
将给出NaN
原型具有该属性,因此所有实例都继承该属性,但它们有自己的实例。我不相信这是真的。否则第一次输出就不会发生。(即,更改原型的测试属性值不会更改对象的测试属性)在对象拥有自己的实例之前,它会自动使用原型的实例。一旦你设置了它自己的实例,它就会继续使用它。我明白了。我不知道this.test++
等同于this.test=this.test+1
。如果以这种方式查看,输出是有意义的。谢谢还有一个问题Foo.prototype.test=(this.test++)
生成第二个输出。。。为什么?@moesef因为,您正在输入this.test
并在递增到Foo.prototype.test
之前分配值。(请记住:var++是后缀运算符)。因此,Food.prototype.test
的值将减少一个。尝试Foo.prototype.test=++this.test代码>,您将能够理解其中的区别:)是的。我试过了。这改变了我的期望。谢谢你的帮助!