Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

140
Views
Have the niceties of extended prototype without actually extending the prototype

What I'm trying to do is have an interface where you can wrap an element into an instance which has an extended prototype, so something like.

const wrappedButton = new WrappedElem(document.getElementById('some-button'))
// we have access to our custom added method:
console.log(`I am the ${wrappedButton.siblingIndex()}th button`)

// but we still have access to the original methods
wrappedButton.addEventListener('click', function(e){
  console.log('I clicked on', e.target)
  // right here we won't have access to siblingIndex, because the prototype of the element itself was not changed.
})

I can extend the original prototype like this

HTMLElement.prototype.siblingIndex = function() {
    if(this.parentNode == null) {
        return -1
    }
    
    return Array.prototype.indexOf.call(this.parentNode.children, this)
}

But extending the prototype is bad practice, and bad performance.

So it possible to do something like this?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

By using a Proxy we can add a new method without protoype changes :

const siblingIndex = () => {}

const handler = {
    get(target, property) {
        
        if(property === 'siblingIndex') {
            return siblingIndex;
        }

        return target[property];
    }
}

const proxyButton = new Proxy(button, handler);

// we can also call the siblingIndex function
proxyButton.siblingIndex();
// we can access the properties of the underlying object
proxyButton.tagName;

e.target however will not return the proxy but the original object, but you can just use proxyButton instead of e.target

if you want you can also override the addEventListener method to return the proxied version instead when the callback is called

about 4 years ago · Juan Pablo Isaza Report

0

This is what seems to work alright. Big thanks to Lk77.

var wrappedElMethods = {
    siblingIndex() {
        if(this.parentNode == null) {
            return -1
        }
        
        return Array.prototype.indexOf.call(this.parentNode.children, this)
    }
}

function wrappedEl(el) {
    return proxyInherit(el, wrappedElMethods)
}

function proxyInherit(item, overwrites) {
    const handler = {
        get(target, property) {
            
            let value
            const overwriteVal = overwrites[property]
            
            if(overwriteVal != undefined) {
                value = overwriteVal
            } else {
                value = target[property]
            }
            
            if(value instanceof Function) {
                return value.bind(item)
            }
            
            return value
        },
        set(target, property, value) {
            target[property] = value
        }
    }
    
    return new Proxy(item, handler)
}


// Usage:
var button = wrappedEl(e.target)
button.onclick = function() {
  console.log(button.siblingIndex())
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!