coffeeScript學習02

閉包

closure = do ->
  _private = "foo"
  -> _private

console.log(closure()) #=> "foo"

//`do`關鍵詞能夠產生一個`Immediate Function`

(function() {
  var closure;

  closure = (function() {
    var _private;
    _private = "foo";
    return function() {
      return _private;
    };
  })();

  console.log(closure());

}).call(this);
  • 閉包中常常須要綁定this的值給閉包的私有變量,CoffeeScript使用特殊的=>語法省去了這個麻煩
element = document.getElementById('id')
@clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => @clickHandler(e)

//
(function() {
  var element;

  element = document.getElementById('id');

  this.clickHandler = function() {
    return alert("clicked");
  };

  element.addEventListener("click", (function(_this) {
    return function(e) {
      return _this.clickHandler(e);
    };
  })(this));

}).call(this);

擴展

  • 在js中,全部的對象都是開放的,有時候會擴展原有對象的行爲
String::expends = -> @replace /_/g, "-"

//
(function() {
  String.prototype.expends = function() {
    return this.replace(/_/g, "-");
  };

}).call(this);

class Person 
  _private = 'value'  //private
  @sex: true          //Person.sex
  @log: ->            //Person.log
    console.log 0

  @create: (name, age)->   
    new Person(name,age)

  constructor: (@name, @age) ->
  log: ->                     //instance.log
    console.log @name
  tell: =>                    //instance.tell
    console.log @age

jinks = new Person('jinks', 23)
jack = Person.create('jack', 22)
  • constructor是構造函數,必須用這個名稱ruby

  • 構造函數中若是給實例變量賦值,直接將@name寫在參數中便可,等價於在函數體中的@name = name閉包

  • 對於實例方法,要用=>來綁定this,這樣能夠做爲閉包傳遞iphone

類的繼承

class Gadget
  constructor: (@name) ->
  sell: =>
    "buy #{@name}"

class Iphone extends Gadget
  constructor: -> super("iphone")
  nosell: =>
    "Don't #{@sell()}"

iphone = new Iphone
iphone.nosell()
  • 使用extends關鍵字能夠繼承父類中的全部實例屬性,好比sell
  • super方法能夠調用父類的同名方法
  • 若是不覆蓋constructor,則她被子類默認調用

混入(Mixin)

在ruby語言中的Mixin,可以讓你的類得到多個模塊的方法,能夠說是對多重繼承一種很好的實現函數

class Module
  @extend: (obj) ->
    for key, value of obj
      @[key] = value

  @include: (obj) ->
    for key, value of obj
      @::[key] = value

classProperties = 
  find: (id) ->
    console.log ("find #{id}")

instanceProperties = 
  save: ->
    console.log ("save")

class User extends Module
  @extend classProperties
  @include instanceProperties

user = User.find
user = new User
user.save()
  • 繼承了Module的類才能夠Mixin,固然,這裏也能夠用組合或者直接爲js的構造函數作Monkey patching
  • classProperties是類成員模塊,使用@extend來Mixin,實現是簡單的拷貝對象的屬性
  • instanceProperties是實例成員模塊,使用@include來Mixin,實現是拷貝對象原型的屬性
  • 須要指出的是,這裏的拷貝是引用拷貝,有可能外部會更改被Mixin的模塊內部值,更好的方法是深層值拷貝(clone)
相關文章
相關標籤/搜索