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

前端 未结 5 1271
悲哀的现实
悲哀的现实 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: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

提交回复
热议问题