ES6

let , const
  • constlet 的区别:1. 声明时必须赋值 2.只能赋值一次
  • let 存在暂时性死区:let会使变量作用域绑定在当前块内;那么这个变量在let之前是未定义的,但它又不能取父作用域的同名变量的值
    暂时性死区
for(let i=0;i<3;i++){
  //此时i的作用域就在括号内
  //但js会自动帮用户在花括号内创建一个同名临时变量i,使得i在打印时不会固定变为3
  button[i].onclick = ()=>{
    console.log(i)
  }
}
Symbol

当我不关心一个一个变量的值,只希望区分该变量与其他变量时
x = Symbol()

默认参数值
  • 当传给函数的参数值为undefined时,默认参数值会生效
  • function x(a,...b) {} 得到的b是一个数组
  • 伪数组转数组两种方法
let arr = Array.from(arguments)
let arr = [...arguments]
  • 简单的值交换
let [a,b] = [1,2];
[a,b] = [b,a]
console.log(a,b) //2,1

需要特别注意的是,在这种情况下,值交换的前一句结束分号一定不能省略,否则会出错

  • 双层解构赋值
var obj = {x:{b:1}}
var {x:{b}} = obj
console.log(b) //1
//先 x = obj.x 而后 b = x.b
  • Object.assign()是浅拷贝,或者说只能深拷贝一层
对象属性增强
  • let obj = {x,y}
  • 对象声明时键名可以用表达式
模块化
  • 依赖:用到了别的模块
  • 导出:给别的模块用
  • 在不同模块中多次导入同一个模块,该模块也只会被下载一次,但会执行多次
  • import 语句只能在声明了 type="module" 的 script 的标签中使用
import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";
  • export
export { name1, name2, …, nameN };
export default expression;
export * from …;//模块透传
class
  • 如何不用class实现继承
function Animal(){
  this.a = 1
}
Animal.prototype.move = function(){}
function Human(){
  Animal.apply(this,aruguments)
  this.b = 2
}
let f = function(){}
f.prototype = Animal.prototype
Human.prototype = new f()
Human.prototype.constructor = Human
转自知乎《JS的new到底是干什么的》——方应杭
  • 使用class实现继承
class Human extends Animal{
  constructor(){
    super()
  }
}
  • 类:拥有共同属性的对象
  • constructor用于构造自有属性
  • extends会使原型链再多一层
  • 在继承时,用到了this就要在使用前加super()
  • class不支持公有属性是非函数
  • get设置可读不可写的属性
class Human{  
  constructor(age){
    this._age = age
  }
  get age (){
    return this._age
  }
}
var human = new Human(19)
console.log(human.age) // 19
  • 用set对属性的写操作进行响应的限制
class Human{  
  constructor(name){
    this._name = name
  }
  set name (value){
    if(value>4){console.log('名字长度不能超过4个字')}
    else{this._name = value}
  }
}
var human = new Human('yyh')
human.name('哈哈哈哈哈哈哈') //名字长度不能超过4个字
  • static 用于声明构造函数的静态方法

promise

  • promise解决了多层的异步嵌套。增加了代码的可读性
  • 手写promise
function fn (){
  return new Promise((resolve,reject)=>{
    if(x){resolve()}
    else{reject()}
}
function rs1(){
  //...
  if(x){return Promise.resolve()//如果不写明返回值,默认返回resolve 
  }else{ return Promise.reject()}
}

}
function rj1(){
   if(x){return Promise.resolve()//如果不写明返回值,默认返回resolve 
  }else{ return Promise.reject()}
}
fn().then(rs1,rj1)
promise.catch()
  • 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。因为执行完它自己的catch方法后,该实例的状态也会变成resolved
  • 只要函数中有错误,就会进入reject() ,而reject()等同于抛出错误。Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
  • 比较下面两种写法
// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误。应该说如果想要捕获then方法执行中的错误,应该这么写

promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  }).then(function(data){},function(err){});

then的第二个参数,只能处理上一层函数的错误,而不能处理上上层的错误,所以第二种写法优于第一种写法

  • 跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。
Promise.prototype.finally()
  • finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
Promise.all()
  • 参数是由promise对象构成的数组
  • 返回值分两种,数组内promise对象的状态都为成功后,返回对象成功后的返回值构成的数组;数组内promise对象有一个失败,返回第一个失败的对象的返回值
promise.race()
  • const p = Promise.race([p1, p2, p3]);
  • 上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

async&await

  • async function 用于声明一个返回Promise对象的函数。该函数内部会有异步操作。async的优点在于处理 then 链,该声明使异步函数看起来像同步函数一样
  • async 函数中可能会有 awaitawait后面接一个Promise对象,这会使 async 函数暂停执行,等待 Promise 的结果出来,然后恢复async函数的执行并返回解析值(resolved)。
  • 正常情况下,await可以接一个 Promise 对象,返回该对象的结果。它会阻塞后面的代码,如果不是 Promise 对象,就直接返回对应的值。
  • 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
  • 这篇文章写的是真真好:https://segmentfault.com/a/1190000007535316
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 含义 async函数是Generator函数的语法糖,它使得异步操作变得更加方便。 写成async函数,就是下面这...
    oWSQo阅读 2,006评论 0 2
  • 本文为阮一峰大神的《ECMAScript 6 入门》的个人版提纯! babel babel负责将JS高级语法转义,...
    Devildi已被占用阅读 2,021评论 0 4
  • 前面的话 ES2017标准引入了async 函数,使得异步操作变得更加方便。本文将详细介绍async函数 概述 a...
    CodeMT阅读 1,364评论 0 3
  • Promiese 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,语法上说,Pr...
    雨飞飞雨阅读 3,375评论 0 19
  • 以下内容是我在学习和研究ES6时,对ES6的特性、重点和注意事项的提取、精练和总结,可以做为ES6特性的字典;在本...
    科研者阅读 3,152评论 2 9