是否有一种方法使'constructor'成为JS对象的有效键?

5

我目前正在制作一个使用马尔可夫链的聊天AI。后端中的一个对象是将字符串映射到它所属的任何链条的对象,例如:

var words = {}

words['test'] = [ ['this','is','a','test'], ['this','too','tests','things'] ]

现在,我有一个问题。'constructor'是一个完全有效的单词,但似乎你不能像我上面描述的那样将它映射,因为'constructor'是JS中每个对象的属性(当然还有其他东西)。那么我的问题是:有没有一种方法来构建这个映射?


你不能使用构造函数吗? - elclanrs
@elclanrs 我认为你没有理解问题的重点:我只需要一个地图;不需要对象功能。 - Seiyria
1个回答

11

constructor不是每个对象的属性。尽管默认情况下,使用文字语法创建的每个对象都将在其原型链中具有constructor。这是因为这些对象继承自Object.prototype,而Object.prototype确实具有该属性。

一种解决方案是使用没有原型链的对象。

var words = Object.create(null);

words['test'] = [ ['this','is','a','test'], ['this','too','tests','things'] ];

现在不会有继承的属性来混淆事情了。但在IE8及以下版本中无法正常工作。


另一种解决方案是使用.hasOwnProperty()来查看constructor属性是否存在于对象本身或继承的属性中。如果是继承的,则它不是您想要的属性。

if (words.hasOwnProperty("constructor"))
    console.log(words.constructor);

如果条件通过,则说明我们不使用继承的属性,而是对象自己的属性。


2
如果键hasOwnProperty被覆盖,.hasOwnProperty会出现问题。将对象用作哈希映射的推荐解决方案是使用has函数,例如function has(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key) } - zzzzBov
如果hasOwnProperty可以成为words的自有属性,覆盖原型中的属性,那将会有所帮助。但是,如果.hasOwnProperty()实际上被重写了,使用Object.prototype.hasOwnProperty也不会真正有所帮助。也许你指的是覆盖。 - cookie monster
嘿,谢谢!我以前不知道 Object.create(null),这个方法确实很有用。 - Seiyria
@cookiemonster,我不确定你的意思。Object.prototype.hasOwnProperty.call在不使用obj上的hasOwnProperty属性的情况下调用函数引用。这样就可以适用于例如obj = {hasOwnProperty: 'break everything'}的示例。 - zzzzBov
@zzzzBov:没错。你提到了覆盖,这意味着Object.prototype.hasOwnProperty本身已经被改变了。你的obj = {hasOwnProperty: 'break everything'}例子并没有真正地覆盖它,只是将其遮蔽了。在这种情况下,你是正确的。从原型中获取.hasOwnProperty才是正确的方法。 - cookie monster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接