nodejs是否预期以下行为?在我看来,越野车很麻烦.如果不是我想念的是什么?
var abc = function(){
console.log("hello");
}
(function(){
console.log("welcome");
})();
我得到以下异常
TypeError: undefined is not a function
at Object.<anonymous> (C:\node\main.js:8:3)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
如果我将代码更改为
var abc = function(){
console.log("hello");
}
(function(){
console.log("welcome");
}());
它产生
welcome
hello
我不得不相信节点解析会错误地假定嵌套IIFE(function(){…})()首先执行,而IIFE的external()会触发其上方的函数定义的执行(如果我引入了a abc定义和IIFE之间的注释行).
解决方法:
这不仅仅是一个node.js问题.您将在浏览器中得到相同的错误.正如其他人所提到的,错误是第一个函数中缺少分号.但是怎么回事?
好吧,首先让我们解释一下什么是IIFE.您可能知道以下语法:
(function(){})();
但这不是IIFE的唯一语法. IIFE是立即调用的函数表达式.因此,它在声明后立即调用函数表达式.
那么,什么是函数表达式?它只是在表达式上下文中声明的函数.在表达式上下文中求值的一种方法是使用大括号运算符().在这里,括号运算符实际上与数学中的括号运算符相同:它强制执行数学运算的优先级.
因此,括号在此:
(function(){})
表示与此完全相同:
(1+1)
它告诉解释器,其中的代码是一个返回值的表达式.这就是表达式上下文的含义-您可以在任何位置进行计算以返回值的地方.
在其他地方,语言会将其解释为表达上下文.其中之一是紧随运算符之后.例如!运算符或-运算符(使数字为负).因此,例如您可以编写:
-12 + 5
您也可以这样编写IIFE:
-function(){}()
javascript解释为表达式上下文的另一个地方是=符号右边的所有内容.例如:
var x = 12 + 5;
这意味着,您可以这样编写IIFE:
var x = function(){}();
这就是导致您的代码出现问题的原因.基本上,javascript会这样解释您的代码:
var abc = function(){
console.log("hello");
}(function(){console.log("welcome")})();
也就是说,您的第一个函数被视为IIFE,它通过将第二个函数作为参数传递而被调用,并尝试调用第一个函数的返回值(未定义,因为您不返回任何东西,而只是返回“ hello” “).
换句话说,如果我们将其分解,它就是这样做的:
function first_function () { console.log('hello') }
function second_function () { console.log('world') }
var temp = first_function(second_function);
var abc = temp; // it errors here because temp is undefined
课程是,在函数声明后不需要分号,但在函数表达式后需要分号.
其次,教训较少:IIFE有多种方法.