почему изменение значения в одном экземпляре изменяет значение в другом?

#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. Спасибо за объяснение! Пометка как ответ!