具有单个String的数组自动且不可取地转换为String

时间:2015-12-02 09:21:54

标签: javascript phantomjs casperjs

在我的CasperJS脚本中,当我通过evaluate函数将数组传递给我的函数时,它可能有一个或多个字符串。当有多个字符串时,它按预期工作,但是当数组只有1个字符串时,它表现得非常奇怪。如果我传递一个内部有一个字符串的数组,它就变成了字符串。我哪里错了?

我的CasperJS脚本:

function myFunction(input) {
  console.log(JSON.stringify(input));
}

//allow console logs through for debugging
casper.on('remote.message', function(message) {
  this.echo(message);
});

//get my page
casper.start(...);

//attempt to call myFunction with an array as input
casper.then(function() {
  var input = ['#someId'];
  this.evaluate(myFunction, input); 
});

期望的输出:

["#someId"]

实际输出:

"#someId"

如果var输入= [' #firstId',' #secondId']

输出
["#firstId", "#secondId"]

2 个答案:

答案 0 :(得分:0)

当您使用JSON.stringify(input)时,此方法会将JavaScript值转换为JSON字符串,并且您发送的单个字符串我认为哪些不是正确的json格式。

JSON.stringify()将值转换为表示它的JSON表示法:

不保证非数组对象的属性按任何特定顺序进行字符串化。不要依赖于字符串化内同一对象内的属性排序。 根据传统的转换语义,在字符串化期间将Boolean,Number和String对象转换为相应的原始值。 如果未定义,则在转换期间遇到函数或符号,或者省略(当在对象中找到它时)或者删除为null(当它在数组中找到时)。 即使使用replacer函数,也将完全忽略所有符号键控属性。 不可枚举的属性将被忽略

请查看JSON API及其相关方法

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

答案 1 :(得分:0)

这正是CasperJS在有两个参数时添加的内容:函数和函数参数。如果它是根据this的数组或对象,它将尝试“解包”您传递的一个参数:

var casper = require('casper').create();

casper.on("remote.message", function(msg) {
    this.echo("Console: " + msg);
});

casper.start('http://example.com/').then(function(){
    var arr = ['#someId'];
    var arrm = ['#someId', '#someOtherId'];
    var obj = {a:'#someId'};
    var objm = {a:'#someId', b:'#someOtherId'};

    this.echo("1");
    this.evaluate(function(arr) {
        console.log(JSON.stringify(arr));
    }, arr);

    this.echo("2");
    this.evaluate(function(arr) {
        console.log(JSON.stringify(arr));
    }, arrm);

    this.echo("3");
    this.evaluate(function(obj) {
        console.log(JSON.stringify(obj));
    }, obj);

    this.echo("4");
    this.evaluate(function(obj) {
        console.log(JSON.stringify(obj));
    }, objm);

    this.echo("5");
    this.evaluate(function(arr, obj) {
        console.log(JSON.stringify(arr));
        console.log(JSON.stringify(obj));
    }, arr, obj);

    this.echo("6");
    this.evaluate(function(a) {
        console.log(JSON.stringify(a));
    }, obj);

    this.echo("7");
    this.evaluate(function(b) {
        console.log(JSON.stringify(b));
    }, objm);

    this.echo("8");
    this.evaluate(function(a, b) {
        console.log(JSON.stringify(a));
        console.log(JSON.stringify(b));
    }, objm);

    this.echo("9");
    this.evaluate(function(b, a) {
        console.log(JSON.stringify(a));
        console.log(JSON.stringify(b));
    }, objm);
}).run();

这会产生一些有趣的行为,如下面的完整脚本所示:

evaluate()

输出:

1
Console: "#someId"
2
Console: ["#someId","#someOtherId"]
3
Console: "#someId"
4
Console: {"a":"#someId","b":"#someOtherId"}
5
Console: ["#someId"]
Console: {"a":"#someId"}
6
Console: "#someId"
7
Console: {"a":"#someId","b":"#someOtherId"}
8
Console: "#someId"
Console: "#someOtherId"
9
Console: "#someOtherId"
Console: "#someId"

请注意,如果对象的键匹配,则会按名称将对象解压缩到create_table="CREATE OR REPLACE TABLE " + data + """ ( fk_id number, DATA VARCHAR(15), VENUE VARCHAR(15), LOCATION VARCHAR(15) )""" cursor.execute(create_table) 回调参数(请参阅测试8和9)。

PhantomJS本身不做任何解包。这都是CasperJS。