1) I have the following code:
var callIt = function(fn) { return fn.apply(this, Array.prototype.slice.apply(arguments, 1)); };
when callIt is called in nodejs, it complains:
return fn.apply(this, Array.prototype.slice.apply(arguments, 1));
^
TypeError: Function.prototype.apply: Arguments list has wrong type
2) If I change the callIt to:
var callIt = function(fn) { return fn.apply(this, Array.prototype.slice.apply(arguments)); };
Nodejs does not complain, but the result is not what expected, with the extra first argument passed in.
3) If I change the callIt to:
var callIt = function(fn) { var args = Array.prototype.slice.apply(arguments); return Function.prototype.apply(fn, args.slice(1)); //return fn.apply(this, args.slice(1)); //same as above };
It works as expected.
4) If I run test in Chrome developer Tools Console like this:
> var o={0:"a", 1:"asdf"} undefined > o Object 0: "a" 1: "asdf" __proto__: Object > Array.prototype.slice.call(o,1) [] > Array.prototype.slice.call(o) []
Now slice does not work on array-like object.
I am baffled on these. Please explain.
I referenced the following: Array_generic_methods
Your problem is that the apply method of functions expects an array as its second parameter - that's where your TypeError comes from, you passed 1. Instead, use [1] or better the call method:
fn.apply(this, Array.prototype.slice.call(arguments, 1));
The reason why it didn't work on {0:"a", 1:"asdf"} is that this is not an array-like object - it has no length property. [].slice.call({0:"a", 1:"asdf", length:2}, 0) would do it.