2

I am trying to write a static version of slice.

What is the difference between

Function.prototype.call.bind(Array.prototype.slice) 

and

Array.prototype.slice.call.

If I write:

var x = Array.prototype.slice.call; 
x([1,2,3]);

I get

TypeError: object is not a function.

Why is this?

asp
  • 201
  • 2
  • 6
  • possible duplicate of [JavaScript "this" keyword](http://stackoverflow.com/questions/3127429/javascript-this-keyword) – Dagg Nabbit Jan 19 '14 at 22:40

2 Answers2

1

The function Array.prototype.slice.call is the same exact function as Function.prototype.call. It does not know that Array.prototype.slice should be this unless you call it as a method, like so:

Array.prototype.slice.call(whatever);

or if you use one of a few other ways to tell it what this is. When you assign it to x, you lose the this information.

Function.prototype.call.bind(Array.prototype.slice) creates a function that does know that Array.prototype.slice is this. Even if you attach it to a new object and call it as a method of the new object:

x = {call: Function.prototype.call.bind(Array.prototype.slice)}
x.call([1, 2, 3])

It will behave as though it were called as Array.prototype.slice.call instead of x.call.

user2357112 supports Monica
  • 215,440
  • 22
  • 321
  • 400
  • There is a section in [Javascript Garden](http://bonsaiden.github.io/JavaScript-Garden/#function.this) that explains this idea, that when you assign a method to a variable you lose the this context. I did not fully digest it, though, so I could not make the connection myself. Thanks. – asp Jan 19 '14 at 22:53
0

Here's your hint - this is true:

Array.prototype.slice.call == (function() {}).call

call is a member of Function.prototype - it expects the this argument to point to the function to call. You're passing it nothing, so this refers to the window object. This will work:

x = Array.prototype.slice.call.bind(Array.prototype.slice)

But from my first code snippet, Array.prototype.slice.call is just Function.prototype.call, so:

x = Function.prototype.call.bind(Array.prototype.slice)

In fact, Function.call == Function.prototype.call, so you can do

x = Function.call.bind(Array.prototype.slice)
Eric
  • 87,154
  • 48
  • 211
  • 332