这是我参与新手入门的第一篇文章
为什么要使用let和const
使用var来声明变量时,存在三个问题:
- 变量声明提升
- 可重复定义
- 全局变量挂载到window上
var --变量声明提升
什么是变量声明提升:即可以先使用再定义,值为undefined,定义变量后会提升至函数的最顶部
例如:
console.log(a); //undefined ===>a已声明未赋值(var a)默认得到undefined值
var a=10;
var--可重复声明
var 声明变量时可重复定义,后面定义的值会覆盖前面的值
var a=10;
var a=15;
console.log(a); // 15
var --全局变量挂载到window上
当我们使用 var 声明一个全局变量时,它会挂载到window上
var a=10;
console.log(window.a); //10
window有很多方法和属性,当我们声明的全局变量名称和window上属性或方法同名时,可能会导致window上属性或方法不可使用
let和const的使用
let和const都是用来声明变量的,用法类似于var,但使用let/const来声明变量时,可以避免var的缺陷
let 的使用
使用let来声明变量,声明的所有变量只在let命令所在的代码块中有效
{
let a=10;
var b=20;
}
console.log(b); // 20
console.log(a); // ReferenceError: a is not defined
{
let a=10;
var b=20;
console.log(a); //10
}
console.log(b); //20
不存在变量提升
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a=10;
不可重复声明
let a=10
let a=20; //SyntaxError: Identifier 'a' has already been declared
块级作用域
在ES6中,let为JavaScript新增了块级作用域
简单来说,let和{ }组成了块级作用域,let声明的变量只有在其所在作用域中才可以使用
{
let a=10;
{
let b=20;
}
console.log(a); // 10
console.log(b); // ReferenceError: b is not defined
}
function test(){
let a=10;
if(true){
let a=20;
}
console.log(a);//10
}
{
let a=10;
{
let b=20;
}
console.log(b);//ReferenceError: b is not defined
}
临时死区(暂时性死区)
let a=10;
{
console.log(a); //ReferenceError: Cannot access 'a' before initialization
let a=20;
}
可以看到,当我们在全局定义了一个a,在块级作用域里也定义了一个a,首先它会在块级作用域里寻找a,不允许区外面找(let所声明的变量就绑定了这个区域,不再受外部影响),发现有,但我们在它没有声明前使用了a,这就造成了临时死区。
再来一个例子:
let a=10;
{
console.log(a); //ReferenceError: Cannot access 'a' before initialization
let a=20;
{
console.log(a); // 20
}
}
可以看到第一个在第一个块级作用域里造成了临时死区
const的使用
const用于声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI=3.14159;
console.log(PI); //3.14159
PI=3; //Assignment to constant variable.
使用const声明变量时,必须给声明的变量赋值,否则会报错
const a; // SyntaxError: Missing initializer in const declaration
const 的作用域与let相同,只在声明所在的块级作用域里有效
const a=10;
{
const a=20;
console.log(a) //20
}
{
const a=10;
}
console.log(a) // a is not defined
const 同样也存在临时死区
const a=10;
{
console.log(a) //ReferenceError: Cannot access 'a' before initialization
const a=20;
}
同样的,const 与 let 一样,都不允许重复声明
let a=10;
const b=20;
let a=30; //SyntaxError: Identifier 'a' has already been declared
const b=30; //SyntaxError: Identifier 'b' has already been declared
如何改变const声明变量的值
上面说到使用const 声明的变量一旦给定一个常量,就不能改变,那么能不能改变其声明变量的值呢?
首先我们要先了解const的本质,并不是变量的值不能改变,而是变量指向的那个内存地址不得改动。对于简单的数据(数值,字符串,布尔值),值就保存在变量指向的那个内存地址。但对于复合类型的数据(对象,数组),变量指向的内存地址,保存的只是一个指针,const 只能保证这个指针是固定的,但对于所指向的数据结构是否是可变的,就不能控制了。所以我们可以使用对象和数组的方法来改变const所声明的值。
使用对象改变const声明的值
const foo={};
foo.a=12;
console.log(foo.a); //12
foo.a=13;
console.log(foo.a) //13
如果把foo指向另一个内存地址,则会报错
const foo={}
foo={} //这里将foo指向了另一个对象 TypeError: Assignment to constant variable.
使用数组改变const声明的值
const a=[];
a.push(123);
console.log(a[0]); //123
a.length=10;
console.log(a.length) //10
同样的,与使用对象一样,改变a的内存地址时也会报错
const a=[];
a=123 //Assignment to constant variable