变量的解构赋值
1. 数组的解构赋值
let [a, b, c] = [1, 2, 3];
如果解构不成功,变量的值就等于undefined
2. 解构赋值允许指定默认值
let [foo = true] = [];
foo // true
var {x = 3} = {};
x // 3
3. 对象的解构赋值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
foo // "aaa"
bar // "bbb"
let { log, sin, cos } = Math;
const { log } = console;
log('hello') // hello
4. 应用场景
1) 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
2) 从函数返回多个值
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
3) 函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
4) 函数参数的默认值
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
} = {}) {
// ... do stuff
};
避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句
5) 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
字符串的扩展
1. 模板字符串
2. 新增的实例方法
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
正则的扩展
略
数值的扩展
Number.isNaN()用来检查一个值是否为NaN
Number.isInteger()用来判断一个数值是否为整数
函数的扩展
1. 函数参数的默认值 // 竟然到 ES6 才提供这个功能……
2. rest 参数,用于获取函数的多余参数,这样就不需要使用arguments对象,rest 参数搭配的变量是一个数组
3. 箭头函数
1) 普通函数 this 可变,箭头函数 this 固定(箭头函数根本没有自己的this,导致内部的this就是外层代码块的this)
2) 不可以使用arguments对象,该对象在函数体内不存在。用 rest 参数代替
3) 尾调用,某个函数的最后一步是调用另一个函数
function f(x){
return g(x);
}
好处:调用帧只有一项,节省内存
4) 尾递归:尾调用自身
数组的扩展
1. Array.from()
将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map),这样就可以使用数组的方法
扩展运算符(...)也可以将某些数据结构转为数组
数组去重:[...new Set(arr)]
2. find() 和 findIndex()
[1, 4, -5, 10].find((n) => n < 0)
用于找出第一个符合条件的数组成员
果没有符合条件的成员,则返回undefined
3. 数组实例的 entries(),keys() 和 values()
这个比较鸡肋
4. includes(), flat(), flatMap()
对象的扩展
略
对象的新增方法
ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for...of循环使用。
let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
表单验证避免 if else 的写法
常见写法:
if(!this.form.xx) {
tools.alert(提示语1)
} else if (!this.form.yy) {
tools.alert(提示语2)
} else if (!this.form.zz) {
tools.alert(提示语3)
}
避免 if else 的写法:
obj = {
this.form.xx: '提示语1',
this.form.yy: '提示语2',
this.form.zz: '提示语3',
}
for (let [key, value] of Object.entries(obj)) {
if(!key) {tools.alert(value)}
}
Symbol, Set 和 Map, Proxy, Reflect, Promise, Iterator, Generator
略过
async 函数
async函数返回一个 Promise 对象,可以使用then方法添加回调函数
正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。
如果不是 Promise 对象,就直接返回对应的值
async function f() {
// 等同于
// return 123;
return await 123;
}
f().then(v => console.log(v))
// 123
前面已经说过,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中
多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发
let foo = await getFoo();
let bar = await getBar();
改写为:
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
网友评论