Object.values/Object.entries
直接获取对象的值是一种非常常见的用例-例如,在将对象用作哈希过滤器时。许多库都有一个“值”函数:lodash 的mapValues
。
Object.values
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
const obj = { foo: "bar", baz: 42 };
Object.values(obj);
// ["bar", 42]
const obj = { 100: "a", 2: "b", 7: "c" };
Object.values(obj);
// ["b", "c", "a"]
复制代码
Object.entries
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
const obj = { foo: "bar", baz: 42 };
Object.entries(obj);
// [ ["foo", "bar"], ["baz", 42] ]
复制代码
Object.entries
的基本用途是
Object.entries
遍历对象的属性
let obj = { one: 1, two: 2 };
for (let [k, v] of Object.entries(obj)) {
console.log(`${JSON.stringify(k)}: ${JSON.stringify(v)}`);
}
// "one": 1
// "two": 2
复制代码
Object.entries
将对象转为真正的 Map 结构。
const obj = { foo: "bar", baz: 42 };
const map = new Map(Object.entries(obj));
map; // Map { foo: "bar", baz: 42 }
复制代码
String padding
ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()
用于头部补全,padEnd()
用于尾部补全。
第一个参数是需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
第二个参数是需要填充的字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 ” “(U+0020)。
"x".padStart(5, "ab"); // 'ababx'
"x".padStart(4, "ab"); // 'abax'
"x".padEnd(5, "ab"); // 'xabab'
"x".padEnd(4, "ab"); // 'xaba'
复制代码
padStart()的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串。
"1".padStart(10, "0"); // "0000000001"
"12".padStart(10, "0"); // "0000000012"
"123456".padStart(10, "0"); // "0000123456"
复制代码
另一个用途是提示字符串格式。
"12".padStart(10, "YYYY-MM-DD"); // "YYYY-MM-12"
"09-12".padStart(10, "YYYY-MM-DD"); // "YYYY-09-12"
复制代码
Object.getOwnPropertyDescriptors
ES2017 引入了 Object.getOwnPropertyDescriptors()
方法,返回指定对象所有自身属性(非继承属性)的描述对象。
value
— 属性实际的值writable
— 属性的值是否可以被修改get
— 获取函数,在读取属性时调用set
— 设置函数,在写入属性时调用configurable
— 属性是否可以通过 delete 删除并重新定义,是否可以修改它的特 性,以及是否可以把它改为访问器属性enumerable
— 属性是否可以通过 for-in 循环返回
该方法的引入目的,主要是为了解决 Object.assign()
无法正确拷贝 get
属性和 set
属性的问题。
const obj = {
getData: () => {
return "a";
},
get getData() {
return "b";
},
set setDate(n) {
return "c";
},
name: "name",
};
const a = Object.assign(obj);
// index.html:29 Uncaught TypeError: a.getData is not a function
console.log(a.getData());
// -----------------------------
const source = {
set foo(value) {
console.log(value);
},
};
const target1 = {};
Object.assign(target1, source);
Object.getOwnPropertyDescriptors(target1, "foo");
// { value: undefined,
// writable: true,
// enumerable: true,
// configurable: true }
复制代码
上面代码中,source 对象的 foo 属性的值是一个赋值函数,Object.assign 方法将这个属性拷贝给 target1 对象,结果该属性的值变成了 undefined。这是因为 Object.assign 方法总是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法。
Object.getOwnPropertyDescriptors()
方法的另一个用处,是配合 Object.create()
方法,将对象属性克隆到一个新对象。这属于浅拷贝。
const shallowClone = (object) =>
// 创建一个新对象
Object.create(
// 返回指定对象的原型
Object.getPrototypeOf(object),
// 返回指定对象所有自身属性
Object.getOwnPropertyDescriptors(object),
);
// 或者
const shallowMerge = (target, source) =>
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
复制代码
更多详细内容参考ES 入门教程-getOwnPropertyDescriptors
函数参数的尾逗号
ES2017 允许函数的最后一个参数有尾逗号(trailing comma)。
此前,函数定义和调用时,都不允许最后一个参数后面出现逗号。
function clownsEverywhere(param1, param2) {
/* ... */
}
clownsEverywhere("foo", "bar");
复制代码
更多详细内容参考ES 入门教程-函数参数的尾逗号
异步函数(Async functions)
ES2017 标准引入了 async
函数,使得异步操作变得更加方便。
async
函数是什么?一句话,它就是 Generator
函数的语法糖。
function fakeRequest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("请求成功");
}, 2000);
});
}
async function getData() {
console.log("start");
const res = await fakeRequest();
console.log(res);
console.log("end");
}
getData();
/*
1.start
2.请求成功
3.end
*/
复制代码
使用 Atomics 共享内存
Atomics
对象提供了一组静态方法对 SharedArrayBuffer
和 ArrayBuffer
对象进行原子操作。
更多详细内容参考MDN-Atomics
最后
文章浅陋,欢迎各位看官评论区留下的你的见解!
觉得有收获的同学欢迎点赞,关注一波!