Свойство экземпляра объекта 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
будет ссылаться на текущий экземпляр функции, а не на прототип.