Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adds new method to Array.prototype in javascript [duplicate]

Tags:

javascript

I am new to Javascript language, recently I started looking into js prototype and got confused by some odd output in below code:

Array.prototype.print = function() {
  console.log(this)
}

[1, 2, 3, 4].print();

Could anyone tell me why it returns

Cannot read property 'print' of undefined'

If I declare var array = [1, 2, 3, 4] then call print function by array.print(), it works fine, so I got confused how is that different?

Array.prototype.print = function() {
  console.log(this)
}

var array = [1, 2, 3, 4]
array.print()
like image 725
chen.w Avatar asked Aug 08 '18 17:08

chen.w


2 Answers

You could just add a semicolon to separate an access to the function.

What you have is a property accessor to the function expression with comma operators which return 4 for the access. The ASI (automatic semicolon insertion) does not work in this case.

Array.prototype.print = function() {
  console.log(this)
}[1, 2, 3, 4] //.print();   // tries to get property 4 of the function
                            // and then tries to call a function from undefined

It needs a semicolon after the block statement of the function expression.

Array.prototype.print = function() {
  console.log(this)
};

[1, 2, 3, 4].print();
like image 126
Nina Scholz Avatar answered Oct 09 '22 20:10

Nina Scholz


If you run the whole code block in one go, there is no guarantee that the last line will run after the first block.

Running the two blocks separately will highlight this difference, and you will see the correct output from the second block.

Run this first:

Array.prototype.print = function() {
  console.log(this)
}

Then run this:

[1, 2, 3, 4].print();

There are several approaches you can take to getting them to run asynchronously. An easy one would be to wrap the last line in a setTimeout (this may not be appropriate depending on your usage).

E.g.

Array.prototype.print = function() {
  console.log(this)
}

setTimeout(()=> { 
    [1, 2, 3, 4].print();
}, 1000)
like image 27
Jamie Weston Avatar answered Oct 09 '22 21:10

Jamie Weston