JavaScript: метод, который никогда не теряет привязку

#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' это прямо внутри тела класса.