How to bind methods when destructuring an object in JavaScript?

左心房为你撑大大i 提交于 2019-12-30 09:10:03

问题


How to bind methods when destructuring an object in JavaScript?

const person = {
  getName: function() {
    console.log(this);
  }
};

var a = person.getName;
var b = person.getName.bind(person);
var {getName: c} = person;

person.getName(); //=> {getName: [Function]}
a();              //=> window or global
b();              //=> {getName: [Function]}
c();              //=> window or global

I want c to log in the console its "parent" object {getName: [Function]}.

Is there any way to bind all methods when destructuring an object in one destructuring line?


回答1:


No, there is no way. Functions detached from objects lose the original context. And destructing in JavaScript has no syntax to do something with extracted values on the fly.




回答2:


You can use a getter or a proxy to bind a method whenever you get it, even using destructuring.

Both solutions, check if method is already bound, by looking for bound at the start of the name using String.startsWith(). If not bound, that method will be bound before returning it.

  1. Auto-bind the method to the object with a getter. This will require a getter for each method.

const person = {
  prop: 5,
  _getName: function() {
    console.log(this.prop);
  },
  
  get getName() {
    // if not bound, bind the method
    if(!this._getName.name.startsWith('bound ')) {
      this._getName = this._getName.bind(this);
    }
    
    return this._getName;
  }
};

var a = person.getName;
var b = person.getName.bind(person);
var {getName: c} = person;

person.getName(); //=> 5
a();              //=> 5
b();              //=> 5
c();              //=> 5
  1. Auto-bind the method to the object with a proxy. Define once for all methods.

var handler = {
  get: function(target, prop, receiver) {
    // if method, and not bound, bind the method
    if(typeof target[prop] === 'function' && !target[prop].name.startsWith('bound ')) {
      target[prop] = target[prop].bind(target);
    }
    
    return target[prop];
  }
};

const person = new Proxy({
  prop: 5,
  getName: function() {
    console.log(this.prop);
  }
}, handler);

var a = person.getName;
var b = person.getName.bind(person);
var {getName: c} = person;

person.getName(); //=> 5
a();              //=> 5
b();              //=> 5
c();              //=> 5



回答3:


There is a simple workaround using ES6 classes. You can use bind in the class constructor to manually set the context of the function.

In the example below, getName() will "survive" the destructuring :

class Person {
  constructor() {
    this.getName = this.getName.bind(this);
  }

  getName() {
    console.log(this);
  }
}

const {
  getName
} = new Person();

getName(); // Person { getName: [Function: bound getName] }



回答4:


Just use an arrow method:

const person = {
  getName = () => {
    console.log(this);
  }
};


来源:https://stackoverflow.com/questions/45910018/how-to-bind-methods-when-destructuring-an-object-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!