JavaScript高级程序设计之函数表达式

函数表达式是JS中一个强大的特性,尤其是ES6支持Lamada表达式后,更是锦上添花。在前边的文章介绍中,曾经介绍过一种创建函数的方式,函数声明,对函数表达式也有简单介绍。这章将会对函数表达有更详细的介绍。

函数表达式最常用的定义方式为:const a = function(){}。其中function是一个匿名函数(也可叫Lamada函数),因为函数的关键字后面没有标识符,也就是说函数的name属性是一个字符串。

函数表达式与函数声明除了一个有标识符和一个没有标识符之外,还有一个很重要的区别,那就是声明提前。所谓声明提前,就是无论函数写在调用前还是调用后,都可以正常得进行调用,不会报错。普通的函数声明,会具有此特性,而函数表达式则没有这个特性。因为函数表达式,归根结底是一个表达式,它和其它赋值表达式没有什么区别,唯一的区别就是它把函数作为值赋给了变量。

闭包

闭包也是JS中比较重要的概念,经常有人搞不清什么是闭包,其实闭包的原理很简单,就是指一个函数有权去访问另一个函数里的变量。闭包最常用的地方就是,一个函数里边,嵌套了另一个函数,嵌套的函数使用了外边这个函数里的变量。在之前文章中讲过,JS中的函数也是对象,拥有自己的属性和方法。那这和作用域链有什么关系呢?其实作用域链就是嵌套函数对象的[Scope]属性存储了一份对外部函数对象的引用。而正是这份引用,使得内部函数可以访问到外部函数的变量,从而造就了闭包。在没有闭包的情况下,随着函数的调用结束,作用域链也会随之销毁,但在使用闭包的时候,外部函数仍然会随着调用结束,而被销毁掉,但是由于闭包,作用域链中指向外部函数对象的引用并不会消失,直到内部函数被销毁后,才会被销毁。

闭包与变量

在使用闭包的时候,内部函数只能取到外部函数变量的最后一个值。这是闭包的一个缺点。那为啥这样呢?这是因为函数中的变量被存到了一个变量对象里边,供内部函数访问。大家都知道,放在对象里边的数据,被称之为属性,而正因为变成了属性,所以内部函数访问的时候,总是访问到最后一个值。解决方案,就是能一个立即执行的匿名函数,然后把值总是会变得变量,当做参数传递进去。

关于this对象

在使用闭包的时候,this指向也是一个问题。JS中函数是会绑定this的,作为函数的函数this是指向Window,作为方法的函数this是指向对象本身,而在方法内部的函数,因为是作为函数存在的,因此它的this指向仍然是Window。如果把方法赋值给变量,用这个变量调用的话,它的this指向也是Window。而这一切的原因,就是因为它们不再是方法,而是作为函数存在。不过虽然存在这样的问题,但是我们可以通过lamada表达式,call、apply、bind、或定义变量存储this的方式,来实现对方法this的访问。

 

内存泄漏

posted on 2017-11-30 12:59  木森焱  阅读(215)  评论(0编辑  收藏  举报

导航