JavaScript学习笔记(九)执行上下文和作用域
- 每个上下文都有一个关联的变量对象(variable object),而这个上下文中定义的所有变量和函数都存在于这个对象上
- 全局上下文是最外层的上下文;
- 在浏览器中,全局上下文就是我们常说的 window 对象;
- 上下文在其所有代码都执行完毕后会被销毁,包括定义在它上面的所有变量和函数;
- 当代码执行流进入函数时,函数的上下文被推到一个上下文栈上。在函数执行完之后,上下文ಖ会弹出该函数上下文,将控制权返还给之前的执行上下文;
- 上下文中的代码在执行的时候,会创建变量对象的一个作用域链(scope chain),其决定了各级上下文中的代码在访问变量和函数时的顺序;
- 活动对象最初只有一个定义变量:arguments;
- 全局上下文的变量对象始终是作用域链的最后一个变量对象;
作用域链增强
- try/catch语句中的catch块
- catch 语句而言,则会创建一个新的变量对象
- with语句
- 语句会向作用域链前端添加指定的对象
变量声明
var作用域声明
- 使用var声明变量时,变量会被自动添加到最接近的上下文;
- 如果变量未经声明就被初始化了,那么它就会自动被添加到全局上下文
- var 声明会被拿到函数或全局作用域的顶部,位于作用域中所有代码之前
- 通过在声明之前打印变量,可以验证变量会被提升。声明的提升意味着会输出 undefined 而不是Reference Error
1
2
3
4
5
6
7var name = "Lacus";
//等价于
name = "Lacus";
var name;
//---------------------
console.log(msg);//underfined
var msg = "boy";
let块级作用域
- 块级作用域由最近的一对包含花括号{}界定;
- if 块、while 块、function 块,甚至连单独的块也是 let 声明变量的作用域;
- let 在同一作用域内不能声明两次。重复的 var 声明会被忽略,而重复的 let 声明会抛出 SyntaxError;
- let 的行为非常适合在循环中声明迭代变量。使用 var 声明的迭代变量会泄漏到循环外部
- let 在 JavaScript 运行时中也会被提升,但由于“暂时性死区”(temporal dead zone)的缘故,实际上不能在声明之前使用 let 变量。
1
2
3
4
5for(var i=0;i<10;i++){}
console.log(i);//10
for(let j=0;i<10;j++){}
console.log(j);//ReferenceError: j没有定义
const常量声明
- const 声明的变量必须同时初始化为౼个值,一经声明,在其生命周期的任何时候都不能再重新赋予新值
- const 声明只应用到顶级原语或者对象
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论