Класс Coffeescript распространяется на большее количество раздувов, чем Backbone. - программирование
Подтвердить что ты не робот

Класс Coffeescript распространяется на большее количество раздувов, чем Backbone.

Я только начинаю изучать Coffeescript и не могу найти определенного ответа на вопрос, почему я должен использовать

class Model extends Backbone.Model
    urlRoot: '//some/url'

компилируется в

Model = (function(_super) {
    __extends(Model, _super);

    function Model() {
        _ref = Model.__super__.constructor.apply(this, arguments);
        return _ref;
    }

    Model.prototype.urlRoot = '//some/url';

    return Model;

})(Backbone.Model);

в отличие от

Model = Backbone.Model.extend
    urlRoot: '//some/url'

компилируется в

var Model = Backbone.Model.extend({
    urlRoot: '//some/url'
});

Основная причина, о которой я прошу, состоит в том, что первая используется почти во всех примерах, на которые я смотрел. Тем не менее, он создает "много" больше раздутия при компиляции в противоположность последнему. Я прочитал этот question, но ответы, похоже, отличаются.

4b9b3361

Ответ 1

Поскольку вы просите только о раздувании, давайте посмотрим на какой-то код.

JavaScript с Backbone.Model.extend

Если вы откроете исходный код Backbone, вы увидите, что функция extend следующая:

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

    if (protoProps && _.has(protoProps, 'constructor')) { // _.has comes from
      child = protoProps.constructor;                     // underscore, even 
    } else {                                              // more 'bloat'
      child = function(){ return parent.apply(this, arguments); };
    }

    _.extend(child, parent, staticProps);                // more underscore

    var Surrogate = function(){ this.constructor = child; };
    Surrogate.prototype = parent.prototype;
    child.prototype = new Surrogate;

    if (protoProps) _.extend(child.prototype, protoProps);

    child.__super__ = parent.prototype;

    return child;
  };

Что на самом деле происходит здесь:

Когда мы вызываем

var Model = Backbone.Model.extend({urlRoot: '//some/url' });

получаем что-то вроде:

  // Create new constructor which calls the parent constructor
  var Model;
  if (({}).hasOwnProperty.call({urlRoot: '//some/url' }, 'constructor') {
      // this is false so...                    
  } else {
      Model = function(){ return Backbone.Model.apply(this, arguments); };
  }

  // Set up prototype chain
  var Surrogate = function(){ this.constructor = model; };
  Surrogate.prototype = Backbone.Model.prototype;
  Model.prototype = new Surrogate;

  // Add properties to the child prototype
  // Same as:
  // Model.prototype.urlRoot = '//some/url';
  _.extend(Model.prototype, { urlRoot: '//some/url' });

  // Set the magical __super__ property
  Model.__super__ = Backbone.Model.prototype;

CoffeeScript с extends

Сравните это с кодом CoffeeScript. Вы увидите, что при использовании extends в начало файла добавляется волшебная функция под названием __extends, которая (при форматировании) выглядит так:

__extends = function(child, parent) { 
    for (var key in parent) { 
        if (__hasProp.call(parent, key)) 
            child[key] = parent[key]; 
    }

    function ctor() { this.constructor = child; } 
    ctor.prototype = parent.prototype; 
    child.prototype = new ctor(); 

    child.__super__ = parent.prototype; 

    return child; 
};

который объединен с сгенерированным JS:

var Model = (function(_super) {
    __extends(Model, _super);

    function Model() {
        _ref = Model.__super__.constructor.apply(this, arguments);
        return _ref;
    }

    Model.prototype.urlRoot = '//some/url';

    return Model;

})(Backbone.Model);

Что на самом деле происходит здесь:

Когда мы вызываем

Model extends Backbone.Model
    urlRoot: '//some/url'

получаем что-то вроде:

// Create new constructor which calls the parent constructor
var Model = function () {
    return Model.__super__.constructor.apply(this, arguments);
}

// Copy static properties from Backbone.Model to Model
for (var key in Backbone.Model) {
    if (__hasProp.call(Backbone.Model, key)) 
        Model[key] = Backbone.Model[key]; 
}

// Set up prototype chain
function ctor() { this.constructor = Model; } 
ctor.prototype = Backbone.Model.prototype; 
Model.prototype = new ctor(); 

// Add properties to the child prototype
Model.prototype.urlRoot = '//some/url';

// Set the magical __super__ property
Model.__super__ = Backbone.Model.prototype; 

Что мы видим?

Они выглядят довольно похожими, не так ли?

CoffeeScript - это просто JavaScript. Если вы уже используете Backbone и хотите избежать добавления функции __extends в сгенерированном источнике, используйте Backbone.Model.extend. Если вы хотите не добавлять в Backbone все вместе, то extends делает практически то же самое. Причина, по которой так много примеров не использует последний, заключается в том, что Backbone не требуется использовать CoffeeScript - просто не имеет смысла иметь пример, который опирается на внешнюю библиотеку.