#javascript #this #custom-element
#javascript #это #пользовательский элемент
Вопрос:
Рассмотрим этот базовый пользовательский элемент:
class XElement extends HTMLElement {
constructor() { super(); }
foo() { console.log( this ); }
} customElements.define( 'x-element', XElement );
Вот в чем проблема:
const xelem = new XElement();
/* `foo` will lose its binding to `xelem`:
*/ someButton.onclick = xelem.foo;
// These will work, but it's too verbose:
someButton.onclick = () => xelem.foo();
someButton.onclick = xelem.foo.bind( xelem );
Я вижу только одно решение — добавить foo
в качестве функции стрелки в конструктор, но это кажется мне неправильным.
constructor() {
super();
this.foo = () => console.log( this );
}
Есть ли какой-нибудь правильный способ создать метод, который никогда не потеряет свою привязку?
Ответ №1:
Вот как this
работает привязка JavaScript.
Вы можете прочитать это: THIS (YDKJS) В принципе, значение this
внутри функции зависит от того, как вызывается эта функция. Поэтому вам нужно явно жестко привязать this
значение к вашей функции foo
, используя метод bind() или определяя foo
как функцию со стрелкой (функции со стрелкой лексически связывают их контекст).
Итак, решение — это то, что вы нашли.
Вы можете сделать:
В вашем конструкторе:
class XElement extends HTMLElement {
constructor() {
super();
this.foo = this.foo.bind(this);
}
foo() { console.log( this ); }
}
Или (мне это не нравится)
class XElement extends HTMLElement {
constructor() {
super();
this.foo = () => console.log(this);
}
}
Или
class XElement extends HTMLElement {
constructor() { super(); }
foo = () => { console.log( this ); }
}
Комментарии:
1. Я никогда не думал, что смогу сделать
foo = 'whatever'
это прямо внутри тела класса.