day16-JavaScript 变量作用域
一、前言
我们今天来聊聊JavaScript的作用域,聊这个之前先卡看看其他语言包括python在内的,作用域的范围是多少,规则是怎么样的。然后再看看JavaScript的作用域。这样就有对比性。
二、其他语言的作用域
2.1、其他语言
说明:以代码块作为作用域
|
1
2
3
4
5
6
7
|
public void Func(){ if(1==1){ string name = "java"; } console.writeline(name);// 报错,因为是以代码块作为作用域的,所以报错。}Func(); |
正确的代码:
|
1
2
3
4
5
6
7
|
public void Func(){ if(1==1){ string name = "java"; console.writeline(name); //正确,出了if的代码块就报错 } }Func(); |
2.2、python的作用域
说明:以函数作为作用域
|
1
2
3
4
5
6
|
def func(): if 1==1: name = "alex"func()print(name) #报错,因为是以函数作为作用域 |
正确的代码:
|
1
2
3
4
5
6
|
def func(): if 1==1: name = "alex" print(name)func() #正确 |
三、 JavaScript的作用域特性
3.1、以函数作为作用域(let除外)
|
1
2
3
4
5
6
7
8
|
function func(){ if(1==1){ var name = 'alex'; } console.log(name); //作用域是以函数作为作用域}func(); |
3.2、函数的作用域在函数未被调用之前,已经创建
|
1
2
3
4
5
6
|
function func(){ if(1==1){ var name = 'alex'; } console.log(name);} //浏览器在解释它的过程当中,作用域已经创建了 |
3.3、函数的作用域存在作用域链,并且也是在被调用之前创建
说明:一个作用域套另外一个作用域,我们称之为作用域链。
示例一:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
name = "alex";function func(){ var name = "sgaogao"; function inner() { var name = "sbhong"; console.log(name) } inner(); //调inner作用域}func();输出:sbhong |
逻辑图:

这张图的意思是:name->先找最近的'sbh'->没有就找'sgg'->再没有就‘alex’->再没有就报错了。
示例二:
说明:作用域链在创建之前被创建
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
name = "alex";function func(){ var name = "sgaogao"; function inner() { //var name = "sbhong"; console.log(name) } return inner;}var ret = func();ret(); //跟上面效果是一样的#输出sgaogao |
注意:就是说在代码在执行之前作用域链就已经生效了,而不是执行的生效,所以在执行之前关系已经建立
示例三:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
name = "alex";function func(){ var name = "sgg"; function inner() { console.log(name) } var name = "tony"; return inner;}var ret = func();ret(); |
逻辑图:

逻辑说明:先在inner函数内部找 - >func 内部找,这个时候发现name的值变化了,找到最新的name值->再找不到,就找最外面的name。
3.4、函数内部的变量 声明提前
示例一
说明:没有声明变量的情况
|
1
2
3
4
5
|
function func(){ console.log(name);}func();//程序直接会报错 |
示例二
说明:只声明,没有赋值,JavaScript给你默认赋值一个特殊的值,叫undefined。
|
1
2
3
4
5
6
7
8
9
|
function func(){ console.log(name); var name = "shuaigaogao";}func();//输出undefined |
因为解释器在解释的过程中,先找到function 内部所有的局部变量,然后执行var name;所以在作用域里面声明了,但是没有赋值,所以这个值就默认为undefined。


浙公网安备 33010602011771号