Я вижу много такого кода:
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;
или это неважно?
Многие фреймворки настраивают свойство constructor, чтобы правильно указывать на конструктор подкласса. У меня есть сообщение, посвященное этой и другим проблемам в коде, который вы указали выше. js-bits.blogspot.com/2010/08/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы хотите проверить, является ли объект в точности экземпляром Sub, используйте оператор instanceof: -
print(s instanceof Sub);
Если вы хотите узнать, является ли объект экземпляром Sub или экземпляром подкласса Sub, используйте метод isPrototypeOf: -
print(Sub.prototype.isPrototypeOf(s));
«конструктор» не делает того, что кажется. Это, помимо его нестандартности, является хорошей причиной избегать его использования - придерживайтесь instanceof и prototype.
Технически: «конструктор» не является свойством экземпляра «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
... вплоть до самого простого объекта, прототип которого вы не меняли.
Is it conventional/better to do this?
При работе с объектами / классами JavaScript нет единого соглашения; система метаклассов каждой библиотеки ведет себя немного по-разному. Я не видел ни одного, который записывал бы «конструктор» в каждый производный класс вручную, но он кажется таким же хорошим решением, как и любое другое, если вы действительно хотите иметь доступный реальный конструктор; он также сделает код совместимым с браузерами / движками, которые не предоставляют вам «конструктор».
Я бы подумал о том, чтобы дать ему другое имя, чтобы избежать путаницы с существующим свойством «конструктор», которое ведет себя иначе.
Ага,
Sub.prototype.constructor = Sub;
давайте использовать instanceof, но есть лучшее решение. Посмотрите здесь:, Наследование TDD JS на GitHub, и найдите шаблон Наследование паразитарных комбинаций. Код написан в TDD, поэтому вы сможете очень быстро его разобрать, а затем просто изменить имена, чтобы начать работу. Это в основном то, что использует YAHOO.lang.extend (источник: сотрудник yahoo и автор статьи Николаса Закаса «Профессиональный JavaScript для веб-разработчиков», 2-е издание, стр. 181). Кстати, хорошая книга (никак не аффилированная!)
Почему? Поскольку классический шаблон, с которым вы работаете, имеет статические ссылочные переменные (если вы создадите var arr = [1,2] в базовом объекте, ВСЕ экземпляры будут иметь чтение / запись и будут "разделять состояние" 'arr'! Если вы используйте кражу конструктора, вы можете обойти это. См. мои примеры.
Я просто провел сравнение через html-страницу как предупреждение (s.constructor == Sub), и оно вернуло true.