ES新特性合集
异步函数
使用 async
关键字声明的函数称为异步函数。
async
与 await
关键字可以使用更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。
举例:
const fetchUser = async (id) => {
try {
const user = await fetchData(id);
console.log('User:', user);
} catch (error) {
console.error('Error:', error);
}
};
fetchUser(123);
async 语法
特征是在 function 名字前加 async
关键字。
1、Async 函数返回一个 Promise 对象,可以使用 then
方法添加回调函数。
async function helloAsync() {
return 'Hello, async!';
}
console.log(helloAsync()); // Promise { <state>: "pending" }
helloAsync().then(result => {
console.log(result)
});
// Hello, async!
2、async 函数执行时遇到 await
关键字就先暂停执行,等到触发的异步操作完成,再恢复 async 函数的执行并返回解析值。
await
关键字仅在 async 函数中有效。
function testAwait() {
return new Promise(resolve => {
setTimeout(() => {
console.log('testAwait');
resolve();
}, 1000);
});
}
async function helloAsync() {
await testAwait();
console.log('helloAsync');
}
helloAsync();
// testAwait
// helloAsync
computed property name
对象的键名可以使用变量定义,在创建对象时使用 bracket notation 方括号圈起来,如 {[phoneType]: 12345}
Spread syntax (…) 扩展
对象字面量扩展属性,相当于 Object.assign() 的简写。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
const obj1 = { foo: 'bar', x: 42 };
const obj2 = { foo: 'baz', y: 13 };
const mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
剔除空值
对象字面量扩展简单应用:利用 Object.assign()
自动剔除源对象中值为 null、undefined 的属性这一特性,实现表单提交时过滤空值
数组字面量使用已存在的数组作为新创建数组的一部分或全部(即复制)。注意:多维数组扩展时,数组项是子数组的 reference(参 Object.assign),那么新数组项改变也将影响源数组项。
const parts = ['shoulders', 'knees'];
const lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]
迭代器 iterator
早期使用 for 循环方式遍历数据。迭代器为各种数据结构提供统一的访问接口。
生成器 generator
列表中所有元素都存在内存中,当数据量过大时,非常耗内存。如果列表元素可以按照某种算法推算出来,就可以在循环中不断推算出后续元素。从而避免创建完整的列表,节省内存。
Proxy
Proxy 和 Reflect 是ES6为操作对象引入的API。Proxy 可以对目标对象的读取、函数调用等操作进行拦截,并根据自己的逻辑进行处理。
Proxy 不直接操作对象,而是通过对象的代理对象进行操作。Reflect 挂载了很多静态方法(类似 Math.round()
直接使用,而无需 new 操作)
Proxy 对象由两部分组成:
- target:目标对象。
- handler:一个对象,其属性是一组函数,声明了对target的指定行为。
举例:
let person = { name: 'Jack', age: 20 };
let handler = {
get: function(target, key) {
console.log(`Getting ${key}`);
return target[key];
},
set: function(target, key, value) {
console.log(`Setting ${key} = ${value}`);
target[key] = value;
}
};
let proxy = new Proxy(person, handler);
proxy.name;
// Getting name
// "Jack"
proxy.age = 21;
// Setting age = 21
// 21
handler 对象方法
除了上面提到的 get
和 set
方法,还有 apply
、has
等。
其中 apply(target, cxt, args)
方法用于拦截函数的调用,并返回函数执行结果。
function sub(a, b) {
return a - b;
}
let handler = {
apply: function(target, cxt, args) {
console.log('handler.apply called');
return Reflect.apply(...arguments); // 等同于 Function.prototype.apply.call(target, cxt, args)
}
};
let proxy = new Proxy(sub, handler);
proxy(10, 3);
// handler.apply called
// 7
has(target, key)
方法用于拦截 in
操作符,判断target对象是否存在属性key。此方法不能判断属性是对象自身的,还是继承的。
let handler = {
has: function(target, key) {
console.log('handler.has called');
return key in target;
}
};
let exam = { name: 'John' };
let proxy = new Proxy(exam, handler);
'name' in proxy;
// handler.has called
// true