javascript - 自定义元素原型(prototype)中的重写函数会更改 this 对象

标签 javascript html custom-element

我创建了一个自定义元素类,然后尝试在原型(prototype)级别包装其中一个函数,以便每个实例都使用该包装器。但是,当我这样做时, this 的值函数内部发生变化。如何更改原型(prototype)函数并访问实例 this在新函数内部?

在这个例子中,每次我登录 thisMyClass2我希望它打印 <my-class-2></my-class-2> ,就像我登录 this 时一样在MyClass它打印 <my-class></my-class> .

Here's a fiddle as well .

class MyClass extends HTMLElement {
    connectedCallback() {
        console.log('Inside MyClass:')
        console.log(this)
    }
}

customElements.define('my-class', MyClass)


class MyClass2 extends HTMLElement {
    connectedCallback() {
        console.log('Inside MyClass2:')
        console.log(this)
    }
}

let connectedCallback = MyClass.prototype.connectedCallback
MyClass2.prototype.connectedCallback = () => {
    console.log('Outside MyClass2')
    console.log(this)
    connectedCallback()
}

customElements.define('my-class-2', MyClass2)
<my-class></my-class>
<my-class-2></my-class-2>

控制台输出:

Inside MyClass:
<my-class>​</my-class>​
Outside MyClass2
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: global, …}
Inside MyClass:
undefined

最佳答案

首先,当您重新定义 connectedCallback() 方法时,您不得使用箭头函数,因为箭头函数调用不会设置 的值this 到对象的引用。

这通常是一个优势,但不是在这里。而是使用经典的 function () 表示法:

 MyClass2.prototype.connectedCallback = function() {
     console.log(this)
 }

其次,当您编写letconnectedCallback = MyClass.prototype.connectedCallback时,实际上您断开了引用的函数与对象的连接。

因此,this 不会引用调用它的对象,而是引用当前上下文,即 window

相反,您可以在调用方法之前使用 bind()this 设置为对象的值:

 MyClass2.prototype.connectedCallback = function() {
     connectedCallback.bind(this)()
 }    

或者,您可以将函数定义为当前对象的方法。

 MyClass2.prototype.connectedCallback_old = MyClass.prototype.connectedCallback
 MyClass2.prototype.connectedCallback = function() {
     this.connectedCallback_old()
 }    

class MyClass extends HTMLElement {
    connectedCallback() {
        console.log('Inside MyClass:')
        console.log(this)
    }
}

customElements.define('my-class', MyClass)


class MyClass2 extends HTMLElement {
    connectedCallback() {
        console.log('Inside MyClass2:')
        console.log(this)
    }
}

let connectedCallback = MyClass.prototype.connectedCallback
MyClass2.prototype.connectedCallback = function () {
    console.log('Outside MyClass2')
    console.log(this)
    connectedCallback.bind(this)()
}

customElements.define('my-class-2', MyClass2)
<my-class></my-class>
<my-class-2></my-class-2>

关于javascript - 自定义元素原型(prototype)中的重写函数会更改 this 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57317940/

相关文章:

javascript - Bootstrap : How to set a viewport to lg even if real screen is smaller ("Classic View")

polymer - 未捕获的 DOMException : Failed to execute 'define' on 'CustomElementRegistry' : this name has already been used with this registry

polymer - 最佳实践 : autonomous custom elements vs extending native HTML elements (customized built-in elements)

javascript - 为什么这个 d3 六边形绘图不正确?

javascript - 如何在 AngularJS 中显示和隐藏代码块

javascript - 无法使用 Javascript/Jquery 动态检查单选按钮

javascript - 如何在 Google Chrome 中使用自定义元素 v1 扩展 <form>?

javascript - Node 异步未运行异步

javascript - ionic 没有正确加载元素?

javascript - 在没有 iframe 的情况下等待页面加载然后显示它?