声明变量的关键字
js中声明变量的方式:var let const
最初声明变量的关键字就是 var,但是为了解决作用域的问题,所以后面新增了 let 和 const 的方式。
作用域
ES5:全局作用域,函数作用域
ES6:新增块级作用域
var
- 没有块级作用域
{
var a = 10;
}
console.log(a); // 10
- 存在全局作用域,函数作用域
var a = 10;
function test(){
var b = 20;
console.log(a);// 10
console.log(b);// 20
}
test()
console.log(a);// 10
console.log(b);// ReferenceError: b is not defined
- 不初始化默认值为undefined
var a;
console.log(a);// undefined
这里 undefined 是 undefined 类型,而不是字符串。
- 存在变量提升(js在编辑阶段的时候,会搜集所有的变量声明,并且提前声明变量)
console.log(a);// undefined
var a = 10;
function test(){
console.log(a); //10
conosle.log(b); //undefined
var b = 20;
}
- 全局作用域下,var声明的变量会挂载到window对象下
var a = 10;
console.log(a); //10
console.log(window.a); //10
console.log(this.a); //10
- 同一作用域下允许重复声明
var a = 1;
var a = 2;
console.log(a)// 2
let
- 存在块级作用域
{
let a = 10;
}
console.log(a); //ReferenceError: a is not defined
- 不存在变量提升
console.log(a) // ReferenceError: Cannot access 'a' before initialization
let a = 1;
- 暂时性死区(使用let/const声明变量之前该变量都是不可用的)
{
//Block Scope
console.log(a); //ReferenceError: Cannot access 'a' before initialization
let a = 20;
}
if (true) {
//TDZ开始(TDZ:暂时性死区)
console.log(a); //ReferenceError: Cannot access 'a' before initialization
let a; //TDZ结束
console.log(a); //undefined
a = 123;
console.log(a); //123
}
- 同一块级作用域下不能重复声明
{
let A;
var A; //SyntaxError: Identifier 'A' has already been declared
}
{
var A;
let A; //SyntaxError: Identifier 'A' has already been declared
}
{
let A;
let A; //SyntaxError: Identifier 'A' has already been declared
}
const
- 声明之后必须立即初始化,不能之后赋值
const a; // SyntaxError: Missing initializer in const declaration }
- 常量的值不能改变
{
const a = 10;
a = 20; // TypeError: Assignment to constant variable
}
const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动
- 对于基本数据类型 (数值、字符串、布尔值) ,值就保存在变量指向的那个内存地址,因此等同于常量。
- 对于引用数据类型(对象和数组) ,变量指向的内存地址,const只能保证这个指针是固定的,不能保证它指向的数据结构是不可变得