在 JavaScript 中解构对象时如何绑定方法?
How to bind methods when destructuring an object in JavaScript?
在 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
我希望 c
登录其 "parent" 对象 {getName:
[Function]}
的控制台。
在一个 destructuring 行中解构对象时,有没有办法绑定所有方法?
不行,没办法。从对象中分离出来的函数失去了原来的上下文。在 JavaScript 中进行破坏没有语法来动态处理提取的值。
您可以使用 getter 或代理来绑定一个方法,只要您 get
它,甚至使用解构。
两种解决方案都通过使用 String.startsWith()
在名称的开头查找 bound
来检查方法是否已经绑定。如果未绑定,该方法将在返回之前被绑定。
- 使用 getter 将方法自动绑定到对象。每种方法都需要 getter。
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
- 使用 proxy 将方法自动绑定到对象。为所有方法定义一次。
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
有一个使用 ES6 classes 的简单解决方法。您可以在 class 构造函数中使用 bind
来手动设置函数的上下文。
在下面的示例中,getName()
将 "survive" 解构 :
class Person {
constructor() {
this.getName = this.getName.bind(this);
}
getName() {
console.log(this);
}
}
const {
getName
} = new Person();
getName(); // Person { getName: [Function: bound getName] }
只需使用箭头方法:
const person = {
getName: () => console.log(this),
};
是的。假设我正确理解你的问题,我们可以用一行代码来完成。
这当然不是最易读的方法,但它是我在个人项目中经常使用的方法:
const person = {
getName: function() {
console.log(this);
}
};
// IIFE for destructuring and applying changes inline
const { a, b, c } = (({ getName }) => ({ a: getName.bind(person), b: getName.bind(person), c: getName.bind(person) }))(person);
现在我们调用解构的道具:
a(); // { getName: [Function: getName] }
b(); // { getName: [Function: getName] }
c(); // { getName: [Function: getName] }
这里发生了什么?如果该行令人困惑,请继续阅读...
我们将所有内容包装在一个 IIFE 中,该 IIFE 接受 person
对象作为输入;我们将 getName
道具内联。1
最后,我们使用 getName
属性将每个调用显式映射到 bind
- 从我们唯一的参数 person
中提取 - 对应于 a, b, c
,我们正在从已解决的 IIFE 中解构它。
1好吧,可以说我在这里作弊了,因为我们有两个解构“语句”但是最终在同一个表达式中解析
在 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
我希望 c
登录其 "parent" 对象 {getName:
[Function]}
的控制台。
在一个 destructuring 行中解构对象时,有没有办法绑定所有方法?
不行,没办法。从对象中分离出来的函数失去了原来的上下文。在 JavaScript 中进行破坏没有语法来动态处理提取的值。
您可以使用 getter 或代理来绑定一个方法,只要您 get
它,甚至使用解构。
两种解决方案都通过使用 String.startsWith()
在名称的开头查找 bound
来检查方法是否已经绑定。如果未绑定,该方法将在返回之前被绑定。
- 使用 getter 将方法自动绑定到对象。每种方法都需要 getter。
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
- 使用 proxy 将方法自动绑定到对象。为所有方法定义一次。
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
有一个使用 ES6 classes 的简单解决方法。您可以在 class 构造函数中使用 bind
来手动设置函数的上下文。
在下面的示例中,getName()
将 "survive" 解构 :
class Person {
constructor() {
this.getName = this.getName.bind(this);
}
getName() {
console.log(this);
}
}
const {
getName
} = new Person();
getName(); // Person { getName: [Function: bound getName] }
只需使用箭头方法:
const person = {
getName: () => console.log(this),
};
是的。假设我正确理解你的问题,我们可以用一行代码来完成。
这当然不是最易读的方法,但它是我在个人项目中经常使用的方法:
const person = {
getName: function() {
console.log(this);
}
};
// IIFE for destructuring and applying changes inline
const { a, b, c } = (({ getName }) => ({ a: getName.bind(person), b: getName.bind(person), c: getName.bind(person) }))(person);
现在我们调用解构的道具:
a(); // { getName: [Function: getName] }
b(); // { getName: [Function: getName] }
c(); // { getName: [Function: getName] }
这里发生了什么?如果该行令人困惑,请继续阅读...
我们将所有内容包装在一个 IIFE 中,该 IIFE 接受 person
对象作为输入;我们将 getName
道具内联。1
最后,我们使用 getName
属性将每个调用显式映射到 bind
- 从我们唯一的参数 person
中提取 - 对应于 a, b, c
,我们正在从已解决的 IIFE 中解构它。
1好吧,可以说我在这里作弊了,因为我们有两个解构“语句”但是最终在同一个表达式中解析