casper.evaluate 使用函数时的差异

Differences when using functions for casper.evaluate

我正在使用 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 中的函数是第一个 class 公民。您可以将它们传递给其他函数。但这不是你在这里做的。您调用函数并将结果传递给评估,但结果不是函数。

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

casper.evaluate(function(){...});的区别在于匿名函数被定义并传递给evaluate()函数。

有些情况下应该调用而不是传递函数。例如,当柯里化完成时,但这不适用于 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 这样的保留关键字作为变量名也不是一个好主意。