如何使用默认原型从没有原型的对象创建JS对象?

时间:2016-10-03 20:37:11

标签: javascript prototype prototypal-inheritance

后台:模块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

的情况下完成此操作

4 个答案:

答案 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);