深入剖析立即执行函数的执行方式

表达式

讲立即函数之前,首先来理解什么是表达式
表达式: 指的是可以被求值的代码,也就是说只要代码能求得(返回)一个值的,它就是表达式。
例子:
以下都是表达式,这里只举一部分例子。

var a = 10 //赋值表达式,它的结果就是 10

a; //变量表达式,它的结果就是10

123; //也是表达式 它的结果就是它本身

'abc'; //字符串表达式 结果是自身

var arr = [1,2,3]; //数组创建表达式,结果是数组的引用地址

a[1]; //数据访问表达式,它的结果就是2

2 * 2;  //运算表达式

var obj = {} //对象创建表达式 结果是对象的引用地址

以上123、‘abc’ a是原始表达式,是表达式中最小的单位,不能包含其他表达式,而其他的表达式都是复杂表达式,也就是说由其他表达式组成的表达式,比如var arr = [1,2,3]; 是由赋值表达式和数组表达式组成的复杂表达式,在比如a[1]是由变量表达式和原始表达式组成的

总结: 表达式指的是可用于计算得出结果的式子,即可能产生一个值的式子。

语句: 是一条完整的指令,就像我们汉字里的一句话一样,使用句号表示句子的结尾,而在程序中是以分号结尾,表示一条指令的结尾。

表达式和语句的区别
表达式是可以被求值的代码,而语句不全是,表达式可以是语句,而语句不全是表达式,比如if、for、break等都是不能被求值的,所以这些代码都不是表达式。

立即执行函数

也叫初始化函数,函数只执行一次就被销毁,适合做初始化的工作。

语法: 函数名可选

(fucntion 函数名(参数,参数)(){
	return;
}())
或者
(fucntion (参数,参数)(){
	return;
})()

为什么这种形式的函数可以被执行呢? 我们执行函数不是需要函数名吗? 别急看看下面的内容你就知道为什么不需要函数名就可以被执行。

函数声明和函数表达式的区别
函数的创建(定义)分为两种,一种是函数声明一种是函数表达式。根据上面的分析,只要能被求值的就叫做表达式,因此函数表达式一定是能被求值的并且它的值就是函数引用,而函数声明是不能被求值,函数声明仅仅是创建函数,函数声明没有结果。

函数声明:
它仅仅是创建,不能被求值,它并没有返回一个值。

function a(){
}

函数表达式:
函数作为赋值的一部分,它必须求得一个函数的引用地址,所以它必然会被js引擎解析为函数表达式,以下函数表达式的值就是该函数的引用地址并把引用地址赋给变量a

var a = function(){}; 

函数表达式的特点:
函数表达式还要补充一点,函数表达式的函数名只在内部有效,在函数外部函数名会被忽略掉,因此立即执行函数为什么会执行一次就销毁,因为函数名在外部是会被忽略掉的。

例子:
函数执行完一次就再也找不到,立即被销毁,函数名fn在函数外部会被忽略掉,因此你在函数外部使用函数名fn会报错,但是在内部是可以使用fn。

(function fn(){
    var a = 123;
    var b = 234;
    console.log(fn); 可以被执行,值是函数
    console.log(a + b);
}());

fn() 报错找不到fn这个标识符

函数的执行:
只有函数表达式才能被执行,函数声明不能被执行,因为我们执行函数就是引用地址加对括号()就能执行,因为执行函数需要引用地址才能找到内存中的函数并执行,函数声明只能是创建函数不能被求值,而函数表达式可以被求值,表达式的值就是函数的引用地址。

分组操作符()
括号()运算符也叫分组操作符,它的作用是将里面表达式的求值结果返回,因此里面必须是一个表达式不能是声明语句,因此里面的函数会被解析成函数表达式而不是函数声明,这就是为什么立即执行函数都是函数表达式。

ps: if for var等语句不能写在()中,因为这些语句不能被解析成表达式

例子1
以下代码中,根据上面说的函数执行需要引用地址才能执行,fn是变量表达式里面保存的就是函数引用地址,因此后面加对括号就能执行,这里的括号就表示函数执行符。

function fn(){
	console.log('success');
}
fn(); 

例子2
以下代码会报错,函数声明不能被求值,根据上面所诉函数执行需要函数地址,没有函数引用地址就无法执行函数,所以()被js解析成了分组操作符就是我们数学当中(),并没有被解析成函数执行的符号。

()被解析成了分组操作符不是函数执行符,分组操作符里面必须是表达式否则报错,
但是下面括号什么东西都没有所以报错了
function fn(){
	console.log('success');
}();

例子3
这里也是和上面同理()被解析成分组操作符,但是这种情况下不会报错,但函数也不会得到执行,因为括号里面是逗号表达式所以才没有报错,如果括号里什么都没写就会报错

function fn(a,b,c){
	console.log('success');
}(1,2,3)

例子4
函数表达式是可以被求值,它的值就是函数的引用,因此可以通过引用地址找到函数,执行函数里面的代码,因此以下代码都可以得到执行。

var a = fucntion(){
	console.log(1111)
}();

(function(){
	console.log(111);
}())

+ function (){
	console.log(2222);
}()

- function(){
	console.log();
}()

上面为什么运算符也可以执行函数? 因为正负是运算符,因此后面的函数必须解析成表达式求得一个结果,才能执行正负运算,声明语句是不能执行正负运算的,()里面必须是表达式,因此()里的函数会被解析成函数表达式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值