您现在的位置是:首页 > Javascript
当前栏目
前端面试 【JavaScript】— 闭包产生的原因?
2023-03-15 22:05:04 时间
要弄清闭包产生的原因,首先要明白作用域链的概念。在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存在着父级作用域的引用,因此产生了闭包,形式变了,本质没有改变。
相关文章
- 六个藉藉无名但迅速崛起的Apache大数据项目
- 到底哪些系统组件应该进行日志记录?
- 用户对一个网站反感的原因是什么?
- 你不知道的六大Apache大数据项目新星
- 百度高级安全工程师吴登辉:Web防火墙大数据分析实践
- 深入实践Spring Boot第1章
- 深入实践Spring Boot1.5 关于Spring Boot配置
- Apache五大主流流计算框架详细对比
- 深入实践Spring Boot第3章
- Hadoop生态系统在壮大:十大炫酷大数据项目
- 深入实践Spring Boot3.4 视图设计
- 介绍下smartclient
- 用Socket实现HTTP文件上传
- SpringBoot修改默认端口号
- SpringBoot热部署
- SpringBoot加载静态资源
- SpringMvc系列之SpringMvc常用请求映射器实例
- jQuery获取数组对象的值
- SAX简单解析XML
- hello React.js