开发者

Attempt to delete prototype of HTMLElement fails

I was trying to delete .insertBefore(); of HTMLElement.prototype but when I check for it, instead of an undefined value, it returns the actual function? Why?

console.log(HTMLElement.prototype.insertBefore); // function insertBefore() { [native code] }

delete HTMLElement.prototype.insertBefore;

console开发者_JAVA百科.log(HTMLElement.prototype.insertBefore); // function insertBefore() { [native code] }

Can you explain why this isn't working. I tried this on my own constructor and it worked, but for the built in ones, it didn't.


You cannot use DELETE like that:

http://perfectionkills.com/understanding-delete/

Property attributes

Every property can have zero or more attributes from the following set — ReadOnly, DontEnum, DontDelete and Internal. You can think of them as flags — an attribute can either exist on a property or not. For the purposes of today’s discussion, we are only interested in DontDelete.

Built-ins and DontDelete

So this is what it’s all about: a special attribute on a property that controls whether this property can be deleted or not. Note that some of the properties of built-in objects are specified to have DontDelete, and so can not be deleted. Special arguments variable (or, as we know now, a property of Activation object) has DontDelete. length property of any function instance has DontDelete as well.

Seriously man, read that article. It has a ludicrously clear and concise explanation of all this!


Note: even though they have the dontDelete attribute set, you can still overwrite it:

HTMLElement.prototype.insertBefore = '';
// or
HTMLElement.prototype.insertBefore = null;
// or
HTMLElement.prototype.insertBefore = undefined;


The browser implementation(s) probably have that property set as non-configurable.

There may be a greater chance that it is writable though:

HTMLElement.prototype.insertBefore = null;

console.log(HTMLElement.prototype.insertBefore); // null

Keep in mind that objects like HTMLElement are host objects, and therefore don't necessarily follow all the same rules of regular JavaScript objects.

For example, trying to delete a non-configurable property when in strict mode should throw an error, but testing this in Chrome, no error is thrown.

http://jsfiddle.net/YrvE4/2/


Seen here, you if you create your own custom property, you can delete that just fine:

"use strict";

HTMLElement.prototype.custom_property = 'value';  // new property

console.log(HTMLElement.prototype.custom_property);  // value

try {
    delete HTMLElement.prototype.custom_property;
} catch (e) {
    console.log(e);
}

console.log(HTMLElement.prototype.custom_property);  // undefined

http://jsfiddle.net/YrvE4/3/


HTMLElement.prototype, like all of DOM, is a "host object", which is basically something provided by the ECMAScript environment that isn't defined in the ECMAScript spec. Host objects have few rules they have to follow: it is perfectly allowable for [[Delete]] to do nothing, even if Object.getPropertyDescriptor has [[Configurable]]: false.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜