Проблема в том, что вы не можете легко создать объект-прототип для B
, так как вызвать конструктор A
невозможно. Это связано с тем, что параметры конструктора неизвестны до выполнения new B
. Вам нужна фиктивная функция конструктора для создания прототипа для B
, который ссылается на прототип A
.
B.prototype = (function(parent){
function protoCreator(){};
protoCreator.prototype = parent.prototype;
// Construct an object linking to A.prototype without calling constructor of A
return new protoCreator();
})(A);
После того как вы настроили объект-прототип для B
, вы должны убедиться, что вызываете конструктор A
в конструкторе B
.
function B(x, y) {
// Replace arguments by an array with A's arguments in case A and B differ in parameters
A.apply(this, arguments);
}
Теперь вы должны иметь возможность создать экземпляр B
, позвонив по номеру new B(x, y)
.
Полный список параметров, включая проверку параметров в A
, см. a jsFiddle .
В исходном коде вы устанавливаете B.prototype.constructor = B
. Я не понимаю, почему вы это делаете. Свойство constructor
не влияет на иерархию наследования, за которую отвечает свойство prototype
. Если вы хотите, чтобы именованный конструктор содержался в свойстве constructor
, вам нужно немного расширить код сверху:
// Create child's prototype – Without calling A
B.prototype = (function(parent, child){
function protoCreator(){
this.constructor = child.prototype.constructor
};
protoCreator.prototype = parent.prototype;
return new protoCreator();
})(A, B);
Используя первое определение B.prototype
, вы получите следующие результаты:
var b = new B(4, 6);
b.constructor // A
console.info(b instanceof A); // true
console.info(b instanceof B); // true
С расширенной версией вы получите:
var b = new B(4, 6);
b.constructor // B
console.info(b instanceof A); // true
console.info(b instanceof B); // true
Причина различного вывода в том, что instanceof
следует за всей цепочкой прототипов b
и пытается найти соответствующий объект-прототип для A.prototype
или B.prototype
(в другом вызове). Прототип b.constructor
относится к функции, которая использовалась для определения прототипа экземпляров. Если вам интересно, почему он не указывает на protoCreator
, это потому, что его прототип был перезаписан с A.prototype
во время создания B.prototype
. Расширенное определение, как показано в обновленном примере , исправляет это свойство constructor
, чтобы указывать на более подходящую (потому что, вероятно, более ожидаемую) функцию.
Для повседневного использования я бы рекомендовал отказаться от идеи полного использования свойства constructor
экземпляров. Вместо этого используйте instanceof
, поскольку его результаты более предсказуемы / ожидаемы.