为了简化我遇到的问题,我提出了以下示例。
var ViewModel = function() {
this.self = this;
self.test = ko.observableArray([]);
self.test2 = ko.observableArray([]);
self.test2.push('1');
self.test.push({
'foo':self.test2()
});
console.log('the following console.log should output an object with foo : [1]');
console.log(self.test());
self.test2.push('2');
self.test.push({
'foo2':self.test2()
});
console.log('this console.log should have two objects, the first one with foo : [1] and the second with foo2 : [1,2]')
console.log(self.test());
};
ko.applyBindings(new ViewModel());
最初两个数组都是空的
test = []
test2 = []
然后我们将'1'推入test2
test = []
test2 = ['1']
然后我们将一个新对象推入测试,等于test2的当前值
test = [ { 'foo' : ['1'] } ]
test2 = ['1']
然后记录test的当前值以检查
然后我们将'2'推到test2
test = [ { 'foo' : ['1'] } ]
test2 = ['1','2']
然后使用test2的当前值
将新对象推送到测试位置test = [ { 'foo' : ['1'] }, { 'foo2' : ['1','2'] } ]
test2 = ['1','2']
当完成所有操作后,JS小提琴上的console.log将向您显示我所期望的(上图)并非完全发生的事情。
两个console.logs都显示以下测试值(注意'foo'有'1','2'不应该这样)
test = [ { 'foo' : ['1','2'] }, { 'foo2' : ['1','2'] } ]
任何人都可以帮助解释这种行为或如何实现所描述的所需功能吗?
JSFiddle:https://jsfiddle.net/xLp3jdr7/
答案 0 :(得分:1)
self.test.push({
'foo':self.test2()
});
这会将self.test2
中包含的对象(数组)放入新对象中。对象在JavaScript中通过引用传递,它们不会被复制,因此当您稍后修改对象时,此复合对象将显示为不同。
获取数组(浅)副本的一种常见方法是slice
:
self.test.push({
'foo':self.test2().slice(0)
});
只要数组本身不是由可能发生变化的对象组成,这就会表现得像你期望的那样。