2013-02-08 51 views
0

[更新] 我的問題可能還不夠清楚...... 的,我想怎樣進一步澄清做到:有兩個object.property和object.property.method()提供的CoffeeScript

我找回對象像這樣的:

p = 
    name: 
    first: 'alan' 
    last: 'smith' 

,並希望建立一個結構(一類,多類?)要能寫出這樣的事情最終:

person.name # alan smith 
person.name.toCap() #Alan Smith 
person.name.first # alan 
person.name.first.toCap() # Alan 
person.name.last # smith 
person.name.last.toCap() # Smith 
... 

so:

  1. 有沒有辦法同時擁有person.name和person.name.first?
  2. 有沒有更好的方法來擴展對象屬性的方法,而不是像字符串那樣擴展本機類型?

[原創]

尋找咖啡這樣做的正確方法:

console.log person.name.last #smith 
console.log person.name.last.capitalize() # SMITH 
console.log person.name.last.initial() # S 

我想出了以下的解決方案,但希望確保這是要走的路...

String::toCap = (remainingToLower=false) -> 
    @[0].toUpperCase() + if remainingToLower then @[1..-1].toLowerCase() 
              else @[1..-1] 
Number::random = (percent) -> 
    offset = @ * percent/100 
    parseInt(Math.floor(Math.random() * 2 * offset) + @ - offset) 

class Name 
    constructor: (@first, @last) -> 

class Person 
    constructor: (@name, @age) -> 
    toString:() => "#{@name.first.toCap(true)} #{@name.last.toCap(true)} 
        (#{@age.random(25)})" 

# GO ---------------------------> 

p = new Person(new Name, 18) 
p.name.first = 'alaN' 
p.name.last = 'smith' 

console.log "#{p.toString()}" 

感謝您的反饋ACK。

Plunk Here

回答

0

語境
我有這樣的原始數據:

data = 
    name: 
    first: 'alan' 
    last: 'smith' 
    age: 18 
    address: [ 
    { 
     name: 'work' 
     street: '1600 amphitheatre parkway' 
     city: 'mountain view' 
     zip: 'CA 94043' 
    },{ 
     name: 'home' 
     street: '1 infinite loop' 
     city: 'cupertino' 
     zip: 'CA 95014' 
    }] 

而且要創建一個結構來操作這樣我的數據:此外

p = New Person(data) 
console.log """ 
    #{p}      # alan smith (18), 2 address lines 
    #{p.name},     # alan smith 
    #{p.name.first},   # alan 
    #{p.address}    # 2 address lines 
    #{p.address.work}   # 1600 amphitheatre parkway, mountain view, CA 94043 
    #{p.address.work.street} # 1600 amphitheatre parkway 
""" 

,我希望能夠將自定義方法應用於任何成員。 例如,假設toCap()是一個大寫字符串的每個字的方法:

console.log """ 
    #{p.name.toCap()},    # Alan Smith 
    #{p.name.first.toCap()}   # Alan 
    #{p.address.work.toCap()}   # 1600 Amphitheatre Parkway, Moutain View, CA 94043 
    #{p.address.work.street.toCap()} # 1600 Amphitheatre Parkway 
""" 

(見本Plunk爲全碼)

  • 使用嵌套類

    class Person 
        constructor: (data) -> 
        @name = new Name(data.name) 
        @address = new AddressList(data.address) 
    
  • 名創建成員動態

    class AddressList 
        constructor: (list) ->  
        @[addr.name] = new Address(addr) for addr in list  
    
  • 包裹你的屬性和使用基類而不是擴展原生對象

    class StringProperty 
        constructor: (@_value) -> 
        toString: => 
        @_value 
        toCap: (remainingToLower=false) => 
        _words = @_value.split ' ' 
        (@_toCap(w,remainingToLower) for w in _words).join ' '  
        _toCap : (s, r) -> 
        s[0].toUpperCase() + if r then s[1..-1].toLowerCase() else s[1..-1] 
    

    ...並直接使用它們...

    class Name 
        constructor: (name) -> 
        @first = new StringProperty(name.first) 
        @last = new StringProperty(name.last) 
        toString: => 
        "#{@first} #{@last}" 
        toCap: => 
        "#{@first.toCap()} #{@last.toCap()}" 
    

    .. 。或動態創建成員:

    @[k] = new StringProperty(data[k]) for k of data when k in Address.fields 
    
  • 不要忘記覆蓋toString()如上

相關問題