作用域
作用域的定义
作用域,即变量或函数生效的区域。
作用域的分类
作用域包括全局作用域、函数作用域(局部作用域)、块级作用域。
- 对于全局作用域来说:
最外层函数和最外层函数外面定义的变量拥有全局作用域;所有未定义直接赋值的变量自动声明为全局作用域;所有window对象的属性拥有全局作用域。
全局作用域有很大的弊端,由于全局作用域下声明的变量可以在程序的任意位置访问,声明过多的全局作用域变量会污染全局命名空间,容易引起命名冲突。 - 对于函数作用域(局部作用域)来说:
声明在函数内部的变量拥有函数作用域,这些变量只能在函数内部访问,不能在函数以外去访问。
eg:
function greet() {
// 在函数内部var声明的变量的作用域是函数作用域,不是全局作用域
var greeting = 'Hello World!';
console.log(greeting);
}
greet();
// Uncaught ReferenceError: greeting is not defined
console.log(greeting);
- 对于块级作用域来说:
在大括号中使用let和const声明的变量存在于块级作用域中,在大括号之外不能访问这些变量。
eg:
{
let greeting = 'Hello World!';
var lang = 'English';
console.log(greeting);
}
console.log(lang);
// Uncaught ReferenceError: greeting is not defined
console.log(greeting);
作用域链(scope chain)
作用域链的定义
在当前作用域中查找所需变量,如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
作用域链的本质
是一个指向变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。作用域链的前端始终都是当前执行上下文的变量对象,全局执行上下文的变量对象(全局对象)始终是作用域链的最后一个对象。
作用域链的作用
保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数。