2

我有以下代码:

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:

第一次编辑的解决方案是后缀与前缀。前缀增量产生第一个输出。

4

2 回答 2

2

第一种情况:

您只增加了原型变量,它将由原型对象的所有实例共享。

这里要注意的重要一点是,当您在第一种情况下访问testwiththis.test时,JavaScript 会尝试查找testin this(当前对象)。它没有找到它,它在原型链中上升了。它test在 中找到Foo.prototype并返回该值。这就是为什么你得到this.test和相同的值Foo.prototype.test

第二种情况:

你在递增this.testthis.test++可以这样理解

this.test = this.test + 1

test现在,它从 Pototype 链中获取 的值(Foo.prototype.test将被使用,即 0),将其加 1 并将结果存储在test当前对象的成员中。因此,您正在创建一个新成员thiscalled test。这就是它的价值与 不同的原因Foo.prototype.test

您可以通过添加另一种方法来确认这一点,如下所示

Foo.prototype.deleteTest = function () {
    delete this.test;
}

...
...
bar.deleteTest();
bar.getTest('bar');

现在bar.getTest将打印0,因为我们删除了testfrom this, with deleteTest()。所以,它会爬上梯子,找到testin Foo.prototype,也就是 0。

于 2014-03-28T07:15:31.620 回答
-1

this引用函数的当前实例,而不是原型。

于 2014-03-28T07:09:20.137 回答