Monkey patching constructors in builtin class hierarchies?

/#!/JoePea joe at trusktr.io
Tue Oct 24 17:19:19 UTC 2017


> This feels like a problem similar to https://esdiscuss.org/topic/block-scoped-prototype-extensions

@Boris, even if it were scoped, how do we monkey patch a
*constructor*? By the way, for some reason your link to
`https://esdiscuss.org/topic/block-scoped-prototype-extensions` posted
as `https://esdiscuss.org/topic/block` which is 404. If you can edit
it it would help others not to stumble on a broken link.

> if that would be possible, then everyone could just monkey patch Object, right?

But everyone can monkey patch the entire class already, aside from the
constructor, by modifying the prototype. Obviously if someone returns
something new from the constructor they might break everything, but it
will be completely obvious and people then won't do that. The same
applies with methods and properties, it is super easy to break entire
applications monkey patching methods.

---

So suppose I want to "polyfill" a concept. For example, I want all
elements to have a new "foo" accessor after they've been constructed.
Or for example, suppose `HTMLElement.prototype.style` and
`SVGElement.prototype.style` didn't exist yet. How would I patch those
in?
/#!/JoePea


On Tue, Oct 24, 2017 at 10:07 AM, Michał Wadas <michalwadas at gmail.com> wrote:
> AFAIR DOM classes are not extensible by any means.
>
>
>
> On 24 Oct 2017 6:51 pm, "/#!/JoePea" <joe at trusktr.io> wrote:
>>
>> Is it possible to monkey-patch an intermediate constructor of a built-in
>> subclass?
>>
>> For example, suppose I want all `Element` instances in a web app to have
>> new instance properties, is there a way to monkey-patch the Element
>> constructor so that when I make a custom element by extending a subclass of
>> `Element` that the new logic will fire?
>>
>> For example:
>>
>> ```js
>> // monkey-patch the Element constructor somehow so that it logs "patched
>> in Element".
>>
>> // then
>> class FooBar extends HTMLElement {}
>> customElement.define('foo-bar', FooBar)
>> new FooBar // "patched in Element"
>> ```
>>
>> I tried
>>
>> ```js
>> const OldElement = window.Element
>>
>> window.Element = function Element() {
>>   const _this = new OldElement
>>   console.log("patched in Element")
>>   return _this
>> }
>>
>> window.Element.prototype = OldElement.prototype
>> window.Element.prototype.constructor = window.Element
>>
>> class FooBar extends HTMLElement {}
>> customElements.define('f-b', FooBar)
>> new FooBar // does not log "patched in Element"
>> ```
>>
>> But when I make a new custom element, constructing it seems to use the old
>> Element constructor, as if a non-global reference to the original
>> constructor is kept inside a module so that modifying the global wouldn't
>> have any effect.
>>
>> Is there a way to monkey patch a constructor in the middle of a built-in
>> prototype chain or to otherwise inject construction logic to base classes of
>> existing class hierarchies?
>>
>>
>> /#!/JoePea
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>


More information about the es-discuss mailing list