一、拓展运算符(…)
这个符号最大的作用就是展开,展开数组和对象。
①argument转数组
以下第一个例子就是编写一个将数组重新排序的方法,通过…我们可以轻而易举地分解数组。
// 例子 12-1
// bad
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// good
const sortNumbers = (...numbers) => numbers.sort();
②调用参数
等同于削弱了apply的作用,减少一些不太便捷的方式,新增了一种更新更优的解决方案。
// 例子 12-2
// bad
Math.max.apply(null, [14, 3, 77])
// good
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
③3构建对象
通过这样的方式可以把一个已经存在的对象在声明新变量的时候展开,从而构建出一个全新的,符合我们需要的对象。
// 例子 12-3
let [a, b, ...arr] = [1, 2, 3, 4, 5];
const { a, b, ...others } = { a: 1, b: 2, c: 3, d: 4, e: 5 };
二、双冒号运算符
// 例子 13-1
foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。
// 例子 13-2
var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;
let log = ::console.log;
// 等同于
var log = console.log.bind(console);
三、解构赋值
①基础的解构
我前面的文章也有介绍到一些基础的结构方式。主要目的是把对象种的属性或者数组中元素取出来重新定义。
// bad
handleEvent = () => {
this.setState({
data: this.state.data.set("key", "value")
})
};
// good
handleEvent = () => {
this.setState(({data}) => ({
data: data.set("key", "value")
}))
};
②对象深度解构
深度解构,跟前面的一个例子是一样的,这里与函数的默认参数结合,实现了更好的默认对象参数的声明方式。
// 例子 14-4
// bad
function test(fruit) {
if (fruit && fruit.name) {
console.log (fruit.name);
} else {
console.log('unknown');
}
}
// good
function test({name} = {}) {
console.log (name || 'unknown');
}
多层解构,层层嵌套。
let obj = {
a: {
b: {
c: 1
}
}
};
const {a: {b: {c = ''} = ''} = ''} = obj;
③数组解构
优化代码,减少多次声明变量,提高代码的阅读性。
// 例子 14-6
// bad
const spliteLocale = locale.splite("-");
const language = spliteLocale[0];
const country = spliteLocale[1];
// good
const [language, country] = locale.splite('-');
④变量重命名
通过以下的方式可以让我们把已经存在的对象属性提取,并重新命名。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz); // "aaa"
⑤增强的对象字面量
有时候我们要把某个变量的传到对象中,总是声明重复含义的变量名,这样对代码阅读性会产生一定的影响,用以下这种方式即可避免。
// bad
const something = 'y'
const x = {
something: something
}
// good
const something = 'y'
const x = {
something
};
四、数组的扩展方法
①includes
判断数组中是否存在某个元素,比起foreach,forof等代码遍历的方式更加快速和简洁。
// bad
function test(fruit) {
if (fruit == 'apple' || fruit == 'strawberry') {
console.log('red');
}
}
// good
function test(fruit) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
if (redFruits.includes(fruit)) {
console.log('red');
}
}
②find
这个API可以根据数组对象中参数的值为条件,提取符合条件的对象元素。
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }