首页 > 程序开发 > web前端 > JavaScript >

js闭包介绍

2017-09-05

js闭包。闭包,顾名思义就是将某个东西包装起来,在js中则是通过包装来限定变量的作用域,可将变量分为全局变量和局部变量,当然,不仅仅是变量,也可限定函数的作用域,如内联函数等。

闭包,顾名思义就是将某个东西包装起来,在js中则是通过包装来限定变量的作用域,可将变量分为全局变量和局部变量,当然,不仅仅是变量,也可限定函数的作用域,如内联函数等。

全局变量:

(1)在web页面中全局变量属于 window 对象。

(2)全局变量可应用于页面上的所有脚本。

(3)它的作用域是全局的。

var a = 4;
function myFunction() {
    return a * a;
}

局部变量:

(1)局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
(2)全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。

function myFunction() {
    var a = 4;
    return a * a;
}

闭包:

有权访问另一个函数作用域内变量的函数都是闭包。js的每个函数都是一个个小黑屋,它可以获取外界信息,但是外界却无法直接看到里面的内容。将变量 a 放进小黑屋里,除了 myFunction 函数之外,没有其他办法能接触到变量a,而且在函数 myFunction外定义同名的变量 a 也是互不影响的,这就是所谓的增强“封装性”。

function myFunction(){
    var a = 0;
    function test(){
        a++;
        console.log(a);
    }
    return test;
}
var test = myFunction();
test();  //控制台输出1
test();  //控制台输出2
而之所以要用 return 返回函数标识 test,是因为在 myFunction 函数外部无法直接调用 test函数,所以 return test与外部联系起来。

当function里嵌套function时,内部的function可以访问外部function里的变量。

function foo(x) {
    var tmp = 3;
    function bar(y) {
        alert(x + y + (++tmp));
    }
    bar(10);
}
foo(2)
不管执行多少次,都会alert 16,因为bar能访问foo的参数x,也能访问foo的变量tmp。
  但,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会获取外部function的变量直到内部function结束。如下:
function foo(x) {
    var tmp = 3;
    return function (y) {
        alert(x + y + (++tmp));
    }
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);
上面的脚本最终也会alert 16,因为虽然bar不直接处于foo的内部作用域,但bar还是能访问x和tmp。但是,由于tmp仍存在于bar闭包的内部,所以它还是会自加1,而且你每次调用bar时它都会自加1。

实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。
JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。

总结:闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

闭包的好处有:
1.缓存
2.面向对象中的对象
3.实现封装,防止变量跑到外层作用域中,发生命名冲突
4.匿名自执行函数,匿名自执行函数可以减小内存消耗

闭包的坏处:
1.内存消耗
通常来说,函数的活动对象会随着执行期上下文一起销毁,但是,由于闭包引用另外一个函数的活动对象,因此这个活动对象无法被销毁,这意味着,闭包比一般的函数需要更多的内存消耗。尤其在IE浏览器中需要关注。由于IE使用非原生javascript对象实现DOM对象,因此闭包会导致内存泄露问题。

2.性能问题
使用闭包时,会涉及到跨作用域访问,每次访问都会导致性能损失。

相关文章
最新文章
热点推荐