Вопрос

Я вижу много такого кода:

function Base() {}
function Sub() {}
Sub.prototype = new Base();

Однако, если вы это сделаете:

s = new Sub();
print(s.constructor == Sub);

Это неверно.Это кажется мне запутанным, поскольку конструктор s действительно Sub.Традиционно/лучше ли это делать?

function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sub.prototype.constructor = Sub;

или это не имеет особого значения?

Это было полезно?

Решение

«конструктор» не делает то, что выглядит.Это, помимо его нестандартности, является веской причиной избегать его использования — придерживайтесь экземпляров и прототипов.

Технически:«Конструктор» не является свойством экземпляра «s», это свойство просвечивающего объекта-прототипа «Sub».Когда вы создаете функцию Sub в Mozilla, вы получаете новый объект Sub.prototype по умолчанию, у которого есть «конструктор», указывающий обратно на функцию Sub в качестве любезности.

Однако затем вы заменяете этот прототип новым Base().Исходный прототип по умолчанию со ссылкой на Sub утерян;вместо этого Sub.prototype является экземпляром Base без какого-либо переопределяющего свойства «конструктор».Так:

new Sub().constructor===
Sub.prototype.constructor===
new Base().constructor===
Base.prototype.constructor===
Base

... вплоть до самого базового объекта, прототип которого вы не изменили.

Традиционно/лучше ли это делать?

При работе с объектами/классами JavaScript не существует единого соглашения;система метаклассов каждой библиотеки ведет себя немного по-разному.Я не видел ни одного, который вручную записывал бы «конструктор» в каждый производный класс, но это кажется таким же хорошим решением, как и любое другое, если вы действительно хотите иметь в наличии настоящий конструктор;это также сделает код совместимым с браузерами/движками, которые не предоставляют вам «конструктор».

Однако я бы подумал дать ему другое имя, чтобы избежать путаницы с существующим свойством «конструктор», которое ведет себя по-другому.

Другие советы

Если вы хотите проверить, является ли объект точно экземпляром Sub, используйте instanceof оператор:-

print(s instanceof Sub);

Если вы хотите узнать, является ли объект экземпляром Sub или экземпляром подкласса Sub, используйте isPrototypeOf метод:-

print(Sub.prototype.isPrototypeOf(s));

Ага,

Sub.prototype.constructor = Sub;

давайте использовать экземпляр, но есть лучшее решение.Смотри сюда:,Наследование TDD JS на GitHub , и найдите Паразитарное комбинированное наследование шаблон.Код создан на основе TDD, поэтому вы сможете очень быстро разобраться с ним, а затем просто изменить имена, чтобы начать работу.По сути, это то, что использует YAHOO.lang.extend (источник:сотрудник Yahoo и автор книги Николаса Закаса «Профессиональный JavaScript для веб-разработчиков», 2-е издание, стр. 181).Хорошая книга, кстати (ни в коем случае не связанная с ней!)

Почему?Поскольку классический шаблон, с которым вы работаете, имеет переменные ссылки на статику (если вы создадите var arr = [1,2] в базовом объекте, ВСЕ экземпляры будут иметь возможность чтения/записи и будут «совместно использовать состояние» «arr»!Если вы используете кражу конструктора, вы можете обойти это.Смотрите мои примеры.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top