闭包:有权访问另一个函数作用域的变量的函数,在一个函数内部创建另一个函数,就可以叫做闭包 闭包会将外部函数的活动对象添加到闭包的作用域中,就算外部函数已经执行完,但如果闭包引用了其中的变量,那么这个被引用的变量不会随着外部函数执行完毕而被销毁,其生命周期会延续到匿名函数被销毁的时候。 具体过程如下:
(1)闭包只能取得外部函数中任何变量的最后一个值
function createArray(){ var arr=[]; for(var i=0;i<3;i++){ arr[i]=function(){ return i; } //匿名函数只取得了变量i的最后一个值3 } return arr; } console.log(createArray())观察结果,此时返回数组中的每一项都为3. 解决问题的方法,创建另外一个匿名函数,并立即执行该匿名函数
function createArray(){ var arr=[]; for(var i=0;i<3;i++){ arr[i]=function(num){ return function(){ return num; }; }(i); } return arr; } console.log(createArray())(2)闭包中的this的问题 由于匿名函数的执行环境具有全局性,所以匿名函数中的this对象通常指向window,如果要闭包想要访问声明其外部函数的对象时,就需要把外部作用域中的this对象保存在一个闭包能够访问到的变量里:
var a=1; var obj={ a:3, getproperty:function(){ var that=this; return function(){ return that.a; }; } } console.log(obj.getproperty()());第二种解决方法:就是可以利用箭头函数来绑定this,箭头函数的作用简而言之就是当前的作用域覆盖了this本来的值
var a=1; var obj={ a:3, getproperty:function(){ return ()=>this.a; } } console.log(obj.getproperty()());第三种解决方法:利用bind()函数绑定this
var a=1; var obj={ a:3, getproperty:function(){ return function(){ return this.a; }.bind(this); } } console.log(obj.getproperty()());