Javascript Coffeescript类扩展比主干扩展更膨胀
我才刚刚开始学习咖啡脚本,还没有找到一个确切的答案来解释为什么我应该使用它Javascript Coffeescript类扩展比主干扩展更膨胀,javascript,backbone.js,coffeescript,Javascript,Backbone.js,Coffeescript,我才刚刚开始学习咖啡脚本,还没有找到一个确切的答案来解释为什么我应该使用它 class Model extends Backbone.Model urlRoot: '//some/url' 编译成 Model = (function(_super) { __extends(Model, _super); function Model() { _ref = Model.__super__.constructor.apply(this, arguments
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);
var Model = Backbone.Model.extend({
urlRoot: '//some/url'
});
相对于
Model = Backbone.Model.extend
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);
var Model = Backbone.Model.extend({
urlRoot: '//some/url'
});
我提出这个问题的主要原因是,我所看到的几乎所有例子都使用了前者。然而,与后者相比,它在编译时会产生“更多”的膨胀。我确实读过这篇文章,但答案似乎有所不同。既然您只是在问膨胀的问题,让我们看看一些代码 带有
Backbone.Model.extend的JavaScript
如果打开主干源代码,您将看到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' });
Model extends Backbone.Model
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;
// 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
将其与CoffeeScript代码进行比较。您将看到,当您使用extends
时,一个名为\uu 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);
这里实际发生了什么:
当我们打电话时
var Model = Backbone.Model.extend({urlRoot: '//some/url' });
Model extends Backbone.Model
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;
// 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。如果您已经在使用主干网,并且希望避免在生成的源代码中添加\u extends
函数,请使用Backbone.Model.extend
。如果您不想同时添加主干,那么extends
也会做同样的事情。这么多示例不使用后者的原因是主干网不需要使用CoffeeScript—有一个依赖于外部库的示例是没有意义的。您认为“膨胀”到底是什么?你为什么认为这不好?如果你说的是冗长的代码,那么。。。为什么?这是生成的代码,没关系。@meagar,如果你编写了一个包含许多模型、集合和视图的大型应用程序,那么生成的代码肯定很重要。另外,我希望生成的代码能够被那些还没有学习过Coffeescript的人轻松阅读。@TyroneMichael不,它真的没有,就像在现代桌面应用程序中生成的二进制文件一样。从这些结果来看,每次通过迷你程序运行,每个类的差异大约为17字节。在一个(相当大的)应用程序中,我有大约45个类,相当于765字节。将其与当前的140000字节总数进行比较。担心这是一个微观优化最多。哇,谢谢你的可怕的信息的答案。我一直在开发主干,因为它的早期发布。我只是看了一些结合使用主干和Coffeescript的示例,大多数都使用类示例。如果您有许多模型、集合和视图,则文件大小可以快速增加。比较两个扩展的运行时间-它们相似。这里的关键区别是主干扩展是一个方法调用,而Coffeescript扩展发出代码。这对代码大小有非常不同的影响。你需要知道你在优化什么。我不确定这是否会增加答案的价值,但《主干网》和《咖啡脚本》的作者都是同一位最伟大的杰里米·阿什凯纳斯,因此我怀疑这两个版本的工作方式是否会有很大的不同(如果有)。