2012-02-19 52 views
1

我不太清楚对不同变量的使用中的CoffeeScript变量类型的CoffeeScript

class Cow 
    @utters = 1 

    constructor: (@name) -> 

    mutate:-> 
    alert @utters 

    heads: 1 
    feet = 9 


c = new Cow 

从我的调查,似乎heads是公共和feet是私人的。当找出nameutters时,我的困惑就出现了。对于name它或多或少地编译为this.name = name,而对于utters它编译为Cow.utters = 1

所以我的问题是。 utters的范围是什么,应该如何访问? name的范围是什么,应该如何访问?

回答

10

让我们一个一个来看看这些。

对于first one

class Cow 
    @utters = 1 

this是类本身,当你打@utters = 1所以这@utters是那种一类变。 JavaScript版本是这样的:

var Cow = (function() { 
    function Cow() {} 
    Cow.utters = 1; 
    return Cow; 
})(); 

子类将能够看到这个,但他们将有自己的副本;所以,对于这个:

class CowCow extends Cow 
    m: -> 
    CowCow.utters = 11 

CowCow.utters开始为1,但将是11 (new CowCow).m()Cow.utters后会留在1场一路过关斩将。

second one

class Cow 
    heads: 1 

本质上是一个默认实例变量; JavaScript版本是这样的:

var Cow = (function() { 
    function Cow() {} 
    Cow.prototype.heads = 1; 
    return Cow; 
})(); 

Cow.prototype.heads = 1;部分意味着heads继承并连接到实例而不是类。

其结果是这样的:

class Cow 
    heads: 1 

class CowCow extends Cow 
    m: -> 
    alert @heads 
    @heads = 11 

(new CowCow).m() 
alert (new Cow).heads 

警报1的两倍。

third one

class Cow 
    feet = 9 
    m: -> alert feet 

是另一个类型的类变量,但是这是一个非常私人的:feet不继承,不可见的子类,并且对外界不可见。 JavaScript版本是这样的:

var Cow = (function() { 
    var feet = 9; 
    function Cow() {} 
    Cow.prototype.m = function() { return alert(feet) }; 
    return Cow; 
})(); 

,所以你可以看到:

  1. feet将是可见的所有Cow方法。
  2. 所有Cow实例将共享相同的feet
  3. feet是不公开的,你不能在没有调用Cow方法(类或实例,要么)的情况下得到它。
  4. feet对子类不可见,因为它不是该类的属性,也不在prototype中(因此它不会被子类的实例继承)。

摘要@utters是那种传统的类变量,heads是默认值的公共实例变量,feet是排序的私有类变量。

+0

哇。非常感谢详细的解释。它真的帮了大忙! – Alexis 2012-02-19 10:04:40

+0

很好的解释! – Richard 2015-11-12 13:24:48