考虑一下我们有这个脚本:
var webPage = require('webpage');
var page = webPage.create();
page.open('http://google.com', function(status) {
var ar = page.evaluate(function() {
// do some magic calculations and return this array:
return [{ x: 1, y: 10 }, { x: 2, y: 20 }];
});
// change the objects inside
for (var i = 0; i < ar.length; i++) {
ar[i].y = ar[i].x;
ar[i].x = 'changed';
}
console.log(ar[0].x,ar[0].y);
console.log(ar[1].x,ar[1].y);
phantom.exit();
});
结果将是:
1 10
2 20
我只需将ar
复制到新的数组对象中就解决了这个问题:
var webPage = require('webpage');
var page = webPage.create();
page.open('http://google.com', function(status) {
var ar = page.evaluate(function() {
// do some magic calculations and return this array:
return [{ x: 1, y: 10 }, { x: 2, y: 20 }];
});
// shallow copy into new array
ar = ar.slice(0);
for (var i = 0; i < ar.length; i++) {
ar[i].y = ar[i].x;
ar[i].x = 'changed';
}
console.log(ar[0].x,ar[0].y);
console.log(ar[1].x,ar[1].y);
phantom.exit();
});
结果是:
changed 1
changed 2
但我的问题是为什么会发生这种情况?
我使用的是phantomjs 1.9.8。
答案 0 :(得分:2)
之前在GitHub issue #10563提出了这个问题。从页面上下文返回的对象/数组的不变性似乎是undocumented behavior:
我认为这是一个&#34; QVariant&#34;行为:返回的对象是不可变的。 我不明白为什么,而且没有明确记录。
该问题还包含一些将不可变对象转换为普通对象的解决方法:
result = JSON.parse(JSON.stringify(result));
在使用结果之前:
var resultStr = page.evaluate(function() {
return JSON.stringify(result);
});
var result = JSON.parse(resultStr);