1.6 ES6+ 新特性
ES6(ECMAScript 2015)是 JavaScript 的一次重大更新,引入了许多新特性,极大提升了开发效率。
一、let 和 const
let(块级作用域)
javascript
// let 声明的变量拥有块级作用域
{
let a = 10;
console.log(a); // 10
}
// console.log(a); // 报错:a is not defined
// 不允许重复声明
let b = 20;
// let b = 30; // 报错
// 不会变量提升
// console.log(c); // 报错,不能在声明前使用
let c = 30;const(常量)
javascript
// const 声明常量,必须初始化
const PI = 3.14159;
// 不能重新赋值
// PI = 3.14; // 报错
// 对象属性可以修改
const user = { name: "张三" };
user.name = "李四"; // 可以
// user = {}; // 报错
// 适用场景
// 1. 不需要改变的值
const MAX_VALUE = 100;
// 2. 导入的模块
const React = require("react");二、解构赋值
数组解构
javascript
const arr = [1, 2, 3, 4, 5];
// 基本解构
const [a, b, c] = arr;
console.log(a, b, c); // 1, 2, 3
// 跳过元素
const [first, , third] = arr;
console.log(first, third); // 1, 3
// 剩余元素
const [x, ...rest] = arr;
console.log(rest); // [2, 3, 4, 5]
// 默认值
const [d, e = 20] = [10];
console.log(d, e); // 10, 20对象解构
javascript
const obj = { name: "张三", age: 25, city: "北京" };
// 基本解构
const { name, age } = obj;
console.log(name, age); // 张三, 25
// 重命名
const { name: userName, age: userAge } = obj;
console.log(userName, userAge); // 张三, 25
// 默认值
const { name: n = "李四" } = {};
console.log(n); // 李四
// 解构剩余属性
const { name, ...rest } = obj;
console.log(rest); // { age: 25, city: "北京" }函数参数解构
javascript
// 对象参数解构
function greet({ name = "张三", age = 18 } = {}) {
console.log(`姓名:${name},年龄:${age}`);
}
greet({ name: "李四", age: 25 });
greet(); // 使用默认值三、模板字符串
javascript
const name = "张三";
const age = 25;
// 多行字符串
const str = `姓名:${name}
年龄:${age}`;
console.log(str);
// 表达式
const message = `姓名:${name},年龄:${age},成年:${age >= 18}`;
// 调用函数
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
console.log(`姓名:${capitalize(name)}`);
// 嵌套模板字符串
const info = `信息:${`姓名:${name},年龄:${age}`}`;
// 标签模板(高级用法)
function tag(strings, ...values) {
console.log(strings);
console.log(values);
return strings.reduce((result, str, i) => {
return result + str + (values[i] || "");
}, "");
}
console.log(tag`姓名${name}年龄${age}`);四、箭头函数
javascript
// 基本语法
const add = (a, b) => a + b;
console.log(add(1, 2)); // 3
// 带大括号(需要 return)
const multiply = (a, b) => {
return a * b;
};
// 无参数
const greet = () => "Hello!";
console.log(greet());
// 单参数(可省略括号)
const square = x => x * x;
// 回调函数(常用场景)
const arr = [1, 2, 3, 4, 5];
const doubled = arr.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// 注意:箭头函数没有自己的 this
const obj = {
name: "张三",
greet: function() {
const self = this;
setTimeout(() => {
console.log(this.name); // 正确指向 obj
console.log(self.name); // self 也指向 obj
}, 1000);
}
};
obj.greet();
// 不适合作为对象方法(this 会指向外层)
const person = {
name: "李四",
sayName: () => {
console.log(this.name); // undefined(this 指向全局或外层作用域)
}
};五、展开运算符
对象展开
javascript
const obj1 = { name: "张三", age: 25 };
const obj2 = { city: "北京" };
// 合并对象(后面的覆盖前面的)
const merged = { ...obj1, ...obj2 };
console.log(merged); // { name: "张三", age: 25, city: "北京" }
// 添加属性
const newObj = { ...obj1, city: "上海" };
console.log(newObj); // { name: "张三", age: 25, city: "上海" }
// 修改属性
const updated = { ...obj1, age: 26 };
console.log(updated); // { name: "张三", age: 26 }
// 复制对象(浅拷贝)
const copy = { ...obj1 };数组展开
javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// 合并数组
const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4, 5, 6]
// 添加元素
const newArr = [...arr1, 4, 5];
console.log(newArr); // [1, 2, 3, 4, 5]
// 函数调用参数(替代 apply)
const numbers = [1, 2, 3];
console.log(Math.max(...numbers)); // 3
// 数组复制(浅拷贝)
const copy = [...arr1];六、数组的常用方法
javascript
const arr = [1, 2, 3];
// Array.from(从类数组创建数组)
const fromString = Array.from("hello");
console.log(fromString); // ['h', 'e', 'l', 'l', 'o']
// Array.of(创建数组)
const ofArray = Array.of(1, 2, 3);
console.log(ofArray); // [1, 2, 3]
// find(查找元素)
const found = arr.find(x => x > 1);
console.log(found); // 2
// findIndex(查找索引)
const index = arr.findIndex(x => x > 1);
console.log(index); // 1
// includes(是否包含)
console.log(arr.includes(2)); // true
console.log(arr.includes(4)); // false
// fill(填充)
const filled = new Array(3).fill(0);
console.log(filled); // [0, 0, 0]
// flat(扁平化)
const nested = [1, [2, [3, [4]]]];
const flat = nested.flat(2);
console.log(flat); // [1, 2, 3, [4]]
// flatMap(映射并扁平化)
const mapped = arr.flatMap(x => [x, x * 2]);
console.log(mapped); // [1, 2, 2, 4, 3, 6]七、对象的新方法
javascript
const obj = { name: "张三", age: 25, city: "北京" };
// Object.keys(获取所有键)
console.log(Object.keys(obj)); // ["name", "age", "city"]
// Object.values(获取所有值)
console.log(Object.values(obj)); // ["张三", 25, "北京"]
// Object.entries(获取键值对数组)
console.log(Object.entries(obj)); // [["name", "张三"], ["age", 25], ["city", "北京"]]
// Object.fromEntries(从键值对数组创建对象)
const entries = [["name", "张三"], ["age", 25]];
const fromEntries = Object.fromEntries(entries);
console.log(fromEntries); // { name: "张三", age: 25 }
// Object.is(比较)
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
console.log(Object.is(+0, -0)); // false
console.log(+0 === -0); // true
// Object.assign(合并对象)
const obj1 = { name: "张三" };
const obj2 = { age: 25 };
const merged = Object.assign({}, obj1, obj2);
console.log(merged); // { name: "张三", age: 25 }八、Promise
javascript
// 基本用法
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功");
}, 1000);
});
promise.then(
data => console.log(data),
error => console.error(error)
);
// Promise.all(全部成功才成功)
Promise.all([
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3)
]).then(([a, b, c]) => {
console.log(a, b, c); // 1, 2, 3
});
// Promise.race(第一个完成的结果)
Promise.race([
new Promise(resolve => setTimeout(() => resolve("A"), 100)),
new Promise(resolve => setTimeout(() => resolve("B"), 200))
]).then(value => console.log(value)); // "A"九、async/await(ES2017)
javascript
// 基本用法
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
fetchData();
// 并行执行
async function parallel() {
const [data1, data2] = await Promise.all([
fetch("url1"),
fetch("url2")
]);
console.log(data1, data2);
}十、Classes(类)
javascript
// 基本类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`姓名:${this.name},年龄:${this.age}`);
}
}
const person = new Person("张三", 25);
person.greet();
// 继承
class Student extends Person {
constructor(name, age, school) {
super(name, age);
this.school = school;
}
study() {
console.log(`${this.name} 在 ${this.school} 学习`);
}
greet() {
super.greet(); // 调用父类方法
console.log(`学校:${this.school}`);
}
}
const student = new Student("李四", 20, "清华大学");
student.greet();
student.study();
// 静态方法
class MathUtil {
static add(a, b) {
return a + b;
}
}
console.log(MathUtil.add(1, 2)); // 3
// Getter 和 Setter
class Circle {
constructor(radius) {
this._radius = radius;
}
get radius() {
return this._radius;
}
set radius(value) {
this._radius = value;
}
get area() {
return Math.PI * this._radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.area); // 78.5398
circle.radius = 10;
console.log(circle.area); // 314.159十一、Set 和 Map
Set
javascript
// 创建 Set
const set = new Set([1, 2, 3, 3, 4, 4]);
// 特点:无重复值
console.log(set); // Set {1, 2, 3, 4}
// 添加元素
set.add(5);
set.add(5); // 不会重复添加
// 检查存在
console.log(set.has(3)); // true
// 删除元素
set.delete(3);
// 获取大小
console.log(set.size); // 4
// 遍历
set.forEach(value => console.log(value));
// 数组去重
const arr = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3]Map
javascript
// 创建 Map
const map = new Map([
["name", "张三"],
["age", 25]
]);
// 特点:键可以是任意类型
const obj = { id: 1 };
map.set(obj, "对象键");
console.log(map.get(obj)); // "对象键"
// 添加/获取
map.set("city", "北京");
console.log(map.get("name")); // "张三"
// 检查存在
console.log(map.has("name")); // true
// 删除
map.delete("age");
// 获取大小
console.log(map.size); // 2
// 遍历
map.forEach((value, key) => {
console.log(key, value);
});十二、其他新特性
Symbol
javascript
// 唯一值,用作对象键
const symbol = Symbol("description");
const obj = {
[symbol]: "唯一值",
name: "张三"
};
console.log(obj[symbol]); // "唯一值"
console.log(obj.name); // "张三"
// 遍历时 Symbol 属性不会出现
for (let key in obj) {
console.log(key); // 只输出 "name"
}
// 获取 Symbol 键
console.log(Object.getOwnPropertySymbols(obj));函数参数默认值
javascript
function greet(name = "张三", age = 18) {
console.log(`姓名:${name},年龄:${age}`);
}
greet(); // "姓名:张三,年龄:18"
greet("李四"); // "姓名:李四,年龄:18"
greet("王五", 20); // "姓名:王五,年龄:20"剩余参数
javascript
function sum(...nums) {
return nums.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15总结
ES6+ 新特性极大提升了 JavaScript 的开发效率和代码可读性,掌握这些特性是现代前端开发的基础。