为何Object.create会干扰Object.keys/values/entries的返回值?
为什么用Object.create实例化对象时,Object.keys/values/entries返回不符合预期?
这问题问到点子上了!本质是对象属性的存储位置和这些方法的遍历规则在搞鬼,咱们一步步拆解清楚:
先看工厂函数的情况
你写的工厂函数testFunction返回的是一个普通对象,firstKey和secondKey都是直接挂在这个对象自身上的(业内叫“自有属性”)。而Object.keys()、Object.values()、Object.entries()这三个方法,默认只遍历对象的自有可枚举属性——简单说就是只认对象自己身上带的属性,所以自然能返回你预期的结果:
// 工厂函数返回的对象,属性是自有属性 let testObject = testFunction('ONE', 'TWO'); console.log(Object.keys(testObject)); // ['firstKey', 'secondKey']
再看Object.create的问题
你用Object.create创建对象时,大概率是把属性放在了原型对象里,比如类似这样的代码:
"use strict" const proto = { firstKey: 'ONE', secondKey: 'TWO' }; let testObject = Object.create(proto); // 创建的空对象,原型指向proto
这里的testObject本身是个空对象!firstKey和secondKey其实存在于它的原型链上,不是这个对象自己的属性。
而Object.keys/values/entries有个关键规则:它们只处理对象自身的可枚举属性,完全不会去遍历原型链上的属性。所以你调用这些方法时,自然拿不到原型上的那些键值对,返回空数组或者不符合预期的结果。
那怎么拿到原型链上的属性?
如果需要包含原型链的属性,有几种办法:
- 用
for...in循环:它会遍历对象自有+原型链上的所有可枚举属性for (const key in testObject) { console.log(key, testObject[key]); // 会输出firstKey ONE、secondKey TWO } - 手动获取原型对象的属性:通过
Object.getPrototypeOf()拿到原型,再用Object.keys遍历const protoKeys = Object.keys(Object.getPrototypeOf(testObject)); console.log(protoKeys); // ['firstKey', 'secondKey']
说白了,核心区别就是:工厂函数给你的对象,属性是“自带的”;Object.create如果把属性放原型里,那属性是“借过来的”,而Object.keys这类方法只认“自带的”属性~
内容的提问来源于stack exchange,提问作者DR01D
相关产品推荐
相关产品推荐

