我正在尝试不使用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
所以,我有这些疑问:
答案 0 :(得分:14)
函数声明,例如
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 = ()
的方式)
答案 1 :(得分:14)
在您的代码中,您没有该函数的名称,这是语法错误的原因。即使您有名字,也会抛出错误。
function func(){
console.log('x')
}();
原因是函数声明没有返回函数的值,但是当您将函数声明包装在()
中时,它将强制它成为返回值的函数表达式。
在第二个示例中,function() {console.log('Inside the function')}
被视为表达式,因为它位于RightHandSide上。因此它执行时没有错误。
有没有一种方法可以立即调用函数声明而无需使用IIFE模式
您可以使用+
来使函数声明成为表达式。
+function(){
console.log('done')
}()
如果您不想使用+
和()
,则可以使用new
关键字
new function(){
console.log('done')
}
@cat 在评论中提出了一个非常有趣的问题。我尝试回答。有三种情况
+function(){} //returns NaN
(+function(){return 5})() //VM140:1 Uncaught TypeError: (+(intermediate value)) is not a function
+function(){return 5}() //5
+function(){}
返回NaN
+
在这里用作一元加号,它将其旁边的值解析为数字。由于Number(function(){})
返回NaN
,所以它也返回NaN
(+function(){return 5;})()
返回错误通常使用()
创建IIFE。 ()
用于进行函数声明,而表达式+
是实现此目的的捷径。现在+function(){}
已经是一个返回NaN
的表达式。因此,调用NaN
将返回错误。代码与
Number(function(){})()
+function(){return 5;}()
返回5
在上面的行+
中,使语句成为表达式。在上面的示例中,第一个函数被调用,然后在其上使用+
将其转换为数字。所以上一行与
Number(function(){return 5}())
在语句证明中,“ +在调用该函数后继续运行” 考虑以下代码段
console.log(typeof +function(){return '5'}());
因此在上面的代码段中,您可以看到返回的值是字符串'5'
,但是由于+
而被转换为数字
答案 2 :(得分:2)
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);
答案 3 :(得分:1)
要调用某些东西,它必须是一个函数值,声明只是声明一个名称,而不会求值到函数值本身,因此您不能调用它。
由于上述原因,不能调用声明。您必须通过分配或分组(IIFE)以某种方式结束表达式。所以这不是。
如果您为我们提供了更多有关为什么要这样做的背景信息,也许我们可以为您提供建议。
答案 4 :(得分:1)
不确定为什么要这么做,但是:
有没有一种方法可以立即调用函数声明而无需使用IIFE模式?
好吧,如果要进行功能声明,则表示使用关键字function
,如下所示:
function name() { return this.name; }
据我所知,没有。如果我理解正确的话,您需要使用额外的括号告诉运行时不要将函数分配给name
变量。
现在,您实际可以做的是使用Function
,如下所示:
new Function('console.log("ey there")')();
将执行console.log
代码。这里不需要IIFE。但是我不认为这会比IIFE更好。
答案 5 :(得分:0)
您可以通过以下两种方式致电-
~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") }()