欢迎光临
我们一直在努力

JavaScript | 初识闭包定义和优缺点

闭包是JavaScript经常用到的编程方法,本篇文章由渐入深逐渐介绍闭包的概念与用途,以及注意事项。闭包的难点在于不同书籍对其定义不尽相同,因此掌握其编程思想才是重中之重,而非学习表面的概念。

古老定义

闭包:指函数变量可以保存在函数作用域内部,变量像是被函数“包裹”起来一样。

也就是说,包含变量的函数就是闭包。

//古老定义,把函数变量放在作用域内,变量被包了起来
function fun(){
    var x = 0;
}
console.log(x);//无法访问,报错

定义一

闭包:指可以访问其所在作用域的函数

也就是说,需要通过作用域链查找变量的函数就是闭包

//定义一:闭包是可以访问其所在作用域的函数
var a = 0;
function fun(){
    console.log(0)
}
fun();

定义二

闭包:指有权访问另一个函数作用域的变量的函数

也就是说,访问上层韩束的作用域的内容函数就是闭包

//定义二:闭包指有权访问另一个函数中的变量的函数
function foo(){
    var b = 0;
    function foo2(){
        console.log(b);
    }
    foo2();
}

定义三

闭包:指在函数声明时的作用域以外的地方被调用的函数

也就是说,可以通过在函数内部声明一个函数,并将其return出去

//返回值
function foo(){
    var a = 0;
    function foo2(){
        console.log(a);
    }
    return foo2;
}
foo()();

//返回值简写
function foo(){
    var a = 0;
    return function(){
        console.log(a);
    }
}
foo()();

或者,可以通过参数传递的形式在函数声明时的作用域以外的地方调用

//参数形式
function foo(){
    var a = 0;
    function foo2(){
        alert(a);
    }
    foo3(foo2);
}
function foo3(fn){
    fn();
}

也就是说,只要将内部函数传递到所在的作用域以外,他都会持有对原始作用域的引用,无论在何处执行这个函数都会使用闭包。

严格来说

严格来说,需要满足下面三个条件才能被称为闭包:访问所在作用域、函数嵌套、在所在作用域以外被调用。

闭包的优缺点

优点不用多说:有利于封装,可以访问局部变量

闭包的缺点在于:内存浪费严重,会造成内存泄漏

什么情况下会造成内存泄漏?看下面的代码

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

可以看到上面nAdd执行后rs()在此执行,n的值+1,也就是说,此时n常驻内存中了。

下面我们每次执行时不创建新的变量rs,直接执行,在下面代码中在nAdd中新增打印n的语句,最后结果如下:

function f1(){
    var n = 999;
    nAdd = function(){
        n = n + 1;
        console.log(n); //新增语句
    }
    function f2(){
        console.log(n);
    }
    return f2;
}
f1()(); //999
nAdd(); //执行了,但随后被销毁 1000
f1()(); //999

不过这么做没什么意义,因为第二次执行f1()()实际上,是先执行f1(),此时n的变量被重置为999,然后执行f1()(),此时自然打印999。

所以,正经闭包通过这种方法还是没办法避免内存泄漏问题。

赞(1) 打赏
未经允许不得转载:散人研 » JavaScript | 初识闭包定义和优缺点
分享到: 更多 (0)

评论 抢沙发

3 + 4 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏