小白都能看懂的闭包(closure)

前言:

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

1. 关于全局变量 和 局部变量的 理解:

函数外面: var a = 20; 此处var声明的a是一个全局变量

函数内部:function getAll() {

//如果是 var 声明的,则是局部变量 (与函数外面声明的相反 )

var a = 20;

//如果是直接写的(省去var声明的),则是全局变量

扫描二维码关注公众号,回复: 4642860 查看本文章

a = 20

}

访问范围:

全局变量,在整个script中,都可以访问到;

但是局部变量只能在函数内部访问到;函数外部是不能访问到的。

有时候,想要在全局访问到函数内部的局部变量,要怎么办?

——闭包,可以实现这一点。

2. 闭包(closure):

何为闭包?

在一个函数中写入另外一个函数,并且可以访问到这个函数的局部变量的函数,这就是闭包。

在js中,只有一个函数内部的子函数才可以读取局部变量,所以,也可以把闭包理解为“定义在一个函数内部的函数”。

(本质上,闭包就是讲函数内部和函数外部链接的一座桥梁。)

function fn1(){

var a = 20;

return function fn2(){

alert(a);

}

}

fn1()();

此处的 fn2函数就是闭包函数。

3. 闭包的作用:

第一:可以读取一个函数内部的函数,

第二:避免“垃圾回收机制”回收,因为子函数会返回一个全局变量,又会调用父函数的局部变量,两个变量相互调用;

所以,两个函数都不会被清除。

4、关于闭包中this的指向问题( 进阶版)。

代码一:

var name = 'The window ';

var object = {

name: ' my object',

fn1 : function(){

alert('1' + this.name); //此处this.name为 my object (因为会继承object)

return function(){

alert('2' + this.name); //此处this.name为The window (没有执行是上下文,所以,找到了windows )

return this.name;

}

}

}

object.fn1()();

难点:红色部分打印出来的为什么是“The window” ?

解释:

我们可以换种写法:

var obj = object.fn1()();

obj();

这里的obj()是函数体 function() { return this.name };

此处的obj指向的是window,所以this.name是The.window

代码二:

var name = "The Window";

  var object = {

    name : "My Object",

    getNameFunc : function(){

        var that = this;

alert(that.name); //?

      return function(){

alert(this.name); //?

alert(that.name); //?

        return that.name;

      };

    }

  };

  object.getNameFunc()();

解释:这里只要是that.name都是指向的“My Object”;

因为,红色的那行代码,把this的指向做了保存。

但是如果用的是,this.name依然指向的是windows(可以参考代码一中的解释)。

猜你喜欢

转载自blog.csdn.net/Allan_L/article/details/81707965