опытное наследование JavaScript

Так как конечные пользователи являются разработчиками, можно предоставить им версию, которая позволяет регистрироваться всех ключевых значений/аргументов, которые передаются. И предоставьте услугу так, чтобы они могли повернуть вход включения - выключения.

16
задан med 7 October 2009 в 20:29
поделиться

6 ответов

Когда вы помещаете новый объект в obj1.list, вы изменяете существующий список по прототипу. Когда вы меняете имя, вы назначаете свойство obj1, экземпляру, , а не прототипу. Обратите внимание, что то же самое произошло бы, если бы вы сделали:

obj1.list = ["from obj1"]
...
console.log(obj2.list) // <--- Will log [] to console
3
ответ дан 30 November 2019 в 21:29
поделиться

Конечно, я бы предпочел, чтобы любой последующие экземпляры подкласса не получают значения из других экземпляров, но если это должно произойти, это должно быть согласованно!

Тогда не наследовать от нового экземпляра A , наследовать от прототипа A . Это гарантирует, что вы не наследуете состояние, вы наследуете только поведение. Это сложная часть прототипного наследования, оно также наследует состояние, а не только поведение, как в классическом наследовании ООП. В JavaScript функции-конструкторы следует использовать только для настройки состояния экземпляра.

var A = function (list) {
    this.list = list;
    this.name = "A";
};

A.prototype.getName = function () {
    return this.name;
};

var B = function (list) {
    this.list = list;
    this.name = "B";
};

B.prototype = A.prototype;   // Inherit from A's prototype
B.prototype.constructor = B; // Restore constructor object

var b = new B([1, 2, 3]);

// getName() is inherited from A's prototype
print(b.getName()); // B

И, кстати, если вы хотите что-то изменить в A через B, вы должны сделать следующее:

B.prototype.name = "obj1";
4
ответ дан 30 November 2019 в 21:29
поделиться

Вы повторно назначаете имя переменной. Происходит то, что вы повторно назначаете новую переменную имени объекту obj1. Ваше объявление имени переопределяет объявление в объекте-прототипе (поэтому вы его не видите). С помощью списка вы изменяете список на месте, не изменяя его ссылку.

2
ответ дан 30 November 2019 в 21:29
поделиться
  • Вы говорите, что в этом коде B является реализация A.
  • Тогда вы говорите, что obj1 - это новый экземпляр B и поэтому должен захватить все значений A.
  • Затем вы добавляете элемент в указанное местоположение списка в obj2 который, в свою очередь, добавляет элемент к указанное местоположение списка в A (потому что они ссылаются на одно и то же).
  • Затем вы меняете значение имени в obj1.
  • Тогда вы говорите, что obj2 - НОВАЯ экземпляр B и поэтому должен захватить все значений A.

Вы изменили значения списка, указанного в A, но не саму ссылку. obj2.name должно быть "A".

4
ответ дан 30 November 2019 в 21:29
поделиться

Проблема с прототипами заключается в том, что вы можете читать их в течение всего дня, и это не изменит основную структуру того, что на что указывает. Однако в первый раз, когда вы выполняете присвоение, вы заменяете на этот экземпляр , на что указывает это свойство.

В вашем случае вы фактически не переназначили прототип свойства, так что давайте продолжим цепочку областей видимости. Далее А. Ага! A имеет 'name', верните это "

Однако, когда вы выполняете запись, интерпретатор фактически не заботится об унаследованном свойстве.

obj1.name = "Fred";

Интерпретатор:« Мне нужно присвоить свойству 'name'. Я нахожусь в рамках этого экземпляра B, поэтому назначьте «Fred» для B. Но я оставляю все остальное, что находится дальше по цепочке областей видимости (т.е. A) »

Теперь, в следующий раз вы читаете ...

obj1.name;

Переводчик: «Мне нужно свойство 'name'. Ага! этот экземпляр объекта B уже имеет свойство name. Просто верните это - меня не волнует остальная часть цепочки областей видимости (например, A.name) "

Итак, когда вы в первый раз пишете имя, он вставляет его как свойство первого класса в экземпляр и не делает этого. ' Меня больше не волнует, что находится на AAname, все еще там , это просто дальше по цепочке областей видимости, и интерпретатор JS не продвинется так далеко, пока не найдет то, что искал.

Если " name "имеет значение по умолчанию в A (как и у вас, это" A "), тогда вы увидите следующее поведение:

B.prototype = new A();
var obj1 = new B();
var obj2 = new B();

obj1.name = "Fred";

alert(obj1.name); // Alerts Fred
alert(obj2.name); // Alerts "A", your original value of A.name

Теперь, в случае вашего массива, вы фактически никогда не заменяли list в цепочке областей видимости с новым массивом. Что вы сделали, так это взяли дескриптор самого массива и добавили к нему элемент. Следовательно, затронуты все экземпляры B.

Интерпретатор: «Мне нужно получить свойство« список »и добавить к нему элемент. Проверка этого экземпляра B ... нет, не имеет свойства« список ». Следующее в цепочке областей видимости: A. Да, у A есть "список", используйте его. Теперь нажмите на этот список "

Это было бы не , если бы вы сделали это:

obj1.list = [];
obj1.push(123);
13
ответ дан 30 November 2019 в 21:29
поделиться

Такое поведение происходит потому, что вы не присваиваете значение «списку», вы его изменяете.

Это совершенно разумное поведение, когда вы понимаете, как работает цепочка прототипов. Когда вы ссылаетесь на obj1.list, он сначала проверяет, существует ли «список» в obj1, использует его, если он найден, а в противном случае использует тот, который находится в obj1.prototype (то есть MyClass.prototype.list).

Итак:

obj1.list.push("test"); // modifies MyClass.prototype.list
obj1.list = ["new"]; // creates a "list" property on obj1
obj1.list.push("test"); // modifies obj1.list, not MyClass.prototype.list
delete obj1.list; // removes the "list" property from obj1
// after the delete, obj1.list will point to the prototype again
obj1.list.push("test"); // again modifies MyClass.prototype.list

] Самый важный вывод: «прототипы - это не классы». Прототипы могут достаточно хорошо подделывать классы, но они не являются классами, поэтому вы не должны относиться к ним как к таковым.

0
ответ дан 30 November 2019 в 21:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: