2013-03-11 82 views
2

我碰到这个代码,不明白为什么代码块中的代码被封装在像自动执行函数一样的parens中。块内的代码被包装在parens里面。为什么?

function foo(a,b) { 
    var b = b || window, 
    a = a.replace(/^\s*<!(?:\[CDATA\[|\-\-)/, "/*$0*/"); 
    if (a && /\S/.test(a)) { 
    (b.execScript || function (a) { 
     b["eval"].call(b, a) 
    })(a); 
    } 
} 

第一个参数是来自脚本标记的文本。我没有得到的唯一部分是为什么脚本eval被包裹在parens中。

回答

5

我假设你是在谈论这一部分:

(b.execScript || function (a) { 
    b["eval"].call(b, a) 
})(a); 

这是写作的缩写形式:

if (b.execScript) { 
    b.execScript(a); 
} 
else { 
    b["eval"].call(b, a); 
} 

即如果已定义则执行b.execScript,否则请致电b["eval"].call(b, a)

分组操作符的用途是在函数调用之前评估... || ...,即无论分组操作符的结果如何,它都被视为函数并通过传递a来调用它。

它看起来像代码可以简化为

(b.execScript || b["eval"])(a); 

但如果明确设置thisb是必要的,那么函数表达式是必要的,也是,有两个函数只接受一个参数,a

+0

...除非不需要在非窗口'b'的上下文中调用'eval'。 – VisioN 2013-03-11 15:15:42

+0

也许,我没有真正看过代码应该做什么。 – 2013-03-11 15:16:31

+0

从某种程度上看,来自jQuery VisioN 2013-03-11 15:24:23

2

因为之后有(a)。表达式:

(b.execScript || function (a) { 
     b["eval"].call(b, a) 
    }) 

返回封闭,然后与a作为参数传递执行。

3

由于||运算符的绑定比函数调用运算符()更松散,所以加括号。如果没有圆括号,仿佛它被写入的表达式将被评估:

b.execScript || (function (a) { b["eval"].call(b, a); })(a) 

即,它会是任一的b.execScript平原值或调用该函数的值。作者想要的是调用b.execScript(这可能是一个函数)的值那个小的匿名函数。

4
(b.execScript || function (a) { 
     b["eval"].call(b, a) 
    })(a) 

因为||语句需要进行评估,以确定哪些功能被传递参数之前运行这个被包裹在括号。

此代码调用b.execScript与参数a如果b.execScript存在,并且是truthy。否则它会定义一个新函数并将a作为参数传递给它。

parens wrap是为了确保||语句在函数执行前被评估。没有它,如果b.exec不存在,那么逻辑基本上会执行,评估为自定义函数的值,如果是,则评估为b.exec。

于是用括号的逻辑等价于:

if(b.execScript){ 
    b.execScript(a) 
} 
else{ 
    function (a) { 
    b["eval"].call(b, a) 
    })(a) 

} 

没有它,其相当于

如果(b.execScript!){ 函数的(a){ B [“EVAL “] .CALL(b,A) })(一) }

0

括号表达式返回b.execScript的结果或一个新函数。无论哪种情况,结果都会以参数的形式被调用。 parens确保解释器评估||在调用之前。

0

为什么代码块中的代码被封装在parens中,就像自动执行函数一样。

由于代码的该特定部分是自动执行功能:

(b.execScript || function (a) { 
    b["eval"].call(b, a) 
})(a); 

这里,变量b参照执行容器,例如windowa包含需要执行的JavaScript代码。

由于一些浏览器支持execScript()而有些只支持eval(),代码通过测试该浏览器的功能,像这样支持他们两个:

var tmp = b.execScript || function (a) { 
    b["eval"].call(b, a) 
}; 

这里,tmp是一个函数,它接受一个参数a并执行内的代码;如果execScript不可用,则使用小型辅助函数。然后,它被称为是这样的:

tmp.call(b, a); 

.call()的第一个参数定义了this是指当tmp被调用;第二个参数成为tmp的第一个参数。

相关问题