我有以下代码:
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
现在我尝试利用this
查找原型链,并将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原型属性吗?到底发生了什么?
编辑:
此外,将行更改为Foo.prototype.test = this.test++;
也会产生第二个输出,我不确定原因。
编辑2:
首次编辑的解决方案是后缀与前缀。前缀增量产生第一个输出。
答案 0 :(得分:2)
第一种情况:
您只是递增原型变量,原型变量的所有实例都会共享该原型变量。
这里需要注意的重要事项是,当您在第一种情况下使用test
访问this.test
时,JavaScript会尝试在test
中找到this
test
(当前对象)。它找不到它,它在原型链中上升。它在Foo.prototype
中找到this.test
并返回该值。这就是为Foo.prototype.test
和this.test
获得相同值的原因。
第二种情况:
您正在递增this.test++
。 this.test = this.test + 1
可以像这样理解
test
现在,它从pototype链中获取Foo.prototype.test
的值(将使用test
,这是0),向其中添加1并将其存储为this
成员当前对象。因此,您要在test
中创建一个名为Foo.prototype.test
的新成员。这就是为什么它的价值与Foo.prototype.deleteTest = function () {
delete this.test;
}
...
...
bar.deleteTest();
bar.getTest('bar');
不同。
您可以通过再添加一个方法来确认这一点,例如
bar.getTest
现在0
将打印test
,因为我们从this
删除了deleteTest()
,test
。因此,它会上升并在Foo.prototype
中找到{{1}},即0。
答案 1 :(得分:-1)
this
将引用函数的当前实例,而不是原型。