knockoutjs可观察数组

时间:2016-01-05 21:25:17

标签: javascript jquery arrays knockout.js

为了简化我遇到的问题,我提出了以下示例。

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/

1 个答案:

答案 0 :(得分:1)

self.test.push({
  'foo':self.test2()
});

这会将self.test2中包含的对象(数组)放入新对象中。对象在JavaScript中通过引用传递,它们不会被复制,因此当您稍后修改对象时,此复合对象将显示为不同。

获取数组(浅)副本的一种常见方法是slice

self.test.push({
  'foo':self.test2().slice(0)
});

只要数组本身不是由可能发生变化的对象组成,这就会表现得像你期望的那样。