js

ES6中的变量声明

ES6中关于变量声明的新特性与变动,let,const与var

Posted by AzirKxs on 2022-09-20
Estimated Reading Time 3 Minutes
Words 868 In Total
Viewed Times

ES6中的变量声明

ECMAScript与JavaScript的区别

前者是后者的规格,后者是前者的一种实现

1.let

let用来声明变量,用法类似于var

let与var的区别:

1.let存在块级作用域,而var不存在块级作用域
1
2
3
4
5
6
{
let number = 10;
var number2 = 20;
}
console.log(number); //error number未定义
console.log(number2); //20

典型的for循环例子 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//案例1
for(var i=0; i<10; i++) {
console.log(i);//依次打印0,1,2,3,5,6,7,8,9,10
a[i] = function(){
console.log(i);
}
}

a[0](); //6

//案例2:遍历三个dom,点击时改变背景色为粉色
for(var i = 0;i<items.length;i++){
//不触发 i=items.length时 不存在items[i]
/* this.onclick = function(){
items[i].style.background = 'pink';
} */
items[i].onclick = function(){
items[i].style.background = 'pink';
}
}
//var声明的i属于全局变量,作用在全局,当调用a[i]()或者事件触发的时候,for循环已经结束,i的值已经变成了items.length

//使用let
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6

//let声明的i具有块级作用域,每一次的i只在本轮循环中起作用
**为什么要有块级作用域?**

var不合理的场景:

第一种场景,内层变量可能会覆盖外层变量。

第二种场景,用来计数的循环变量泄露为全局变量。

2.let不存在变量提升
1
2
3
4
5
console.log(number); // undefined
var number = 10;

console.log(number2); //ReferenceError
let number2 = 20;

var会有变量提升,上面的代码可以等同为:

1
2
3
var number;
console.log(number); // undefined
number = 10;

而let不存在变量提升,在执行到打印number2的时候number2没有定义

3.暂时性死区(TDZ)

1.不受外部影响:只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

2.不可以在声明前使用:ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

1
2
3
4
5
6
7
8
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError

let tmp; // TDZ结束
console.log(tmp); // undefined

tmp = 123;
console.log(tmp); // 123
4.不允许重复声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//报错
function test(args){
let args = 10;
console.log(args);//10
}

//不报错
function test(args){
{
let args = 10;
}
console.log(args);//20
}

test(20);

1
2
3
4
5
6
7
8
//不报错
function test(args){
var args = 10;
console.log(args);
}

let num = 20;
test(num);

2.const

const用来声明一个只读的常量,如果尝试更改将会报错,对于引用类型的数据来说,只要保证地址值不变,就不会报错

1
2
3
4
5
const foo ={};
foo.num = 10; //添加属性成功,不报错
console.log(foo.num);//10

foo = {}; //尝试赋值为新的引用类型,报错

如果不希望更改对象内部的属性,可以将对象冻结,任何修改将不会起作用,Object.freeze()

const拥有块级作用域,没有变量提升,存在暂时性死区

3.顶层对象

在ES5,顶层对象的属性(在浏览器环境下,顶层对象指的是window)与全局变量是等价的

1
2
3
4
5
window.a = 1;
a // 1

a = 2;
window.a // 2

在ES6中,全局变量不属于顶层对象的属性了

1
2
3
4
5
6
7
var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1

let b = 1;
window.b // undefined

如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!