最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to bind `this` to reduce? - Stack Overflow

programmeradmin1浏览0评论

I have a simple reducer, how do I bind this from outside to use that inside the reducer this.teacherInstance?

this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
  if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
     teacherIdArr.push(this.teacherInstance.getTeacherModelById(teacher.teacherId));
  }
  return teacherIdArr;
}, []);

I have a simple reducer, how do I bind this from outside to use that inside the reducer this.teacherInstance?

this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
  if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
     teacherIdArr.push(this.teacherInstance.getTeacherModelById(teacher.teacherId));
  }
  return teacherIdArr;
}, []);
Share Improve this question edited Dec 30, 2018 at 0:35 11684 7,52712 gold badges52 silver badges74 bronze badges asked Dec 28, 2018 at 14:56 POVPOV 12k40 gold badges128 silver badges229 bronze badges 4
  • 1 Have you tried using an arrow function => instead of the function keyword? – Kokodoko Commented Dec 28, 2018 at 14:59
  • 2 Bind it to the function by using .bind(this) after the function. Or use a var self = this; outside of the reduce loop and use self.teachInstance. Or use an arrow function. Or alternatively, turn the logic around and use .map(), which supports a this argument as the second parameter and filter out the duplicates after. You could also make the reduction function a method of this so you can use this.plans.reduce( this.findTeacherModels ); or something. – Shilly Commented Dec 28, 2018 at 15:01
  • @OPV see this hacks.mozilla/2015/06/es6-in-depth-arrow-functions – Sagar P. Ghagare Commented Dec 28, 2018 at 15:05
  • are you sure, that this.teacherInstance.getTeacherModelById returns a single id? which is possible to use with indexOf? – Nina Scholz Commented Dec 28, 2018 at 15:13
Add a ment  | 

3 Answers 3

Reset to default 8

Using explicit binding with Function.prototype.bind:

this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
      teacherIdArr.push(this.teacherInstance.getTeacherModelById(teacher.teacherId));
   }
   return teacherIdArr;
}.bind(this), []);

Using a closure/reference:

const self = this;
this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
      teacherIdArr.push(self.teacherInstance.getTeacherModelById(teacher.teacherId));
   }
   return teacherIdArr;
}, []);

Using an ES6 arrow function that doesn't have a this of its own, preserving the "outer" this:

this.teachersDropMenu = this.plans.reduce((teacherIdArr, teacher) => {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
      teacherIdArr.push(this.teacherInstance.getTeacherModelById(teacher.teacherId));
   }
   return teacherIdArr;
}, []);

Use an ES6 arrow function as they work in lexical scope, so this is determined depending on "where" it is written:

this.teachersDropMenu = this.plans.reduce((teacherIdArr, teacher) => {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
        teacherIdArr.push(this.teacherInstance.getTeacherModelById(
          teacher.teacherId));
   }
       return teacherIdArr;
}, []);

Also have a look here: How to access the correct `this` inside a callback?

If you can't use arrow functions you can simply use the bind method with the anonymous function like this:

this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
        teacherIdArr.push(this.teacherInstance.getTeacherModelById(
          teacher.teacherId));
   }
       return teacherIdArr;
}.bind(this), []);

Another approach would be to store this in another variable and use the lexical scope:

var that = this;
this.teachersDropMenu = this.plans.reduce(function (teacherIdArr, teacher) {
   if (teacherIdArr.indexOf(teacher.teacherId) == -1) {
        teacherIdArr.push(that.teacherInstance.getTeacherModelById(
          teacher.teacherId));
   }
       return teacherIdArr;
}, []);

Both approaches are fine.

发布评论

评论列表(0)

  1. 暂无评论