Backbone.extend函数如何工作?

时间:2018-09-03 02:34:54

标签: javascript oop backbone.js

我想知道这个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;
  };

为什么将父级添加到子变量?

1 个答案:

答案 0 :(得分:1)

extend具有两个参数protoPropsstaticPropsprotoProps是将分配给Class原型的属性,以便在创建对象的实例时,该对象会将其属性作为其原型链的一部分1staticProps是道具(不适用于通过类创建的对象(使用new),但是可以从类本身访问,例如,通过调用CatClass.defaultMeow

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

在下面的讨论中,我们将称为parent的基类,即我们要将其原型扩展到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方法创建一个新Class,如下所示:以及所有传入的protoProps。从本质上讲,这是_extended原型链`,它作为原型被分配给扩展类。

 child.prototype.constructor = child;

此行起初是令人困惑的,因为我们在上面的条件语句中看到扩展类已经被分配了构造函数。不错,但是,在上一条语句中,当我们做_.create(...)时,我们用基础类的构造函数重写了扩展类的构造函数!现在我们要重新分配它。

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

就像评论中所说的那样,扩展类可以访问***静态属性* __super__中的基类。这是一个便利属性,可从扩展类对象本身访问。那么,在我们之前的示例中,如果从CatClass扩展了一个AnimalClass,则以下条件成立:CatClass.__super__ === AnimalClass

    return child;
  };