Вопрос наследования JavaScript - PullRequest
       21

Вопрос наследования JavaScript

3 голосов
/ 02 февраля 2011

Это функция расширения из книги "Pro JavaScript Design Patterns"

function extend(subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor) {
       superClass.prototype.constructor = superClass;
    }
}

У меня проблемы с первыми 3 строками ... Создает пустую функцию, а затем устанавливает прототип F.в superClass.prototype, что означает (для 2 новых функций конструктора, например, foo, bar и foo extends bar), что F.prototype будет иметь свойство конструктора: bar и proto : Object или нет?И в строке 3: subClass.prototype = new F ();случается что-то, чего я не могу понять .. Почему наследование происходит здесь, когда F [[Prototype]] является Object?


Каковы различия между первыми 3 строками и

subClass.prototype = new superClass();

когда код выполняется?Я имею в виду, как первый делает то же самое, что и второй.


Просто добавим, что есть вызов конструктора суперкласса в подклассе.Вызов "className" .superclass.constructor.call (this);

Ответы [ 3 ]

1 голос
/ 02 февраля 2011
function extend(subClass, superClass) {

    // create a new empty function
    var F = function() {}; 

    // set the prototype of that function to prototype object of the superclass
    F.prototype = superClass.prototype;

    // now set the prototype of the subClass to a new instance of F
    // this is done so that subClass.prototype.foo = does not affect
    // superClass.prototype.foo
    // if you don't do this, changes to one subClass will affect superClass and all
    // other subClasses of superClass
    subClass.prototype = new F();

Примечание: subClass.prototype = new superClass() вызовет конструктор и будет использовать возвращенный новый объект в качестве прототипа.В результате свойства superClass сами по себе появятся в цепочке прототипов (поскольку этот экземпляр является объектом-прототипом).

0 голосов
/ 04 февраля 2011

В качестве альтернативы вы можете рассмотреть прототип библиотеки javascript.Включает наследование.

Библиотека Javascript прототипа

Вот пример из документации по прототипу.

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },

  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});

// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});

var ringneck = new Snake("Ringneck");
ringneck.speak();
//-> alerts "Ringneck says: hissssssssss!"

var rattlesnake = new Snake("Rattler");
rattlesnake.speak();
//-> alerts "Rattler says: hissssssssss!"

Вот страница документации

0 голосов
/ 02 февраля 2011

У нас есть конструкторы:

F, Super & Sub.

У нас есть объекты f, super, & sub, которые созданы с использованием указанных конструкторов.

т.е. f = new F, super = new Super, sub = new Sub

Мы знаем f.__proto__ === super.__proto__ === Super.prototype из строки 2

Из строки 3 мы видим, что sub.__proto__ === f & sub.__proto__.__proto__ === Super.prototype

Также у нас есть Sub.superClass === Super.prototype из строки 5.

и из строк 4 и 6 можно сказать, что sub.constructor === Sub & super.constructor === Super

Причина, по которой мы можем вызвать new F перед строкой 3 перед строкой 7, заключается в том, что в строке 7 установлено значение

f.__proto__.constructor === Super, где f.constructor уже Sub. в основном строка 7 очищает Super и не должна влиять на Sub, потому что вы никогда не должны вызывать .__proto__.constructor в реальном коде.

Эта конкретная функция explicity не вызывает Super как функцию, а только удостоверяется, что объекты, построенные через Sub, имеют Super.prototype в своей цепочке.

...