Js学习笔记:闭包

# 1、前言javascript

这个周末,注意力都在学习基础Js知识上面,恰好看到了闭包这个神圣的东西,因此打算把这两天学到的总结下来,算是巩固本身所学。也可能有些不正确的地方,也请你们看到了,麻烦在评论下提醒一下,算是互相学习了。html

2、什么是闭包?

百度百科定义:闭包就是可以读取其余函数内部变量的函数。

在解释以前,得先讲讲做用域。先来看下面这个示例:java

var a = 1;
function f(){
  var b = 2;
  console.log(a) // 1
}
console.log(b) // undefined

示例中包含了两种做用域,一种是属于全局的全局做用域,另外一种是属于函数f的局部做用域。因为Javascript这种链式做用域(父做用域是能够被其子做用域访问的,而子做用域却不能被父做用域访问)的机制,使得示例最后一行输出了undefined闭包

今后能够看出,没法从父做用域中访问子做用域。而咱们再来看闭包的定义:闭包就是可以读取其余函数内部变量的函数。也就是闭包可让咱们从父做用域中访问到子做用域,具体怎么实现的呢?来看这个经典的例子:异步

function foo(){
    var a = 2;
    function bar(){
        console.log(a);
    }
    return bar;
}

var baz = foo();

baz(); // 2 -> 这就是闭包的效果

这个示例中,闭包就是函数bar。能够看到,咱们经过在函数foo内部定义其子函数bar,并将其做为foo返回值,由于bar函数做用域能够访问foo的做用域,因此实现了从全局做用域访问foo函数做用域的效果。函数

3、闭包的应用

其实,平时你所写的代码中,早就用到了闭包,只是你还没发现而已。性能

本质上,不管什么时候何地,若是将函数看成值传递到其余地方使用(非函数所在做用域),你就已经使用了闭包。例如上面示例说的函数bar,咱们将他传递到了全局做用域下,经过这种方式访问到本该不能访问的变量a学习

在定时器、事件监听器、Ajax请求、任何其余异步(或同步)任务中,只要使用了回调函数,实际上就是在使用闭包!code

4、注意事项

闭包会让他所在做用域中的变量始终保存在内存中,而不会被垃圾回收机制回收。htm

function foo(p){
    function bar(){
        console.log(++p);
    }
    return bar;
}

var baz = foo(1);
baz(); // 2
baz(); // 3
baz(); // 4

var bazz = foo(2);

bazz(); // 3
bazz(); // 4
bazz(); // 5

baz(); // 5

看到了没,闭包的使用,函数调用以后,让其外层函数的内部变量(foo函数内的变量)始终保存在了内存中,而不会被回收。

值得注意的是,每次调用一次foo,都会生成一个新的闭包,都会在内存中保存下其外层函数的内部变量。所以要注意闭包的使用,不然会致使性能问题。

5、总结

闭包的做用:

  • 可以读取其余函数内部变量。
  • 让其余函数的内部变量始终保存在内存中。

参考:

附:你不知道的Javascript系列电子书网盘连接, 密码:i8jf

相关文章
相关标签/搜索