ES6语法
什么是ES6+
2015 年 6 月正式发布了ECMAScript 6.0语法正式发布了, 简称"ES6", 他是对原有javascript语法的扩充, 每年都有新的语法扩充进来, 在本文中,这里把后续新增的语法统称"ES6+"语法。
知识点思维导图
思维导图图片来自菜鸟教程,仅作知识分享之用,无其他用处。
这里我们主要学习ES6+中新增的语法:
- 声明与表达式(let与const、解构赋值、Symbol)
- 内置对象(新增Map与Set、Proxy与Reflect;扩展字符串、数值、对象、数组)
- 运算符与语句(函数扩展与箭头函数、迭代器的两种迭代循环、class类、模块的引包导包与复合)
- 异步编程(Promise对象、Generator函数、异步编程)
let
定义变量, 区别于"var", 他所声明的变量只在"let"所在的代码块内有效, 总之一句话: "var"就不要用了, 都替换成"let".
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
const
定义常量, 定义后的变量不可修改
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
数组解构赋值
let [a, b, c] = [1, 2, 3];
// 等价
let a = 1;
let b = 2;
let c = 3;
对象的解构赋值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
函数参数的解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
模板字符串
字符串中可以优雅的插入变量.
const a = '你好';
const b = `${a} Vue`;
// b == '你好vue'
函数参数默认值
function add(a,b=1){
return a+b;
}
add(3) // 4
箭头函数
function a(){
return '你好'
}
const a = function(){
return '你好';
}
// 箭头函数
const a = ()=>{
return '你好';
}
// 还可以更简单
const a = ()=>'你好'
箭头函数内部是没有自己的this
的, 其this
的值指向外层的作用域:
function A(){
this.w = 100
const b = ()=>{
console.log('b',this)
}
function c (){
console.log('c',this)
}
b();
c();
}
new A()
数组的扩展运算符
// 等价于 console.log(1,2,3);
console.log(...[1, 2, 3]);
// 合并数组
const a = [1,2,3];
const b = [...a,4,5]; // [1,2,3,4,5]
对象属性的简洁表示法
const a = 1;
const obj = {a: a};
// 简写
const obj = {a}; // {a: 1}
对象方法的简洁表示法
const obj = {
say:function (){
return '你好!';
}
};
// 简写,可以省略":function"
const obj = {
say (){
return '你好!';
}
};
对象属性名表达式
对象的属性名可以支持变量.
const a = 'abc';
let obj = {};
obj[`${a}123`] = 1;
console.log(obj) // {abc123:1};
链判断运算符(?)
实现对"?"左边的表达式是否为null或者undefined的判断, 如果是立即停止判断, 返回undefined或null.
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || “default”;
// 简写
const fristName = message?.body?.user?.firstName || “default”;
const foo = {
value: {
a: "12345"
}
}
const a = foo.value?foo.value.a:"6789"
// 简写
const a = foo.value?.a:"6789"
console.log(a)
// 结果12345
// 如果foo空对象即undefined,结果6789
// 如果foo.value为undefined,结果undefined
let test = {
say() {
console.info(“Hello,world!”)
}
}
// 判断对象是否有这样一个函数,如果有就执行,没有就返回undefined
test.say?.()
// 结果 Hello,world!
test.read?.()
// 结果 undefined
// 这里其实还有更复杂的形式和使用方式,熟悉理解之后能大大简化你的代码
Null判断运算符(??)
注意注意(🥸🥸🥸敲黑板~):运算符?? 有一个运算优先级问题,它与 && 和 || 的优先级孰高孰低。现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。
console.log(0 ?? 1); // 0
console.log(false ?? 1); // false
console.log(undefined ?? 1); // 1
console.log(null ?? 1); // 1
只有"??"左侧的值是null或undefined才返回"??"右侧的值.
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案"回调函数和事件"更合理.
在这里大概了解下即可, 主要是为了讲解后面的"async/await", 因为在开发中我们使用的第三方插件很多都是封装成Promise格式的, 初期需要自己封装的需求很少.
// 封装代码成Promise格式
const promiseA = ()=> new Promise(function(resolve, reject) {
// === 你的代码 ===
setTimeout(()=>{
if(0.5 < Math.random()){
resolve('成功');
} else {
reject('失败');
}
},200);
// === 你的代码 ===
});
// 执行
promiseA().then(value=>{
// '成功' == value
console.log(value);
}).catch(error=>{
// '失败' == error
console.log(error);
});
async/await
字面意思:async "异步"简写,理解为申明一个function是异步的;await可以认为是 async wait,理解为等待一个异步方法执行完成。
async函数(包括 语句和表达式),执行成功,通过Promise.resolve()封装,返回一个Promise对象,在最外层没有使用await获取返回值时,其返回值需要用 then()链 来处理这个Promise对象
没有await 运算符时,async函数会立即执行,返回Promise对象,并不会阻塞后面的语句
await 是在等待一个返回值(不仅仅是async函数完成后返回的Promise对象,还有任意表达式的结果)。敲黑板了~🫣 如果他等的不是Promise对象时,那么await表达式的运算结果就是他等到的东西,比如下面这个截图,await 函数等待了一个字符串格式的返回结果
如果await等到的是一个 Promise 对象,那就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果
执行Promise函数"更优雅". 用上面封装"promiseA函数"为例:
function funA(){
promiseA().then(value=>{
console.log(value);
}).catch(error=>{
console.log(error);
});
}
// 改写, 需要用try/catch来捕获"reject"触发的异常
async function funA(){
try{
const value = await promiseA();
console.log(value);
} catch(error){
console.log(error);
}
}
敲黑板了🧐 await只能出现在async函数中,可以这么去理解:await阻塞等待Promise对象resolve或者reject,因此必须写在异步函数里
export
导出模块
// xyz.js
export const a = 1;
export let x =123;
export function abc(){
}
export default {
b:'2',
c:3
};
import
导入模块
import {a,x,abc},dd from './xyz.js';
dd // {b:'2',c:3}
更多
(async () => {
console.log(await asyncFunction());
})();
(async function () {
console.log(await asyncFunction());
})();
const myFunction = async (a, b, c) => {
// Code here
}
//等同于
async function myFunction (a, b, c) => {
// Code here
}
在这里我只是给大家讲解了几个常用的语法, 更多请参考阮一峰老师的教程