JS中的异步
所谓立即执行函数就是声明一个匿名函数,立即执行它
一般有三种写法:
(function(){})();
(function(){}());
!function(){}();
首先我们需要搞清楚函数表达式和函数声明区别,ECMAScript规范中定义的相当模糊:
函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省略这个标示符:
函数声明:
function 函数名称 (参数:可选){ 函数体 }
函数表达式:
function 函数名称(可选)(参数:可选){ 函数体 }
其实我们常用的区分方式是根据上下文,如果function fn(){}作为右值出现(赋值表达式右边)那么就是表达式,否则就是函数声明。有几种看起来不常规的方式需要我们注意
new function fn(){}; //表达式,因为在new 表达式中
(function(){}());//表达式,在分组运算符中
这样我们就能理解第二种写法了,就是利用分组运算符改变了语法树。同样第三种写法其实是利用了一元运算符后面跟表达式的原理,我们也可以写成
+function(){}()
-function(){}()
~function(){}()
知道了这些看个传入参数调用的立即执行函数
(function f(f){
return typeof f();
})(function(){return 1;});// "number"
立即执行函数不再是以空括号()来调用了,同时传入了一个function作为参数传入调用。
当函数执行有命名冲突的时候,函数依次填入 变量=》函数=》参数,所以最后被填入的参数f会覆盖函数定义f,typeof f()是对参数的调用,参数是立即执行函数传入的function参数,返回数字1,typeof 1是 "number"。
表达式返回值
函数定义表达式返回的是函数对象本身,我们在调用alert或者console.log的时候会调用其toString方法
console.log(function(){alert('a');}) //function (){alert('a');}
函数调用表达式自然是返回函数的return结果,但在JavaScript中并不是所有的函数都有return语句,对于没有return语句的function,其调用表达式返回undefined,对于只写个return的坑爹做法同样也是返回undefined
(function(){})(); //undefined
(function(){return;})();//undefined
对象创建表达式本来也应该很简单,返回new的对象就可以了
typeof new Date(); //"object"
当使用function的构造函数创建对象(new XXX)的时候,如果函数return基本类型或者没有return(其实就是return undefined)的时候, new 返回的是对象的实例;如果 函数return的是一个对象,那么new 将返回这个对象而不是函数实例。