Конструкторы и наследование в JavaScript - PullRequest
3 голосов
/ 19 марта 2010

Это о "наследовании" в JavaScript.

Предположим, я создаю конструктор Bird () и еще один, называемый Parrot (), который я делаю, чтобы "наследовать" свойства Bird, назначая его экземпляр прототипу Parrot, как показано в следующем коде:

function Bird() {
    this.fly = function(){};
}

function Parrot() {
    this.talk = function(){ alert("praa!!"); };
}
Parrot.prototype = new Bird();

var p = new Parrot();

p.talk(); // Alerts "praa!!"
alert(p.constructor); // Alerts the Bird function!?!?!

После того, как я создал экземпляр Parrot, почему свойство .constructor его Bird (), а не Parrot (), который является конструктором, который я использовал для создания объекта?

Ответы [ 2 ]

3 голосов
/ 20 марта 2010

Prototype - это объект, как и все остальное в JavaScript, и назначение объектов осуществляется по ссылке. Вы только что назначили новую птицу прототипу попугая, поэтому прототип попугая теперь является экземпляром птицы. И птичий конструктор - Птица.

Вы можете исправить это с помощью строки

Parrot.prototype.constructor = Parrot;

Другой способ сделать это - назначить клон прототипа Bird для Parrot.prototype

function deepClone(obj) {
    var clone = {};
    for(var i in obj) {
        if(typeof(obj[i])==="object") {
            clone[i] = deepClone(obj[i]);
        } else {
            clone[i] = obj[i];
        }
    }
    return clone;
}


Parrot.prototype = deepClone(Bird.prototype);
Parrot.prototype.constructor = Parrot;

Я предпочитаю это, потому что:

1) это экономит создание произвольного экземпляра птицы (что, если что-то считает, если было создано много птиц)

2) Что, если конструктор Bird принял аргумент, который был проверен в теле конструктора? затем вызов:

Parrot.prototype = new Bird();

может вызвать нулевой указатель

1 голос
/ 19 марта 2010

Конструктор ссылается на функцию, которая создает прототип экземпляра (а не экземпляр).

...