簡體   English   中英

JavaScript對象實例屬性意外設置

[英]Javascript object instance property getting set unexpectedly

我有以下代碼:

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.testthis.test引用Foo原型屬性嗎? 這到底是怎么回事?

編輯:

此外,將行更改為Foo.prototype.test = this.test++; 也會產生第二個輸出,我不確定為什么。

編輯2:

首次編輯的解決方案是后綴和前綴。 前綴增量產生第一個輸出。

第一種情況:

您只增加了原型變量,該變量將由原型對象的所有實例共享。

這里要注意的重要一點是 ,在第一種情況下,當您使用this.test訪問test時,JavaScript會嘗試在this (當前對象)中找到test 它找不到它,並且沿着原型鏈上升。 它在Foo.prototype找到test並返回該值。 這就是為什么this.testFoo.prototype.test獲得相同值的this.test

第二種情況:

您正在遞增this.test 可以這樣理解this.test++

this.test = this.test + 1

現在,它從pototype鏈中獲取test的值(將使用Foo.prototype.test ,該值為0),將其加1並將結果存儲在當前對象的test成員中。 因此,您正在this test中創建一個新成員。 這就是為什么它的值不同於Foo.prototype.test

您可以通過添加另一種方法來確認這一點,例如

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

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

現在bar.getTest將打印0 ,因為我們刪除了test ,從this ,用deleteTest() 因此,它將爬上梯子並在Foo.prototype找到test ,該test為0。

this將引用函數的當前實例,而不是原型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM