Создать метод, который никогда не теряет привязки - PullRequest
1 голос
/ 22 апреля 2019

Рассмотрим этот основной пользовательский элемент:

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 );
}

Есть ли правильный способ создания метода, который никогда не потеряет свою привязку?

Ответы [ 2 ]

6 голосов
/ 22 апреля 2019

Так работает привязка 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 ); }
}
0 голосов
/ 22 апреля 2019

Вот еще один вариант определения несвязываемого метода, который также можно использовать:

class XElement extends HTMLElement {
  constructor() { super(); }

  foo = (function() {
    console.log( this );
  }).bind( this )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...