1

So I'm used to automatically writing things such as this:

Array.prototype.slice.call(arguments);

--and similar such applications of various methods via Array.prototype.XXX.call or Object.prototype.XXX.call([]).

So I went to try out the Array.isArray method which I didn't know existed, and automatically wrote Array.prototype.isArray.call, which of course failed since isArray isn't defined on the prototype.

But then I tried Array.isArray.call([]) slightly unthinkingly and got false, which confused me.

It worked fine on the third try when I went the plain ol' boring way (the correct usage) and simply wrote Array.isArray(thing_to_be_tested), but why did I get false on the previous attempt? I don't understand why that doesn't work.

5
  • 1
    Why would you "automatically" write stuff like that ? Commented Feb 1, 2015 at 21:58
  • Because you were basically calling Array.isArray() (only in a [] context), and without arguments it tells you that undefined is not an array. Commented Feb 1, 2015 at 21:59
  • @Adeneo When you're in the middle of working with the native APIs and playing with them and bending what they can do.... Commented Feb 1, 2015 at 22:00
  • Well, isArray is not part of the prototype chain, and it only accepts one argument, and doesn't care about the this value or scope, so don't ! Commented Feb 1, 2015 at 22:02
  • And you should generally avoid converting arguments, nodelist etc. to array that way as well, even if it is useful sometimes, and I must confess to do doing it quite a bit myself, even knowing the proper way is to use a for loop Commented Feb 1, 2015 at 22:04

2 Answers 2

4

Because Array.isArray has one argument, which you are not passing along. You are simply passing the this value, which is not used in the function:

Array.isArray.call(null, [])
Sign up to request clarification or add additional context in comments.

1 Comment

I knew that. Really I swear I did. Not enough coffee. 12 minutes til I can accept answer, lol.
2

The first thing .call() expects is the context. So you're basically calling .isArray() with the context of an Array, but an undefined value.

Call instead:

Array.isArray.call( null, [] );

or to make it more realistic:

var isarr = Function.prototype.call.bind( Array.isArray, null );

Now you can call that like

isarr( [] );

5 Comments

or to make it more simple: var isArr = Array.isArray;
If at all, use var isArr = Array.isArray.bind(Array);.
haha yes indeed. For that method the context has no meaning and it should just be referenced directly.
Ah I though with ES6 and subclassable arrays that might change, but apparently it doesn't.
Still, the method is not on the prototype chain. So contrary to for instance Object.prototype.toString we can just reference the method in a variable whilst that would not work for the toString example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.