简体   繁体   中英

JavaScript: Method That's Never Loses Binding

Consider this basic custom element:

class XElement extends HTMLElement {
  constructor() { super(); }
  foo() { console.log( this ); }
} customElements.define( 'x-element', XElement );

Here is the problem:

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

I see only one solution is to add foo as arrow function in constructor, but it seems to me wrong.

constructor() {
  super();
  this.foo = () => console.log( this );
}

Is there any right way to create method that will never lose its binding?

That is how JavaScript this binding works.

You can read this: THIS (YDKJS) Basically, the value of this inside a function depends upon how that function is invoked. So you need to explicitly hard bind the this value to your function foo by using the bind() method or defining foo as arrow function (arrow functions lexically bind their context).

So the solution is what you found.

You can do:

In your constructor:

class XElement extends HTMLElement {
  constructor() { 
   super(); 
   this.foo = this.foo.bind(this);   
  }
  foo() { console.log( this ); }
}

Or (I don't like this one)

class XElement extends HTMLElement {
  constructor() { 
   super(); 
   this.foo = () => console.log(this);   
  }
}

Or

class XElement extends HTMLElement {
  constructor() { super(); }
  foo = () => { console.log( this ); }
}

Here is another variant of defining unbindable method that could be used too:

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

  foo = (function() {
    console.log( this );
  }).bind( this )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM