要了解清楚js中的闭包制机,那么得先了解全局执行环境、块级执行环境、函数执行环境、变量对象、环境栈、作用域链、摧毁执行环境。
全局执行环境
全局执行环境指的是最外层的执行环境。在web中全局执行环境被认为window对象,所以你在全局环境中创建的变量与函数都是对象的属性和方法。
函数执行环境
函数执行环境指的是函数体。
块级执行环境
块级执行环境指的是块级定义区域。
'use strict';
// 全局执行环境
// .....
{
// 块级执行环境
// 代码 ....
} function func() {
// 函数执行环境
//...
}
变量对象
每一个执行环境最有一个与之关联的变量对象,变量对象中存储当前环境中定义的变量与函数。在使用变量或函数时,都是在个变量对象上去寻找成员的。这个对象是无法访问的,但是你可以在作用域链[scope]中查看到所定义的成员(如果没有使用的话可能无法看到,这和优化有关)。
环境栈
每个函数或块都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入“环境栈”中。函数执行完后,栈将其弹出并销毁变量对象,然后把控制权返回在给之前的执行环境。如果内执行环境的变量对象,被外部执行环境引用,那么内部环境变量对象就无法被销毁(如:闭包)。
作用域链
作用域链是一个列表,存储着与执行环境相关的变量对象,通过【scope】属性可查看变量对象列表。
关系图
实例讲解
// 例子1:常见的函数嵌套
'use strict';
function a() {
let x = 2;
return function() {
return x;
}
}
let func = a(); // 返回a函数体内的 匿名函数
console.log(func()); // 在全局执行环境中,访问a函数内部变量。 如果是非闭包函数,那么执行完后
我们来看一下,a函数体内匿名函数的作用域链。
[Scopes] : 是当前匿名函数的作用域链。
索引为 0 的:是a函数的执行环境的变量对象, x 表示 变量对象中的。
索引为 1 的:全局执行环境变量对象。
// 例子2:访问块内部变量
1:返回块级内容函数 实现在全局执行环境中访问块级内容变量。
'use strict';
let func = null;
{
let x = "你好";
func = function () {
return x;
}
}
// 返回块级内容函数 实现在全局执行环境中访问块级内容变量。
console.log(func());
作用域链图:
我的百度经验地址:https://jingyan.baidu.com/article/adc81513c23327f722bf7358.html