前端面试 JavaScript— 闭包产生的原因?
Posted aiguangyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端面试 JavaScript— 闭包产生的原因?相关的知识,希望对你有一定的参考价值。
要弄清闭包产生的原因,首先要明白作用域链的概念。在ES5中只存在两种作用域:全局作用域和函数作用域,当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链。值得注意的是,每一个子函数都会拷贝上级的作用域,形成一个作用域的链条。
比如:
var a = 1;
function f1() {
var a = 2;
return function f2() {
console.log(a);
// 2
}
};
var num = f1();
num();
在这段代码中,f1 的作用域指向有全局作用域 (window) 和它本身,而 f2 的作用域指向全局作用域 (window)、f1 和它本身。而且作用域是从最底层向上找,直到找到全局作用域window为止,如果全局还没有的话就会报错。
这里 num 会拿到父级作用域中的变量,输出2。因为在当前环境中,含有对函数 f2 的引用,f2 恰恰引用了window、f1和f2的作用域,因此f2可以访问到f1的作用域的变量。
闭包产生的本质就是,当前环境中存在指向父级作用域的引用。
那是不是只有返回函数才算是产生了闭包呢?
回到闭包的本质,我们只需要让父级作用域的引用存在即可,因此我们还可以这么做:
var f2;
function f1(){
var a=2
f2 = function(){
console.log(a);
// 2
}
};
f1();
f2();
让f1执行,给f2赋值后,等于说现在f2拥有了window、f1和f2本身这几个作用域的访问权限,还是自底向上查找,最近是在f1中找到了a,因此输出2。
在这里是外面的变量f2存在着父级作用域的引用,因此产生了闭包,形式变了,本质没有改变。
以上是关于前端面试 JavaScript— 闭包产生的原因?的主要内容,如果未能解决你的问题,请参考以下文章