constructor
является обычным свойством объекта-прототипа (с установленным флагом DontEnum
, поэтому он не отображается в циклах for..in
). Если вы замените объект-прототип, свойство constructor
также будет заменено - см. это объяснение для получения дополнительной информации.
Вы можете обойти проблему, вручную установив Obj2.prototype.constructor = Obj2
, но таким образом флаг DontEnum
не будет установлен.
Из-за этих проблем не стоит полагаться на constructor
для проверки типов: вместо этого используйте instanceof
или isPrototypeOf()
.
Андрей Федоров поднял вопрос, почему new
не присваивает свойство constructor
объекту экземпляра. Я предполагаю, что причина этого в следующем:
Все объекты, созданные из одной и той же функции конструктора, имеют общее свойство конструктора, а общие свойства находятся в прототипе.
Настоящая проблема заключается в том, что в JavaScript нет встроенной поддержки иерархий наследования. Есть несколько способов решения этой проблемы (один из них у вас), еще один «в духе» JavaScript будет следующим:
function addOwnProperties(obj /*, ...*/) {
for(var i = 1; i < arguments.length; ++i) {
var current = arguments[i];
for(var prop in current) {
if(current.hasOwnProperty(prop))
obj[prop] = current[prop];
}
}
}
function Obj1(arg1) {
this.prop1 = arg1 || 1;
}
Obj1.prototype.method1 = function() {};
function Obj2(arg1, arg2) {
Obj1.call(this, arg1);
this.test2 = arg2 || 2;
}
addOwnProperties(Obj2.prototype, Obj1.prototype);
Obj2.prototype.method2 = function() {};
Это также делает тривиальное наследование тривиальным.