闭包的理解

主要参考:阮一峰博客

js变量作用域

在理解闭包之前,需要先理解js中变量的作用域。

js中的变量分为全局变量和局部变量。

var m = 'hello'
function a () {
	var mm = 'world'
	console.log(m)  // hello
}
console.log(m)    // hello
console.log(mm)	  // undefined 报错		

m为全局变量,mm 为函数内部的局部变量,在函数内部可以访问全局变量,但是在函数外部不可以访问函数内部的局部变量。

函数内部的变量在声明时使用 var mm = ‘world’ 则声明的变量为局部变量 ,若省略var 使用 mm = ‘world’,则声明的变量为全局变量。

若想要在函数外部访问函数内部的变量呢? 这时候就出现了闭包。

什么是闭包

闭包简单概括一句话就是 能够访问其他函数内部变量的函数。

下面用一张图来说明
在这里插入图片描述

如上图所示,有function 1、 function 2、function3 三个方法,

function2 → funciton1中变量a √

function3 → function1中变量a ×

在function2中可以访问function1中的变量a,这是由于原型链的原因,可以访问。

在function3中不能访问function1中的变量a,函数外部不能访问函数内部的变量。

如果想要访问函数内部的变量呢? 我们该怎么做,通过上图我们已知,function1内部的函数function2是可以访问到函数内部的变量的,那么我把function2 retrun导出,再在外部通过变量接收,不就可以访问function1内部的变量了吗,这就是闭包的由来。

简单代码

function function1 () {
	var a = 1
	function function2 () {
		console.log('a:'+a)
	}
	return function2
}
			
	var result = function1()
	result()

运行结果如下:
在这里插入图片描述

如上例子中function2 即为闭包。闭包是函数内部变量和函数外部的连接桥梁,使得外部函数可以访问函数内部的变量。

闭包的使用

function f1() {    
	var n = 999;    
	nAdd = function() {
		n += 1
	}    
	function f2() {      
		console.log(n);    
	}    
	return f2;  
}  
var result = f1();  
result(); // 999
  
nAdd();  
result(); // 1000

如上代码,result为闭包,var result = f1() ,将f1赋值给result,而f1中返回值为f2,则result为闭包。
第一次调用result() 输出999
调用nAdd()函数后,再调用result() 输出1000
可见在函数执行完后,函数中的变量并没有被垃圾回收机制给回收,因为将f1赋值给了result全局变量,变量被保存到了内存中,全局变量不会被回收。

nAdd = function() {n+=1} 这里的nAdd前没有var,所以为全局变量,可以在函数外被访问,nAdd相当于setter,对f1中的变量进行操作。

使用闭包的注意点

1.闭包使用的过程中,会将函数内部的变量变成全局变量存储到内存中,如果大量使用闭包,会导致内存泄漏,因此闭包使用完之后要及时关闭。

2.闭包在使用的过程中,可能会改变原有父函数中的变量值,因此要注意不要随意修改父函数中的变量值。

思考

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());
var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值