当前位置: 首页 > news >正文

JavaScript的现代进阶:从ES6到ES15

自从ES6(ECMAScript 2015)以来,JavaScript作为一门语言经历了前所未有的变革,每年的新版本都带来了令人振奋的新特性和优化,极大地提升了开发者的生产力和代码的可维护性。本文将深入探讨从ES6ES15(ECMAScript 2024)期间JavaScript的演变历程,旨在为开发者提供一份全面的指南,涵盖语言的关键更新和实用示例。

1. ES6 (ECMAScript 2015): 现代JavaScript的起点

1.1. let 和 const

  • let 用于声明块级作用域的变量,解决了变量提升的问题。
  • const 用于声明不可重新赋值的常量,提高了代码的可预测性。
let count = 0;
const PI = 3.14;

1.2. 解构赋值

对象解构和数组解构提供了从复杂数据结构中快速提取数据的便捷方式。

const {firstName, lastName} = {firstName: 'John', lastName: 'Doe'};
console.log(firstName, lastName); // John Doe
const [first, second] = [1, 2];
console.log(first, second); // 1 2

测试:

1.3. 模板字符串

允许在字符串中嵌入表达式,极大地提高了字符串拼接的可读性和效率。

const name = 'Alice';
console.log(`Hello, ${name}!`); // Hello, Alice!

测试:

1.4. 箭头函数

提供了一种更简洁的函数定义方式,同时自动绑定this,避免了闭包中的this问题。

const add = (a, b) => a + b;
add(1, 2); // 3

测试:

1.5. 类

虽然JavaScript本质上是基于原型的,但类语法提供了面向对象编程的语法糖,使代码更易于理解和维护。

class Person {constructor(name) {this.name = name;}greet() {console.log(`Hello, ${this.name}`);}
}const person = new Person('John');
person.greet()

测试:

1.6. 模块系统

引入了importexport关键字,实现了真正的模块化编程,提高了代码的组织性和复用性。

// myModule.js
export const PI = 3.14;// main.js
import {PI} from './myModule.js';

1.7. Promises

为异步编程提供了一个更优雅的解决方案,替代了回调地狱,使异步代码更易于理解和调试。

const promise = new Promise((resolve, reject) => {setTimeout(() => resolve('Done!'), 1000);
});
console.log(promise)

测试:

1.8. Symbols

用于创建唯一属性键,避免了命名冲突,特别适用于私有属性的实现。

const uniqueId = Symbol('id');
console.log(uniqueId);

测试:

1.9. Array.from()

  • 从类数组对象或可迭代对象创建新的数组实例。
const arrayLike = {length: 3, 0: 'a', 1: 'b', 2: 'c'};
console.log(arrayLike)
const arr = Array.from(arrayLike);
console.log(arr)

测试:

1.10. Map 和 Set

Map 是一种容器,用于存储键值对。与普通的JavaScript对象不同,Map 的键可以是任意类型的值,包括函数、对象、基本类型等。Map 的一些主要特性包括:

  • 键值对的顺序是基于插入顺序的。
  • 可以通过键来快速检索值。
  • 键和值都可以是任意类型的值。
  • 提供了 get, set, delete, has, clear 等方法来操作数据。
  • Map 的大小可以通过 size 属性获取。
const myMap = new Map();
myMap.set('key1', 'value1');
myMap.set(123, 'another value');
console.log(myMap.get('key1')); // 输出: value1
console.log(myMap.size);        // 输出: 2

测试:

Set 是一种集合,用于存储唯一的元素列表。Set 自动确保没有重复的值。其主要特性包括:

  • 元素的顺序也是基于插入顺序的。
  • 可以检查元素是否存在,添加新元素,删除元素等。
  • Set 的元素可以是任何类型的值,但每个值只能出现一次。
  • Set 的大小同样可以通过 size 属性获取。
const mySet = new Set();
mySet.add('a');
mySet.add('b');
mySet.add('a'); // 这不会添加,因为 'a' 已经存在
console.log(mySet.has('a')); // 输出: true
console.log(mySet.size);    // 输出: 2

1.11. Array.of()

  • 从零个或多个参数创建新的数组实例。
const arr = Array.of(1, 2, 3);
console.log(arr)

测试:

1.12. 生成器函数 function* () {}

  • 可以使用yield关键字暂停和恢复函数的执行。当生成器函数被调用时,它不会立即执行,而是返回一个迭代器对象。当迭代器的next()方法被调用时,函数会从上一次暂停的地方继续执行,直到遇到下一个yield表达式或函数结束。
  • 可以返回一个序列。生成器函数可以产生一系列的值,而不是像普通函数那样只能返回一个值。
  • 可以接收外部传入的值。通过next()方法的参数,可以向生成器函数内部传递值。
function* numberGenerator() {yield 1; // 第一次调用next()时返回yield 2; // 第二次调用next()时返回return 'done'; // 可以返回一个最终值,但通常不使用
}const gen = numberGenerator();console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 'done', done: true }
console.log(gen.next()); // { value: undefined, done: true }

测试:

在这个例子中,numberGenerator是一个生成器函数,它会产生两个数字,然后结束。每次调用gen.next()都会执行生成器函数直到遇到下一个yield表达式或者函数结束,并返回一个包含valuedone属性的对象。value属性包含了yield表达式产生的值,而done属性表示生成器是否已经完成了所有的迭代。

1.13. 默认参数和剩余参数

  • 函数参数变得更加灵活,支持默认值和收集不定数量的参数。
// 参数默认值
function sum(a = 10, ...nums) {return a + nums.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum()); // 10// 剩余参数
function sum(...nums) {return nums.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

测试:

1.14. String.prototype.repeat()

  • 重复字符串多次。
const str = 'abc'.repeat(3);
console.log(str); // 'abcabcabc'

测试:

2. ES7 (ECMAScript 2016): 数学运算的提升

2.1. 指数运算符 (**)

  • 简化了幂运算的语法。
const result = 2 ** 3;
console.log(result); // 8

测试:

3. ES8 (ECMAScript 2017): 异步编程的革命

3.1. 异步函数 (async/await)

  • 使异步代码看起来更像同步代码,极大地简化了异步流程的控制。
async function fetchData() {const response = await fetch('/data');return await response.json();
}

3.2. 扩展运算符 (...)

  • 用于复制数组和对象中的元素,也用于函数调用时收集参数。
const arr = [...[1, 2], ...[3, 4]];
console.log(arr)

测试:

3.3. Array.prototype.includes()

  • 检查数组是否包含特定元素,返回布尔值。
const arr = [1, 2, 3];
console.log(arr.includes(2)); // true

测试:

3.4. String.prototype.padStart() 和 String.prototype.padEnd()

  • 在字符串的开始或结束填充字符。
const str1 = '123'.padStart(7, '0'); 
console.log(str1); // '0000123'const str2 = '123'.padEnd(7, '0'); 
console.log(str2); // '1230000'

测试:

4. ES9 (ECMAScript 2018): 异步迭代的引入

4.1. 异步迭代 (async iterators)

  • 支持异步遍历数据流,为处理大量数据提供了新的途径。
const asyncIterable = {[Symbol.asyncIterator]() {return {next: () => Promise.resolve({done: false, value: 1})};}
};
console.log(asyncIterable)

测试:

4.2. String.prototype.trimLeft() 和 String.prototype.trimRight()

  • 左右两侧去除空白字符。
const str1 = '   hello world   ';
console.log(str1.trimLeft()); // 'hello world   '
const str2 = '   hello world   ';
console.log(str2.trimRight()); // '   hello world'

测试:

5. ES10 (ECMAScript 2019): 数组和字符串的增强

5.1. 扁平化数组 (flat and flatMap)

  • 提供了将多维数组扁平化到指定深度的能力。
  • 它可以接受一个可选的参数 depth,表示要展开的数组的深度。如果不提供 depth 参数,或者将其设置为 1,那么 flat 将只会展开第一层的子数组。
const arr = [1, [2, [3, [4]]]];
const flatArr = arr.flat(2);
console.log(flatArr); // [1, 2, 3, [4]]const deepArr = [1, [2, [3, [4, [5]]]]];
const deepFlatArr = deepArr.flat(4);
console.log(deepFlatArr); // [1, 2, 3, 4, 5]

测试:

5.2. Array.prototype.flatMap()

  • Array.prototype.flatMap() 结合了 map()flat() 的功能。flatMap() 首先对数组中的每个元素应用一个映射函数,然后将结果展平一层。这使得处理和转换嵌套数组变得更加简单和高效。

语法:array.flatMap(callback(element[, index[, array]])[, thisArg])

  • flatMap() 接受一个回调函数作为参数,这个函数会被应用于数组的每个元素,并且可以返回一个新的数组。flatMap() 会自动将这些新数组展平到一个数组中,而不是返回一个嵌套数组。
  • callback: 必需。一个函数,其参数与 map() 方法相同。
  • element: 当前被处理的数组元素。
  • index: 可选。当前元素的索引。
  • array: 可选。调用 flatMap 的数组本身。
  • thisArg: 可选。指定执行回调函数时 this 的值。
const numbers = [[1, 2], [3, 4], [5, 6]];const flattened = numbers.flatMap(x => x);console.log(flattened); // 输出: [1, 2, 3, 4, 5, 6]

5.3. String.prototype.trimStart 和 trimEnd

  • 提供了更细粒度的字符串修剪功能。
const str1 = '   Hello World   ';
console.log(str1.trimStart());
const str2 = '   Hello World   ';
console.log(str2.trimEnd());

5.4. String.prototype.matchAll

  • 返回字符串中所有匹配正则表达式的迭代器,便于处理复杂的文本模式。
const str = 'hello world';
const regex = /l/g;
const matches = str.matchAll(regex);
for (const match of matches) {console.log(match);
}

测试:

6. ES11 (ECMAScript 2020): 高级数据操作

6.1. 可选

http://www.dtcms.com/a/265663.html

相关文章:

  • 机器学习-03(机器学习任务攻略)
  • npm 命令入门指南(前端小白版)
  • 使用numpy的快速傅里叶变换的一些问题
  • 记忆翻牌记忆力小游戏流量主微信小程序开源
  • 万能公式基分析重构补丁复分析和欧拉公式原理推导
  • 国外开源集成平台(业务编排)camel及Mule介绍
  • 为什么是直接在**原型(prototype)上**添加函数
  • 构建引擎: 打造小程序编译器
  • 边缘计算解决方案:电力作业行为图像识别
  • Mac电脑 触摸板增强工具 BetterTouchTool
  • Linux开发工具——gcc/g++
  • 虚拟机网络检查
  • 数据结构-栈的实现
  • 电动车信用免押小程序免押租赁小程序php方案
  • 数据库运维手册指导书
  • 移动端Html5播放器按钮变小的问题解决方法
  • Laravel8中使用phpword生成word文档
  • LeetCode--40.组合总和II
  • 【ArcGIS Pro】属性表咋不能编辑了?
  • wvp-GB28181-pro 项目 ZLMediaKit 部署 (Centos7)
  • XILINX Ultrascale+ Kintex系列FPGA的架构
  • R语言开发记录,二(创建R包)
  • vue-37(模拟依赖项进行隔离测试)
  • 《导引系统原理》-西北工业大学-周军-“2️⃣导引头的角度稳定系统”
  • 定时点击二次鼠标 定时点击鼠标
  • Node.js中exports与module.exports区别
  • DPDK开发环境配置
  • SpringCloud系列(49)--SpringCloud Stream消息驱动之实现生产者
  • 《Spring 中上下文传递的那些事儿》 Part 1:ThreadLocal、MDC、TTL 原理与实践
  • 使用 Docker Swarm 部署高可用集群指南