从page.evaluate返回的数组的奇怪行为

时间:2014-12-31 19:19:24

标签: javascript phantomjs

考虑一下我们有这个脚本:

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。

1 个答案:

答案 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);