-3

这两张图的解释 图 1 图 2

编码

showUserProfile: (user_data)->
    console.log "Routers.AppRouter showUserProfile()", user_data
    window.user_profile = user_data

    playlists_both_people = user_profile['playlists']

    my_profile['playlists'].forEach (pl)-> playlists_both_people.push(pl)

    @playlists = new Playlists.Collections.PlaylistsCollection( playlists_both_people )

    $("#app").html( new Playlists.Views.User.ShowView(user_data).render().el )
    @ok()
4

1 回答 1

13

既然每个人都打完了你,我会很好地告诉你你做错了什么。

你有一个简单的引用问题。您从user_data传递给您的函数的对象开始。然后,您再次参考user_data此处的要点:

window.user_profile = user_data

现在您的数据如下所示:

window.user_profile ->-+
                       |
                       +->- {playlists: [ ], ...}
                       |
user_data ----------->-+

然后你在这里做另一个参考user_data.playlists

playlists_both_people = user_profile['playlists']

现在你手上有这个:

window.user_profile ->-+
                       |
                       +->- {playlists: [ ], ...}
                       |      ^
user_data ----------->-+      |
                              |
playlists_both_people --->----+

然后你把一堆东西推到playlists_both_people数组上,想知道为什么它user_data.playlists也会改变。该图告诉您原因:您从未复制任何内容,您只是通过多个变量引用同一条数据。

你正在使用 Backbone,所以你有下划线,也许_.clone可以帮助你:

playlists_both_people = _(user_profile['playlists']).clone()

这将为您提供(与此时相同)的(浅)副本,并且user_profile.playlists下一个不会更改.user_data.playlistsplaylists_both_peopleforEachuser_data

请注意,您仍然可能对window.user_profile. 你不能只用一个_.clone来解决这个可能的问题,你必须分别克隆每个成员,因为_.clone只做浅拷贝。但是,您可能拥有 jQuery 并$.extend支持深度复制,因此这可能是一种选择。

我还建议不要将东西直接放入window. 您最好为您的应用程序设置一个命名空间,例如window.app,然后使用该命名空间:

window.app.user_profile = ...
于 2012-04-16T22:04:33.757 回答