深入理解 JS 闭包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjuwwj/article/details/76155815

1. 什么是闭包

简而言之:内部函数被外部函数之外的其他变量引用时,就形成了闭包。

2. GC 回收机制

在js里,如果一个对象不再被引用时,就会被GC回收,否则就一直保存在内存中。

3. 闭包有什么用

当我们需要在模块中定义一些变量,并希望这些变量一直保存在内存中但又不会“污染”全局的变量时,就可以用闭包来定义这个模块。

4. 最简单的闭包

function A() {
    var count = 0;
    function B() {
        count ++;
        console.log(count);
    }
    return B;
}
var C = A();
C(); //1
C(); //2
C(); //3

5. 实用的闭包

闭包允许将函数与其所操作的某些数据(环境)关连起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。因而,一般说来,可以使用只有一个方法的对象的地方,都可以使用闭包。

以下是一个实际的示例:假设我们想在页面上添加一些可以调整字号的按钮。一种方法是以像素为单位指定 body 元素的 font-size,然后通过相对的 em 单位设置页面中其它元素(例如页眉)的字号:

CSS 如下:

body {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}

h2 {
  font-size: 1.2em;
}

HTML 如下:

<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>

JS 如下:

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

6. 慎用闭包

如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用,方法都会被重新赋值一次(也就是说,为每一个对象的创建)。

7. 网易游戏笔试题

写一个add()函数,使得add(a,b)和add(a)(b)输出结果相同

function add(a,b) {
    if(arguments.length==2) {
        return a + b;
    } else {
        return function(b) {
            return a + b;
        }
    }
}
add(3,4);//7
add(3)(4);//7

参考文章:干货分享:让你分分钟学会JS闭包MDN闭包教程

猜你喜欢

转载自blog.csdn.net/zjuwwj/article/details/76155815