变量作用域
1.在JavaScript中定义变量有两种方式
ES6之前: var 变量名称;
ES6开始: let 变量名称;
2.两种定义变量方式的区别
- 如果通过
var
定义变量,可以重复定义同名
的变量,并且不会报错
,后定义的会覆盖
先定义的; - 如果通过
var
定义变量,可以先使用后定义
(预解析); - 如果通过
let
定义变量,不可以重复定义
同名变量; - 如果通过
let
定义变量,不可以先使用再定义
,因为浏览器不会对let定义的变量进行预解析. - 通过
var
定义的变量是不区分全局变量和局部变量
,通过let
定义的变量是区分全局变量和局部变量的
3.全局变量和局部变量
全局变量:就是定义在{}外面的变量.
局部变量:就是定义在{}里面的变量.
4.全局变量和局部变量的区别
如果是全局变量,那么有效范围就是从定义变量的那一行开始直到文件的末尾都可以使用(无论是通过var还是通过let定义的全局变量);
如果是局部变量,那么有效范围就是从定义变量的那一行开始知道到括号结束位置(只有在大括号中才能使用)
如果是通过var定义的局部变量,和全局变量一样,后续都可以被使用,如果是通过let定义的局部变量,那么这个变量只能在当前定义变量的{}中使用
5.函数中变量作用域
- 在JavaScript中{}外面的作用域,我们称之为
全局作用域
; - 在JavaScript中
函数后面{}
中的作用域,我们称之为局部作用域
; - 在ES6中只要{}没有和函数结合在一起,那么就是
块级作用域
; - 块级作用域和局部作用域的区别:
1.在块级作用域中通过var定义的变量是全局变量;
2.在局部作用域中通过var定义的变量是局部变量; - 无论是在块级作用域中还是局部作用域,省略变量前面的let或者var就会变成一个全局变量.
{
//块级作用域
}
if(false){
//块级作用域
}
while(false){
//块级作用域
}
for(::){
//块级作用域
}
do{
//块级作用域
}while(false);
switch(){
//块级作用域
}
function say(){
//局部作用域
}
注意点:在不同的作用域范围内,是可以出现同名的变量的.
作用域链
ES6之前
1.定义变量只能通过var;
2.没有块级作用域,只有全局作用域和局部作用域;
3. 函数大括号外的都是全局作用域;
4. 函数大括号中的都是局部作用域
ES6之前的作用域链:
1.全局作用域又称为0级作用域;
2.定义函数开启的作用域就是1级/2级/3级/…作用域;
3.JavaScript会将这些作用域链接在一起形成一个链条,这个链条就是作用域链;
0—>1—>2—>3—>4
4.除0级作用域以外,当前作用域级别等于上一级+1.
变量在作用域链的查找规则
1.现在当前找,找到就使用当前作用域找到的;
2.如果在当前作用域中没有找到,就去上一级作用域中查找;
3.以此类推直到0级为止,如果0级作用域还没找到,就报错.
ES6开始
1.定义变量通过let;
2.除了全局作用域和局部作用域以外,还新增了块级作用域;
3.虽然新增了块级作用域,但是通过let定义变量并无差异(都是局部变量)
ES6作用域链
1.全局作用域又称为0级作用域;
2.定义函数或者代码块都会开启的作用域就是1级/2级/3级/…作用域;
3.JavaScript会将这些作用域链接在一起形成一个链条,这个链条就是作用域链;
0—>1—>2—>3—>4
4.除0级作用域以外,当前作用域级别等于上一级+1.