我在React JSX中编写一个函数,其中包含需要与this
交谈的回调
this.socket.on('addWashedMission', washedMission => {
console.log('onAddWashedMission - %s - %s', washedMission.name,
new Date(washedMission.birthtime));
this.state.washedMissions.filter(function(o) {
return o.name === washedMission.name;
}).forEach(function(element, i, arr) {
// HERE IT IS //
this.state.washedMissions.state.washedMissions.slice(
this.state.washedMissions.state.washedMissions.indexOf(element), 1);
});
this.state.washedMissions.push(washedMission);
this.state.washedMissions.sort(function(a,b) {
return b.birthtime - a.birthtime;
});
this.setState({
washedMissions: this.state.washedMissions
});
});
注意this.state.washedMissions
?当我在回调中时,Firefox脚本调试器向我显示浏览器不知道this
是什么,因此我无法以这种方式操纵我的数组。
如何确保this
在我的回调范围内 - 注意,回调是同步的,所以我不担心任何计时。
答案 0 :(得分:3)
你有
...forEach(function(element, i, arr) {
this.state.washedMissions.state.washedMissions.slice(
this.state.washedMissions.state.washedMissions.indexOf(element), 1);
});
您需要提供thisArg
作为Array.prototype.forEach
...forEach(function(element, i, arr) {
this.state.washedMissions.state.washedMissions.slice(
this.state.washedMissions.state.washedMissions.indexOf(element), 1);
}, this); // <--- note the `this` after the function() {}
或者你需要一个arrow function词汇绑定this
值
...forEach((element, i, arr) =>
this.state.washedMissions.state.washedMissions.slice(
this.state.washedMissions.state.washedMissions.indexOf(element), 1)
);
或者您可以使用其他答案中提供的石头年龄慢Function.prototype.bind
答案 1 :(得分:2)
为所有功能使用更多箭头功能
this.socket.on('addWashedMission', washedMission => {
console.log('onAddWashedMission - %s - %s', washedMission.name,
new Date(washedMission.birthtime));
this.state.washedMissions
.filter(o => {
return o.name === washedMission.name;
})
.forEach((element, i, arr) => {
const elementIndex = this.state.washedMissions.state.washedMissions.indexOf(element);
this.state.washedMissions.state.washedMissions.slice(elementIndex, 1);
});
this.state.washedMissions.push(washedMission);
this.state.washedMissions.sort((a,b) => {
return b.birthtime - a.birthtime;
});
this.setState({
washedMissions: this.state.washedMissions
});
});
答案 2 :(得分:1)
问题是匿名函数范围内的this
不会引用定义它的包含范围。它将引用它所分配的对象的范围,以及稍后从中调用它的范围。
因此,您需要“欺骗”它以使this
引用您想要的this
。
有几种方法可以达到你想要的效果。
在匿名函数之外使用var that = this;
定义,并在其中引用它而不是this
来创建闭包。 (旧版浏览器的向后兼容性更好)
var that = this;
this.state.washedMissions.filter(function(o) {
return o.name === washedMission.name;
}).forEach(function(element, i, arr) {
// HERE IT IS //
that.state.washedMissions.state.washedMissions.slice(
that.state.washedMissions.state.washedMissions.indexOf(element), 1);
});
将匿名函数的范围绑定到其定义范围的this
,然后将其传递给forEach
方法(用于处理此问题的首选ECMA5方法)
this.state.washedMissions.filter(function(o) {
return o.name === washedMission.name;
}).forEach(function(element, i, arr) {
// HERE IT IS //
this.state.washedMissions.state.washedMissions.slice(
this.state.washedMissions.state.washedMissions.indexOf(element), 1);
}.bind(this));