ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念。
ES6 中新增块级作用域。块作用域由
{ }包括,if语句和for语句里面的{ }也属于块作用域。
var
- 没有块作用域
{
var a = 1
console.log(a); // 1
}
console.log(a); // 1
if (true) {
var d = 4
}
console.log(d); // 4
for (var index = 0; index < 4; index++) {
var e = 5
}
console.log(index); // 4
console.log(e); // 5
var具有函数级作用域。这意味着用var声明的变量可以在声明它的整个函数内部访问,不管在函数中的哪个位置声明的。
(function C() {
var c = 3
console.log(c); // 3
})()
console.log(c); // c is not defined
- 用
var声明的变量会被提升到其所在函数或全局作用域的顶部。这意味着你可以在代码中在变量声明之前使用一个var变量,但它的初始值会是undefined。
{
console.log(a); // undefined
var a = 1
}
console.log(a); // 1
let
- 有块作用域
{
let a = 1
console.log(a); // 1
}
console.log(a); // a is not defined
(function C() {
let c = 3
console.log(c); // 3
})()
console.log(c); // c is not defined
if (true) {
let d = 4
}
console.log(d); // d is not defined
for (let index = 0; index < 4; index++) {
let e = 5
}
console.log(index); // index is not defined
console.log(e); // e is not defined
// 以上代码同样适用于const
const
- 有块作用域,但是他只能赋值一次。
- 对于一些常量,可以使用const声明,声明之后不可更改
- 对于一些对象(函数)也可以使用const声明,这样可以
避免对象(函数)被意外修改,可以更改对象(函数)内部的值,但是不可以整体重新赋值
const a = 1
a = 4 // Uncaught TypeError: Assignment to constant variable
const b = {
age: 1
}
b.name = 'lili'
console.log(b); // {age: 1, name: 'lili'}
b = {
age: 2,
name: 'Mary'
} // Uncaught TypeError: Assignment to constant variable
const c = function (arr) {
return arr.map(item => {
return {
...item,
age: item.age * 2
}
})
}
console.log(c([{ age: 3, name: 'n1' }, { age: 4, name: 'n2' }])); // { age: 6, name: 'n1' }, { age: 8, name: 'n2' }
c = function (arr) {
return arr.join('-')
} // Uncaught TypeError: Assignment to constant variable.
let 和 const 的相同点
- 用
let和const声明的变量只能在其声明的块(由花括号括起来的区域)内部访问。 - 用
let和const声明的变量也会被提升,但它们不会被初始化。如果你在代码中尝试在变量声明之前访问它们,会得到一个ReferenceError错误。
{
console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
const b = 2
}
{
console.log(c); // Uncaught ReferenceError: Cannot access 'c' before initialization
let c = 3
}