Как именно работает функция Backbone.extend? - PullRequest
0 голосов
/ 03 сентября 2018

Я хотел бы знать, как эта функция 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 голосов
/ 05 сентября 2018

extend принимает два параметра protoProps и staticProps. protoProps - это свойства, которые будут назначены прототипу Class, чтобы при создании экземпляра объекта это свойство было частью его цепочки прототипов 1 . staticProps - это реквизиты, которые недоступны для объектов, созданных из класса (используя 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.walk является методом в цепочке прототипов для AnimalClass, _.create(parent.prototype, protoProps) создаст новый класс с методом walk в этой цепочке прототипов нового класса, а также все переданные protoProps in. Это, по сути, _extended prototype chain`, и он назначается расширенному классу, как и его прототип.

 child.prototype.constructor = child;

Эта строка сначала сбивает с толку, поскольку в приведенном выше условном выражении мы видели, что расширенному классу уже был назначен конструктор. Да, это так, но в последнем утверждении, когда мы сделали _.create(...), мы переписали конструктор расширенного класса конструктором базового класса! Теперь мы переназначаем это.

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

Как сказано в комментарии, расширенный класс имеет доступ к базовому классу в статическом свойстве *** * __super__. Это удобное свойство, доступ к которому осуществляется из самого объекта Extended Class. В нашем предыдущем примере, если CatClass расширен от AnimalClass, то верно следующее: CatClass.__super__ === AnimalClass.

    return child;
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...