ES5中定义作用域有两种:全局作用域和函数作用域,ES6中新增了块级作用域,用"{}"表示。
var的用法
var 存在全局作用域和函数作用域两种。但是因为var声明的变量会有一定的缺点(内层变量可能覆盖外层变量的问题以及用来计数的循环变量泄露为全局变量)。
function sum(a,b){
var add = a+b;
return add;
}
console.log(sum(2,3));//5
console.log(add);//add is not defined
由于是在function中定义的add,所以这里的add就会被添加到function的局部环境中,之后再进行调用当然就是不可以的了。
但是在下面操作中:
for(var i = 0;i<10;i++){
}
console.log(i);//10
由于当前的执行环境是全局环境,那么js直接将定义的变量i添加到了全局环境中,那么在for循环之后,依然可以对循环中定义的i进行操作。
用于补全ES5标准中var声明变量的不足,ES6中新增了块级作用域。
let的用法
-
块级作用域
-
一个 {}可以看作一个作用域
-
if语句和 for语句里面的{ }也属于块作用域
for(let i = 0;i<5;i++){
let j = 'abc';
console.log(j);//abc打印5次
}
console.log(i)//i is not defined
在作用域之外 i 不能被访问。
-
let不允许重复声明
-
在相同的作用域内,不能
重复声明
同一个变量
{
let i = 'a';
let i = 'b';
//直接报错
//Identifier 'i' has already been declared
}
{
let i = 'a';
var i = 'b';
//直接报错
//Identifier 'i' has already been declared
}
function fn(a){
let a;
}
fn()//Identifier 'a' has already been declared
function fun(a){
{
let a = 'a';
}
}
fun()//不报错
-
脱离顶层作用域
-
用 var 声明的变量,可以通过
window.变量名
的形式使用 - 用let/const声明的变量不会绑定在顶层作用域window或globle中
var name="张三";
// 常用 this.name
window.name
let age = 15
window.age // undefined
-
临时死区
-
只要一进入当前作用域,所要使用的变量就
已经存在
,但是不可获取
,只有等到声明变量
的那一行代码出现,才可以获取和使用该变量
-
凡是在
声明之前
就使用的变量,就会报错
if(true) {
name = "张三" ;// 没有声明,报错
console.log(name); //报错
let name; // 声明不定义
console.log(name); // undefined
name = "张三";//定义
console.log(name); // 张三
}
const的用法
-
const 声明一个只读的常量
-
一旦声明,常量值就不可以改变。所以const一旦声明就必须立即初始化。
-
只声明,不赋值,会报错
-
不能重新赋值const定义的值,但是可以修改const声明的对象类型。
const i;//Missing initializer in const declaration
const i = 5;
i = 10//Assignment to constant variable.
//不允许重复声明
const i = 5;
const i =10;
//Identifier 'i' has already been declared
-
const 保存的是指向数组或对象的指针
- 对于基本类型值,使用const声明的变量是不可以被修改的。
- 对于对象,指针依然不能被修改,但是指针指向内容可以修改。
const obj = {
name:'张三',
age:25
}
obj = {
name:"李四",
age:30
}
//报错,Invalid or unexpected token
obj.name='李四';
obj.age=30
console.log(obj)//{ name: '李四', age: 30 }
总结
1、块级作用域允许相互嵌套
2、外层作用域不能访问内层变量
3、不同层级作用域可以定义同名变量
4、const 的作用域与let命令相同,只在声明所在的块级作用域内有效
5、const声明的变量也不存在变量提升,同样存在暂时性死区,只能在声明位置的后面使用
6、const声明的常量和let一样不可重复声明
7、es6允许在块级作用域下声明函数,在块级作用域外面不可引用
凡是有{}者都有块级作用域
8、ES6的块级作用域必须有大括号 {} 如果没有{} js引擎认为不存在块级作用域