注意:我搜索过这个错误,但我发现的一切都是关于调用函数的。我没有打电话给任何功能。我只是想要访问一个房产。
执行这个简单代码时出现错误:
var a = document.getElementById("something");
var b = Object.create(a);
console.log(b.baseURI) //Throws error with any property of a
<p id="something">Hi! I exist just for demo purposes. This error can occur with any element.</p>
我不知道为什么会这样。如果我尝试从b
...
var a = document.getElementById("something");
var b = Object.create(a);
console.log( Object.getPrototypeOf(b.baseURI) ) //Works
...还使用普通对象。
var a = {foo: "Foo!"};
var b = Object.create(a);
console.log(b.foo) //Works
为什么会这样?对我来说完全是无稽之谈。 MDN说:
当试图访问对象的属性时,不仅会在对象上搜索该属性,而且还会在对象的原型,原型的原型等上搜索该属性,直到找到具有匹配名称的属性为止或者到达原型链的末尾。
b
的原型链(在第一个例子中)是:
HTMLParagraphElement --> HTMLParagraphElement (the actual element object) --> HTMLParagraphElement --> HTMLElement --> Element --> Node --> EventTarget --> Object --> null
(Proof)
编辑:请注意原型链中的1 st 对象是HTMLParagraphElement
。这是正常的,所以这不是问题。 (Image)
问题(我认为)是礼仪被复制到主b
对象而不仅仅是b
的原型。这意味着浏览器在第一个对象中找到匹配的名称并尝试访问它,但它会引发错误。 (Image;点击(...)
会导致错误)。
但是,我仍然不明白为什么会发生这种情况,也不知道为什么会抛出错误。
答案 0 :(得分:1)
此行为是由specification的实现引起的。这些DOM节点就是所谓的“平台对象”,它们实现getter的方式与“普通” javascript稍有不同。
简而言之:没有额外的工作就无法扩展它们。
var a = document.getElementById("something");
var b = Object.create(a);
访问baseURI
的{{1}}时,其b
指向this
,这不是有效的“平台对象”。这将导致b
错误。通过Illegal invocation
进行访问确实可行,因为然后它的prototype
指向有效的“平台对象” this
。
对Chrome问题的评论对此进行了更详细的说明,并且在您确实需要时提供了一种解决方法:https://bugs.chromium.org/p/chromium/issues/detail?id=495437#c7
答案 1 :(得分:0)
DOM对象在浏览器中非常特殊地实现。使用像Object.create()
这样的通用函数复制其中一个时,结果不会像原始函数一样链接到DOM中。许多属性需要访问DOM,因此当您尝试访问副本中的这些属性时会出现错误。