从事web开发工作的,难免会听到作用域链这个词,如果你还是似懂非懂的话,那么看这篇文章就足够了。要理解什么是作用域链,那必须先理解变量作用域,函数作用域,下面我来一一介绍。
变量作用域
在js中,变量分为全局变量和局部变量。全局变量的作用域是全局的,在任意地方都是被定义的。而局部变量可以是函数的参数、函数内定义以及{}内(ES6语法)定义,如果局部变量与全局变量重名的话,会优先取局部变量。下面我们来看看例子:
引用全局变量例子:
var num = 1; //定义一个全局变量
function func(){
console.log(num); //这里引用了全局变量
}
func(); //输出:1
同名变量优先局部变量例子:
var num = 1; //定义一个全局变量
function func(){
var num = 2; //声明局部变量时一定要使用var,否则解释器会将该变量当做全局对象window的属性
console.log(num); //这里引用了局部变量
}
func(); //输出:1
函数作用域
变量在声明它们的函数体以及这个函数体内的任意函数体都是定义的,请看例子:
function func(){
var num = 1;
console.log(num); //输出:1
function func1(){
console.log(num); //输出:1
}
func1();
}
func();
作用域链
把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止,当函数中需要查询一个变量的值的时候,js解释器会去从作用域链查找,从最前面的本地变量中先找,如果没有找到对应的变量,则到下一级的链上找,一旦找到了变量,则不再继续,如果找到最后也没有找到需要的变量,则解释器返回undefined。请看例子:
例子1:
var num = 1;
function func(){
var num = 2;
function func1(){
var num = 3;
console.log(num); //输出:3 先找函数自身的本地变量
}
func1();
}
func();
例子2:
var num = 1;
function func(){
var num = 2;
function func1(){
console.log(num); //输出:2 先找函数自身的本地变量,再找父级函数中的变量
}
func1();
}
func();
例子3:
var num = 1;
function func(){
function func1(){
console.log(num); //输出:1 先找函数自身的本地变量,再找父级函数中的变量,然后再找到全局对象的变量
}
func1();
}
func();
例子4:
function func(){
function func1(){
console.log(num); //输出:undefined 先找函数自身的本地变量,再找父级函数中的变量,然后再找到全局对象的变量,还是没找到就返回undefined
}
func1();
}
func();
网友评论