后台:模块query-string例如能够将key=value&hello=universe
解析为对象{key: 'value', hello: 'universe'}
。但是,模块作者已决定返回的对象没有原型。换句话说,这个“混蛋”对象是由Object.create(null)
创建的。
问题:使用parsed.hasOwnProperty('hello')
会很方便,但如果没有默认对象原型,这是不可能的。当然,人们可以Object.prototype.hasOwnProperty.call(parsed, 'hello')
,但我认为我们都同意这样的表达是在出生后立即杀死丑陋。
问题:如何很好地将无原型对象转换为默认对象原型和hasOwnProperty
等方法?此外,是否可以在不使用the feared __proto__
或setPrototypeOf
?
答案 0 :(得分:4)
使用
,这是不可能的parsed.hasOwnProperty('hello')
会很方便,但如果没有默认对象原型
创造这样一个"混蛋对象"的重点。是你不能这样做 - 如果有人向你的服务器发送了一个查询字符串?hasOwnProperty=oops
怎么办?
如何很好地将无原型对象转换为默认对象原型和
hasOwnProperty
等方法?
不要。您应该将长格式与call
一起使用,或者只使用符合您需要的in
operator:
'hello' in parsed
在ES6环境中,您可能还希望将对象转换为正确的Map
并使用has
方法。
答案 1 :(得分:2)
我不建议更改第三方软件包的原型,它可能会被冻结并容易出现运行时错误。我要么使用@Bergi建议的内置in
运算符,要么使用ES6 Reflect API。
const _ = console.info
const parsed = (
{ __proto__: null
, foo: 'fu'
, bar: 'bra'
}
)
_('foo' in parsed) // true
_('fu' in parsed) // false
/** ES6 (fully supported in current browsers) */
_(Reflect.has(parsed, 'foo')) // true
_(Reflect.has(parsed, 'fu')) // false

答案 2 :(得分:0)
我不能说我以前做过这个,但这是一种方法
let bastard = Object.create(null);
bastard.father = 'vader';
let adopted = Object.assign({}, bastard);
console.log(adopted.hasOwnProperty('father')); // => true
答案 3 :(得分:0)
setPrototypeOf()
没有什么可担心的,但如果没有它,你可能会做如下的事情;
var o1 = Object.create(null),
o2;
o1.test = "42";
o2 = Object.assign({},o1);
console.log(o2.test);
console.log(o2.constructor.prototype);