模拟环境
// 如何判断原型链上重复的属性 // 模拟一个原型链 Baz => Bar => Foo => FooProto => Object => null const FooProto = { ak: 1 } const Foo = Object.create(FooProto) Foo.ak = 2 Foo.aj = 4 const Bar = Object.create(Foo) Bar.ak = 3 Bar.aj = 5 Bar.am = 7 const Baz = Object.create(Bar)
解答
/** * @method collProtoAttrs * @description 收集对象原型链上重复的属性 * @param {Object} obj 目标对象 * @return {Array} [[${key}, ${count}],...] */ function collProtoAttrs (obj) { let lastProto = Object.getPrototypeOf(obj) const isRepeatAttrs = new Map() while (lastProto !== null) { Object.keys(lastProto).forEach(k => { if (isRepeatAttrs.has(k)) { isRepeatAttrs.set(k, isRepeatAttrs.get(k) + 1) } else { isRepeatAttrs.set(k, 1) } }) lastProto = Object.getPrototypeOf(lastProto) } // 列出所有属性名及出现的次数,过滤次数大于一的属性即为重复的属性。 // console.log(isRepeatAttrs) // {${key} => count} ... return [...isRepeatAttrs].filter(([, count]) => count > 1) // [[${key}, ${count}],...] } console.log(collProtoAttrs(Baz)) // [["ak",3],["aj",2]]
很久很久以前,在一次面试中,面试官问了我这样一个奇怪的问题,这个问题一直萦绕在脑袋里面,所以将他写下来。