
ES8系列目录
- 1 async函数
- 2 Promise.prototype.finally()
- 3 Object.values(),Object.entries()
- 4 Object.getOwnPropertyDescriptors()
- 5 字符串填充 padStart和padEnd
- 6 函数参数列表与调用中的尾部逗号
- 7 共享内存与原子操作
所有整理的文章都收录到我《Cute-JavaScript》系列文章中,访问地址:http://js.pingan8787.com
3 Object.values(),Object.entries()
ES7中新增加的 Object.values()和 Object.entries()与之前的 Object.keys()类似,返回数组类型。
回顾下 Object.keys():
-
var a = { f1: 'hi', f2: 'leo'}; -
Object.keys(a); // ['f1', 'f2']
3.1 Object.values()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。
-
let a = { f1: 'hi', f2: 'leo'}; -
Object.values(a); // ['hi', 'leo']
如果参数不是对象,则返回空数组:
-
Object.values(10); // [] -
Object.values(true); // []
3.2 Object.entries()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。
-
let a = { f1: 'hi', f2: 'leo'}; -
Object.entries(a); // [['f1','hi'], ['f2', 'leo']]
- 用途1:
遍历对象属性。
-
let a = { f1: 'hi', f2: 'leo'}; -
for (let [k, v] of Object.entries(a)){ -
console.log( -
`${JSON.stringfy(k)}:${JSON.stringfy(v)}` -
) -
} -
// 'f1':'hi' -
// 'f2':'leo'
- 用途2: 将对象转为真正的Map结构。
-
let a = { f1: 'hi', f2: 'leo'}; -
let map = new Map(Object.entries(a));
手动实现 Object.entries()方法:
-
// Generator函数实现: -
function* entries(obj){ -
for (let k of Object.keys(obj)){ -
yield [k ,obj[k]]; -
} -
} -
// 非Generator函数实现: -
function entries (obj){ -
let arr = []; -
for(let k of Object.keys(obj)){ -
arr.push([k, obj[k]]); -
} -
return arr; -
}
4 Object.getOwnPropertyDescriptors()
之前有 Object.getOwnPropertyDescriptor方法会返回某个对象属性的描述对象,新增的 Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象
-
let a = { -
a1:1, -
get f1(){ return 100} -
} -
Object.getOwnPropetyDescriptors(a); -
/* -
{ -
a:{ configurable:true, enumerable:true, value:1, writeable:true} -
f1:{ configurable:true, enumerable:true, get:f, set:undefined} -
} -
*/
实现原理:
-
function getOwnPropertyDescriptors(obj) { -
const result = {}; -
for (let key of Reflect.ownKeys(obj)) { -
result[key] = Object.getOwnPropertyDescriptor(obj, key); -
} -
return result; -
}
引入这个方法,主要是为了解决 Object.assign()无法正确拷贝 get属性和 set属性的问题。
-
let a = { -
set f(v){ -
console.log(v) -
} -
} -
let b = {}; -
Object.assign(b, a); -
Object.a(b, 'f'); -
/* -
f = { -
configurable: true, -
enumable: true, -
value: undefined, -
writeable: true -
} -
*/
value为 undefined是因为 Object.assign方法不会拷贝其中的 get和 set方法,使用 getOwnPropertyDescriptors配合 Object.defineProperties方法来实现正确的拷贝:
-
let a = { -
set f(v){ -
console.log(v) -
} -
} -
let b = {}; -
Object.defineProperties(b, Object.getOwnPropertyDescriptors(a)); -
Object.getOwnPropertyDescriptor(b, 'f') -
/* -
configurable: true, -
enumable: true, -
get: undefined, -
set: function(){...} -
*/
Object.getOwnPropertyDescriptors方法的配合 Object.create方法,将对象属性克隆到一个新对象,实现浅拷贝。
-
const clone = Object.create(Object.getPrototypeOf(obj), -
Object.getOwnPropertyDescriptors(obj)); -
// 或者 -
const shallowClone = (obj) => Object.create( -
Object.getPrototypeOf(obj), -
Object.getOwnPropertyDescriptors(obj) -
);
5 字符串填充 padStart和padEnd
用来为字符串填充特定字符串,并且都有两个参数:字符串目标长度和填充字段,第二个参数可选,默认空格。
-
'es8'.padStart(2); // 'es8' -
'es8'.padStart(5); // ' es8' -
'es8'.padStart(6, 'woof'); // 'wooes8' -
'es8'.padStart(14, 'wow'); // 'wowwowwowwoes8' -
'es8'.padStart(7, '0'); // '0000es8' -
'es8'.padEnd(2); // 'es8' -
'es8'.padEnd(5); // 'es8 ' -
'es8'.padEnd(6, 'woof'); // 'es8woo' -
'es8'.padEnd(14, 'wow'); // 'es8wowwowwowwo' -
'es8'.padEnd(7, '6'); // 'es86666'
从上面结果来看,填充函数只有在字符长度小于目标长度时才有效,若字符长度已经等于或小于目标长度时,填充字符不会起作用,而且目标长度如果小于字符串本身长度时,字符串也不会做截断处理,只会原样输出。
6 函数参数列表与调用中的尾部逗号
该特性允许我们在定义或者调用函数时添加尾部逗号而不报错:
-
function es8(var1, var2, var3,) { -
// ... -
} -
es8(10, 20, 30,);
7 共享内存与原子操作
当内存被共享时,多个线程可以并发读、写内存中相同的数据。原子操作可以确保那些被读、写的值都是可预期的,即新的事务是在旧的事务结束之后启动的,旧的事务在结束之前并不会被中断。这部分主要介绍了 ES8 中新的构造函数 SharedArrayBuffer 以及拥有许多静态方法的命名空间对象 Atomic 。
Atomic 对象类似于 Math 对象,拥有许多静态方法,所以我们不能把它当做构造函数。 Atomic 对象有如下常用的静态方法:
- add /sub :为某个指定的value值在某个特定的位置增加或者减去某个值
- and / or /xor :进行位操作
- load :获取特定位置的值

