0

[更新]私の質問は十分に明確ではないかもしれません...私が達成したいことのさらなる明確化:

次のようなオブジェクトを取得します。

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

そして、最終的にこのようなものを書くことができるように構造(1つのクラス、複数のクラス?)を作成したい:

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
...

それで :

  1. person.nameとperson.name.firstの両方を持つ方法はありますか?
  2. Stringのようなネイティブタイプを拡張するよりも、メソッドを使用してオブジェクトプロパティを拡張するより良い方法はありますか?

[オリジナル]

コーヒーでこれを行う正しい方法を探しています:

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()}"

ご意見をいただきありがとうございます。

ここにプランク

4

1 に答える 1

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  
"""

解決策(完全なコードについては、このプランクを参照してください)

  • ネストされたクラスを使用する

    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()をオーバーライドすることを忘れないでください

于 2013-02-11T22:21:59.850 に答える