#javascript
#javascript
Вопрос:
Почему foo.value
изменяется в примере ниже?
var Zzz = function() {};
Zzz.prototype.foo = {};
Zzz.prototype.set = function (v) {
this.foo.value = v;
};
var Z1 = new Zzz();
Z1.set(100);
var Z2 = new Zzz();
Z2.set(200);
console.log(Z1.foo, Z2.foo); // 200, 200
console.log(Z1 === Z2); // false
console.log(Z1.foo.value == Z2.foo.value); // true < WHY????
Ответ №1:
Поскольку foo
это часть прототипа, это похоже на статическую переменную в таких языках, как Java или PHP (и, вероятно, многих других).
Это означает, что изменение значения в одном из них повлияет на все экземпляры этого класса.
Для отдельных экземпляров попробуйте:
var Zzz = function() {
this.foo = {};
};
Zzz.prototype.set = function(v) {
this.foo.value = v;
};
Комментарии:
1. Черт, ты быстрый. 1
2. Спасибо за решение.
Ответ №2:
Я думаю, у вас уже есть ответ здесь, но на случай, если вы все еще не понимаете.
prototype
свойство конструктора — это объект, в котором все экземпляры будут иметь свойства, которые ссылаются на свойства этого объекта.
Когда вы создаете новый экземпляр и спрашиваете о его свойстве ( foo
), JS сначала посмотрит на этот экземпляр и попытается найти его собственное свойство foo
. Если здесь нет foo
, то JS посмотрит на прототип экземпляра и спросит о foo
там.
Пример кода:
var Zzz = function() {};
Zzz.prototype.foo = {};
Zzz.prototype.set = function (v) {
this.foo.value = v;
};
var Z1 = new Zzz();
Z1.set(100);
var Z2 = new Zzz();
Z2.set(200);
// but when we create new object only for Z1 instance
Z1.foo = {};
Z1.set(100); // this.foo in set function refers to that new object
console.log(Z1.foo, Z2.foo); // 100, 200
console.log(Z1.foo === Zzz.prototype.foo); // false
console.log(Z2.foo === Zzz.prototype.foo); // true
Также, если вы удалите foo
свойство позже с:
delete Z1.foo;
console.log(Z1.foo === Zzz.prototype.foo); // is true again
Когда вам нужно уникальное свойство для каждого экземпляра, вы привязываете его к этому в конструкторе. Когда вам нужно общее свойство для всех экземпляров (например, набор функций), вы привязываете его к prototype. Если вы не знаете, то свойства из прототипа всегда можно переопределить позже.
Комментарии:
1. Спасибо за объяснение! Пометка как ответ!