一、 块级作用域{}
ES5 中作用域有:全局作用域、函数作用域。
ES6 中新增了块级作用域 块级作用域由{ }包括。if语句和for语句里面的{ }也属于块级作用域
{
var a = 1;
console.log(a); // 1
}
console.log(a); // 1
通过var定义的变量可以跨块作用域访问到
(function A() {
var b = 2;
console.log(b); // 2
})();
// console.log(b); // 报错 b is not defined
通过var 定义的变量不能跨函数作用域访问到
if (true) {
var c = 3;
}
console.log(c); // 3
for (var i = 0; i < 4; i++) {
var d = 5;
}
console.log(i); // 4
console.log(d); // 5
if语句和for语句中用var 定义的变量可以在外面访问到
if语句和for语句属于块级作用域,不属于函数作用域
二、var、let、const的区别
1.var
作用:
声明变量
特点:
- 函数作用域
- 可以变量提升(预解析)
- 值可以更改
2.let
特点:
- let声明的变量只在所处于的块级有效
好处 : 可以防止循环变量变成全局变量 : (使用var就不会报错)
for (let i = 0; i < 2; i++) {}
console.log(i);//报错: i is not defined
- 不存在变量提升,不能重复声明
console.log(a); // a is not defined
let a = 20;
- 暂时性死区
利用let声明的变量会绑定在这个块级作用域,不会受外界的影响
var tmp = 123;
if (true) { //因为在此块级作用域中,使用了let声明了tmp变量,那么tmp会与此块级作用域进行绑定,形成死区,不受外界影响(无法访问外部的tmp)
tmp = 'abc';//这里会报错,变量未声明,不能赋值
let tmp;
}
3.const
作用:
声明常量,常量就是值(内存地址)不能变化的量
常量:常态的量,值是常态的量,值无法改变
特点:
- 具有块级作用域
if (true) {
const a = 10;
}
console.log(a) // a is not defined
- 声明常量时必须赋值
const PI; // Missing initializer in const declaration,声明常量时丢失初始化
- 常量赋值后,值不能修改,如果声明的是复合类型数据,可以修改其属性
const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改;如果声明的是复合类型数据,可以修改其属性
const person = {
name: 'zs',
sex: '男'
}
person.name = 'ls';
console.log(person.name); // ls person对象的name属性被修改了
// 对象是引用类型的,person中保存的仅是对象的指针,const仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所有是被允许的
// 简单来说:const定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的
// const只是一个指针,指向一个内存空间,内存空间的内容可以改变,但是const指向一个新的空间就会报错
// person = {
// name: 'haha',
// sex: '女'
// } // 报错
注意:
-
var 定义的变量,没有块的概念,可以跨块访问,不能跨函数访问
-
let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
-
var声明变量存在变量提升,let和const不存在变量提升,所以用 let 定义的变量一定要在声明后再使用,否则会报错
-
var 变量可以多次声明,而 let 不允许在相同作用域内,重复声明同一个变量
-
const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改;如果声明的是复合类型数据,可以修改其属性
// 块作用域
{
var a = 6;
let b = 7;
const c = 8;
// c = 9; // 报错 const 定义常量,不能修改
var aa;
let bb;
// const cc; // const 用来定义常量,使用时必须赋值
console.log(a); // 6
console.log(b); // 7
console.log(c); // 8
console.log(aa); // undefined
console.log(bb); // undefined
}
console.log(a); // 6
// console.log(b); // 报错
// console.log(c); // 报错
// 函数作用域
(function B() {
var e = 9;
let f = 10;
const g = 11;
console.log(e); // 9
console.log(f); // 10
console.log(g); // 11
})();
// console.log(e); // 报错
// console.log(f); // 报错
// console.log(g); // 报错