通常,我们声明一个函数test){},可以通过test()来调用这个函数。但是,如果我们在这个函数声明的末尾加上(),解析器是无法理解的。
function test(){ console.log('hello world!'); }();//解析器是无法理解的。
那为什么将函数体部分用()包裹起来就可以了呢?
(function test(){ console.log('hello world!'); })(); //输出hello world!
解释器在解释一个语句时,如果以function开头,就会理解为函数声明。而使用括号包裹定义函数体,解析器将会以函数表达式的方式去处理定义的函数,而函数表达式后面又添加了一个()就变成了一个立即执行的函数了。也就是说,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。所以,赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,并且对函数来说使用一元运算可以算的上是消除歧义最快的方式,常见的感叹号只是其中之一。任何能将函数变成一个函数表达式的作法,都可以使解析器正确的调用定义函数。
例如:
!function () { console.log('hello world!'); }();//输出hello world
而省略了!的话:
function() { console.log('hello world!'); }();
就会理解为函数声明,而函数声明没有名字会报错。如果有函数名:
function f() { console.log('hello world!'); }();
还是会报错,因为function f(){}函数声明会提升,相当于:
function f(){ console.log('hello world!'); } //其他代码... (); // 这里报错。
ps:
如果不在乎返回值,这些一元运算都是有效的
+function(){alert('hello world!')}() // NaN -function(){alert('hello world!')}() // NaN ~function(){alert('hello world!')}() // -1
如有问题,欢迎留言(・∀・)