2011-01-12 64 views
7

考虑下面的CoffeeScript代码:为什么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在匿名函数中封装了很多东西来控制范围泄漏,但是这里可能会泄漏什么?

+3

一个主观的和议论性的近距离投票?真?这是一个有效的问题,询问为什么有必要将函数包装在匿名函数中。 – ryeguy 2011-01-12 16:19:57

回答

12

生成的代码可以在Internet Explorer中可靠地命名函数。 (在这种情况下,“动物”)。如果您只是在顶级作用域使用命名函数,它将与可能存在的任何var Animal =声明发生冲突......即使在较小的作用域中,也会阻止它们被正确引用。为了解决IE错误,我们在类定义中包含了函数包装器。

2

这是为了支持包括类名的回溯,而不是在引发异常时的函数名称。

+0

你能详细说一下吗?我不确定我是否理解这是如何工作的。 – casablanca 2011-01-12 16:39:53

+0

@casablanca - 参见:http://www.javascriptkata。com/2010/05/19/how-to-de-anonymize-your-anonymous-functions /在堆栈跟踪中查看`aonon(),aonon()`和`func1(),func2()` 。 – 2011-01-12 16:49:06

+0

@Sean:这解释了为什么这个函数被命名为`Animal`,但似乎没有解释为什么它被封装在一个匿名函数中。 – ryeguy 2011-01-12 16:58:39

2

CoffeeScript方法也具有缩小的优点。

my other answer

对于最合理的类,由CoffeeScript的所产生的闭合产生较小的缩小的输出。 封闭包装是25个字节缩小的开销,但它节省你重复类名,节省k * N字节(K =字母合名,N =参NUM-的-)。例如,如果像BoilerPlateThingyFactory这样的类具有2+方法,则封闭包装生成较小的缩小代码。



详细...

的咖啡生成的代码使用封闭minifies到:

// 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的另类 “习惯” 实施minifies这个:

// 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”的名称是否存在一次,以及ryeguy的“惯用”变量中N = 2次。现在“动物”只有6个字母,只有1个方法,所以咖啡在这里应该减少25-6 = 19个字节。咨询我的缩小代码,它是138字节到119字节,增量为... 19字节。再添加4种方法,优势将转为咖啡。这不仅仅是方法;类常量和其他参考类型也会计数。