ES6做项目 - 必备知识

文章目录

  • 1 .ECMAScript 6 简介
        • ECMAScript 和 JavaScript 的关系
        • ES6 与 ECMAScript 2015 的关系
        • Babel 转码器
  • 2. let 和 const 命令 和var的区别
        • 不存在变量提升
        • let不允许在相同作用域内,重复声明同一个变量
        • 顶层对象的属性 § ⇧
        • 块级作用域
        • 暂时性死区 TDZ
        • CONST 声明
  • 3. ES6 声明变量的六种方法
  • 4. 变量的解构赋值
      • 数组的解构赋值
      • 对象的解构赋值
      • 字符串的解构赋值
  • 5. 数组的方法
  • 6. 对象扩展
  • 7. 字符串的方法
  • 8. Set和Map
  • 9. Promise
      • 基本API
      • 概念:
      • 特点:
      • 使用:
        • 解决俩个问题
      • reject的用法
      • catch的用法
      • all的用法
      • race的用法
  • 10. Generator + CO
      • 区别:
      • yield 表达式
      • next方法
      • 用途:
    • co 是什么
        • 特点:
      • co实现generator自动执行的条件
      • 使用:

1 .ECMAScript 6 简介

ECMAScript 和 JavaScript 的关系

- ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现

ES6 与 ECMAScript 2015 的关系

-	 ES6 这个词的原意,就是指 JavaScript 语言的下一个版本
-	ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017  8 9 等等

Babel 转码器

- 可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持 

2. let 和 const 命令 和var的区别

不存在变量提升

let不允许在相同作用域内,重复声明同一个变量

顶层对象的属性 § ⇧

  • 顶层对象,在浏览器环境指的是window对象,
  • 在 Node 指的是global对象。ES5 之中,
  • 顶层对象的属性与全局变量是等价的。

块级作用域

  • 第一种场景,内层变量可能会覆盖外层变量。
  • 第二种场景,用来计数的循环变量泄露为全局变量。

暂时性死区 TDZ

CONST 声明

  • const声明一个只读的常量。一旦声明,常量的值就不能改变。
  • const一旦声明变量,就必须立即初始化,不能留到以后赋值。
  • 变量指向的那个内存地址不得改动

3. ES6 声明变量的六种方法

  • ES5 只有两种声明变量的方法:var命令和function命令。
  • ES6 除了添加let和const命令,
  • 另外两种声明变量的方法:import命令和class命令。

4. 变量的解构赋值

数组的解构赋值

  • 完全解构
  • 不完全解构
  • 赋默认值

对象的解构赋值

  • 键名解构
  • 起别名

字符串的解构赋值

  • 用途
    -交换变量的值
  • 函数参数的定义
  • 提取 JSON 数据
  • 函数参数的默认值
  • 遍历 Map 结构( Iterator 接口的对象)

5. 数组的方法

  • 扩展运算符
  • Array.from()
  • Array.of()
  • 数组实例的 copyWithin()
  • 数组实例的 find() 和 findIndex()
  • 数组实例的 fill()
  • 数组实例的 entries(),keys() 和 values()
  • 数组实例的 includes()
  • 数组实例的 flat(),flatMap()
  • 数组的空位

6. 对象扩展

  • Object.is()
  • Object.assign()
  • Object.keys(),Object.values(),Object.entries()
  • Object.fromEntries()

7. 字符串的方法

  • String.fromCodePoint()
  • String.raw()
  • 实例方法:codePointAt()
  • 实例方法:normalize()
  • 实例方法:includes(), startsWith(), endsWith()
  • 实例方法:repeat()
  • 实例方法:padStart(),padEnd()
  • 实例方法:trimStart(),trimEnd()
  • 实例方法:matchAll()

8. Set和Map

  • set.size:类似于length 长度

  • add(value):添加某个值,返回 Set 结构本身

  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

  • has(value):返回一个布尔值,表示该值是否为Set的成员。

  • clear():清除所有成员,没有返回值。

  • map.set(key,val)

  • map.get(key)

  • map.has()

9. Promise

基本API

  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.prototype.finally()
  • Promise.all()
  • Promise.race()
  • 应用
  • Promise.try()

在 JavaScript 中,所有代码都是单线程的,也就是同步执行的。而 Promise 就
Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。

概念:

Promise 对象用于表示一个异步操作的最终完成(或失败),及其结果值。为异步编程提供了一种解决方案。

特点:

  1. 对象的状态不受外界影响。

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

  1. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise对象的状态,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。

使用:

Promise 对象是由 关键字 new 构造函数来创建的。

let p = new Promise((resolve, reject)=> {
   //做一些异步操作
    setTimeout(()=> {
            console.log('执行完成');
            resolve('可以任何数据例如接口返回数据');
    }, 1000);
});
//执行结果:执行完成
//执行过程:执行一个异步操作,也就是setTimeout,1秒后,输出“执行完成”,并且调用resolve方法。

注意!我只是new了一个对象,并没有调用它,就已经执行了。所以用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数。

 <button onclick="promiseClick()">开始异步</button>

 <script>
 const promiseClick = () => {
    return new Promise((resolve, reject) => {
       //做一些异步操作
       setTimeout(() => {
           console.log('执行完成');
           resolve('可以任何数据例如接口返回数据');
       }, 1000);
    });
 }
 </script>
 //刷新页面的是没有执行的,点击后控制台打出。
 //执行:执行完成

解决俩个问题

1、为什么要放在函数里面

2、resolve是个什么

我们包装好的函数后,会 return 出 Promise 对象,执行这个函数我们得到了一个Promise对象。接下来就可以用Promise对象上的then、catch方法了,这就是Promise的强大之处了。

promiseClick().then((data)=>{
    console.log(data);
    //后面可以用传过来的数据做些其他操作
    //......
})
//执行:执行完成
//resolve('xx');中的内容或数据

首先方法被调用执行了promise,最后执行了promise的then方法,then方法是一个函数接受一个参数是resolve返回的数据;就输出了 resolve 中内容。

then里面的函数就是回调函数,能够在promiseClick这个函数异步任务执行完成后被执行。这就是Promise的作用。简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

那么,如果有多层回调该怎么办?

而Promise的优势在于可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。

所以:Promise能够简化层层回调的写法 Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,优点简单、灵活。

//函数返回promise对象
 let a = ()=>{
    return new Promise((r, j) => {
       setTimeout(() => {
            r("a数据");
       }, 2000)
    })
 }
  //函数返回promise对象
 let b = ()=>{
    return new Promise((r, j) => {
       setTimeout(() => {
               //使用数据
               // console.log("bbb" + data);
               r("b数据");
       }, 1000)
    })
 }
 //有了以上执行函数,用一个Promise对象来执行它们
let sum = ()=>{
    return new Promise((r, j) => {
        setTimeout(() => {
                r("第一");
        }, 500)
    })
}
 //执行
 sum().then((sum)=>{
      console.log(sum);
      return a();
 })
 .then((aa)=>{
      console.log(aa);
      return b();
 }).then((bb)=>{
      console.log(bb);
 })
 .catch((err) => {
      console.log(err); // err 输出 j("失败信息")
 })
 //执行:第一
// a数据
// b数据

这样按顺序,每个异步回调成功后的内容,在sum中传给resolve的数据,能在接下来的then方法中拿到依次类推。

reject的用法

以上是resolve用法进行了解释,resolve是对promise成功时候的回调,它把promise的状态修改为

fullfiled(已成功)。

在 then中可以传两个参数。
then方法可以接受两个参数分别是函数,第一个对应resolve的回调,第二个对应reject的回调。所以我们能够分别拿到回调函数中成功的数据和失败的原因,并不会卡死 Js 代码运行。

 //执行
 sum().then((sum)=>{
     console.log(sum);
     return a();
 },(err)=>{
     console.log(err); // j("失败内容")
 })     
 .then...      

catch的用法

reject 就是失败的时候的回调,他把promise的状态修改为 rejected,这样我们在 catch 中就能捕捉到,然后执行“失败”情况的回调。

//执行
 .catch((err) => {
     console.log(err);
 })

all的用法

与then同级的另一个方法,该方法提供了并行执行异步的操作,在所有异步操作执行完且执行结果都是成功的时候才执行。

let a = ()=>{
    return new Promise((r, j) => {
             setTimeout(() => {
                     r("aaa数据");
             }, 1000)
     })
}

let b = ()=>{
    return new Promise((r, j) => {
            setTimeout(() => {
                    r("bbb数据");
                    //j("失败了")
            }, 1000)
    })
}

	Promise.all([a(),b()])
	.then((result) => {
	        console.log(result);
	}).catch((err) => {
	        console.log(err);
	});

使用 Promise.all 来执行,all接收一个数组参数,这组参数为需要执行异步操作的所有方法,里面的值最终都算返回Promise对象。
异步操作是并行执行的,等到它们都执行完后才会进到then里面。all会把所有异步操作的结果放进一个数组中传给then,然后再执行then方法的成功回调将结果接收。

应用场景:比如你需要提前准备好所有数据才渲染页面时就可以使用all,执行多个异步操作将所有的数据处理好,再渲染。

race的用法

all是所有的异步操作都执行完再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调。
(赛跑规则)

let a = () => {
     return new Promise((r, j) => {
             setTimeout(r,300,'r-300');
     })
}

let b = () => {
     return new Promise((r, j) => {
             setTimeout(r,100,'r-100');
     })
}

Promise.race([a(), b()])
     .then((result) => {
             console.log(result);
     }).catch((err) => {
             console.log(err);
     });
//执行:r-100

10. Generator + CO

Generator 函数是一个普通函数。

区别:

  1. function关键字与函数名之间有一个星号。(ES6 没有规定,function关键字与函数名之间的星号,写在哪个位置都能通过。)
  2. 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
  3. 调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。必须调用遍历器对象的 next() 方法,使得指针移向下一个状态
 function * helloWorldGenerator() {
     yield console.log('hello');
     yield console.log('world');
     return console.log('ending');
}

var hw = helloWorldGenerator();

— 控制台输入 hw.next();

hw.next();
index.html:156 hello

hw.next();
index.html:157 world

hw.next();
index.html:158 ending

必须调用遍历器对象的 next() 方法,使得指针移向下一个状态。每次调用next方法,内部指针就从上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。

换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

上面代码定义了一个 Generator 函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。

yield 表达式

由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

next方法

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为 JavaScript 提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。

用途:

ajax的异步处理,需要等待别的异步成功后再执行

function* main() {
	...
    var result = yield request("http://www.xxx.com?rows=10&f={firstName}");
    console.log(result);
    //do 别的ajax请求;
}

co 是什么

co是用来自动执行generator函数的工具。generator的好处是可以在定义函数时候就打上“断点”,调用函数时候可以在断点的地方暂停函数的执行。Generator带来的问题是如何控制什么时候进行下一步调用。co可以解决这个问题。

特点:

1、co 模块,它基于 ES6 的 generator 和 yield ,能用同步的形式编写异步代码的nodejs模块。

代码如下:

const co = require ('co');

function* main() {
    执行代码。。。
});

co(main);

co 模块可以将异步解改成同步。co 函数接受一个 generator 函数作为参数,在函数内部自动执行 yield 。

co实现generator自动执行的条件

需要yield后面的数据类型为:

  • promises
  • thunks (functions)
  • array (parallel execution)
  • objects (parallel execution)
  • generators (delegation)
  • generator functions (delegation)

最后两种类型是官方建议避免使用的。

使用:

安装:

$ npm install co

index.js

function* helloWorldGenerator() {
   var a = Promise.resolve(1);
   var b = Promise.resolve(2);
   var c = Promise.resolve(3);
   var res = yield [a, b, c];
   console.log(res);
}

co(helloWorldGenerator).catch(onerror);
// 执行: [1, 2, 3]

function onerror(err) {
   console.error(err);
}

你可能感兴趣的:(ES6)