主页 > 创业  > 

JavaScript系列05-现代JavaScript新特性

JavaScript系列05-现代JavaScript新特性

JavaScript作为网络的核心语言之一,近年来发展迅速。从ES6(ECMAScript 2015)开始,JavaScript几乎每年都有新的语言特性加入,极大地改善了开发体验和代码质量。本文主要内容包括:

ES6+关键特性:解构赋值与扩展运算符:模块化开发:Proxy与Reflect:新的API与语法糖:兼容性与Polyfill: 1、ES6+关键特性

ES6是JavaScript发展的一个重要里程碑,带来了大量革命性的改变,后续版本继续添加了许多实用特性。

箭头函数

箭头函数提供了更简洁的函数定义语法,并且自动绑定词法上下文的this。

// 传统函数 function add(a, b) { return a + b; } // 箭头函数 const add = (a, b) => a + b; // 箭头函数与this const person = { name: '张三', sayHiTraditional: function() { setTimeout(function() { console.log(`你好,我是${this.name}`); // this不是person }, 1000); }, sayHiArrow: function() { setTimeout(() => { console.log(`你好,我是${this.name}`); // this绑定到person }, 1000); } };

箭头函数的特点:

更简洁的语法没有自己的this,继承外围作用域的this没有arguments对象不能用作构造函数没有prototype属性 let与const

ES6引入了块级作用域的变量声明方式:

// var的问题:没有块级作用域 if (true) { var x = 10; } console.log(x); // 10,x泄漏到外部作用域 // let的块级作用域 if (true) { let y = 20; } // console.log(y); // ReferenceError: y未定义 // const声明常量,值不可重新赋值 const PI = 3.14159; // PI = 3.14; // TypeError: 赋值给常量变量 // const声明的对象内容可以修改 const person = { name: '李四' }; person.name = '王五'; // 这是允许的 // person = {}; // 错误:不能重新赋值

let/const与var的主要区别:

块级作用域vs函数作用域没有变量提升(实际上有"暂时性死区")禁止重复声明全局声明的变量不会成为window的属性 类语法

ES6引入了类语法,使面向对象编程更直观:

class Animal { // 构造函数 constructor(name) { this.name = name; } // 实例方法 speak() { return `${this.name}发出声音`; } // 静态方法 static isAnimal(obj) { return obj instanceof Animal; } // ES2022+:私有字段 #privateField = 'private'; getPrivate() { return this.#privateField; } } // 继承 class Dog extends Animal { constructor(name, breed) { super(name); // 调用父类构造函数 this.breed = breed; } speak() { return `${this.name}汪汪叫`; } // 获取器方法 get description() { return `${this.breed}犬${this.name}`; } } const dog = new Dog('旺财', '哈士奇'); console.log(dog.speak()); // "旺财汪汪叫" console.log(dog.description); // "哈士奇犬旺财" Promise及异步编程

Promise为异步操作提供了更优雅的处理方式:

// Promise基本用法 function fetchData(url) { return new Promise((resolve, reject) => { const success = Math.random() > 0.3; setTimeout(() => { if (success) { resolve(`来自${url}的数据`); } else { reject(`获取${url}失败`); } }, 1000); }); } fetchData('api/users') .then(data => { console.log(data); return fetchData('api/orders'); }) .then(data => { console.log(data); }) .catch(error => { console.error(error); }) .finally(() => { console.log('请求结束,无论成功或失败'); });

ES2017引入的async/await使异步代码更像同步代码:

async function fetchAllData() { try { const users = await fetchData('api/users'); console.log(users); const orders = await fetchData('api/orders'); console.log(orders); return { users, orders }; } catch (error) { console.error('获取数据失败:', error); } finally { console.log('操作完成'); } } // 调用异步函数 fetchAllData().then(result => { console.log('所有数据:', result); }); 可选链与空值合并

ES2020引入了两个非常实用的运算符:

// 可选链运算符 ?. const user = { profile: { // address: { // city: '北京' // } } }; // 使用前:防御性编程 const city = user && user.profile && user.profile.address && user.profile.address.city || '未知城市'; // 使用后:简洁优雅 const city2 = user?.profile?.address?.city || '未知城市'; // 空值合并运算符 ?? // 与 || 不同,?? 只在值为 null 或 undefined 时生效 const count = 0; console.log(count || 10); // 10,因为0是假值 console.log(count ?? 10); // 0,因为0不是null或undefined 2、解构赋值与扩展运算符

解构赋值和扩展运算符是现代JavaScript中最常用的语法特性之一。

数组解构 // 基本数组解构 const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5] // 交换变量,无需临时变量 let a = 1, b = 2; [a, b] = [b, a]; console.log(a, b); // 2 1 // 忽略某些值 const [x, , z] = [1, 2, 3]; console.log(x, z); // 1 3 // 设置默认值 const [p = 0, q = 0] = [10]; console.log(p, q); // 10 0 对象解构 // 基本对象解构 const person = { name: '张三', age: 30, job: '开发者', address: { city: '上海', street: '南京路' } }; const { name, age, hobby = '阅读' } = person; console.log(name, age, hobby); // "张三" 30 "阅读" // 重命名 const { name: fullName, job: occupation } = person; console.log(fullName, occupation); // "张三" "开发者" // 嵌套解构 const { address: { city } } = person; console.log(city); // "上海" // 解构与函数参数 function printPerson({ name, age, job = '无业' }) { console.log(`${name}, ${age}岁, 职业: ${job}`); } printPerson(person); // "张三, 30岁, 职业: 开发者" 扩展运算符

扩展运算符(...)在数组、对象和函数参数中非常有用:

// 数组合并 const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const combined = [...arr1, ...arr2]; console.log(combined); // [1, 2, 3, 4, 5, 6] // 数组克隆 const original = [1, 2, 3]; const copy = [...original]; original.push(4); console.log(original); // [1, 2, 3, 4] console.log(copy); // [1, 2, 3] // 对象合并与克隆 const obj1 = { a: 1, b: 2 }; const obj2 = { b: 3, c: 4 }; // b将覆盖obj1的b const mergedObj = { ...obj1, ...obj2 }; console.log(mergedObj); // { a: 1, b: 3, c: 4 } // 对象克隆(浅拷贝) const originalObj = { a: 1, b: { c: 2 } }; const shallowCopy = { ...originalObj }; originalObj.a = 10; originalObj.b.c = 20; console.log(shallowCopy.a); // 1 (不受影响) console.log(shallowCopy.b.c); // 20 (受影响,因为是浅拷贝) 实际应用解构与扩展 // React组件中的状态更新 const [state, setState] = useState({ count: 0, loaded: false }); setState(prevState => ({ ...prevState, count: prevState.count + 1 })); // API响应处理 async function fetchUser(id) { const response = await fetch(`/api/users/${id}`); const data = await response.json(); // 只提取需要的字段并设置默认值 const { name, email, roles = ['user'], settings: { theme = 'light' } = {} } = data; return { name, email, roles, theme }; } 3、模块化开发

JavaScript模块化经历了从无到有的发展过程,ES6正式将模块系统引入语言标准。

模块系统的演进

ES模块基本语法 // 导出语法 (math.js) // 命名导出 export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } // 默认导出 export default function multiply(a, b) { return a * b; } // 导入语法 (app.js) // 导入默认导出 import multiply from './math.js'; // 导入命名导出 import { add, subtract } from './math.js'; // 导入所有导出为一个对象 import * as mathUtils from './math.js'; // 重命名导入 import { add as sum, subtract as minus } from './math.js'; // 混合导入 import multiply, { add, subtract } from './math.js'; // 使用 console.log(add(5, 3)); // 8 console.log(multiply(4, 2)); // 8 console.log(mathUtils.subtract(10, 5)); // 5 动态导入

ES2020标准化了动态导入,支持按需加载模块:

// 静态导入(在顶层) import { feature1 } from './features.js'; // 动态导入(按需) button.addEventListener('click', async () => { try { // 只有用户点击按钮后才加载 const { feature2 } = await import('./features.js'); feature2(); } catch (error) { console.error('模块加载失败:', error); } }); CommonJS与ES模块的区别 // CommonJS (Node.js) const fs = require('fs'); const { join } = require('path'); module.exports = { readFile: function(path) { /* ... */ }, writeFile: function(path, data) { /* ... */ } }; // ES模块 (ES6+) import fs from 'fs'; import { join } from 'path'; export function readFile(path) { /* ... */ } export function writeFile(path, data) { /* ... */ }

主要区别:

加载时机:CommonJS是运行时加载,ES模块是静态加载导入类型:CommonJS导入的是值的拷贝,ES模块导入的是值的引用this指向:CommonJS顶层this指向当前模块,ES模块顶层this是undefined语法位置:CommonJS可以在条件语句中require,ES静态import必须在顶层 模块设计最佳实践 单一职责原则:每个模块只负责一个功能显式导出API:明确声明公共API,减少副作用避免循环依赖:可能导致未初始化的变量合理使用默认导出:每个模块最多一个默认导出保持一致的命名约定:文件名与默认导出内容一致 // 模块设计示例 // api.js - 负责API调用 export async function fetchUsers() { /* ... */ } export async function fetchPosts() { /* ... */ } // formatters.js - 负责数据格式化 export function formatDate(date) { /* ... */ } export function formatCurrency(amount) { /* ... */ } // index.js - 聚合模块,简化导入 export { fetchUsers, fetchPosts } from './api.js'; export { formatDate, formatCurrency } from './formatters.js'; export { default as utils } from './utils.js'; 4、Proxy与Reflect

Proxy和Reflect是ES6引入的强大特性,允许拦截和自定义对象的基本操作。

Proxy基础

Proxy允许创建一个对象的代理,拦截并重新定义该对象的基本操作:

const target = { name: '张三', age: 30 }; const handler = { // 拦截属性读取 get(target, prop, receiver) { console.log(`正在获取${prop}属性`); return target[prop]; }, // 拦截属性设置 set(target, prop, value, receiver) { console.log(`正在设置${prop}属性为${value}`); // 可以添加验证逻辑 if (prop === 'age' && typeof value !== 'number') { throw new TypeError('age必须是一个数字'); } target[prop] = value; return true; // 表示设置成功 } }; // 创建代理 const proxy = new Proxy(target, handler); // 使用代理 console.log(proxy.name); // 输出: 正在获取name属性 张三 proxy.age = 31; // 输出: 正在设置age属性为31 try { proxy.age = '很老'; // 抛出TypeError } catch (e) { console.error(e.message); } Proxy提供13种可拦截的基本操作: const handler = { // 属性操作 get(target, prop, receiver) {}, set(target, prop, value, receiver) {}, has(target, prop) {}, // 拦截in操作符 deleteProperty(target, prop) {}, // 拦截delete操作 // 函数操作 apply(target, thisArg, argumentsList) {}, // 拦截函数调用 construct(target, args, newTarget) {}, // 拦截new操作 // 原型操作 getPrototypeOf(target) {}, setPrototypeOf(target, prototype) {}, // 扩展/配置 isExtensible(target) {}, preventExtensions(target) {}, // 属性描述符 getOwnPropertyDescriptor(target, prop) {}, defineProperty(target, prop, descriptor) {}, // 获取所有键 ownKeys(target) {} // 拦截Object.keys等 }; Reflect API

Reflect是一个内置对象,提供与Proxy处理程序方法相同的静态方法:

// 使用Reflect的Proxy const handler = { get(target, prop, receiver) { console.log(`获取${prop}属性`); // 使用Reflect.get代替target[prop] return Reflect.get(target, prop, receiver); }, set(target, prop, value, receiver) { console.log(`设置${prop}属性`); // 使用Reflect.set代替target[prop] = value return Reflect.set(target, prop, value, receiver); } }; const proxy = new Proxy({x: 1, y: 2}, handler); console.log(proxy.x); // 获取x属性 1 proxy.z = 3; // 设置z属性

使用Reflect的好处:

操作返回状态(成功/失败)而非抛出错误接收相同的参数,方便与Proxy配合提供函数式的对象操作API Proxy实际应用

1. 数据验证

function createValidator(target, validations) { return new Proxy(target, { set(target, prop, value) { if (validations[prop]) { const validateFn = validations[prop]; if (!validateFn(value)) { throw new Error(`Invalid value for ${prop}`); } } target[prop] = value; return true; } }); } const user = createValidator( { name: '张三', age: 30 }, { name: value => typeof value === 'string' && value.length > 0, age: value => typeof value === 'number' && value >= 0 && value < 150 } ); user.name = '李四'; // 有效 // user.age = -5; // 抛出错误

2. 响应式数据系统

// 简化版Vue 3响应式系统 function reactive(obj) { return new Proxy(obj, { get(target, prop, receiver) { const result = Reflect.get(target, prop, receiver); track(target, prop); // 跟踪依赖 // 深层响应式 return typeof result === 'object' && result !== null ? reactive(result) : result; }, set(target, prop, value, receiver) { const oldValue = target[prop]; const result = Reflect.set(target, prop, value, receiver); if (oldValue !== value) { trigger(target, prop); // 触发更新 } return result; } }); } // 模拟实现 function track(target, prop) { console.log(`追踪 ${prop} 变化`); } function trigger(target, prop) { console.log(`属性 ${prop} 已变化,触发更新`); } const state = reactive({ count: 0, user: { name: '张三' } }); state.count++; // 触发更新 state.user.name = '李四'; // 深层响应式,触发更新 5、新的API与语法糖

除了主要特性外,现代JavaScript还引入了大量实用的API和语法糖。

数组新方法 // ES6+引入的数组方法 const numbers = [1, 2, 3, 4, 5]; // 查找元素 const found = numbers.find(n => n > 3); // 4 const foundIndex = numbers.findIndex(n => n > 3); // 3 // 检查包含 const includes = numbers.includes(3); // true // 数组填充 const filled = new Array(5).fill(0); // [0, 0, 0, 0, 0] const modified = [1, 2, 3, 4, 5].fill(0, 2, 4); // [1, 2, 0, 0, 5] // 平铺数组 const nested = [1, [2, [3, 4]]]; const flat1 = nested.flat(); // [1, 2, [3, 4]] const flatAll = nested.flat(Infinity); // [1, 2, 3, 4] // 映射后平铺 const mappedAndFlat = [1, 2, 3].flatMap(x => [x, x * 2]); // [1, 2, 2, 4, 3, 6] // ES2022: 按索引位置替换元素,并返回替换的元素 const arr = ['a', 'b', 'c', 'd', 'e']; console.log(arr.at(1)); // 'b' console.log(arr.at(-1)); // 'e' (从末尾数) 对象新方法 // 对象新方法 const person = { name: '张三', age: 30, job: '工程师' }; const skills = { programming: true, design: false }; // Object.assign: 合并对象 const merged = Object.assign({}, person, skills); // 对象属性描述 console.log(Object.getOwnPropertyDescriptors(person)); // 对象条目、值、键 console.log(Object.entries(person)); // [['name','张三'], ['age',30], ['job','工程师']] console.log(Object.values(person)); // ['张三', 30, '工程师'] console.log(Object.keys(person)); // ['name', 'age', 'job'] // 从条目创建对象 const entries = [['name', '李四'], ['age', 25]]; const obj = Object.fromEntries(entries); // { name: '李四', age: 25 } // 对象扩展运算符(ES2018) const personWithSkills = { ...person, ...skills }; const { name, ...rest } = person; // 解构与剩余属性 字符串与正则新特性 // 字符串模板字面量 const name = '张三'; const greeting = `你好,${name}!`; // 标签模板字面量 function highlight(strings, ...values) { return strings.reduce((result, str, i) => { return result + str + (values[i] ? `<em>${values[i]}</em>` : ''); }, ''); } const highlighted = highlight`我叫${name},我今年${30}岁。`; // "我叫<em>张三</em>,我今年<em>30</em>岁。" // 字符串新方法 console.log('Hello'.padStart(10, '*')); // '*****Hello' console.log('Hello'.padEnd(10, '*')); // 'Hello*****' console.log('Hello'.startsWith('He')); // true console.log('Hello'.endsWith('lo')); // true console.log('Hello'.includes('ll')); // true console.log(' trim '.trim()); // 'trim' console.log(' trim '.trimStart()); // 'trim ' console.log(' trim '.trimEnd()); // ' trim' // 正则表达式命名捕获组(ES2018) const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const match = pattern.exec('2023-05-15'); console.log(match.groups.year); // '2023' console.log(match.groups.month); // '05' 数值与数学增强 // 数值分隔符(ES2021) const billion = 1_000_000_000; // 更易读 const bytes = 0xFF_FF_FF_FF; // 字节分组 // BigInt(ES2020) const bigNumber = 9007199254740991n; // BigInt字面量 const anotherBig = BigInt('9007199254740991'); // 构造函数 console.log(bigNumber + 1n); // 9007199254740992n // console.log(bigNumber + 1); // 错误:不能混合BigInt和Number // 指数运算符 console.log(2 ** 10); // 1024 let num = 2; num **= 3; // 8 // 数学方法 console.log(Math.trunc(3.9)); // 3 (去除小数部分) console.log(Math.sign(-5)); // -1 (符号函数) console.log(Math.log10(1000)); // 3 (底数为10的对数) console.log(Math.log2(8)); // 3 (底数为2的对数) 其他语法特性 // 逻辑赋值运算符(ES2021) let a = null; a ||= 10; // 等同于 a = a || 10 console.log(a); // 10 let b = 5; b &&= 20; // 等同于 b = b && 20 console.log(b); // 20 let c; c ??= 30; // 等同于 c = c ?? 30 console.log(c); // 30 // 可选catch绑定(ES2019) try { // 可能抛出错误的代码 } catch { // 不需要错误变量时可以省略 console.log('发生错误'); } // 顶层await(ES2022) // 可以在模块顶层使用await,无需async函数包装 // module.js const response = await fetch(' api.example /data'); export const data = await response.json(); // 私有类字段和方法(ES2022) class Counter { #count = 0; // 私有字段 get value() { return this.#count; } #increment() { // 私有方法 this.#count++; } increment() { this.#increment(); } } ES2023 新特性 数组新增反向查找方法 findLast() 和 findLastIndex():从数组末尾开始查找元素 const array = [1, 2, 3, 4, 5]; console.log(array.findLast(x => x % 2 === 1)); // 5 console.log(array.findLastIndex(x => x % 2 === 1)); // 4 数组的非修改性方法

以下方法返回新数组而不修改原数组:

toReversed(): 返回反转后的新数组toSorted(): 返回排序后的新数组toSpliced(): 返回删除/替换元素后的新数组with(): 返回替换指定索引元素后的新数组 const arr = [1, 2, 3, 4, 5]; console.log(arr.toReversed()); // [5, 4, 3, 2, 1] console.log(arr); // [1, 2, 3, 4, 5] - 原数组不变 console.log(arr.with(2, 10)); // [1, 2, 10, 4, 5] Hashbang 语法

允许在JavaScript文件开头使用#!/usr/bin/env node这样的语法,使JS文件可作为可执行脚本。

Symbol 作为 WeakMap 键

允许使用Symbol作为WeakMap的键,前提是该Symbol通过Symbol.for()创建。

ES2024 新特性 Promise.withResolvers()

提供了更简洁的Promise创建方式,返回promise及其控制函数:

const { promise, resolve, reject } = Promise.withResolvers(); // 等同于: // let resolve, reject; // const promise = new Promise((res, rej) => { // resolve = res; // reject = rej; // }); 数组分组方法 Object.groupBy(): 按条件将数组元素分组为对象Map.groupBy(): 按条件将数组元素分组为Map const people = [ { name: "张三", age: 25 }, { name: "李四", age: 30 }, { name: "王五", age: 25 } ]; const groupedByAge = Object.groupBy(people, person => person.age); // { "25": [{name:"张三",age:25}, {name:"王五",age:25}], "30": [{name:"李四",age:30}] } Import 属性

允许在import语句中添加元数据:

import data from "./data.json" with { type: "json" }; 装饰器(Decorators)

类装饰器正式标准化,可以修改或扩展类和类成员的行为:

function logged(value, { kind, name }) { if (kind === "method") { return function(...args) { console.log(`正在调用 ${name} 方法`); return value.call(this, ...args); }; } } class Person { @logged greet() { return "你好!"; } } String Unicode 处理 isWellFormed(): 检查字符串是否包含有效的UTF-16代码点toWellFormed(): 替换无效代码点,返回格式正确的字符串 ArrayBuffer 传输 transfer() 和 transferToFixedLength(): 转移ArrayBuffer所有权,避免内存复制 Temporal API

新的日期时间API,解决了现有Date对象的问题,提供更丰富的时间和日期操作功能。

RegExp Unicode 集合支持

新增v标志,支持Unicode属性转义和集合操作。

// 匹配所有希腊字母但不包括元音 const regex = /\p{Script=Greek}--[αεηιοωυ]/v; 6、兼容性与Polyfill

现代JavaScript特性在不同环境中的支持情况各不相同,需要通过工具确保代码的兼容性。

浏览器兼容性现状

主流浏览器已经支持大部分ES6+特性,但旧版浏览器不支持。Node.js各版本支持的特性也不同。

什么是Polyfill与转译

为了在不支持新特性的环境中使用现代JavaScript,我们需要两种解决方案:

转译(Transpilation): 将新语法转换为等效的旧语法Polyfill: 为缺失的API提供兼容实现 // 转译示例:箭头函数 // 现代代码 const add = (a, b) => a + b; // 转译后 var add = function(a, b) { return a + b; }; // Polyfill示例:Array.prototype.includes if (!Array.prototype.includes) { Array.prototype.includes = function(searchElement, fromIndex) { // 实现逻辑... if (this === null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); var len = o.length >>> 0; // 更多实现代码... return false; }; } Babel: JavaScript转译器

Babel是最流行的JavaScript转译工具,能将现代JavaScript转为兼容性更好的代码:

// babel.config.js module.exports = { presets: [ ["@babel/preset-env", { targets: { browsers: ["> 1%", "last 2 versions", "not dead"], node: "10" }, useBuiltIns: "usage", corejs: 3 }] ], plugins: [ "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-private-methods" ] };

Babel工作流程:

常用Polyfill库 core-js: 最全面的JavaScript标准库polyfillregenerator-runtime: 为生成器和async/await提供运行时支持whatwg-fetch: Fetch API的polyfillpromise-polyfill: Promise的polyfill实现 // 手动引入polyfill import "core-js/stable"; import "regenerator-runtime/runtime"; import "whatwg-fetch"; // 或者在webpack配置中 entry: ["core-js/stable", "regenerator-runtime/runtime", "./src/index.js"] 构建工具与兼容性

现代前端工具链通常集成了转译和polyfill功能:

// webpack.config.js module.exports = { // ... module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [ ['@babel/preset-env', { targets: '> 0.25%, not dead', useBuiltIns: 'usage', corejs: 3 }] ] } } } ] } }; 差异化加载策略

为现代浏览器提供现代代码,为旧浏览器提供兼容代码,可以优化性能:

<!-- 现代浏览器使用模块版本 --> <script type="module" src="app.modern.js"></script> <!-- 旧浏览器使用nomodule后备 --> <script nomodule src="app.legacy.js"></script> // 在Webpack或Rollup中配置差异化构建 // webpack.config.js module.exports = [ { // 现代浏览器构建 output: { filename: '[name].modern.js' }, module: { rules: [{ test: /\.js$/, use: { loader: 'babel-loader', options: { targets: { esmodules: true } } } }] } }, { // 旧浏览器构建 output: { filename: '[name].legacy.js' }, module: { rules: [{ test: /\.js$/, use: { loader: 'babel-loader', options: { targets: '> 0.25%, not dead' } } }] } } ]; 特性检测

除了构建时处理兼容性,还可以在运行时检测特性并提供替代方案:

// 特性检测示例 if ('IntersectionObserver' in window) { // 使用IntersectionObserver const observer = new IntersectionObserver(entries => { // ... }); } else { // 降级处理,如监听scroll事件 window.addEventListener('scroll', handleScroll); } // 动态加载polyfill (async function() { if (!window.fetch) { await import('whatwg-fetch'); } // 现在可以安全使用fetch fetch('/api/data').then(/* ... */); })(); 总结:现代JavaScript特性的价值

现代JavaScript极大改善了开发体验,使代码更加简洁、可维护,同时提高了应用性能和可扩展性。主要优势包括:

开发效率提升 更简洁的语法:箭头函数、解构赋值、模板字符串等减少了样板代码强大的异步处理:Promise、async/await让异步代码更易理解和维护模块化系统:原生支持模块化开发,代码组织更合理 代码质量改善 更好的作用域控制:let/const减少作用域问题不可变编程支持:扩展运算符简化了不可变数据更新可选链与空值合并:大幅减少防御性编程的样板代码 可维护性提高 类语法:更直观的面向对象编程模型模块化:明确的依赖关系,降低耦合标准化的API:统一的实现,减少框架依赖
标签:

JavaScript系列05-现代JavaScript新特性由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JavaScript系列05-现代JavaScript新特性