JavaScript继承问题

时间:2011-02-02 18:12:31

标签: javascript inheritance prototype extend

这是“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;
    }
}

前三行有问题...它创建一个空函数,然后将F.prototype设置为superClass.prototype,这意味着(对于2个新的构造函数,例如foo,bar和foo extends bar)F .prototype将有一个构造函数属性:bar和 proto :对象是不是? 第3行:subClass.prototype = new F();发生了一些我无法理解的事情。当F [[Prototype]]是对象时,为什么继承会发生?


前3行和

之间有什么区别?
subClass.prototype = new superClass();

代码执行时?我的意思是第一个与第二个相同。


只需要添加,就可以调用subClass中的superClass构造函数。 调用是“className”.superclass.constructor.call(this);

3 个答案:

答案 0 :(得分:1)

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本身的属性会出现在原型链上(因为该实例是原型对象)。

    // set the constructor, this indicates that 'subClass' is a function
    subClass.prototype.constructor = subClass;

    // add a property to indicate what the superClass is
    // this way one can call super methods via this.superclass.something
    subClass.superclass = superClass.prototype;

    // in case the superClass was an object...
    if(superClass.prototype.constructor == Object.prototype.constructor) {

       // change the constructor?
       // no idea why they do this here
       // this introduces a side effect to the function
       superClass.prototype.constructor = superClass;
    }
}

答案 1 :(得分:0)

我们有施工人员:

FSuper& Sub

我们有对象fsuper和&使用所述构造函数创建的sub

即。 f = new Fsuper = new Supersub = new Sub

我们知道第2行的f.__proto__ === super.__proto__ === Super.prototype

从第3行我们可以看到sub.__proto__ === f& sub.__proto__.__proto__ === Super.prototype

我们也从第5行开始Sub.superClass === Super.prototype

并从第4行& 6我们可以说sub.constructor === Sub& super.constructor === Super

我们可以在第7行之前第3行调用new F的原因是因为第7行设置了

f.__proto__.constructor === Super f.constructor已经Sub。基本上第7行正在清理Super,根本不应影响Sub,因为您不应该在实际代码中调用.__proto__.constructor

此特定函数明确表示不会将Super作为函数调用,但只能确保通过Sub构造的对象在其链中具有Super.prototype

答案 2 :(得分:0)

作为替代方案,您可以考虑原型javascript库。它包括继承。

Prototype Javascript Library

以下是原型文档中的示例。

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!"

Here is the documentation page