JavaScript 作用域(scope)和作用链(scope chain)
作用域(scope)
-
全局作用域
//在所有函数和中括号(区块)外面 const me = 'chen'; //变量定义在全局作用域可以在任何地方访问 console.log(me) //chen
-
函数作用域
function name(){ //只能在该函数内访问 const me = 'chen' console.log(me) //chen } console.log(me) //ReferenceError
-
区块作用域
const me = 'chen' if(me === 'chen'){ //let,const变量定义在区块作用域只能在区块中访问 const age = 20 console.log(age)//20 } console.log(age)//ReferenceError if(me === 'chen'){ //var 可以在区块外访问 var job = 'programer' } console.log(job)//programer
作用域链(Scope China)
先看个例子:
const global_variable = 1;
function first(){
const first_variable = 2;
function second(){
const second_variable = 3
console.log(global_variable) //输出 1
console.log(first_variable) //输出 2
console.log(second_variable) //输出 3
}
second()
console.log(global_variable) //输出 1
console.log(first_variable) //输出 2
// console.log(second_variable) ReferenceError
}
first()
console.log(global_variable) //输出 3
// console.log(first_variable) ReferenceError
// console.log(second_variable) ReferenceError
首先,判断一下变量的作用域
-
global_variabe
属于全局作用域 -
first_variable
属于first函数作用域 -
second_variable
属于second函数作用域
在second函被调用时,遇到语句 console.log(global_variable)
执
行引擎会这样执行
-
找second函数作用域内有没有变量global_variable
-
找定义second函数的作用域,就是first函数作用域有没有变量global_variable
-
找定义first函数的作用域,就是全局作用域有没有变量global_variable
在以上任意一步,找到了就返回
而且可以看出,作用域链是单向的,second中可以访问first的变量,但是first不能访问second的变量。同理,对于first和global也一样。
作用域链跟函数调用栈没有半点关系,可以看一下例子
const global_variable = 1; function third() { console.log(global_variable);//输出 1 //运行到这是,函数调用栈是这样的:third()->second()->first() //但是运行一下两个语句,会报引用错误(找不到变量) //由此可以知道,作用域链跟函数调用栈没有什么关系 //console.log(first_variable) ReferenceError //console.log(second_variable) ReferenceError } function first() { const first_variable = 2; function second() { const second_variable = 3; third(); } second(); } first();