JavaScript ES6教程(下)
ES6新增方法
数组新增方法:
方法 | 描述 | 原数组 |
---|---|---|
.forEach() | 按顺序为数组中的每个元素调用一次指定的函数(遍历数组) | 不改变 |
Symbol 类型
Symbol 是 ES6 新增的一种基本数据类型,它表示独一无二的值( Symbol 值 ),Symbol 类型的值可以作为对象的属性名,它保证每个属性的名字都是独一无二的,不会出现因属性重名而冲突的问题,这也是该数据类型仅有的目的
Symbol 值通过Symbol()
函数得到,一个Symbol()
函数返回一个 Symbol 值
例:
1 | let s = Symbol(); |
Symbol()
函数不能通过new Symbol()
来调用,这是因为 Symbol 类型是一个基本数据类型,而非对象,因此无需使用 new 来调用,不过 Js 引擎会将 Symbol 值包装成 Symbol 类型对象( 临时对象 )来使用
Symbol()
函数可以接受一个字符串作为参数,表示对 Symbol 值的描述,这样在输出 Symbol 值时,比较容易区分
例:
1 | let s1 = Symbol('foo'); |
属性:
description
描述:获取 Symbol 值的描述
例:
1
2const sym = Symbol('foo');
console.log(sym.description); // "foo"
Symbol 值可以作为对象的属性名,这样就能保证不会出现同名的属性
例:
1 | let symbol = Symbol(); |
Symbol值作为属性名时,需要注意两点:
- 使用 Symbol 值定义属性时,Symbol 值必须放在方括号(
[]
)之中使用 - 遍历对象的时候,Symbol 属性名不会出现在
for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回
如果要想从对象中获取 Symbol 属性名,可以使用Object.getOwnPropertySymbols()
方法,该方法会返回对象中所有 Symbol 属性名
例:
1 | const obj = {}; |
Iterator 迭代器
迭代器是一个符合迭代器协议的对象,它提供了顺序遍历的机制。允许你依次访问一个容器( 例如:数组、字符串、Set、Map 等 )中的每一个元素,而无需了解容器的内部结构
迭代器对象需要具有一个 next()
方法,该方法返回一个对象,需包含两个属性:
value
:当前迭代的值done
:一个布尔值,表示迭代是否结束。done
为true
表示迭代结束
Iterrable 可迭代对象
可迭代对象是实现了 @@iterator
方法的对象。一个对象如果具有 Symbol.iterator
属性(即具有一个默认的迭代器方法),它就是可迭代的。常见的可迭代对象包括:数组、字符串、Set
、Map
、arguments
对象等
例:
1 | let array = [1, 2, 3]; |
for…of 循环
for...of
循环是一种简化的方式来遍历可迭代对象,内部使用了 Iterator
。它自动处理 next()
的调用,直到 done
为 true
为止
例:
1 | let array = [1, 2, 3]; |
Symbol.iterator
Symbol.iterator
是一个特殊的符号,定义了对象的默认迭代器方法。实现了 Symbol.iterator
的对象被认为是可迭代的,可以用 for...of
来遍历,JavaScript 中的内置类型,如数组、字符串、Map
、Set
等,默认具有迭代器方法,如果没有我们可以手动创建迭代器方法( Symbol.iterator
)
手动创建对象的迭代器方法:
1 | let customIterable = { |
Generator 生成器
Set 集合
Set 是 ES6 新增的一种数据结构,它是一种无重复的集合,类似于数组
Set 类型中的值是唯一的,即使向 Set 类型重复添加相同的值,也只会保留一个
常用方法和属性:
add(value)
:向 Set 类型中添加一个值delete(value)
:从 Set 类型中删除一个值has(value)
:判断 Set 类型中是否包含某个值clear()
:清空 Set 类型size
:返回 Set 类型中的值的个数
例:
1 | /* 例1 */ |
遍历方法:
keys()
:返回键名的遍历器values()
:返回值的遍历器entries()
:返回键值对的遍历器forEach()
:使用回调函数遍历每个成员
keys
方法、values
方法、entries
方法返回的都是遍历器对象(详见 Iterator 遍历器)。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以 keys
方法和 values
方法的行为完全一致
例:
Map 类型
ES6 模块化( Module )
在 ES6 中引入的标准化模块系统,它允许开发者将代码分割成独立的模块,并通过导入和导出机制来组织和重用代码。在这之前,JavaScript 一直没有模块(module)系统,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于 Node.js 环境,后者用于浏览器环境
导出与导入( export
& import
)
在浏览器环境中,模块就是一个被 ES6 模块化系统所管理的 JavaScript 文件或代码,你可以使用 export
关键字从一个模块中导出变量、函数或类,如果要在别的模块中使用该模块导出的内容,可以使用 import
关键字从其他模块中导入
具名导出与导入:
可以在一个模块中导出多个变量、函数、类等。每个导出的名称都是明确指定的,在导入时,可以选择性地导入所需的内容
1 | /* module1.js */ |
1 | /* module2.js */ |
1 | <!-- index.html --> |
默认导出与导入:
一个模块只能有一个默认导出。它通常用来导出模块的主要功能或值,在导入时,不需要使用花括号,并且可以自定义导入的名称( 名称在导入时决定 )
1 | /* utils.js */ |
1 | /* main.js */ |
1 | <!-- index.html --> |
组合导出与导入:
1 | /* shapes.js */ |
1 | /* main.js */ |
1 | <!-- index.html --> |
导入所有:
1 | // 将 module.js 导出的所有内容作为对象属性保存在变量 m 中 |
模块的使用方式
在 HTML 中使用
<script type="module">
标签来告诉浏览器这是一个模块文件。浏览器会自动识别并处理模块中的依赖关系和导入导出。在 Web浏览器中你需要通过 Web 服务器去运行,这是因为浏览器需要通过 HTTP 协议并且会按照 CORS 规则来访问模块是独立作用域的
每个模块都有自己的作用域,不会污染全局命名空间。模块内的变量、函数、类等,默认是模块私有的,只有通过
export
导出才能被其他模块访问模块自动采用严格模式
无需手动指定
"use strict"
,模块文件会自动在严格模式下运行异步加载
浏览器会异步加载模块文件,这意味着不会阻塞页面的渲染。即使使用
import
来加载多个模块,浏览器也会并行下载这些模块,优化性能模块的静态的
import
和export
是静态的,也就是说,它们必须在模块的顶层使用,不能在条件语句或函数中。这样编译器可以提前分析模块的依赖关系,进行优化,如 tree-shaking
Proxy
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性