CoffeeScript攻略2.5:鏈式呼叫物件

CoffeeScript Cookbook發表於2011-11-19

問題

你想呼叫一個物件上的多個方法,但不想每次都引用該物件。

方案

在每次鏈式呼叫後返回this(即@)物件

class CoffeeCup
    properties:
        strength: 'medium'
        cream: false
        sugar: false
    strength: (newStrength) ->
        @properties.strength = newStrength
        @
    cream: (newCream) ->
        @properties.cream = newCream
        @
    sugar: (newSugar) ->
        @properties.sugar = newSugar
        @

morningCup = new CoffeeCup()

morningCup.properties # => { strength: 'medium', cream: false, sugar: false }

eveningCup = new CoffeeCup().strength('dark').cream(true).sugar(true)

eveningCup.properties # => { strength: 'dark', cream: true, sugar: true }

討論

jQuery庫使用類似的手段從每一個相關的方法中返回選擇符物件,並在後續方法中通過調整選擇的範圍修改該物件:

$('p').filter('.topic').first()

對我們自己物件而言,一點點超程式設計就可以自動設定這個過程並明確宣告返回this的意圖。

addChainedAttributeAccessor = (obj, propertyAttr, attr) ->
    obj[attr] = (newValues...) ->
        if newValues.length == 0
            obj[propertyAttr][attr]
        else
            obj[propertyAttr][attr] = newValues[0]
            obj

class TeaCup
    properties:
        size: 'medium'
        type: 'black'
        sugar: false
        cream: false

addChainedAttributeAccessor(TeaCup.prototype, 'properties', attr) for attr of TeaCup.prototype.properties

earlgrey = new TeaCup().size('small').type('Earl Grey').sugar('false')

earlgrey.properties # => { size: 'small', type: 'Earl Grey', sugar: false }

earlgrey.sugar true

earlgrey.sugar() # => true

enter image description here

相關文章