coffeescript的N个tip

继续下学习coffeescript中学习到的一些小技巧。

构造函数的参数列表中可以直接指定类的成员变量

constructor: (@a,@b) -> 

这段代码会被翻译为

function A(a, b) {
  this.a = a;
  this.b = b;
}

这样既指定了成员变量又进行了赋值,一举两得。

更复杂一点的用法如下:

constructor:({@a,@b}={},c,@d)->

这里结合使用了@参数和普通参数,这是可以的。同时使用了默认参数与解构。编译后的代码:

function A(arg, c, d) {
  var ref;
  ref = arg != null ? arg : {}, this.a = ref.a, this.b = ref.b;
  this.d = d;
}

在成员函数中引用所属于的类

这其实是一个javascript的tip。

引用所属类,那还不简单,叫啥就写啥呗:

class A
    @static = 'A'

    func: ->
        console.log A.static

new A().func()

这样做会有一个不好的地方,就是如果A类重构的时候修改了名字的话,如果忘记了修改A类中所有调用自己的地方,就要出错咯。而别的语言中使用的多半是selfstatic这种与类名无关特殊变量,所以无此顾虑。

不过也不必顾虑,因为js中,方法的原型中的constructor指向方法本身。而js中的类也不过就是方法本身。所以可以这么写:

class A
    @static = 'A'

    func: ->
        console.log @constructor.static

new A().func()

coffeescript类继承实现原理

coffeescript作为javascript的高级语法糖,提供了同意的类继承方法:直接使用extend即可

TODO

coffeescript中如果定义了子类的构造函数,需要注意的地方

class A
    constructor: ->
        @name = 'A class'

    getName: ->
        console.log @name

class B extends A

a = new A
a.getName()  # A class
b = new B
b.getName()  # A class

B作为A的子类,继承了A的方法和成员变量name

但是如果B类明确定义了构造函数的话:

class B extends A
    constructor: ->
        # xxx

a = new A
a.getName()  # A class
b = new B
b.getName()  # undefined

可以看到,这时,B类中就没有A类的实力变量了。这时因为coffeescript使用的寄生组合式继承,需要在子类的构造函数中调用父类的构造函数,如果你不自定子类的构造函数,coffeescript会自动为你生成一个调用父类构造函数的构造函数,但是如果你自己定义了构造函数的话,coffeescript就无法这么做了。

看生成的js代码就明白了:

如果你没有为B书写构造函数,coffeescript自动生成了一个:

B = (function(superClass) {
    extend(B, superClass);

    function B() {
      return B.__super__.constructor.apply(this, arguments);
    }

    return B;

  })(A);

如果你为B定义了一个空的构造函数:

  B = (function(superClass) {
    extend(B, superClass);

    function B() {}

    return B;

  })(A);

为了完整的继承,如果我们声明了子类的构造函数,需要在最开始显式地调用super()以调用父类的构造函数。

发布了27 篇原创文章 · 获赞 13 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/mazhibinit/article/details/50412631
TIP
今日推荐