Monkey patching constructors in builtin class hierarchies?

Michał Wadas michalwadas at gmail.com
Tue Oct 24 17:30:16 UTC 2017


You can use getters mutating an object for this task.

But why do you need this?

On 24 Oct 2017 7:25 pm, "/#!/JoePea" <joe at trusktr.io> wrote:

> Well, I know I can set accessors on a prototype easily, but what I
> mean is, I need each instance of an `Element` to have exactly one
> instance of something right after construction during the same
> synchronous operation.
>
> For example, if we have an application with a bunch of pre-existing
> Elements that do not extend from any classes of mine, I'd like for the
> all to have `foo` properties, so that I can do this:
>
> ```js
> const el = new SomeCustomElementThatWasDefinedCreatedByMe
> console.log(el.foo) // it exists and is specific to the instance, not
> a prototype property
>
> // or
>
> const div = document.createElement('div')
> console.log(div.foo) // it exists and is specific to the instance, not
> a prototype property
> ```
>
> Can this be done?
> /#!/JoePea
>
>
> On Tue, Oct 24, 2017 at 10:19 AM, /#!/JoePea <joe at trusktr.io> wrote:
> >> 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
> >>>
> >>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171024/861a49db/attachment-0001.html>


More information about the es-discuss mailing list