js闭包

参考链接:https://www.cnblogs.com/echolun/p/11897004.html

1、什么是闭包?

闭包在JavaScript高级程序设计(第3版)中是这样描述:闭包是指有权访问另一个函数作用域中的变量的函数

我个人的理解更多是 :A函数里面嵌套了一个B函数,B函数使用了A函数的内部变量,且A函数返回B函数,这就是闭包。还有一种概念就是:所谓闭包其实就是一个自带了执行环境(由外层函数提供,即便外层函数销毁依旧可以访问)的特殊函数;那么回到文章开头的提问,这段代码中的闭包指代的就是内部函数 insider,而非外部函数outer所包含的范围,这一点一定得弄清楚。

2、闭包产生的条件

1.函数嵌套
2.内部函数引用了外部函数的数据(变量/函数)
3.执行外部函数

3、闭包的特征

1. 首先他是一个函数。 
2.闭包能访问外部函数作用域中的自由变量,即使外部函数上下文已销毁。

 1 function fn1() {
 2     //此时闭包就已经产生了(函数提升, 内部函数对象已经创建了)
 3     var a = 2
 4     function fn2 () {
 5       a++
 6       console.log(a)
 7     }
 8 //    var fn2 = function () { //若是这样写要等这行执行完闭包才产生,函数定义执行
 9 //
10 //    }
11     return fn2
12   }
13  //fn1()  //若是这样执行,第一次执行完成以后闭包就不再存在
14   var f = fn1() 
15   f() // 3
16   f() // 4
17   f = null //不再引用,闭包死亡(包含闭包的函数对象成为垃圾对象)

这是一个典型的闭包,fn2嵌套在fn1里面,fn2引用了fn1的局部变量a,fn1返回了fn2,执行了fn1函数,当执行完 var f = fn1(),fn1会从执行上下文中弹出并销毁。

那么为什么函数都销毁了,为啥还能访问到它里面的变量,我个人的理解应该是引用和作用域链的关系,需要查资料核实。

当我们不再使用的时候就让它等于null,进行释放,以免造成内存泄漏。

4.闭包的作用

创建私有属性和方法

构造函数:

function Person(name) {
    //这是一个私有属性
    var age = 3;
    //这些是构造器属性
    this.name = name;
    this.hello = function () {
        console.log(`我的名字是${this.name},我今年${age}岁了`);
    };
};
var person = new Person('leah');
person.hello();//我的名字是leah,我今年3岁了

如果某个属性方法在所有实例中都需要使用,我们一般推荐加在构造函数的prototype原型链上,还有种做法就是利用私有属性。比如这个例子中所有实例都可以正常使用变量 age。同时我们将age称为私有属性的同时,我们也会将this.hello称为特权方法,因为你只有通过这个方法才能访问被保护的私有属性age啊。

函数工厂:

function makeAdder(x) {
    return function (y) {
        console.log(x + y);
    };
};

var a = makeAdder(5);
var b = makeAdder(10);
a(2); // 7
b(2); // 12

在这个例子中,我们利用了闭包自带执行环境的特性(即使外层作用域已销毁),仅仅使用一个形参完成了两个形参求和的骚操作,是不是很奈斯。当然例子函数还有个更专业的名词,叫函数柯里化。

不积跬步无以至千里
原文地址:https://www.cnblogs.com/lyt0207/p/12039934.html