闭包
2018-02-05 本文已影响0人
zy懒人漫游
作用域
理解闭包之前我们要弄清楚js的变量作用域,变量作用域就2种,
- 全局变量
- 局部变量
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
var a=1;
function fn(){
console.log(a);
}
fn(); //1
函数外部不能读取函数内部的局部变量
function fn(){
var a=1;
}
console.log(a);//报错
注意:函数内部声明变量的时候,一定要使用var声明。如果不用的话,实际上声明的是一个全局变量。如下
function fn(){
var a=1;
}
fn()
console.log(a);//1
外部读取局部变量
当有时候我们需要从外部得到函数内部的变量时,这个时候我们可以在函数内部再定义一个函数
function fn1(){
a=1;
function fn2(){
console.log(a); // 1
}
}
- 函数fn2就被包括在函数fn1内部,这时fn1内部的所有局部变量,对fn2都是可见的。但是反过来就不行,fn2内部的局部变量,对fn1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构.
- 子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
- 既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量。如下
function fn1(){
a=1;
function fn2(){
console.log(a);
}
return fn2;
}
var result=fn1();
result(); // 1
闭包的概念
- 闭包就是指函数可以记住并访问所在的词法作用域,并且保持着对词法作用域的引用,即使函数在当前作用域之外执行,就会形成闭包。
- 对于闭包的形成,实质上就是所涉及的词法作用域和将函数作为值return
- 当在函数内部声明了内部函数,并将内部函数作为值返回,就会产生闭包。
- 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。