我想做的是有一個介面,您可以在其中將元素包裝到具有擴展原型的實體中,例如。
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.
})
我可以像這樣擴展原始原型
HTMLElement.prototype.siblingIndex = function() {
if(this.parentNode == null) {
return -1
}
return Array.prototype.indexOf.call(this.parentNode.children, this)
}
但是擴展原型是不好的做法,也是不好的表現。
所以有可能做這樣的事情嗎?
uj5u.com熱心網友回復:
通過使用代理,我們可以添加一個新方法而無需更改原型:
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 不會回傳代理而是回傳原始物件,但是您可以只使用 proxyButton 而不是 e.target
如果需要,您還可以覆寫 addEventListener 方法以在呼叫回呼時回傳代理版本
uj5u.com熱心網友回復:
這似乎作業正常。非常感謝 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())
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/471695.html
標籤:javascript 哎呀 原型
