Reputation: 12271
This version of my es6 function doesn't work:
Array.prototype.concatAll = () => {
let results = [];
this.forEach((subArray) => {
subArray.forEach((item) => {
results.push(item);
});
});
return results;
};
When I use it like this:
var stocks = exchanges.concatAll();
The console says: Cannot read property 'forEach' of undefined
However this es5 version works just fine:
Array.prototype.concatAll = function() {
let results = [];
this.forEach((subArray) => {
subArray.forEach((item) => {
results.push(item);
});
});
return results;
};
Why is this? What exactly is happening with this
inside the es6 version? I would like to understand.
Upvotes: 0
Views: 318
Reputation: 53829
This has already been mentioned, but this isn't a good use-case for arrow functions due to the fact that they bind the value of this
. Another way you can do this with ES6 is to use Object.assign
.
For your example:
Object.assign(Array.prototype, {
concatAll() {
let results = [];
this.forEach(subArr => {
subArr.forEach(item => {
results.push(item);
});
});
return results;
}
});
And then you could just use the code like this:
let arr = [
[1, 2, 3],
[4, 5, 6]
];
console.log(arr.concatAll()); // -> [1, 2, 3, 4, 5, 6]
You can also add on multiple methods like this:
Object.assign(Array.prototype, {
sum() {
return this.reduce((a, b) => a + b);
},
max() {
return this.reduce((a, b) => (a > b) ? a : b);
},
min() {
return this.reduce((a, b) => (a < b) ? a : b);
}
});
let arr = [1, 2, 3];
console.log(arr.sum()); // -> 6
console.log(arr.max()); // -> 3
console.log(arr.min()); // -> 1
Upvotes: 1
Reputation: 20928
The arrow function's scope of this
is it's parent scope. So in this case this
is undefined. So in this case you would still need a function.
Check the start of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.
An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous.
ES6 can still simplify your code though by using for of
:
Array.prototype.concatAll = function(){
let results = []
for(let subArray of this)
for(let item of subArray)
results.push(item)
return results
}
Upvotes: 0