Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

265
Vistas
Javascript create custom attribute getter (like in python)

Say I have a class in JavaScript (yes bad bad class, bad class in JS, but its for web components, one has to use classes).

I would like to create a cached attribute getter for elements on a class, in python it would be this:

class Foo(object):
    _elements = {}
    def __getattr__(self, name):
        if name in ['widget1', 'widget2', 'widget3']:  # A long list of items, don't want to create getters for each one individiually
            if not _elements.get(name):
                self._elements[name] = self.getElementById(name)     
            return self._elements[name] 
       else:
            # Default behaviour
            return object.__getattr__(self, name)

This is the closest I got, but its ugly to use:

  • One must call it as this.el['widget1']
  • Instead of this.widget1
class Foo extends HTMLElement {
    el(id) {
        // Cached get element by id
        this._els = this._els || {};
        if (!this._els[id]) {
            this._els[id] = this.getElementById(id)
        }
        return this._els[id]
    }
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

getElementById is slower

But does your cached performance gain outway extra code, code complexity and time coding?

1 PICO second equals 0.00000001 Milliseconds

<div style="display:grid;grid-template-columns:1fr 1fr">
  <test-component id="CACHED"></test-component>
  <test-component id="BYID"></test-component>
</div>
<div id="DIFF"><b>100.000 calls per run:</b></div>
<script>
  customElements.define("test-component", class extends HTMLElement {
    el(id) {
      this._els = this._els || {};
      if (!this._els[id]) this._els[id] = document.getElementById(id);
      return this._els[id]
    }
    get CACHED() {
      return this.el("CACHED");
    }
    get BYID() {
      return document.getElementById("BYID");
    }
    connectedCallback() {
      let count = 100000;
      for (let run = 1; run < 9; run++) {
        let log = [];
        for (let cnt = 0; cnt < count; cnt++) {
          const t0 = performance.now();
          this == CACHED ? this.CACHED : this.BYID;// test performance
          log.push(performance.now() - t0);
        }
        this.average = (log.reduce((a, b) => a + b) / log.length)*1e9;
        let diff = (BYID.average - CACHED.average).toPrecision(2);
        if (this == BYID) DIFF.innerHTML += `<div>Run #${run} = <b>${diff/count}</b> PICO seconds slower per call<div>`;
      }
    }
  })
</script>

about 4 years ago · Juan Pablo Isaza Denunciar

0

For anyone else who has the same issue, this is what I went with, quite a lot of code upfront, but at least its easy to use, e.g. this.PROGRESS

class Foo extends HTMLElement {
    el(id, docEl=false) {
        // Cached get element by name
        // Parameter: docEl
        //  Set to true to search the document instead of the shadowRoot
        this._els = this._els || {};
        if (!this._els[id]) {
            const searchNode = docEl ? document : this.shadowRoot;
            this._els[id] = searchNode.getElementById(id)
        }
        return this._els[id]
    }

    // Document Elements
    get TEMPLATE()          { return this.el('TEMPLATE_wc-uploader', true) }
    get TEMPLATE_WC_UPLOAD(){ return this.el('TEMPLATE_wc-upload', true) }
    // Shadow Root Elements
    get PROGRESS()          { return this.el('PROGRESS') }
    get PROGRESS_HEADING()  { return this.el('PROGRESS_HEADING') }
    get DRAG_OVERLAY()      { return this.el('DRAG_OVERLAY') }
    get UPLOAD_LIST()       { return this.el('UPLOAD_LIST') }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda