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
a = {
foo: 'bar',
things: [1, 2, 3],
showFooForEach: function() {
this.things.map(function(thing) {
console.log(this.foo, thing);
});
}
}
a.showFooForEach();
Say I want to map
an array, but in the function, I need access to the this
to which foo
belongs. The function
of map
creates a new this
context, so I obviously need to coerse that context back in somehow, but how do I do that while still having access to thing
?
To use a condition inside map() in React: Call the map() method on an array. Use a ternary operator to check if the condition is truthy. The operator returns the value to the left of the colon if the condition is truthy, otherwise the value to the right is returned.
Definition and Usage map() creates a new array from calling a function for every array element. map() calls a function once for each element in an array. map() does not execute the function for empty elements. map() does not change the original array.
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));
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
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
.
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
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With