深入理解ES6中的关键特性

286 阅读4分钟

ES6(ECMAScript 2015)是JavaScript语言的一次重大更新,引入了许多新特性,使开发者能够编写更简洁、灵活和可维护的代码。本文将结合一些代码示例,详细介绍ES6中的关键特性。

变量声明

var、let 和 const

在ES6之前,JavaScript只有var关键字用于声明变量。ES6新增了letconst,它们提供了更好的作用域控制和不可变性。

栗子🌰:

console.log(b); // undefined
var b = 1;

console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 2;

var c = 3;
if (1) {
    console.log(c); // ReferenceError: Cannot access 'c' before initialization
    let c = 4;
}

在上述代码中,var声明的变量会提升(hoisting),而letconst声明的变量不会,因此在它们声明之前访问会导致错误。letconst的作用域是块级作用域,而var的作用域是函数级作用域。此外,const声明的变量必须初始化,并且在初始化后不能再被重新赋值。

BigInt和Symbol

BigInt

BigInt是一种新的原始数据类型,用于表示任意精度的整数。传统的Number类型只能安全地表示和比较-(2^53 - 1)2^53 - 1之间的整数。

栗子🌰:

let big = 1234n; // BigInt
console.log(big + 1n); // 1235n

Symbol

Symbol是ES6引入的一种新的原始数据类型,用于生成独一无二的值,常用于对象属性的唯一标识。

栗子🌰:

let s = Symbol('1');
let s2 = Symbol('2');
console.log(s == s2); // false

每个Symbol都是唯一的,即使它们的描述相同。Symbol可以避免对象属性名冲突。

解构赋值

解构赋值是一种便捷的语法,可以从数组或对象中提取数据并赋值给变量。

数组解构

const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a, b, c); // 1, 2, 3
const arr = [1,2,3]
console.log(...arr);//1,2,3   对象不能用...解构

对象解构

const obj = {a: 1, b: 2, c: 3};
const {a, b, c} = obj;
console.log(a, b, c); // 1, 2, 3

解构赋值不仅可以用于变量声明,还可以用于函数参数传递,极大地简化了代码书写。

栗子🌰:

const arr2 = [1, 2, {a: 3}];
const [d, e, {a: f}] = arr2;
console.log(d, e, f); // 1, 2, 3

const obj2 = {a: 1, b: 2, c: 3, d: {n: 4}};
const {a: g, b: h, c: i, d: {n}} = obj2;
console.log(g, h, i, n); // 1, 2, 3, 4

字符串模板

模板字符串(Template Literals)提供了更便捷的字符串拼接方式,可以通过反引号``和${}来插入变量或表达式。

栗子🌰:

let name = "Tom";
let greeting = `Hello, I am ${name}. How are you?`;
console.log(greeting); // Hello, I am Tom. How are you?

模板字符串不仅支持多行字符串,还支持嵌入表达式,使得字符串拼接更加简洁和易读。

逻辑运算符

短路运算

逻辑运算符可以用于条件判断和短路求值。

栗子🌰:

let x = 1;
let y = x && 2; // 如果x为真,则y为2
console.log(y); // 2

let a = '';
let b = a || 100; // a为假,b为100
let c = a ?? 100; // a为null或undefined,c为100
console.log(b); // 100
console.log(c); // 100

&&运算符会在左侧表达式为真时返回右侧表达式的值,而||运算符会在左侧表达式为假时返回右侧表达式的值。??运算符是空值合并运算符,仅在左侧表达式为null或undefined时返回右侧表达式的值。

Map、WeakMap和Set

Map

Map对象允许你使用任何类型的值作为键,并且键值对保持插入顺序。它弥补了传统对象只能用字符串作为键的缺陷。

栗子🌰:

const map = new Map([['name', 'Tom']]);
const objKey = {a: 1};
map.set(objKey, 'hello');

console.log(map.get(objKey)); // hello
console.log(map.has(objKey)); // true
map.delete(objKey);
console.log(map); // Map(1) {"name" => "Tom"}

WeakMap

WeakMap与Map类似,但只接受对象作为键,这是因为 WeakMap 的设计是为了让键对象能够被垃圾回收,因此需要引用类型。并且对键是弱引用,这意味着,如果没有其他强引用存在,那么这个键对象可以被垃圾回收机制回收,即使它还在 WeakMap 中,不会阻止垃圾回收。

栗子🌰:

let obj = {name: 'Jesper'};
let ws = new WeakMap();
ws.set(obj, 1);
obj = null; // obj被置为null,垃圾回收机制可能会销毁它
console.log(ws); // WeakMap { <items unknown> }

WeakMap的键是弱引用,因此如果没有其他引用存在,垃圾回收机制会自动回收这些对象。WeakMap常用于存储与对象关联的临时数据。

Set

Set对象允许你存储任何类型的唯一值,无论是原始值还是对象引用。在Set中,任何重复的值都会被自动过滤掉。

栗子🌰:

const arr = [1, 1, 2, 2, 4, 4];
const set = new Set(arr);
console.log([...set]); // [1, 2, 4]

结语

ES6引入了许多新特性,使得JavaScript变得更加强大和灵活。这些特性不仅改善了JavaScript的开发体验,还为复杂应用程序的开发提供了更好的工具和方法。希望通过这篇文章,你能更好地理解和应用这些ES6特性,并在实际开发中应用这些知识。