龙空技术网

一字之差,大相径庭——作用域与作用域链

尚硅谷教育 64

前言:

而今各位老铁们对“块级作用域和局部作用域有什么区别”大体比较着重,同学们都需要分析一些“块级作用域和局部作用域有什么区别”的相关文章。那么小编也在网摘上汇集了一些对于“块级作用域和局部作用域有什么区别””的相关文章,希望我们能喜欢,咱们一起来学习一下吧!

作用域是变量和表达式在其中“可见”或可被访问到的上下文。如果一个变量或者其他表达式不 “在当前的作用域中”,那么它就是不可用的。换句话说,作用域决定了代码区块中变量和其他资源的可见性。

只要是代码都在一个作用域中,写在函数内部的在局部作用域中,未写在任何函数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个新的作用域;根据在内部函数可以访问外部函数变量的这种机制,用链式查找来决定哪些数据能被内部函数访问,就称为作用域链(scope chain)。

一、作用域

作用域就是变量的可用性的代码范围,就叫做这个变量的作用域。简单理解,就是在这个范围内,变量是可以使用的,超过这个范围,变量就无法使用,这个范围就是作用域。

作用域分为三种:全局作用域、局部作用域、块级作用域。

全局作用域

作用于当前所有代码执行的环境(script标签内部)或者一个独立的js文件。

script标签可以有多个,不同的script标签里的代码都在全局作用域内,script标签的解析是有先后顺序的,在前面的script标签先解析,后面的后解析。所以后面的script标签里的代码能访问到前面script里的变量/函数,而前面的script标签里的代码无法访问后面script标签里的变量/函数。

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。

▷全局变量在代码的任何位置都可以使用。

▷在全局作用域下var声明的变量是全局变量。

▷特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)。

//示例:创建一个拥有全局作用域的变量a

var a=0;

function fun(){

conslie.log(a);//在函数局部内访问变量a

}

console.log(a);//在全局访问变量a

局部作用域

作用于函数内的代码环境,就是局部作用域。因为跟函数有关系,所以也称为函数作用域。

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量),在局部作用域下声明的函数叫局部函数。

▷局部变量只能在该函数内部使用。

▷在函数内部 var 声明的变量是局部变量。

▷函数的形参实际上就是局部变量。

//示例:创建一个拥有局部作用域的变量b

function fun(){

var b=1;

console.log(b);//1

}

console.log(b);//b is not defined

块级作用域

▷在ES6中新增了块级作用域的概念,使用{}扩起来的区域叫做块级作用域

▷所有用let和const声明的变量符合块作用域。

▷块作用域指非函数的{},if语句和for语句里面的{}也属于块作用域。

▷在块内使用let声明的变量,只会在当前的块内有效。

//全局声明一个变量b

let b = 1;

fn1();

function fn1() {

//当前的作用于没有b,沿着作用于寻找到全局的b

console.log(b);

if (true) {

//只在当前的作用于中生效

let b = 2;

}

}

二、作用域链

▷作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。

▷作用域链是在函数定义的时候就已经产生了,但是并不完整,因为当前函数没有调用,所以当前函数的变量对象还没有产生。

▷当函数调用的时候,会创建当前上下文的变量对象,然后添加在已经生成的作用域链的开始位置,构成完整的作用域链。

▷作用域链的开始位置一定是当前的执行环境的变量对象,结束位置一定是window。

▷变量的解析是沿着作用域链搜索的过程,直到寻找到位置,如果一直找不到,则报错。

案例分析1:

function f1() {

var num = 123;

function f2() {

console.log( num );

}

f2();

}

var num = 456;

f1();

变量查找原则:沿着作用域链一级一级的搜索,从作用域链的前端开始,然后逐级地向上找,直至找到该变量为止,如果找不到标识符,通常会导致错误发生。

简单来说就是:就近原则的方式来查找变量最终的值。

案例分析2:

var a = 1;

function fn1() {

var a = 2;

var b = '22';

function fn2() {

var a = 3;

function fn3() {

var a = 4;

console.log(a); //a的值 4

console.log(b); //b的值 "22"

}

fn3();

}

fn2();

}

fn1()

三、总结

1. 作用域和作用域链是两码事

2. 作用域是变量起作用的范围,定义的时候就确定了。

3. 作用域链是程序找变量的过程,用一个变量对象数组去描述的。调用的时候才能确定。

4. 函数在定义的时候就确定了作用域和上一级作用域链。

5. 函数在调用的时候就确定自己执行上下文的作用域链和this指向。

标签: #块级作用域和局部作用域有什么区别