ES6常用语法总结

ES6(ECMAScript 6)是 JavaScript 的下一代标准。当前版本的 ES6 是在2015年6月发布的,所以又称 ECMAScript 2015。也就是说,ES6 就是 ES2015。ES6 是 ECMAScript 标准十余年来变动最大的一个版本,新增了许多新的语法特性。虽然目前并不是所有浏览器都能兼容 ES6 全部特性,但越来越多的程序员在实际项目当中已经开始使用 ES6,同时这也是很多大厂前端岗面试的重点之一。

这篇博客详细介绍了 ES6 的部分常用语法,在后续的Vue学习笔记系列中会用到。

配套可执行代码示例 => GitHub

let 块级作用域

作用域即变量在什么范围内是可用的。ES5中的var是没有块级作用域的,包括if块和for块,这会引起一些问题:

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
  {
    var btns = document.getElementsByTagName('button')
    for(var i=0; i<btns.length; i++){
      btns[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮被点击了')
      })
    }
  }
</script>

这样的结果是,点击每个按钮,打印出的都是“第5个按钮被点击了”。

在ES5中,可以用闭包解决上述问题,因为函数是有作用域的,给函数传入的变量作为参数,在函数内不会受到变量在函数外改变的影响。所以在很多时候,我们都必须借助于函数作用域来解决应用外面变量的问题。

var btns = document.getElementsByTagName('button')
for(var i=0; i<btns.length; i++){
  (function (num) {
    btns[num].addEventListener('click', function () {
      console.log('第' + num + '个按钮被点击了')
    })
  })(i)
}

而ES6中的let是有块级作用域的。只要把for循环中的var i=0改为let i=0即可轻松解决上述问题。

var btns = document.getElementsByTagName('button')
for(let i=0; i<btns.length; i++){
  btns[i].addEventListener('click', function () {
    console.log('第' + i + '个按钮被点击了')
  })
}

const 常量

const修饰的标识符为常量:

  • 一旦赋值,不能修改
  • 声明时,必须赋值
  • 常量的含义是指向的对象(地址)不能修改,但是可以改变对象内部的属性
  • const是有块级作用域的

建议在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let

对象字面量的增强写法

属性的增强写法

const name = 'Perry'
const age = 22
//ES5
const obj = {
  name: name,
  age: age
}
//ES6
const obj = {
  name,
  age
}

函数的增强写法

//ES5
const obj = {
  run: function () {
    console.log('running')
  }
}
//ES6
const obj = {
  run(){
    console.log('running')
  }
}

箭头函数

箭头函数也是一种定义函数的方式,箭头左边为函数参数,右边为函数体。当把一个函数作为参数传到另一个函数中时经常使用箭头函数。

//常规写法
const add = (a,b) => {
  return a + b
}
//函数只有一个参数时可以省略小括号
const power = num => {
  return num * num
}
//函数体中只有一行代码时可以省略大括号和return
const mul = (a,b) => a * b

注:function定义的函数中的 this引用的是 window,箭头函数中的 this引用的是向外一层作用域的 this。

Promise 异步

Promise:异步编程的一种解决方案。当开发中有异步操作时,可以用Promise对异步操作进行封装。

异步的应用场景:网络请求。我们封装一个网络请求的函数,因为不能立即拿到结果返回,用户界面可能会阻塞,所以往往需要传入另一个函数,在数据请求成功后,执行这个回调函数,使用数据。

回调地狱:回调函数里又有回调函数,一层又一层。Promise可以以一种非常优雅的方式来解决这个问题。

Promise的基本使用

Promise是一个类,new创建Promise对象时需要传入一个函数作为参数,这个函数的参数也是两个函数:

  • resolve:异步操作成功的时候调用,可以通过参数把数据传入到then的处理函数中。
  • reject:异步操作失败的时候调用,可以通过参数把数据传入到catch的处理函数中。可选参数。
new Promise((resolve, reject) => {
  //异步操作代码,如网络请求
  setTimeout(() => {
    resolve('Hello')
    // reject('Error')
  }, 1000)
}).then(data => {
  //异步操作成功的处理代码
  console.log(data);
}).catch(err => {
  //异步操作失败的处理代码
  console.log(err);
})

另一种写法:不用catch,给then传入两个参数,分别是是异步操作成功和失败的处理函数。

new Promise((resolve, reject) => {
  ...
}).then(data => {
  console.log(data);
}, err => {
  console.log(err);
})

Promise的三种状态

  1. pending:等待状态。比如正在进行网络请求时,或者定时器没有到时间。
  2. fulfill:满足状态。当主动回调了resolve时,就处于该状态,并且会回调then。
  3. reject:拒绝状态。当主动回调了reject时,就处于该状态,并且会回调catch。

Promise的链式调用

异步操作(网络请求)的代码在Promise对象里,所有处理的代码都在上一个Promise对应的then里。

new Promise(resolve => {
  setTimeout(() => {
    console.log('网络请求...得到结果:aaa');
    resolve('aaa')
  }, 1000)
}).then(res => {
  console.log('第一层处理代码...得到结果:aaa111');
  return new Promise(resolve => {
    resolve(res + '111')
  })
}).then(res => {
  console.log('第二层处理代码...得到结果:aaa111222');
  return Promise.resolve(res + '222')
}).then(res => {
  console.log('第三层处理代码...');
  console.log(res);
}).catch(err => {
  console.log(err);
})

注:如果某一步主动回调了 reject,则后面所有的 then处理代码都不再执行,直接回调最后的 catch。

链式调用中 return new Promise() 的简写:

//原始写法
return new Promise(resolve => {
  resolve(res + '222')
})
return new Promise((resolve, reject) => {
  reject('error message')
})
//一次简写
return Promise.resolve(res + '222')
return Promise.reject('error message')
//二次简写
return res + '222'
throw 'error message'

Promise的all方法

有时候一个需求可能依赖两个网络请求,只有两个请求都完成,才能进行下一步。Promise可以使用all方法,实现同时处理多个异步操作,当所有操作都完成的时候,再在统一的地方拿到所有操作的结果。

Promise.all([
  new Promise((resolve, reject) => {
    console.log('网络请求一...得到结果:res111');
    resolve('res111')
  }),
  new Promise((resolve, reject) => {
    console.log('网络请求二...得到结果:res222');
    resolve('res222')
  })
]).then(results => {
  console.log(results[0]);	//res111
  console.log(results[1]);	//res222
})

数组遍历

遍历数组下标:

  • for (let i=0; i<this.arr.length; i++) { }
  • for (let i in this.arr) { }

遍历数组元素:

  • arr.forEach (function (val) { })
  • ES6语法:for (let val of this.arr) { }

其他语法

  • 面向对象:class声明类,extends继承类,super访问父类。
  • 解构:从对象或数组中提取值,对变量进行赋值。
  • 函数默认参数:声明函数时default设置默认参数,用于调用函数时没有传参的情况。
  • 模板字符串:``反引号,${}模板占位符。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值