2

いくつかの API データを繰り返し処理し、API のデータを Coffeescript オブジェクトにマッピングしています。私が困惑しているのは、これらの 2 つの console.log ステートメントの間でそのデータの一部だけが消える理由です。

items = (for item in @apiFeedPage.items
         fi = new API.FeedItem(item, @apiFeedPage.instance_url)
         console.log fi.comments.comments
         window.API.itemHash[fi.id] = fi  #save for later usage
         fi )       
console.log items[0].comments.comments

上記では、最初の console.log が期待どおりのコメントを出力します: fi.comments.comments は Comment オブジェクトの配列と同じです (Comments は FeedItem のプロパティです)が割り当てられていない - コメントなしで API 応答に対して Comment コンストラクターが実行されたかのように。

コンストラクタは次のようになります。

class API.FeedItem extends API.FeedComponent 
  # instance vars
  comments: {}

  constructor: (data, instance_url) ->
    super(data, instance_url)
    @parent = new API.User( data.parent )
    @comments.comments = (new API.Comment(api_comment) for api_comment in data.comments.comments)   
    @comments.total = data.comments.total
    @comments.nextPageUrl = data.comments.nextPageUrl

そして、コンストラクター内で @comments.comments が適切に割り当てられていることを確認しました。これは、最初の console.log ステートメントに期待されるオブジェクトがあるため、期待どおりです。上記のコードの最初のブロックは、太い矢印を使用して Ajax コールバック関数に配置されているため、これが「this」のコンテキストを失うことに関係しているという最初の疑いは当てはまらないようです。ある...

2 番目のステートメントで items[0].comments.comments が [] と等しい理由について何か考えはありますか?

4

2 に答える 2

3

data.comments.commentsコンストラクター内の最後API.FeedItemは空だと思います。それ@comments.comments[]. しかし、次のように尋ねます。

最後のdata.comments.comments値が変わるのはなぜitems[0]ですか?

答えは簡単です。

class API.FeedItem extends API.FeedComponent 
  # instance vars
  comments: {}

comments = { }プロトタイプにアタッチされ、API.FeedItemしたがって のすべてのインスタンスによって共有される単一のオブジェクトを作成しますAPI.FeedItem。つまり、コメントは嘘であり、インスタンス変数ではありません。

あなたの状況にこの単純化された類似物を考慮してください:

class AFI
  comments: { }
  constructor: (n) ->
    @comments.comments = [ 1 .. n ]

fitems = [ 1 .. 4 ]
items = (new AFI(i) for i in fitems)
console.log item.comments for item in items

おそらく , , が表示されることを期待して[1][1,2]ますが[1,2,3]、代わりに[1,2,3,4]4 つの同一[1,2,3,4]の s が表示されます: http://jsfiddle.net/ambiguous/hf9zL/

@commentsインスタンスごとに初期化するようにクラスを修正する場合:

class AFI
  constructor: (n) ->
    @comments = { }
    @comments.comments = [ 1 .. n ]

次に、期待している[1], [1,2],が表示されます。[1,2,3][1,2,3,4]

デモ: http://jsfiddle.net/ambiguous/qs9Zy/

あなたも投げることができます

console.log items[0].comments.comments == items[1].comments.comments
console.log [1] == [1]

配列が実際には同じ配列であることを確認します。追加の比較は、オブジェクトの内容ではなくオブジェクトを実際に比較して[1] == [1]いることを証明することです(つまり、CoffeeScript のものは JavaScript のものです)。=======

経験則: クラス定義でインスタンス変数を定義しようとせず、コンストラクターで定義してください。

于 2012-05-15T02:38:30.933 に答える