1

This is going to be a quick discussion, but I just wanted some feedback on a revelation I had this morning. Knowing that this...

var addTwoNumbers = function(intOne, intTwo) {
    if ((typeof intOne == 'number') && (typeof intTwo == 'number')) {
        document.write(intOne + intTwo);
    } else {
        document.write('Unable to perform operation.');
    }
};

addTwoNumbers(3, 4);

... behaves essentially the same as this...

(function(intOne, intTwo) {
    if ((typeof intOne == 'number') && (typeof intTwo == 'number')) {
        document.write(intOne + intTwo);
    } else {
        document.write('Unable to perform operation.');
    }
})(3, 4);

... is that to say that the first set of parentheses in the self-invoking function is a "tool" to bypass or work around function execution by reference? In effect, () is the name of the method without actually being the name of the method? Also, because the function is being declared directly at execution, is it faster than the technique using a variable name reference? Just wondrin'.

4

1 回答 1

3

好的,这就是“自调用函数”(实际上不是“自调用”;有一个显式调用并且它在函数本身之外)被写为(按照惯例)作为带括号的子表达式的原因。

JavaScript 有两个涉及关键字的结构function

  1. 函数声明语句,它定义了一个函数对象并将其绑定到本地范围内的名称(以及函数的本地范围内,但现在让我们忽略它):

    function foo() { /* code */ }
    
  2. 函数实例化子表达式,它在表达式的上下文中创建函数对象:

    var f = function() { /* code */ };
    

当你想要第二件事并且你想要它在表达式语句的开头时,问题就出现了。 当语句以关键字开始function时,解析器假定您在上面执行1,而不是2因此,通过在函数实例化周围引入括号——并记住始终允许给子表达式加上括号并且不会以任何方式影响其值——使得function关键字的使用被解释为上面的2

还有其他强制解析器将语句视为表达式的方法:

  • !function() { /* code */ }();
  • 0, function() { /* code */ }();
  • +function() { /* code */ }();

只是一些例子。

至于性能,这里不是问题。我要注意的一件事是,这种将标识符绑定到函数对象的方式:

var name = function() { /* code */ };

真的不比:

function name() { /* code */ }

在某些方面情况更糟。特别是,使用函数声明语句给出的名称将显示在堆栈跟踪中,而定义函数时var不会。

于 2012-04-05T17:11:34.367 回答