2

我遇到了这段代码,不明白为什么块中的代码像自动执行函数一样被包裹在括号中。

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 被包裹在括号中。

4

6 回答 6

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.

于 2013-03-11T15:06:17.003 回答
4
(b.execScript || function (a) {
      b["eval"].call(b, a)
    })(a)

这包含在括号中,因为||需要评估该语句以确定在传递参数之前要运行的函数。

如果存在并且是真实的,则此代码b.execScript使用参数调用。否则它定义一个新函数并作为参数传递给它。ab.execScripta

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

因此,使用括号,逻辑等效于:

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

}

没有它,它相当于

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

于 2013-03-11T15:06:15.397 回答
3

加括号是因为||操作符比函数调用操作符绑定得更松散()。如果没有括号,表达式将被评估,就好像它是这样写的:

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

也就是说,它要么是普通值,b.execScript要么是调用该函数的值。作者想要的是调用的值b.execScript(可能是一个函数)那个小匿名函数。

于 2013-03-11T15:06:11.623 回答
2

因为(a)后来。表达方式:

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

返回一个闭包,然后a将其作为参数传递来执行。

于 2013-03-11T15:05:57.350 回答
0

为什么块中的代码像自动执行函数一样被包裹在括号中。

因为代码的特定部分自动执行功能:

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

这里,变量b引用了执行容器,例如window,并a包含需要执行的 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

于 2013-03-11T15:28:56.110 回答
0

括号表达式返回 b.execScript 的结果或新函数。在任何一种情况下,都会使用 a 作为参数调用结果。括号确保解释器评估 || 在调用之前。

于 2013-03-11T15:07:12.910 回答