不使用分组运算符立即调用函数表达式

Immediately invoked function expression without using grouping operator

我试图在不使用 IIFE 模式(将函数定义括在括号内)的情况下立即调用函数。这里我看到两种情况:

  1. 当立即调用函数声明时:给出SyntaxError.

  2. 立即调用函数表达式时:执行成功.

示例 1: 给出 SyntaxError

//gives `SyntaxError`
function() {
    console.log('Inside the function');
}();

示例 2: 执行无任何错误

// Executes without any error
var x = function() {console.log('Inside the function')}(); // Inside the function

所以,我有这些疑惑:

函数声明,如

function foo() {
}

将变量名 foo 定义(并提升)为当前作用域中的一个函数。函数声明不求值;它只是 某事,有点像 if 做某事(而不是求值)。

您只能调用作为函数的值,例如

<somevalue>()

其中 somevalue 是引用函数的变量名。

请注意,函数声明需要函数名,否则就没有变量名可将函数分配给 - 您的原始

//gives `SyntaxError`
function() {
    console.log('Inside the function');
}();

抛出不是因为最后的(),而是因为缺少名称。

可以在函数声明的末尾放置圆括号,只要圆括号内有内容即可 - 但这些圆括号不调用函数,它们的计算结果是一个值:

function x() {
    console.log('Inside the function');
}(console.log('some expression inside parentheses'));

解释器将它们视为两个单独的语句,例如

function x() {
    console.log('Inside the function');
}
// completely separate:
(console.log('some expression inside parentheses'));

括号内的内容会被求值然后被丢弃,因为它没有被分配给任何东西。

(空括号是被禁止的,因为它们不能被评估为一个值,类似于 const foo = () 被禁止的方式)

为了调用某些东西,它必须是一个函数值,一个声明只是声明一个名称,而不是计算函数值本身,因此你不能调用它。

由于上述原因无法调用声明。您必须通过赋值或分组 (IIFE) 以某种方式结束表达式。所以这是一个没有。

如果您向我们提供更多关于您为什么要这样做的背景信息,也许我们可以提供建议。

在您的代码中,您没有函数的名称,这就是语法错误的原因。即使你有名字,它也会抛出错误。

function func(){
  console.log('x')
}();

原因是函数声明没有 return 函数的值,但是当您将函数声明包装在 () 中时,它会强制它成为一个函数表达式 return值。

在第二个示例中,function() {console.log('Inside the function')} 被视为表达式,因为它位于 RightHandSide。所以它执行没有错误。

Is there a way we can immediately invoke a function declaration without using IIFE pattern

您可以使用 +,这将使函数声明成为表达式。

+function(){
  console.log('done')
}()

如果您不想使用 +(),您可以使用 new 关键字

new function(){
  console.log('done')
}

额外

@cat在评论中提出了一个非常有趣的问题。我试着回答it.There三种情况

+function(){} //returns NaN
(+function(){return 5})() //VM140:1 Uncaught TypeError: (+(intermediate value)) is not a function
+function(){return 5}() //5

+function(){} returns NaN

+ 在这里充当一元加号,将其旁边的值解析为数字。正如 Number(function(){}) returns NaN 所以它也 returns NaN

(+function(){return 5;})() returns 错误

通常使用 () 创建 IIFE。 () 用于使函数声明成为表达式 + 是一种简写方式。现在 +function(){} 已经是 returns NaN 的表达式。所以调用 NaN 会 return 错误。代码与

相同
Number(function(){})()

+function(){return 5;}() returns 5

在上面的行中,+ 用于使语句成为表达式。在上面的示例中,第一个函数被调用,然后 + 被用于将其转换为数字。所以上面一行与

相同
Number(function(){return 5}())

在语句证明中 "+ 在调用函数后继续运行" 考虑以下代码段

console.log(typeof +function(){return '5'}());

所以在上面的代码片段中你可以看到 returned 值是字符串 '5' 但由于 +

被转换为数字

IIFE 中的 E 代表表达式,如果没有括号,您的函数将不会作为表达式求值,因此会出现语法错误。

创建表达式是一种欺骗解释器并能够立即调用函数的方法

(function() {
    console.log('Inside the function');
})();

在您的示例中,您有一个函数语句,后跟 grouping operator,但它在语法上是不正确的,原因有二,首先它没有名称,其次因为分组运算符内部必须有一个表达式它,事实上,如果你添加一个有效的错误将消失,你仍然不会获得你想要的结果。

function foo() {
    console.log('Inside the function');
}();

function foo() {
    console.log('Inside the function');
}(1+2);

不确定为什么要这样做,但是:

Is there a way we can immediately invoke a function declaration without using IIFE pattern?

好吧,如果对于 函数声明 ,您的意思是使用关键字 function,如:

function name() { return this.name; }

据我所知,没有。您需要额外的括号来告诉运行时不要将函数分配给 name 变量,如果我理解正确的话。

现在,您实际上可以做的是使用Function,如:

new Function('console.log("ey there")')();

这将执行 console.log 代码。这里不需要 IIFE。但我看不出这比 IIFE 更好。

您可以通过以下方式调用 -

~function(){console.log("hi")}()
!function(){console.log("hi")}()
+function(){console.log("hi")}()
-function(){console.log("hi")}()
(function(){console.log("hi")}());
var i = function(){console.log("hi")}();
true && function(){ console.log("hi") }();
0, function(){ console.log("hi") }();
new function(){ console.log("hi") }
new function(){ console.log("hi") }()