can't read Element.prototype in firefox

2020-02-29 08:01发布

问题:

If I run this javascript:

var a,b=Element.prototype;
for(a in b)b[a];

Firefox gives me this error:

TypeError: Value does not implement interface Element.

Here is a test case: http://codepen.io/WilliamMalo/pen/AJkuE

It works in all other browsers. How can I make it work in firefox? It's driving me nuts!

回答1:

The Firefox (and recent IE) behavior here is because the property getters for some properties (say firstChild) are on the prototype object bu the properties make no sense on the prototype itself. Trying to get them on the prototype will throw.

This is the behavior required by the specification, in fact. See http://dev.w3.org/2006/webapi/WebIDL/#dfn-attribute-getter step 2 substep 2 subsubstep 2. Firefox and IE are following the spec here and WebKit-based browsers are not.



回答2:

Consider the following:

console.log('parentNode' in Element.prototype
   ? Element.prototype.parentNode
   : 'no parentNode here');

Pretty innocent, right? It gives you no parentNode string in Chrome (and probably in Safari too)... yet it fails both in Firefox (21) and IE (10):

  • Firefox: value does not implement interface Node
  • IE10: invalid calling object

Why is that? See, we've entered the Host Objects Zone, also known as The Zone Of No Rules. The point is that while some properties seem to be attached to Element.prototype, they're inaccessible from there - only from Element instances.

What can be done about it? An obvious way out is wrapping the offender in 'try-catch' block:

var a, b = Element.prototype, arr = [];
for (a in b) {
  try {
    b[a];
    arr.push(a); 
  } catch (e) {}
}


回答3:

You might want to try using Object.getOwnPropertyDescriptor() in your loop instead of accessing each property directly using the key on the prototype: http://codepen.io/seraphzz/pen/aJgcr