problems with Array.prototype.slice.appy(arguments, 1)

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.