ES6

1.const let

  1. const 值是固定的(常量)

需要赋初始值
块级作用域
在数组里面,const的值是允许被修改的,这是因为const存储的是地址,值的内容可以变化

  1. let 声明的变量具有块作用域的特征。

在同一个块级作用域,不能重复声明变量。
声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。
js里对象(引用数据类型)是地址,常量对象地址不能改变,里面的属性可以改变

  1. var 有变量提升:先把var定义的内容(赋值不提)提在最前面;

允许重复声明变量

使用

能用const的情况尽量使用const

2. 箭头函数

()=>{}

  • 不绑定this

本身没有this 里面的this指的是定义时的上层作用域的this
通过call、apply调用箭头函数
由于箭头函数没有自己的this指针,通过call()、apply()方法调用时,第一个参数会被忽略。

  • 箭头函数没有 arguments( 普通函数的参数列表,是一个类数组对象 )
  • 不能当构造函数
  • 没有原型

    3. rest参数 浅拷贝

    …是为了让你不覆盖,是追加的意思
    .function date(...args){} //数组
    date('1','2','3')
  1. 扩展运算符

image.png
image.png

ES9 为对象提供了像数组一样的rest参数和运算符

  1. //除了a,b 其他都是c
  2. function fn({a,b,...c}){
  3. }

4. Iterator 迭代器

  • 一种接口,目的是为不同的数据结构提供统一的数据访问机制
  • 只有实现了 Iterator接口的对象才能够使用 for of 来进行遍历取值
  • 已默认部署 Iterator 接口的对象主要包括数组、字符串、Set、Map 、类似数组的对象(比如 arguments 对象、DOM NodeList 对象)。
  • 默认调用Symbol.iterator方法:
    • 解构赋值
    • 扩展运算符
    • yield* 关键字

Symbol.iterator 是一个表达式,返回 Symbol 对象的 iterator 属性,这是一个预定义好的、类型为 Symbol 的特殊值。

  1. function createIterator(items) {
  2. let i = 0;
  3. return {
  4. next: function() {
  5. var done = (i >= items.length);
  6. var value = !done ? items[i++] : undefined;
  7. return {
  8. done: done,
  9. value: value
  10. };
  11. }
  12. };
  13. }

5. Generator 生成器

Generator 函数是 ES6 提供的一种异步编程解决方案

  • function关键字与函数名之间有一个星号
  • 通过yield关键字可以暂停执行
  • 通过next方法才会遍历到下一个内部状态
  • 因为Generator函数返回Iterator对象,因此我们还可以通过for…of进行遍历
  • 调用return方法后,函数直接被终止。然后将传入的值作为迭代器对象的value,并且将done改为true。

    1. function* gen() {
    2. yield 1
    3. yield 2
    4. yield 3
    5. }
    6. const g = gen()
    7. console.log(g.next()) // { value: 1, done: false }
    8. console.log(g.next()) // { value: 2, done: false }
    9. console.log(g.next()) // { value: 3, done: false }
    10. console.log(g.next()) // { value: undefined, done: true }

    使用场景:

    文件分片

    6.promise

    概念:

    Promise是为了解决回调地狱而产生的,将回调函数的嵌套,改成链式调用

  • 链式操作减低了编码难度

  • 代码可读性明显增强

    状态:

    promise对象仅有三种状态:pending(进行中),fulfilled(已成功),rejected(已失败)

  • 对象的状态不受外界影响,只有异步操作的结果,可以决定

  • 一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果

    参数:

  • resolve,将Promise对象的状态从“未完成”变为“成功”(pending变为fulfilled)

  • reject,将Promise对象的状态从“未完成”变为“失败”(pending变为rejected)

    实例方法:

  • then()

  • catch() // 处理状态为rejected的回调函数
  • finally()
  • resolve() // 返回成功或者失败的Promise对象
  • reject() // 返回一个失败的Promise对象
  • all() // 用于多个 Promise 实例,两个或多个异步事件均完成后再触发回调,如果有失败,失败原因是第一个失败promise的结果
  • race() // 只要有一个promise返回了就会结束 ( 图片请求超时
  • allSettled() // 并行地运行 promise,并将状态(fulfilled 或reject)收集到一个聚合数组中

    • [{ status: ‘fulfilled’, value: value } 如果对应的 promise 已经 fulfilled
    • {status: ‘rejected’, reason: reason}]如果相应的 promise 已经被 rejected

      Promise的缺点

  • 一旦新建,立即执行,无法中途取消

  • Promise内部抛出的错误,无法反映到外部
  • pending状态时无法知道进展到哪一个阶段

    7.async

  • async/await作用是用同步方式,执行异步操作

  • await只能在async函数中使用,不然会报错
  • async函数返回的是一个Promise对象,有无值看有无return值

    1. // 先请求完接口1,再去请求接口2
    2. async function fn2() {
    3. await request(1)
    4. await request(2)
    5. }
    6. fn2()
    7. // 先请求完接口1,再拿接口1返回的数据,去当做接口2的请求参数
    8. async function fn () {
    9. const res1 = await request(5)
    10. const res2 = await request(res1)
    11. console.log(res2) // 2秒后输出 20
    12. }
    13. fn()

    8.set && map

    Set

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

  • Set 本身是一个构造函数,用来生成 Set 数据结构
  • 可以用set实现数组去重


  • new Set(iterable) —— 创建一个 set,如果提供了一个 iterable 对象(通常是数组),将会从数组里面复制值到 set 中。

  • set.add(value) —— 添加一个值,返回 set 本身
  • set.delete(value) —— 删除值,如果 value 在这个方法调用的时候存在则返回 true ,否则返回 false
  • set.has(value) —— 如果 value 在 set 中,返回 true,否则返回 false
  • set.clear() —— 清空 set。
  • set.size —— 返回元素个数。

我们可以使用 for..offorEach 来遍历 Set:

  1. let set = new Set(["oranges", "apples", "bananas"]);
  2. for (let value of set) alert(value);
  3. // 与 forEach 相同:
  4. set.forEach((value, valueAgain, set) => {
  5. alert(value);
  6. });

Map 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)

它的方法和属性如下:

  • new Map() —— 创建 map。
  • map.set(key, value) —— 根据键存储值。
  • map.get(key) —— 根据键来返回值,如果 map 中不存在对应的 key,则返回 undefined
  • map.has(key) —— 如果 key 存在则返回 true,否则返回 false
  • map.delete(key) —— 删除指定键的值。
  • map.clear() —— 清空 map。
  • map.size —— 返回当前元素个数。

    1. var m = new Map(); // 空Map
    2. m.set('Adam', 67); // 添加新的key-value
    3. m.has('Adam'); // 是否存在key 'Adam': true
    4. m.get('Adam'); // 67
    5. m.delete('Adam'); // 删除key 'Adam'
    6. m.get('Adam'); // undefined

    Map 还可以使用对象作为键。
    运行 forEach 函数
    与普通对象 Object 的不同点:

  • 任何键、对象都可以作为键。

  • 有其他的便捷方法,如 size 属性。

    8.class

    new 会自动调用 constructor() 方法,因此我们可以在 constructor() 中初始化对象。
    类字段重要的不同之处在于,它们会在每个独立对象中被设好,而不是设在 User.prototype
    Class 提供了 "super" 关键字。

  • 执行 super.method(...) 来调用一个父类方法。

  • 执行 super(...) 来调用一个父类 constructor(只能在我们的 constructor 中)。

继承类的 constructor 必须调用 **super(...)**,并且 (!) 一定要在使用 **this** 之前调用。
受保护的属性通常以下划线 **_** 作为前缀。
get/set

  1. class MyClass {
  2. prop = value; // 属性
  3. constructor(...) { // 构造器
  4. // ...
  5. }
  6. method(...) {} // method
  7. get something(...) {} // getter 方法
  8. set something(...) {} // setter 方法
  9. [Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)
  10. // ...
  11. }
  1. //es5
  2. function phone(price,brand){
  3. this.price=price;
  4. this.brand=brand;
  5. }
  6. phone.prototype.call = function(){
  7. console.log("111");
  8. }
  9. let huawei = new phone(12222,'huawei');
  10. huawei.call();
  11. console.log(huawei);
  12. //es6 class
  13. class shouji{
  14. constructor(price,brand){
  15. this.price=price;
  16. this.brand=brand;
  17. }
  18. call(){
  19. consolle.log("2222");
  20. }
  21. }
  22. let xiaomi = new shouji(12211,'xiaomi');
  23. console.log(xiaomi);
  1. class Animal {
  2. constructor(name) {
  3. this.speed = 0;
  4. this.name = name;
  5. }
  6. run(speed) {
  7. this.speed = speed;
  8. alert(`${this.name} runs with speed ${this.speed}.`);
  9. }
  10. stop() {
  11. this.speed = 0;
  12. alert(`${this.name} stands still.`);
  13. }
  14. }
  15. class Rabbit extends Animal {
  16. hide() {
  17. alert(`${this.name} hides!`);
  18. }
  19. stop() {
  20. super.stop(); // 调用父类的 stop
  21. this.hide(); // 然后 hide
  22. }
  23. }
  24. let rabbit = new Rabbit("White Rabbit");
  25. rabbit.run(5); // White Rabbit 以速度 5 奔跑
  26. rabbit.stop(); // White Rabbit 停止了。White rabbit hide 了!

静态属性和静态方法

我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype"。这样的方法被称为 静态的(static)
{ECDD5F9B-7D89-FE35-E001-84151AB8FC64}.jpg

  1. class Person {
  2. name;
  3. age;
  4. static stand(){
  5. console.log("人类站起来了");
  6. }
  7. run() {
  8. console.log(`${this.age}岁的${this.name}跑起来了`);
  9. }
  10. }
  11. Person.stand();
  12. (new Person('张三',32)).run();
  13. (new Person('11',22)).run();

类继承 super()

  1. //es5 构造函数继承
  2. function Person(sex,age){
  3. this.age=age;
  4. this.sex=sex;
  5. }
  6. Person.prototype.call = function(){
  7. console.log(1111);
  8. }
  9. function Chidren(sex,age,name,phone){
  10. Person.call(this,sex,age);
  11. this.name=name;
  12. this.phone=phone;
  13. }
  14. //设置子集构造函数的原型
  15. Chidren.prototype = new Person;
  16. Chidren.prototype.constructor=Chidren;
  17. //es6 类继承
  18. class Person{
  19. constructor(age,sex){
  20. this.age=age;
  21. this.sex=sex;
  22. }
  23. }
  24. class Chidren extends Person{
  25. constructor(age,sex,name,phone){
  26. super(age,sex);
  27. this.name=name;
  28. this.phone=phone;
  29. }
  30. }
  1. class User {
  2. constructor(name) {
  3. this.name = name;
  4. }
  5. get name() {
  6. return this._name;
  7. }
  8. set name(value) {
  9. if (value.length < 4) {
  10. alert("Name is too short.");
  11. return;
  12. }
  13. this._name = value;
  14. }
  15. }
  16. let user = new User("John");
  17. alert(user.name); // John
  18. user = new User(""); // Name is too short.

9. 对象方法扩展

  1. Object.is(a,b) 判断两个值是否完全相等
  2. Object.assign(a,b) 对象的合并
  3. Object.setPrototypeOf 设置原型对象

    10.模块化

  • export 关键字标记了可以从当前模块外部访问的变量和函数。
  • import 关键字允许从其他模块导入功能。

    如果同一个模块被导入到多个其他位置,那么它的代码仅会在第一次导入时执行,然后将导出(export)的内容提供给所有的导入(importer)。
    在实际开发中,顶级模块代码主要用于初始化,内部数据结构的创建,并且如果我们希望某些东西可以重用 — 请导出它。
    !!!!type="module" 的 js 里函数无法用 ```javascript

//static.js //分别暴露 export let school=’a’; export function b(){ console.log(“qqqq”); }

//统一暴露 let person = ‘ww’; function sex(){ console.log(“men”); } export {sex,person}; //默认暴露 数组 export default { school:’qqq’, change:function(){ console.log(“www”); } }

  1. <a name="XzYhh"></a>
  2. ## 11.解构函数
  3. ```javascript
  4. const obj = {
  5. name: '1',
  6. age: 20,
  7. doing: {
  8. morning: '学习',
  9. afternoon: '学习',
  10. evening: 'sleep'
  11. }
  12. }
  13. const { name, age, gender } = obj
  14. console.log(name, age, gender) // 1 22 男
  15. // 解构重名
  16. const { name: myname } = obj
  17. console.log(myname) // 1
  18. // 嵌套解构
  19. const { doing: { evening } } = obj
  20. console.log(evening) // sleep

ES7

xxx.includes()

传入元素,如果数组中能找到此元素,则返回true,否则返回false

  1. const arr = [1, NaN]
  2. console.log(arr.indexOf(NaN)) // -1 indexOf找不到NaN
  3. console.log(arr.includes(NaN)) // true includes能找到NaN

2 **10 幂运算

<= Math.pow(2,10)

ES8

async 和 await

Async/await 是以更舒适的方式使用 promise 的一种特殊语法

async

async 确保了函数返回一个 promise,也会将非 promise 的值包装进去。
image.png

await

  • 关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。
  • await 只在 async 函数中有效。
  • await返回promise成功的值
  • await的promise失败了则会抛出异常,try{} catch(){}来捕获

    async/await的执行顺序

    遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。以下面的代码分析:

    async/await的优缺点

  1. 优点
    相对于promise,async/await处理 then 的调用链,代码要清晰很多,几乎和同步代码一样
    2. 缺点
    滥用 await 可能会导致性能问题,因为 await 会阻塞代码

    对象方法扩展

    Object.values() 获取对象所有的值

    Object.entries()获取遍历属性的数组

    ```javascript const school = { name:”aa”, cities:[‘吉林’,’河南’], xueke:[‘c’,’python’,’java’]

} a = Object.entries(school) console.log(a) const m = new Map(a) console.log(m)

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21583754/1632451600851-11d48cff-a2c7-4843-b3fd-33fa8058c186.png#clientId=u4eabc2e0-9888-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=129&id=ua5d73126&margin=%5Bobject%20Object%5D&name=image.png&originHeight=258&originWidth=578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33474&status=done&style=none&taskId=u2cd480b4-3012-441d-939e-f3af56beb5d&title=&width=289)
  2. <a name="VhYlG"></a>
  3. ### `Object.getOwnPropertyDescriptors`对象属性的描述对象
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21583754/1632451824437-2d545aa0-98a6-44d6-999f-67dcd8ce9592.png#clientId=u4eabc2e0-9888-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=132&id=u28124c80&margin=%5Bobject%20Object%5D&name=image.png&originHeight=264&originWidth=373&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15606&status=done&style=none&taskId=uc4dbd8ae-db09-4596-a6d1-9efa127a5fa&title=&width=186.5)
  5. <a name="tNWGU"></a>
  6. ## 函数
  7. <a name="V9VOr"></a>
  8. ### `Padstart()` `PadEnd()` 填充字符串达到当前长度
  9. <a name="pY3fc"></a>
  10. ## 函数参数列表结尾允许逗号
  11. <a name="LKbiD"></a>
  12. # ES10 2019
  13. <a name="FsLBH"></a>
  14. ### 1. Array的`arr.flat()` `arr.flatMap()`
  15. ` flat(depth) //depth是指定要提取嵌套数组的结构深度,默认值为 1 ` 将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
  16. ```javascript
  17. const numbers1 = [1, 2, [3, 4, [5, 6]]]
  18. console.log(numbers1.flat())// [1, 2, 3, 4, [5, 6]]
  19. const numbers2 = [1, 2, [3, 4, [5, 6]]]
  20. console.log(numbers2.flat(2))// [1, 2, 3, 4, 5, 6]

flatMap() 是综合了map和flat的操作,所以它也只能打平一层

  1. let arr = [1, 2, 3]
  2. console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]
  3. console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]

2. Object的Object.fromEntries()

与 Object.entries 相反的操作

  1. const object = { x: 23, y:24 };
  2. const entries = Object.entries(object); // [['x', 23], ['y', 24]]
  3. const result = Object.fromEntries(entries); // { x: 23, y: 24 }

3. String.trimStart()String.trimEnd()

移除开头和结尾的空格

String.prototype.matchAll

返回的是遍历器

4. BigInt

BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

  1. const aNumber = 111;
  2. const aBigInt = BigInt(aNumber);
  3. aBigInt === 111n // true
  4. typeof aBigInt === 'bigint' // true
  5. typeof 111 // "number"
  6. typeof 111n // "bigint"
  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (new in ECMAScript 2015)
  • BigInt (new in ECMAScript 2019)

    5. Symbol.prototype.description

6. Function.prototype.toString()

之前执行这个方法时,得到的字符串是去空白符号的。而现在,得到的字符串呈现出原本源码的样子

ES11

1.Promise.allSettled

2.?.??

?.:中文名为可选链,不确定存不存在
??||最大的区别是,在??这,只有undefined和null才算假值

ES12

1. Promise.any

2. 数字分隔符

  1. const num = 1000000000
  2. // 使用数字分隔符
  3. const num = 1_000_000_000

3.||=&&=

或等于(||=) a ||= b等同于 a || (a = b);
且等于(&&=) a &&= b 等同于 a && (a = b);