ES6、7、8学习笔记

ES6新特性
  • 模块化
    ES6中模块作为重要的组成部分被添加进来。模块的功能主要由export 和 import 组成,每个模块都有自己单独的作用域,模块之间的相互调用关系是通过export来规定模块对外暴露的接口,通过import 来引用其他模块提供的接口。同时还为模块提供命名空间,防止函数的命名冲突。
    1、导出(export)
    ES6允许在一个模块中使用export来导出多个变量或函数
  • 箭头函数
  • 函数参数默认值
  • 模板字符串
  • 结构赋值
    结构赋值语法是JS中的一种表达式,可以方便的从数组或者对象中快速提取值 赋给定义的变量。
    1、获取数组中的值
var foo = ["one","two","three","four"];

var [one,two,three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

// 如果你要忽略某些值,可以按照下面写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

// 也可以这样写
var a, b; // 先声明变量

[a,b] = [1,2]
console.log(a); // 1
console.log(b); // 2
// 如果没有从数组中获取到值,你可以为变量设置一个默认值
var a,b
[a=5,b=7] = [1]
console.log(a) // 1
console.log(b) // 7
通过结构赋值可以方便的交换两个变量的值
var a = 1;
var b = 3;
[a,b] = [b,a]
console.log(a) // 3
console.log(b) // 1
  • 延展操作符
    延展操作符 ... 可以在函数调用时或数组构造时,将数组表达式或者string在语法层面展开;还可以在构造对象时,将对象表达式按key-value的方式展开。
    语法:
    函数调用时:
myFunction(...obj)

数组构造或字符串

[...obj,'4',...'hello',6];

构造对象时,进行克隆或者属性拷贝

let obj = {...objs}
实例:
function fun(a,b,c){
  return a+b+c;
}
const numbers = [1,2,3];

// 不使用延展操作符
console.log(fun.apply(null,numbers));

// 使用延展操作符
console.log(fun(...numbers)) // 6



// 构造数组
/* 
  没有展开语法的时候,只能组合使用push,splice,concat等方法,来将
  已有数组元素变成新数组的一部分。有了展开语法,构造新数组会变得更简单,优雅;
*/
const students = ["Jine","Tom"];
const persons = ["Tony",...students,"Aarm","Anna"];
console.log(persons) // ["Tony","Jine","Tom","Aarm","Anna"];
// ...在构造数组时,可以在任意位置多次使用


// 数组拷贝
var arr = [1,2,3];
var arr2 = [...arr];
arr2.push(4);
console.log(arr2) // [1,2,3,4];
// 展开语法和 Object.assign()行为一致,执行的都是浅拷贝(只遍历一层)


// 连接多个数组
var arr1 = [0,1,2];
var arr2 = [3,4,5];
var arr3 = [...arr1,...arr2];
// 等同于
var arr4 = arr1.concat(arr2);


/* 
  在React中的应用
    通常我们在封装一个组件时,会对外公开一些props用于实现功能。
    大部分情况下在外部使用都应显示的传递props。但是当传递大量的props,会非常繁琐,
    这时我们可以使用...(延展操作符,用于取出参数对象的所有可遍历属性)来进行传递。
*/
// 一般情况下我们应该这样写
<CustomComponent name="Jine" age={21}/>

// 使用 ... 等同于上面的写法
const params = {
  name : "jine",
  age : 21
};
<CustomComponent {...params} />


// 配合结构赋值避免传入一些不需要的参数
var params = {
  name: "123",
  title: "456",
  type: "aaa",
}
var { type,...other } = params;
<CustomComponent type='normal' number={2} {...other} />
// 等同于
<CustomComponent type='normal' number={2} name='123' title='456' />
  • 对象属性简写
// 对象属性简写
// 在ES6中允许我们在设置一个对象的属性的时候不指定属性名

// 不使用ES6
const name="Ming",age="18",city="Shanghai";
const student = {
  name: name,
  age: age,
  city: city
};
console.log(student); // {name: "Ming",age: "18",city: "Shanghai"}

// 使用ES6
const name="Ming",age="18",city="Shanghai";
const student = {
  name,
  age,
  city
};
console.log(student); // {name: "Ming",age: "18",city: "Shanghai"}
  • Promise
/* 
  promise 是异步编程的一种解决方案,比传统的解决方案callback更加优雅。
  它最早由社区提出和实现的,ES6将其写进了语言标准,统一了用法,原生提供了promise对象
*/

// 不使用ES6
setTimeout(function(){
  console.log("hello"); // 1秒后输出'hello'
  setInterval(function(){
    console.log("hi") // 2秒后输出'hi'
  },1000)
},1000)

// 使用ES6
var waitSecond = new Promise(function(resolve,reject){
  setTimeout(resolve,1000)
});
waitSecond.then(function(){
  console.log('hello'); // 1秒输出'hello'
  return waitSecond;
}).then(function(){
  console.log('hi'); // 2秒输出'hi'
})
// 上面的代码使用两个then来进行异步编程串行化,避免回调地狱
  • let与const
/* 
  在之前JS是没有块级作用域的,const与let填补了这方面的空白,
  const与let都是块级作用域。
*/
// 使用var定义的变量为函数级作用域:
{
  var a = 10;
}
console.log(a); // 10

// 使用let与const定义的变量为块级作用域:
{
  let a = 10;
}
console.log(a) // -1 or Error"ReferenceError: a is not defind"
ES7新特性

在ES6之后,ES的发布频率更加频繁,基本每年一次,所以自ES6之后,每一个版本的新特性的数量就比较少。

  • includes()
/* 
  1.Array.prototype.includes()
    includes() 函数用来判断一个数组是否包含一个指定的值,如果包含则返回true,否则返回false。
*/
// includes 函数 indexOf 函数很相似,下面两个表达式是等价的
arr.includes(x)
arr.indexOf(x) >= 0

// 我们来判断数字中是否包含某个元素:
// 在ES7之前的做法
// 使用indexOf()验证数组中是否存在某个元素,这时需要根据返回值是否为-1来判断:
let arr = ['react','angular','vue'];
if (arr.indexOf('react') !== -1){
  console.log("react存在")
}

// 使用ES7的includes()
let arr = ['react','angular','vue'];
if (arr.includes('react')){
  console.log("react存在")
}

  • 指数操作符
/* 
  2.指数操作符
    在ES7中引入指数运算符**,**具有与Math.pow(...)等效的计算结果
*/
// 不使用指数操作符
// 使用自定义的递归函数calculateExponent或者Math.pow()进行指数运算:
function calculateExponent(base,exponent){
  if (exponent === 1){
    return base;
  }else{
    return base * calculateExponent(base,exponent - 1);
  }
}

console.log(calculateExponent(2,10)) // 1024
console.log(Math.pow(2,10)) // 1024

// 使用指数运算符**,就像+、-等操作符一样
console.log(2**10) // 
ES8新特性
  • async / await
// async和await
/* 
  在ES8中加入了对async和await的支持,也就是我们所说的异步函数,
    async和await将我们从头痛的回调地狱中解脱出来,使整个代码看起来很简洁
*/

// 使用async和await 与 不使用async和await的差别

login(userName) {
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve('1001')
    },600)
  })
}

getDate(userId){
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      if (userId === '1001'){
        resolve('Success');
      } else {
        reject('Fail');
      }
    },600);
  });
}

// 不使用async和await ES7
doLogin(userName) {
  this.login(userName)
  .then(this.getDate)
  .then(result => {
    console.log(result)
  })
}

// 使用async和await ES8
async doLogin2(userName){
  const userId=await this.login(userName);
  const result=await this.getData(userId);
}
this.doLogin() // Success
this.doLogin2() // Success
// async和await的几种应用场景
// 1、获取异步函数的返回值
// 异步函数本身会返回一个promise,所以我们可以通过then来获取异步函数的返回值
async function charCountAdd(data1,data2){
  const d1 = await charCount(data1);
  const d2 = await charCount(data2);
}
charCountAdd('hello','hi').then(console.log); // 通过then获取异步函数的返回值
function charCount(){
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve(data.length);
    },1000)
  });
}
// async和await在并发场景中应用
/* 
  对于上述例子,我们调用await两次,每次都是等待1秒一共2秒,效率比较低,
  而且两次await的调用并没有依赖关系,那么可以让它并发执行;通过
  Promise.all来实现await的并发调用
*/
async function charCountAdd(data1,data2){
  const [d1,d2]=await Promise.all([charCount(data1),charCount(data2)]);
  return d1+d2;
}
charCountAdd('hello','hi').then(console.log); // 通过then获取异步函数的返回值
function charCount(){
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve(data.length);
    },1000)
  });
}

// 2、async和await的几种错误处理方式
// -1.捕捉整个async/await函数的错误
async function charCountAdd(data1,data2){
  const d1 = await charCount(data1);
  const d2 = await charCount(data2);
}
charCountAdd('hello','hi')
            .then(console.log)
            .catch(console.log); // 捕捉整个async/await函数的错误
/* 
  这种方式可以捕捉整个charCountAdd运行过程中出现的错误,错误可能是由charCountAdd本身产生的,
  也可能是由对data1的计算中或data2的计算中产生的。
*/

// -2.捕捉单个的await表达式的错误
async function charCountAdd(data1,data2){
  const d1 = await charCount(data1)
      .catch(e => console.log('d1 is null'));
  const d2 = await charCount(data2)
      .catch(e => console.log('d2 is null'));
  return d1+d2;
}
charCountAdd('hello','hi').then(console.log);
/* 
  通过这种方式可以捕捉每一个await表达式的错误,如果既要捕捉每一个await表达式的错误,
  又要捕捉整个charCountAdd函数的错误,可以在调用charCountAdd的时候加个catch。
*/
charCountAdd('hello','hi')
            .then(console.log)
            .catch(console.log); // 捕捉整个async/await函数的错误

// 3.同时捕捉多个的await表达式的错误
async function charCountAdd(data1,data2){
  let d1,d2;

  try {
    d1 = await charCount(data1);
    d2 = await charCount(data2);
  }catch (e){
    console.log('d1 is null')
  }

  return d1+d2;
}
charCountAdd('hello','hi').then(console.log); // 通过then获取异步函数的返回值
function charCount(){
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve(data.length);
    },1000)
  });
}

  • Object.values()
/* 
  Object.values() 是一个与Object.keys()类似的新函数,但返回的是Object自身属性的所有
  值,不包括继承的值。
*/
// 假设我们要遍历如下对象obj的所有值
const obj = {a: 1,b: 2,c: 3};

// 不使用Object.values()  ES7
const vals = Object.keys(obj).map(key => obj[key]);
console.log(vals); // [1,2,3]

// 使用Object.values() ES8
const values = Object.values(obj);
console.log(values); // [1,2,3]

  • Object.entries()
// Object.entries()函数返回一个给定对象自身克枚举属性的键值对的数组
const obj = {a: 1,b: 2,c: 3};

// 不使用Object.entries()  ES7
Object.keys(obj).forEach(key => {
  console.log('key:'+key+'value:'+obj[key]);
})
// key:a value:1
// key:b value:2
// key:c value:3

// 使用Object.entries()  ES8
for(let [key,value] of Object.entries(obj)){
  console.log(`key: ${key} values: ${value}`)
}
// key:a value:1
// key:b value:2
// key:c value:3
  • String padding
  • 函数参数列表结尾允许逗号
  • Object.getOwnPropertyDescriptors()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值