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
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));
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);
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
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
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
.