2012-06-07 19 views
3

我从MDN文档说的。适用和.CALL第一个参数是“这个”对象读取,但了解.CALL的行为。适用在Javascript

var stringToEval = "console.log(this)"; 
eval.call(null, stringToEval); 
eval.apply(null, [stringToEval]); 

在上述两个密码行最终会记录Window对象(在浏览器中)。它不应该记录为空,这是我作为第一个参数在两个方法中传递?

回答

1

MDN

的这个规定的呼叫乐趣的值。请注意,这可能不是该方法看到的实际值:如果该方法是非严格模式代码中的函数,则null和undefined将被全局对象替换,并且原始值将被装箱。

全局对象是窗口。

编辑因为无论您传递null,undefined还是带有eval的对象都没有关系。在eval内,this将与eval呼叫之前的this相同。

根据ECMA-262 5.1的第15.1.2.1节,eval接受一个字符串并将其解析为ECMAscript。如果它是有效的ECMAscript,那么它在它被调用的上下文中运行它。所以在你的情况下,你可以考虑eval的调用,就好像它们在运行时用console.log(this)代替它们一样。与更换你最终方案:

var stringToEval = "console.log(this)"; 
console.log(this); 
console.log(this); 

这使得它很清楚,为什么它输出DOMWindow对象两次。让您可以这样说:

var stringToEval = "console.log(this)"; 
(function(str){ eval(str); }).call({not: "empty"}, stringToEval); 
(function(str){ eval(str); }).apply({not: "empty"}, [stringToEval]); 

从什么时候开始的eval与console.log(this)替换本身这将是在匿名函数中this将参考传入的对象的上下文

See this JSFiddle

+1

好,VAR stringToEval = “执行console.log(本)”; eval.call({},stringToEval); eval.call(“”,stringToEval); eval.call({not:“empty”},stringToEval);仍然全部返回窗口对象...它不是null或undefined了... –

+1

您的jsfiddle在Chrome和Firefox中为我返回Window ... –

+0

这是间接eval调用,'this'将始终是'window'。它与'.call'或'无关。申请' – Esailija

0

您打电话eval明确设置thisnull,这与this对象将在撤回 代码内无关,无处我是t表示eval评估代码与this设置为相同的this,你称为eval与。实际上,这样做是调用evalindirectly并导致eval代码在全球上下文中为现代浏览器运行。

因此,你想与正常功能测试:

function test() { 
    console.log(this); 
} 

test.call({}); 
test.apply({});