如何从一个没有原型的对象创建一个有默认原型的JS对象?
How to create a JS object with the default prototype from an object without a prototype?
背景: 例如,模块 query-string 能够将 key=value&hello=universe
解析为对象 {key: 'value', hello: 'universe'}
。但是,模块作者已决定返回的对象没有原型。也就是说,这个“混蛋”对象是由Object.create(null)
.
创建的
问题:使用parsed.hasOwnProperty('hello')
会很方便,但如果没有默认的对象原型是不可能的。当然,可以Object.prototype.hasOwnProperty.call(parsed, 'hello')
,但我想我们都同意这样的表达方式是 kill-immediately-after-birth 丑陋的。
问题:如何将无原型的对象漂亮的转换为具有默认的对象原型和方法,如hasOwnProperty
?此外,是否可以在不使用 the feared __proto__
或 setPrototypeOf
的情况下完成?
我不能说我以前做过这个,但这是一种方法
let bastard = Object.create(null);
bastard.father = 'vader';
let adopted = Object.assign({}, bastard);
console.log(adopted.hasOwnProperty('father')); // => true
setPrototypeOf()
没有什么可怕的,但是没有它你可能会这样做;
var o1 = Object.create(null),
o2;
o1.test = "42";
o2 = Object.assign({},o1);
console.log(o2.test);
console.log(o2.constructor.prototype);
It would be convenient to use parsed.hasOwnProperty('hello')
but that is not possible without the default object prototype
创建这样一个 "bastard object" 的全部意义在于你不能这样做 - 如果有人向你的服务器发送了一个查询字符串 ?hasOwnProperty=oops
怎么办?
How to nicely convert the prototypeless object to have a default object prototype and methods such as hasOwnProperty
?
不要。 您应该使用带 call
的长格式,或者直接使用 in
operator,它完全符合您的需要:
'hello' in parsed
在 ES6 环境中,您可能还想将对象转换为适当的 Map
并使用它 has
方法。
我不建议更改第三方包的原型,它可能会被冻结并容易出现运行时错误。我会按照@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
背景: 例如,模块 query-string 能够将 key=value&hello=universe
解析为对象 {key: 'value', hello: 'universe'}
。但是,模块作者已决定返回的对象没有原型。也就是说,这个“混蛋”对象是由Object.create(null)
.
问题:使用parsed.hasOwnProperty('hello')
会很方便,但如果没有默认的对象原型是不可能的。当然,可以Object.prototype.hasOwnProperty.call(parsed, 'hello')
,但我想我们都同意这样的表达方式是 kill-immediately-after-birth 丑陋的。
问题:如何将无原型的对象漂亮的转换为具有默认的对象原型和方法,如hasOwnProperty
?此外,是否可以在不使用 the feared __proto__
或 setPrototypeOf
的情况下完成?
我不能说我以前做过这个,但这是一种方法
let bastard = Object.create(null);
bastard.father = 'vader';
let adopted = Object.assign({}, bastard);
console.log(adopted.hasOwnProperty('father')); // => true
setPrototypeOf()
没有什么可怕的,但是没有它你可能会这样做;
var o1 = Object.create(null),
o2;
o1.test = "42";
o2 = Object.assign({},o1);
console.log(o2.test);
console.log(o2.constructor.prototype);
It would be convenient to use
parsed.hasOwnProperty('hello')
but that is not possible without the default object prototype
创建这样一个 "bastard object" 的全部意义在于你不能这样做 - 如果有人向你的服务器发送了一个查询字符串 ?hasOwnProperty=oops
怎么办?
How to nicely convert the prototypeless object to have a default object prototype and methods such as
hasOwnProperty
?
不要。 您应该使用带 call
的长格式,或者直接使用 in
operator,它完全符合您的需要:
'hello' in parsed
在 ES6 环境中,您可能还想将对象转换为适当的 Map
并使用它 has
方法。
我不建议更改第三方包的原型,它可能会被冻结并容易出现运行时错误。我会按照@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