鉴于以下coffeescript代码:
class Animal
constructor: (@name) ->
speak: (things) -> "My name is #{@name} and I like #{things}"
生成:
var Animal = (function() {
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function(things) {
return "My name is " + this.name + " and I like " + things;
};
return Animal;
})();
但为什么这个惯用代码不会生成呢?
var Animal = function Animal(name) {
this.name = name;
};
Animal.prototype.speak = function(things) {
return "My name is " + this.name + " and I like " + things;
};
我知道coffeescript在匿名函数中包含很多东西来控制范围泄漏,但是这里可能会泄漏什么?
答案 0 :(得分:12)
生成的代码可以在Internet Explorer中可靠地具有命名功能。 (在本例中,“Animal”。)如果您只是在顶级范围内使用命名函数,它将与可能存在的任何var Animal =
声明冲突......即使在较低范围内,也会阻止它们出现正确引用。要解决IE错误,我们在类定义中包含函数包装器。
答案 1 :(得分:2)
这是为了支持包括类名的回溯,而不仅仅是在抛出异常时的函数名。(
答案 2 :(得分:2)
CoffeeScript方法也有缩小的优势。
对于大多数合理的类,CoffeeScript生成的闭包会产生较小的缩小输出。
闭包装器是25字节的缩小开销,但 可以避免重复类名 ,节省k * N
个字节(k =字母名称,N NUM-的-参)=。
例如,如果像BoilerPlateThingyFactory
这样的类有2个以上的方法,则闭包装器生成较小的缩小代码。
更详细......
使用闭包的Coffee生成的代码缩小为:
// Uglify '1.js' = 138 bytes (197 w/ whitespace):
var Animal=function(){function e(e){this.name=e}return e.prototype.speak=function(e){return"My name is "+this.name+" and I like "+e},e}();
// with whitespace ("uglifyjs -b"):
var Animal = function() {
function e(e) {
this.name = e;
}
return e.prototype.speak = function(e) {
return "My name is " + this.name + " and I like " + e;
}, e;
}();
ryeguy的替代“惯用”实现缩小了这一点:
// Uglify '2.js' = 119 bytes (150 w/ whitespace):
var Animal=function(t){this.name=t};Animal.prototype.speak=function(e){return"My name is "+this.name+" and I like "+e};
// with whitespace ("uglifyjs -b"):
var Animal = function(t) {
this.name = t;
};
Animal.prototype.speak = function(e) {
return "My name is " + this.name + " and I like " + e;
};
注意名称“Animal”名称在Coffee形式中只存在一次,而在ryeguy的“惯用”变量中N = 2次。现在“动物”只有6个字母,而且只有1个方法,所以这里的咖啡应该输掉25-6 = 19个字节。咨询我的缩小代码,它是138字节到119字节,对于19字节的增量。再添加4种方法,优势将转向咖啡。而且这不仅仅是方法;类常量和其他引用类型也算数。