1

This is not for a job interview, don't worry :)

I am curious as to why these two functions return differently:

var redundantSlice1 = function() {
    return arguments[0].slice(Array.prototype.slice.call(arguments).slice(1).join())
};

var redundantSlice2 = function() {
    return arguments[0].slice(1,2)
};

redundantSlice1([1,2,3], 1, 2) // [1,2,3]

redundantSlice2([1,2,3], 1, 2) // [2]

redundantSlice2 returns what I expect, but the 1,2 are hardcoded, this is what I am trying to avoid.

Why does the first function have what I expect to be 1,2 as undefined?

5
  • .join returns a string. So the first example is equivalent to arr.slice("1,2"). That's very different from arr.slice(1, 2). I'm not sure how .slice treats invalid arguments (apparently it treats it like 0 or nothing was passed). Commented Nov 8, 2015 at 2:06
  • Yeah, that's what I found. I had the same results passing null and undefined. Commented Nov 8, 2015 at 2:07
  • May as well make that the answer :) Commented Nov 8, 2015 at 2:12
  • you need to look at function.apply - but as slice only ever takes 0, 1 or 2 arguments, I'd define your wrapper function as function(array, begin, end) then simply return [].slice.call(array, begin, end) - that's just as much a re-implementation as you've written Commented Nov 8, 2015 at 2:13
  • There are more constraints to the problem that I didn't want to give away as to not cheat, but @FelixKling answered my initial question. It's a string. Commented Nov 8, 2015 at 2:26

2 Answers 2

1

In redundantSlice1, .join( ) converts the arguments into a string with , as the delimiter by default. So with your sample, the statement

Array.prototype.slice.call( arguments ).slice( 1 ).join( )

Is actually "1,2" not [ 1, 2 ] like you're expecting.

In addition to this, you're only passing one argument to .slice( ). In order to match the behavior of redundantSlice2, you must use .apply( ).

var redundantSlice1 = function() {
    var firstArg = arguments[ 0 ];

    return Array.prototype.slice.apply(
        firstArg,
        Array.prototype.slice.call( arguments, 1 )
    );
};
Sign up to request clarification or add additional context in comments.

3 Comments

This could probably also just be done with arguments[0].slice(arguments[1], arguments[2]).
what if arguments[0] is "array-like"?
@FelixKling Yep, I'm just being consistent with the OP's approach.
1

If you want to do this so you can pass an array or an array-like object and get the same result

var redundantSlice1 = function(array, begin, end) {
    return Array.prototype.slice.call(array, begin, end)
};

this will work with 1, 2 or 3 arguments passed in exactly like Array.slice works

If you insist on slicing the arguments and have no "formal parameters" to the function

var redundantSlice1 = function() {
    return Array.prototype.slice.apply(arguments[0], Array.prototype.slice.call(arguments, 1));
};

Comments

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.