前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6 常用知识总结

ES6 常用知识总结

作者头像
EchoROne
发布2022-08-15 08:30:22
4640
发布2022-08-15 08:30:22
举报
文章被收录于专栏:玩转大前端玩转大前端

一、ES6简介

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

二、新特性

1. let、const

新特性注意点let1. 不存在变量提升 2. 暂时性死区(块级作用域) 3. 不允许重复声明const声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。 其只保证指针不发生改变,因此可以修改保存的对象的值

  • ES6 声明变量的6种方法:var function let const import class
代码语言:javascript
复制
// 取顶层对象
// 方法一
(typeof window !== 'undefined'
   ? window
   : (typeof process === 'object' &&
      typeof require === 'function' &&
      typeof global === 'object')
     ? global
     : this);

// 方法二
var getGlobal = function () {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

2. 解构赋值

代码语言:javascript
复制
// 数组
let [x, y='b'] = ['a'] // x=''a, y='b'

// 对象
let { foo:f, bar:l=2 } = { foo: 'aaa', bar: undefined } // f,l才是变量名
f // aaa
l // 2

// 字符串
let {length: len} = 'hello'
len // 5

// 数组和布尔值的解构赋值
// 只要等号右边的值不是对象或数组,就先将其转为对象。
// 由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

// 函数参数解构
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
  • 作用: (1) 交换变量的值: [x, y] = [y, x]; (2) 从函数返回多个值: let { foo, bar } = example(); (3) 函数参数的定义: function f([x, y, z]) { ... } (4) 提取 JSON 数据: let { id, status, data: number } = jsonData; (5) 函数参数的默认值 (6) 遍历 Map 结构const map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world // 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... } (7) 输入模块的指定方法: const { SourceMapConsumer, SourceNode } = require("source-map");

3. 字符串的扩展

(1) 字符的 Unicode 表示法 (2) 字符串的遍历接口 (3) 直接输入U+2028和U+2029 (4) Json的stringify()的改造 (5) 模版字符串

4. 字符串的新增方法

(1) String.fromCodePoint():String.fromCharCode(0x20BB7) // "ஷ" (2) String.raw():该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法 (3) codePointAt(): 能够正确处理 4 个字节储存的字符,返回一个字符的码点 (4) normalize(): 用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化 (5) includes():返回布尔值,表示是否找到了参数字符串/ startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。 endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。 这三个方法都支持第二个参数,表示开始搜索的位置。

代码语言:javascript
复制
let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

(6) 'x'.repeat(3) // "xxx" (7) padStart()、padEnd(): ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全 (8) trimStart()、trimEnd():消除字符串头、尾部的空格 (9) matchAll(): 返回一个正则表达式在当前字符串的所有匹配

5. 正则的扩展

6. 数值的扩展

Number.isNaN() Number.isFinite() Number.isInteger():是否为整数 Number.EPSILON:极小的常量 Math.trunc(): 去除小数部分,返回整数部分 Math.sign()判断正负、0,其他值返回NaN、指数运算符**,2**3 // 8

7. 函数的扩展

ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

箭头函数

  • 使用注意点: (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。 (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。 (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替 (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
  • 不适用场合: (1)定义对象的方法,且该方法内部包括thisconst cat = { lives: 9, jumps: () => { this.lives--; } } // 对象不构成单独的作用域,导致jumps箭头函数定义时的作用域就是全局作用域。 (2) 需要动态this的时候,也不应使用箭头函数var button = document.getElementById('press'); button.addEventListener('click', () => { this.classList.toggle('on'); }); (3) 如果函数体很复杂,有许多行,或者函数内部有大量的读写操作,不单纯是为了计算值,这时也不应该使用箭头函数,而是要使用普通函数,这样可以提高代码可读性。

尾调用优化、尾递归

8. 数组的扩展

  • 扩展运算符:任何定义了遍历器(Iterator)接口的对象(参阅 Iterator 一章),都可以用扩展运算符转为真正的数组,背后调用的是遍历器接口(Symbol.iterator)
  • Array.from(): 用于将两类对象转为真正的数组: 类似数组的对象(array-like object,比如 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象,本质是具有length属性)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)// 对于还没有部署该方法的浏览器,可以用Array.prototype.slice方法替代 const toArray = (() => Array.from ? Array.from : obj => [].slice.call(obj) )(); // Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。 Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
  • Array.of()方法用于将一组值,转换为数组。Array.of(3, 11, 8) // [3,11,8]
  • copyWithin(): [1, 2, 3, 4, 5].copyWithin(0, 3, 4) // 将3号位复制到0号位 [4, 2, 3, 4, 5]
  • find(): 用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined----[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10
  • findIndex()与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1,弥补了indexOf的不足,可以发现NaN[NaN].findIndex(y => Object.is(NaN, y)) // 0
  • fill():['a', 'b', 'c'].fill(7) // [7, 7, 7] new Array(3).fill(7) // [7, 7, 7] // 还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。 ['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
  • entries()、keys()、values(): keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
  • includes(): 表示某个数组是否包含给定的值,与字符串的includes方法类似 [1, 2, NaN].includes(NaN) // true
  • flat(): 将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响[1, [2, [3]]].flat(Infinity) // [1, 2, 3]
  • flatMap(): 对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

9. 对象的扩展

代码语言:javascript
复制
let propKey = 'foo';
let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
};

属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。

  • 属性的遍历方法有5种: (1)for...in for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。 (2)Object.keys(obj) Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。 (3)Object.getOwnPropertyNames(obj) Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。 (4)Object.getOwnPropertySymbols(obj) Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。 (5)Reflect.ownKeys(obj) Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。 this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象
  • Object.is() :用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
  • Object.assign():用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。注意点: (1)浅拷贝 (2)同名属性的替换 (3)数组的处理Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3] (4) 取值函数的处理:只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
  • Object.getOwnPropertyDescriptors() 返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象
  • __proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf() 、Object.keys(),Object.values(),Object.entries() 、Object.fromEntries():Object.fromEntries([ ['foo', 'bar'], ['baz', 42] ]) // { foo: "bar", baz: 42 }

10. Symbol:

  • ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
  • Symbol 值不能与其他类型的值进行运算,会报错。 但是,Symbol 值可以显式转为字符串。另外,Symbol 值也可以转为布尔值,但是不能转为数值。 可用来消除魔法字符串、模块的Singleton模式

11. Set、Map 数据结构

Set类似于数组,但是成员的值都是唯一的,没有重复的值。

代码语言:javascript
复制
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
// 去除数组的重复成员
[...new Set(array)]
[...new Set('ababbc')].join('')
// "abc"

在 Set 内部,两个NaN是相等。另外,两个对象总是不相等的。

  • 方法: Set.prototype.add(value):添加某个值,返回 Set 结构本身。 Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。 Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。 Set.prototype.clear():清除所有成员,没有返回值。 Set.prototype.keys():返回键名的遍历器 Set.prototype.values():返回键值的遍历器 Set.prototype.entries():返回键值对的遍历器 Set.prototype.forEach():使用回调函数遍历每个成员
  • Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用。
  • WeakSet:WeakSet 结构与 Set 类似,也是不重复的值的集合。 但是,它与 Set 有两个区别: (1)WeakSet 的成员只能是对象,而不能是其他类型的值。其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。 (2)WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏
  • Map: 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。const m = new Map(); const o = {p: 'Hello World'}; m.set(o, 'content') m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false

Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。

  • WeakMap: 首先,WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。

12. Proxy

在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写,很合适用来写 Web 服务的客户端。

13. Reflect

(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。 (2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。 (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。 (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

  • 方法: Reflect.apply(target, thisArg, args) Reflect.construct(target, args) Reflect.get(target, name, receiver) Reflect.set(target, name, value, receiver) Reflect.defineProperty(target, name, desc) Reflect.deleteProperty(target, name) Reflect.has(target, name) Reflect.ownKeys(target) Reflect.isExtensible(target) Reflect.preventExtensions(target) Reflect.getOwnPropertyDescriptor(target, name) Reflect.getPrototypeOf(target) Reflect.setPrototypeOf(target, prototype)

14. Promise

  • 特点: (1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。 (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
  • 缺点: 首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
代码语言:javascript
复制
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
  • Promise.all(): 用于将多个 Promise 实例,包装成一个新的 Promise 实例。const p = Promise.all([p1, p2, p3]);
  • p的状态由p1、p2、p3决定,分成两种情况。 (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。 (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。

  • Promise.race(): const p = Promise.race([p1, p2, p3]);只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
  • Promise.resolve()、Promis.reject()、Promise.try()

15. Iterator

任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

  • 作用: (1)为各种数据结构,提供一个统一的、简便的访问接口; (2)使得数据结构的成员能够按某种次序排列; (3)ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

16. Generator

  • Generator 函数是一个普通函数,但是有两个特征: (1)function关键字与函数名之间有一个星号; (2)函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
  • 调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。
  • 异步编程: (1)回调函数 (2)事件监听 (3)发布/订阅 (4)Promise 对象 (5)Generator 函数

17. async

  • async函数对 Generator 函数的改进,体现在以下四点。 (1)内置执行器。 (2)更好的语义。 (3)更广的适用性: co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。 (4)返回值是 Promise。

18. Class

  • 与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。类的属性名,可以采用表达式。
  • 父类Foo有一个静态方法,子类Bar可以调用这个方法。 静态方法也是可以从super对象上调用的。 为class加了私有属性。方法是在属性名之前,使用#表示。
  • extends 继承,子类的构造函数必须执行一次super函数

19. Module

  • import、export
  • ES6模块的好处: (1)不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点。 (2)将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。 (3)不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。
  • import(): 类似于 Node 的require方法,区别主要是前者是异步加载,后者是同步加载。 (1)按需加载。(2)条件加载(3)动态的模块路径
  • defer是“渲染完再执行”,async是“下载完就执行”
  • 浏览器加载 ES6 模块,也使用<script>标签,但是要加入type="module"属性。

三、ES6 最佳实践

https://es6.ruanyifeng.com/#docs/style

四、辅助链接、工具

  1. 查看各浏览器对 ES6 的支持:https://kangax.github.io/compat-table/es6/
  2. 检查各种运行环境对 ES6 的支持情况:ruanyf.github.io/es-checker ,es-checker命令查看支持程度
  3. ES6 在线编译器:http://google.github.io/traceur-compiler/demo/repl.html#

参考阮一峰 ECMAScript 6 入门

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、ES6简介
  • 二、新特性
  • 1. let、const
  • 2. 解构赋值
  • 3. 字符串的扩展
  • 4. 字符串的新增方法
  • 5. 正则的扩展
  • 6. 数值的扩展
  • 7. 函数的扩展
  • 箭头函数
  • 尾调用优化、尾递归
  • 8. 数组的扩展
  • 9. 对象的扩展
  • 10. Symbol:
  • 11. Set、Map 数据结构
  • 12. Proxy
  • 13. Reflect
  • 14. Promise
  • 15. Iterator
  • 16. Generator
  • 17. async
  • 18. Class
  • 19. Module
  • 三、ES6 最佳实践
  • 四、辅助链接、工具
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档