var let const

var

  • 在全局作用域声明
  • 存在变量提升
  • 可以对变量进行重载
1
2
3
4
5
6
7
8
//虽然a的变量得到提升,但是是未赋值的,因此输出undefined
console.log(a); //undefined
var date = '10/17'

//对比let
//let、const不存在变量提升
console.log(a); //报错
let year = '2023'

let

  • 只在块作用域内有效,块作用域外访问报错

  • 只能声明一次

  • 存在暂时性死区(temporary died zone)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (true) {
    // TDZ开始
    tmp = 'abc'; // ReferenceError
    console.log(tmp); // ReferenceError

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

const

  • 指定义一个常量,且定义时必须赋值

  • 只在块作用域内有效

循环计数器(var与let)

1
2
3
4
5
6
7
8
9
10
11
12
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
})
}
// 输出十个 10
for (let j = 0; j < 10; j++) {
setTimeout(function(){
console.log(j);
})
}
// 输出 0123456789

变量ivar命令声明的,在全局范围内都有效,所以全局只有一个变量i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。

变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6

顶层对象的属性

用var和function声明的变量,都是顶层对象windows的属性。而let、const声明的属性不再是顶层对象的属性。

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

解构赋值

​ 是对赋值运算的一种扩展,是代码简洁易读,针对的对象是数组和对象

  • 对对象解构

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
let node = {
type:'iden',
name:'foo'
}
//es5写法
let type = node.type;
let name = node.name;
//es6写法
//完全解构
let{type,name} = node;
let obj ={
a:{
name:'张三'
},
b:[1,2,3],
c:'hello world'
}
let {a,b}=obj;
console.log(a,b);

//不完全解构
let {a} = obj;
console.log(a);

//剩余运算符rest
//剩余的内容被作为一个对象赋值给rest
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40,e:50};
console.log(a,b,rest); //rest输出{c: 30, d: 40,e:50}

let{a,b=20}={a:20};

  • 对数组解构

1
2
3
4
5
6
7
8
9
10
11
//完全解构
let arr = [1,2,3];
let [a,b,c] = arr;
console.log(a,b,c)//1,2,3

//不完全解构
let [a,b] = arr;
console.log(a,b)//1,2

//可嵌套
let[a,[b],c] = [1,[2],3];

扩展的对象功能

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
34
35
36
37
38
39
40
41
42
const name = "空羽",
age = 19;

//属性名和属性值相同可以省略
const person={
//name:name,
name,
//age:age,
age,
//sayName:function(){
//
//}
sayName(){

}
}

function fn(x,y){
//return {x:x,y:y}
return {x,y};
}

//对象属性名可以用表达式来写
const name = 'a';
const obj = {
isShow:true,
[name+'bc'] : 1,
['f'+name](){
console.log(this);
}

}
console.log(obj);//{isShow: true, abc: 1, fa: ƒ}

//对象的is()方法,解决NaN问题
console.log(NaN==NaN);//false
console.log(Object.is(NaN,NaN));//true

//对象的assign()方法
let newObj = Object.assign({a:1},{b:2},{c:3});
console.log(newObj);
//{a: 1, b: 2, c: 3}

Symbol

新的原始数据类型,最大的用途:用于定义对象的私有变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const name = Symbol('name');
const name2 = Symbol('name');
console.log(name===name2);

let s1 = Symbol('s2');
console.log(s1);//Symbol(s2)
let obj = {};
//如果使用中括号形式进行赋值,输出就一定要使用中括号
//也可以使用"."来赋值
obj[s1] = '空羽';//obj.s1='空羽'
console.log(obj[s1]);
//另外一种写法
let obj2={
[s1]:'呵呵'
}