1

I have tried this:

// You can pass an array on the addArr method, and each element from the 
// passed array is pushed to the array on which addArr was called.
Array.prototype.addArr = function( arr ){
   console.log( this );

   // As `this` is the array, we use this.push to insert arr's elements
   arr.forEach(function(elm){
     this.push( elm );
   });

   // And then finally return this.
   return this;
};

The code has been explained using comments, but let me put in straight. I am trying to create a new method on the Array object called addArr, which can pass an array [1, 2, 3] to the method and each of the element is added to the array on which the method was called.

For e.g

var myArr = [1, 2, 3];
myArr.addArr( [4, 5, 6] );
// The output is supposed to be [1, 2, 3, 4, 5, 6]

I am getting Uncaught TypeError: this.push is not a function, I have tried debugging, this always returns the parent array still it says that push is not a function.

How can I solve it? I could use libraries like Lodash for these, but I don't prefer to for such a small application.

Thanks!

Deepak Kamat
  • 1,536
  • 3
  • 16
  • 35
  • 1
    `this` is specific for each function. `forEach(function () …)` is a new function with its own value for `this`… – deceze Aug 18 '16 at 08:02
  • The array `.forEach()` method does *not* set `this` to the array when calling your callback. Though you can make it do so with `arr.forEach(function(){}, arr)`. Also, it *really* doesn't make sense for the callback to add a new element to the same array you're iterating over. – nnnnnn Aug 18 '16 at 08:02
  • Oh I feel so stupid! Didn't even noticed that. Thank you very much all of you. – Deepak Kamat Aug 18 '16 at 08:04
  • By the way, your desired output can be achieved with `this.push.apply(this, arr);` instead of the `forEach`. – nnnnnn Aug 18 '16 at 08:05

1 Answers1

4

Store this into a variable outside of the function.

 Array.prototype.addArr = function( arr ){
 var that = this;
 arr.forEach(function(elm){
 that.push( elm );
 });

  return this;
 };
var myArr = [1,2,3];
myArr.addArr([4,5]);

Alternative, as @nnnnnn pointed out, you could pass this as an argument to the .forEach function.

 Array.prototype.addArr = function( arr ){
 arr.forEach(function(elm){
 this.push( elm );
 },this);
 return this;
 };

var myArr = [1,2,3];
myArr.addArr([4,5]);
Dylan Meeus
  • 5,300
  • 1
  • 24
  • 47
  • @DeepakKamat You're welcome! :-) – Dylan Meeus Aug 18 '16 at 08:05
  • 1
    Wouldn't `arr.forEach(function(){}, this)` be easier than creating a new variable? (The optional second argument to `forEach()` specifies the value of `this` within the callback.) – nnnnnn Aug 18 '16 at 08:08
  • @nnnnnn that is true. Not sure if it would do a lot for performance here, but maybe it can be considered the more clean solution :-) I've altered my answer to add that, thank you! – Dylan Meeus Aug 18 '16 at 08:15
  • Yeah, any performance difference wouldn't be worth worrying about. I just meant easier as in less to type or think about. There might be a performance improvement in replacing the `forEach()` with `this.push.apply(this, arr);`. (Or there might not. I don't know.) – nnnnnn Aug 18 '16 at 08:19
  • @nnnnnn would depend on the implementation of `this.push.apply` I guess. For extremely large arrays, there *might* be a difference, but I don't know either ^^ ty – Dylan Meeus Aug 18 '16 at 08:31
  • `this.push.apply` works well, and requires less code. Thank you all, got to learn a lot of stuffs today :) – Deepak Kamat Aug 18 '16 at 14:47