Backbone.extend函数究竟是如何工作的?

问题描述 投票:2回答:1

我想知道这个extend函数在Backbone.js中是如何工作的。请在内部帮助我完成它究竟在做什么。

var extend = function(protoProps, staticProps) {
    var parent = this;
    var child;

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call the parent constructor.
    if (protoProps && _.has(protoProps, "constructor")) {
      child = protoProps.constructor;
    } else {
      child = function() {
        return parent.apply(this, arguments);
      };
    }

    // Add static properties to the constructor function, if supplied.
    _.extend(child, parent, staticProps);

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function and add the prototype properties.
    child.prototype = _.create(parent.prototype, protoProps);
    child.prototype.constructor = child;

    // Set a convenience property in case the parent's prototype is needed
    // later.
    child.__super__ = parent.prototype;

    return child;
  };

这里为什么父项被添加到子变量?

javascript oop backbone.js
1个回答
1
投票

extend采取两个参数protoPropsstaticPropsprotoProps是将分配给Class原型的属性,因此当您创建对象的实例时,该对象将该属性作为其原型chain1的一部分。 staticProps是从类创建的对象不可用的道具(使用new),但可以从类本身访问,例如,通过调用CatClass.defaultMeow

var extend = function(protoProps, staticProps) {
    var parent = this;
    var child;

在下面的讨论中,parent是我们称之为Base Class的类,我们想要扩展到child的原型类,在这里我们称之为扩展类。

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call the parent constructor.
    if (protoProps && _.has(protoProps, "constructor")) {
      child = protoProps.constructor;

如果protoProps是一个函数,或者有一个constructor属性(这是在类上调用new时被调用的属性(作为方法))。

    } else {
      child = function() {
        return parent.apply(this, arguments);
      };
    }

如果没有,扩展类将使用父级的constructor(当你调用new时,它将调用父级的constructor方法)。

    // Add static properties to the constructor function, if supplied.
    _.extend(child, parent, staticProps);

_.extend(target, src1,...,srcN)和UnderscoreJS方法将源对象属性的浅表副本复制到目标对象。这里复制了所有父(静态)属性,所有属性都传递给staticProp对象(如果提供)到新的扩展类。

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function and add the prototype properties.
    child.prototype = _.create(parent.prototype, protoProps);

这可能是Backbone.extend例程中最重要的功能:这是扩展类“继承”基类的原型链的地方。例如,如果AnimalClass.prototype.walkAnimalClass原型链中的一个方法,_.create(parent.prototype, protoProps)将在这个新的Class原型链中创建一个带有walk方法的新类,以及传入的所有protoProps。这实际上是_extended原型链`并将其分配给扩展类,因为它是原型。

 child.prototype.constructor = child;

由于我们在上面的条件语句中看到扩展类已经分配了一个构造函数,因此这行首先令人困惑。嗯,确实如此,但是在最后一个声明中,当我们执行_.create(...)时,我们用Base Class的构造函数覆盖了Extended Class的构造函数!现在我们重新分配它。

    // Set a convenience property in case the parent's prototype is needed
    // later.
    child.__super__ = parent.prototype;

与评论说的一样,扩展类可以访问***静态属性* __super__中的基类。它是一个方便的属性,可以从Extended Class对象本身访问。在我们之前的例子中,如果aCatClassAnimalClass扩展,那么以下是真的:CatClass.__super__ === AnimalClass

    return child;
  };
© www.soinside.com 2019 - 2024. All rights reserved.