General reasons not to deal with Document's an

2019-02-09 04:36发布

问题:

Are there general reasons not to deal with Document's and Element's prototype?

I like to create my own little framework, because my current project doesn't need the mass of features of the existing frameworks.

I don't need to support browsers which don't support Element/Document-constructor and also will not execute scripts that are not under my control.

So would you recommend to extend the prototype or should I go the usual way and create own objects from Element/Document?

回答1:

Do you plan to extend default DOM elements? If so, please don't. Juriy Zaytsev (aka Kangax) clearly describes why not in What’s wrong with extending the DOM.



回答2:

Yes, unfortunately. It would be lovely to be able to add functionality by fiddling the DOM prototypes, but in practice it's just not reliable given today's technology.

Document, Element and others etc may be ‘host objects’ implemented by the browser with no ability to fiddle with their prototypes. Host objects may potentially have many other weird behaviours that a native JavaScript object wouldn't. DOM Nodes are host objects in IE6-7 and many older, niche and mobile browsers.

Even if they are implemented as native-JavaScript objects, there is no standard (yet) that described where the constructor-function for them is to be found, for you to go fishing about in the .prototype. Document, Element and so on are just W3 DOM interface names, they say nothing about what the implementation objects are to be found.

It happens that modern browsers (IE8 native mode and recent versions of Firefox, Opera and WebKit) do make constructor-functions available so you can start adding methods to Document or HTMLElement. But even then, there are differences between what objects are exposed, as not every browser provides the DOM interfaces with implementations under the same names. (The subinterfaces/implementations of NodeList are particularly troublesome.)

You can see how DOM prototyping has worked in practice by looking at the Prototype.js framework. When it works, it's super smooth. But because you can't prototype everywhere, you end up with some extremely ugly stuff where the framework has to deal with places prototyping won't work by copying methods into every instance of a Node. And then you've got the situation where your code might forget it needs to force this ‘augmentation’ and so it might work or not work depending on whether some other function happened to augment the same node before. This leads to really horrible browser-specific, interaction-order-specific, race-condition-prone debugging pain.

If you can limit your prototyping work to a few well-supported interfaces, and give up on all but the latest browsers, you can probably get away with it.