对casper.eevaluate使用函数时的差异

Differences when using functions for casper.evaluate

本文关键字:函数 casper eevaluate      更新时间:2023-09-26

我使用的是PhantomJS v2.0和CasperJS 1.1.0-beta3。我想查询页面DOM中的特定部分。

这里的代码没有工作:

function myfunc()
{
    return document.querySelector('span[style="color:#50aa50;"]').innerText;    
}
var del=this.evaluate(myfunc());
this.echo("value: " + del);

这里的代码确实有效:

var del=this.evaluate(function() 
{
   return document.querySelector('span[style="color:#50aa50;"]').innerText; 
});
this.echo("value: " + del);

它看起来是一样的,但效果不同,我不明白。

这里有一个同样有效的代码:

function myfunc()
{
    return document.querySelector('span[style="color:#50aa50;"]').innerText;    
}
var del=this.evaluate(myfunc);
this.echo("value: " + del);

这里的区别是,我称myfunc不带"()"。

有人能解释一下原因吗?

问题是:

var text = this.evaluate(myfunc());

JavaScript中的函数是一流的公民。您可以将它们传递到其他函数中。但你在这里不是这么做的。您调用函数并将结果传递给evaluate,但结果不是函数。

此外,casper.evaluate()是页面上下文,并且只有页面上下文可以访问文档。当您在执行casper.evaluate()之前基本上调用函数(使用())时,您会错误地尝试访问文档,而这是不可能的。

casper.evaluate(function(){...});的不同之处在于,匿名函数被定义并传递到evaluate()函数中。

有些情况下,应该调用函数而不是传递函数。例如,当currying完成时,但这不适用于casper.evaluate(),因为它是沙盒的,并且最终在casper.evaluate()中运行的函数不能使用外部变量。它必须是自给自足的。因此,以下代码也将不起作用

function myFunc2(a){
    return function(){
        // a is from outer scope so it will be inaccessible in `evaluate`
        return a;
    };
}
casper.echo(casper.evaluate(myFunc2("asd"))); // null

你应该使用

var text = this.evaluate(myfunc);

传递先前定义的函数以在页面上下文中运行。

使用保留关键字(如del)作为变量名也不是一个好主意。