JavaScript--我发现,原来你是这样的JS:函数表达式和闭包

本次博客主要介绍函数表达式的内容,主要是闭包。

二、函数表达式

定义函数的两种方式:一个是函数声明,另一个就是函数表达式。

//1.函数声明写法 function fn2(){ console.log('函数声明'); } //2.函数表达式写法 var fn1 = function(){ console.log('函数表达式'); }

区别:
1.函数声明是用function后面有函数名,函数表达式是赋值形式给一个变量。
2.函数声明可以提升函数,而函数表达式不会提升

函数提升就是函数会被自动提升到最前方,以至于再调用函数后再声明函数也不会有错:

//例子: //先调用运行 sayName(); //再声明函数 function sayName(){ console.log('ry'); } //运行结果 'ry'

函数表达式就不会被提升:

//先调用 sayBye(); //函数表达式 var sayBye = function(){ console.log('bye bye'); } //运行报错

但是下面的写法很危险:因为存在函数声明的提升

//书上代码 if(condition){ function sayHi(){ console.log('hi'); } } else{ function sayHi(){ console.log('yo'); } }

解说一下: 这段代码想表达在condition为true时声明sayHi,不然就另一函数sayHi,但是运行结果往往出乎意料,在当前chrome或firefox可能能做到,但是在IE10以下的浏览器(我测试过)往往不会遵循你的意愿,不管condition是true还是false都会输出yo。

这时函数表达式能派上用场了:

//换成函数表达式,没问题因为不会被提升,只有当执行时才赋值 var sayHi = null; if(condition){ sayHi = function (){ console.log('hi'); } } else{ sayHi = function sayHi(){ console.log('yo'); } } 三、闭包

闭包的定义:有权访问另一个函数作用域中的变量的函数

有人觉得闭包很难理解,一开始我也是这样的,我认为那是对一些概念还不够了解。

定义中说明了什么是闭包,最常见的形式就是在函数中再声明一个函数。

重点理解这里:

1.闭包能访问外围函数的变量是因为其作用域链中有外围函数的活动对象(这个活动对象即使在外围函数执行完还会存在,不会被销毁,因为被闭包引用着)。

2.闭包是函数中的函数,也就是说其被调用时也创建执行上下文,对于执行上下文这部分可以看看这篇:深入理解js执行--创建执行上下文这篇博客。

理解了上面之后我们再来看闭包的例子:

function a(){ //a函数的变量 var val_a = "我是a函数里的变量"; //声明函数b,b能访问函数a的变量 function b(){ console.log(val_a); } //a函数将b返回 return b; } //全局变量fn,a执行返回了b给fn var fn = a(); //调用fn,能够在全局作用域访问a函数里的变量 fn(); //我是a函数里的变量

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssjzd.html