How do I get the right “this” in an Array.map?

前端 未结 5 1255
悲哀的现实
悲哀的现实 2020-11-27 22:33

I assume there is some application of call or apply here but I\'m not sure how to implement it.

http://codepen.io/anon/pen/oXmmzo



        
相关标签:
5条回答
  • 2020-11-27 22:35

    Just realized I should have read the documentation for Array.map() more carefully. One simply needs to pass in the this value as the second parameter of map()

    http://codepen.io/anon/pen/VLggpX

    a = {
      foo: 'bar',
      things: [1, 2, 3],
      showFooForEach: function() {
        this.things.map(function(thing) {
          console.log(this.foo, thing);
        }, this);
      }
    }
    a.showFooForEach();
    

    In addition, understanding how bind(), call() and apply() work are a must for serious JavaScript developers. These allow us to skip silly assignments like

    var self = this;
    myItems.map(function(item) {
      self.itemArray.push(item);
    });
    

    with

    myItems.map(function(item) {
      this.itemArray.push(item);
    }.bind(this));
    
    0 讨论(0)
  • 2020-11-27 22:41

    map allows a second argument called "thisArg" so you just use that like so:

    showFooForEach: function() {
        this.things.map(function(thing) {
          console.log(this.foo, thing);
        },this);
    
    0 讨论(0)
  • 2020-11-27 22:45

    As of 2018, you could use an arrow function:

    a = {
      foo: 'bar',
      things: [1, 2, 3],
      showFooForEach: function() {
        this.things.map((thing) => {
          console.log(this.foo, thing);
        });
      }
    }
    
    a.showFooForEach();
    

    You could use bind() it to your context.

    a = {
      foo: 'bar',
      things: [1, 2, 3],
      showFooForEach: function() {
        this.things.map(function(thing) {
          console.log(this.foo, thing);
        }.bind(this));
      }
    }
    
    a.showFooForEach();
    

    That's because of JS lexical scope

    From MDN:

    The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

    Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

    And here: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/

    Also, map() does accept a second parameter as "this"

    a = {
      foo: 'bar',
      things: [1, 2, 3],
      showFooForEach: function() {
        this.things.map(function(thing) {
          console.log(this.foo, thing);
        }, this);
      }
    }
    
    a.showFooForEach();
    

    From MDN map() documentation:

    Parameters

    callback Function that produces an element of the new Array

    thisArg Optional. Value to use as this when executing callback.

    Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

    Short advice

    PS.: Array.map is usually called when you want to do something with your array, for example adding 10 to each item, or something like that... Since the Array.map returns a new array. If you're only using console.log or something that wont affect the array itself you could just use a Array.forEach call instead

    0 讨论(0)
  • 2020-11-27 22:54

    Nothing complex needed! map takes a second param of thisArg, so you just pass it in with the function you want to invoke on each item:

    a = {
      foo: 'bar',
      things: [1, 2, 3],
      showFooForEach: function() {
        this.things.map(function(thing) {
          console.log(this.foo, thing);
        }, this);
      }
    }
    
    a.showFooForEach();
    

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

    0 讨论(0)
  • 2020-11-27 22:56

    There are three ways:

    An plain-old variable

    One that doesn't have the special oddness of this:

    var self = this;
    this.things.map(function(thing) {
      console.log(self.foo, thing);
    });
    

    Function.prototype.bind

    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }.bind(this));
    

    Use the second parameter of Array.prototype.map

    The (optional) second parameter is the context that the inner function is called with.

    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }, this);
    

    The first two ways are generic ways of dealing with this; the third is specific to map, filter, forEach.

    0 讨论(0)
提交回复
热议问题