不使用分组运算符立即调用函数表达式
Immediately invoked function expression without using grouping operator
我试图在不使用 IIFE 模式(将函数定义括在括号内)的情况下立即调用函数。这里我看到两种情况:
当立即调用函数声明时:给出SyntaxError
.
立即调用函数表达式时:执行成功.
示例 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
所以,我有这些疑惑:
- 使用这种方法,为什么它对 函数声明 报错但对 函数表达式 报错?
- 有没有一种方法可以不使用 IIFE 模式立即调用函数声明?
函数声明,如
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") }()
我试图在不使用 IIFE 模式(将函数定义括在括号内)的情况下立即调用函数。这里我看到两种情况:
当立即调用函数声明时:给出
SyntaxError
.立即调用函数表达式时:执行成功.
示例 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
所以,我有这些疑惑:
- 使用这种方法,为什么它对 函数声明 报错但对 函数表达式 报错?
- 有没有一种方法可以不使用 IIFE 模式立即调用函数声明?
函数声明,如
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") }()