Свойство экземпляра объекта Javascript неожиданно устанавливается

У меня есть следующий код:

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:

Решение для первого редактирования было постфикс против префикса. Приращение префикса дает первый вывод.

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 из цепочки прототипов (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(), Итак, он пойдет вверх по лестнице и найдет test в Foo.prototype, который равен 0.

this будет ссылаться на текущий экземпляр функции, а не на прототип.

Другие вопросы по тегам