1、含义
闭包是指有权访问另外一个函数作用域中的变量的函数
闭包是一种特殊的对象,它由两部分组成:执行上下文(代号 A),以及在该执行上下文中创建的函数 (代号 B),当 B 执行时,如果访问了 A 中变量对象的值,那么闭包就会产生,且在 Chrome 中使用这个执行上下文 A 的函数名代指闭包。
2、变量的作用域
1、全局变量:
在函数内部可以直接读取全局变量
var a = 5 //定义全局变量a
function closure() {
console.log('获取全局变量a:' + a) //在函数内部访问全局变量a
}
closure() // 获取全局变量a:5
2、局部变量:
在函数外部自然无法读取函数内的局部变量
,提示报错:局部变量 is not defined
function closure() {
var a = 5 //定义局部变量a
}
closure()
console.log('获取局部变量a:' + a) //在函数外部访问函数内部变量a 报错 Uncaught ReferenceError:a is not defined
注意:
函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上是声明了一个全局变量
function closure() {
a = 5 // 此时a是一个全局变量
}
closure()
console.log("a在closure函数内部没有使用var来声明,此时a就是一个全局变量,\r\a证明:a="+ a +",window.a == a的结果是:"+(window.a==a)) // a在closure函数内部没有使用var来声明,此时a就是一个全局变量,
a证明:a=5,window.a==a的结果是:true
3、本质:
当前环境中存在指向父级作用域的引用
4、一般如何产生闭包
- 返回函数
- 函数当做参数传递
5、应用场景
- 柯里化 bind
- 模块
6、如何从外部去得到内部的值呢?
请看如下:
function a () {
var num = 5;
function b () {
console.log(num)
}
return b;
}
// a() // b函数
var test = a()
test() // 5
注意点:this关键字
var name = "hello"
var fun = {
name: "zhangsan",
getName: function() {
return function() { // 匿名函数的执行有全局性,所以指向了全局name
return this.name
}
}
}
alert(fun.getName()()) // 'hello'
将this对象赋值给了一个名叫this的变量而定义了闭包之后,闭包可以访问到这个变量
var name = "hello"
var fun = {
name: "zhangsan",
getName: function() {
var that = this;
return function() {
return that.name
}
}
}
alert(fun.getName()()) // 'zhangsan'
7、实现的条件
- 内部函数访问了外部函数的变量
- 外部函数已经退出
- 内部函数仍可以访问
function fun() {
var x = 0;
return function (y) {
x = x + y;
console.log(x);
}
}
var a = fun();
a(1); //1
a(1); //2