Programming Questions

  • Newest
  • Popular Tags
  • Ask A Question
  • JavaScript slice vs shift functions
    I was looking at a solution for the Array Addition problem, posted in another CoderByte Question: http://coderbyte.com/CodingArea/Questions/Q/?q=array-addition-recursion My question is regarding this piece of code:
    var n = array[0];
    array = array.slice(1);
    
    This piece of code is within a recursive function. I tried to rewrite these steps into one line, ultimately trying these two methods to directly modify the array (instead of slicing it):
    var n = array.shift();
    
    and
    var n = array.splice(0, 1)[0];
    
    However, I do not get the same answer when using these methods, and I'm not sure why. Why would modifying the array directly (using shift or splice) be different than re-assigning it using array = slice(1)? Thanks!
    hokennethk posted this question on 2/15/15 | javascript, array
    Answers
  • +
  • 8
  • -
  • Have you studied C? Or any language with pointers? If not, hopefully this will still make sense... Here's what's going on:
    var array = [1,2,3,4]; //<Made an array
    var n = array[0]; //<Saved first element in n.
    array = array.slice(1); //Created new array from slice, destroyed reference to original
    
    What you've done in line 3 is made a copy, then destroyed the *pointer* to the original. If the original has another pointer, it still exists unchanged. Like this:
    var A = B = [1,2,3,4];
    var n = A[0];
    A = A.slice(1); //B still exists, and it's still [1,2,3,4]
    
    //but...
    
    var C = D = [1,2,3,4];
    var n = C.shift(); //C and D are now both [2,3,4];
    
    In the particular example you gave:
    function recursion( array ){ //"array" here is a local variable, pointing to an array created elsewhere
        // ... stuff ...
        var n = array[0]; //new local variable
        //array[1] = 123; //Don't Do This! You'll Change The Original Array!
        array = array.slice(1); //This is OK. You've made a new array, 
                                        // and pointed the local variable "array" at it.
                                        // The original array is still alive and well and unharmed
                                        //  somewhere outside of this function! :-)
        // ... stuff ...
      }
    
    Does that make sense? Arrays and variables started to make sense to me after a little practice. If you've got it now, you can stop reading. If not, this code might help:
    var a = [1,2,3,4];
    a[0] = 5;
    console.log(a); //logs: [5,2,3,4]. Changed the original array!
    
    a = [1,2,3,4]; //a is *pointing* to [1,2,3,4] (stored somewhere in memory)
    function change( array ) { //"array" is also *pointing* to [1,2,3,4] (stored somewhere in memory)
      array[0]=5; //array[0] tells JavaScript: change the 0th element of [1,2,3,4]. (Now [5,2,3,4])
      array = "Hello!"; //This just tells JavaScript: 
                              //"array" isn't pointing at [5,2,3,4] anymore.
                              //now, it's pointing at "hello" (stored somewhere else in memory).
                              //[5,2,3,4] is not lost though! Var "a" outside this function still points to it.
    }
    change( a ); //runs the function above on variable "a"
    console.log(a); //logs: [5,2,3,4]. The function changed the original array! But, it did not destroy it.
    
    a = [1,2,3,4]
    function dontChange( arr ) {
      var b = array[0]; //b is copied from 0th of [1,2,3,4], which is 1.
      arr = arr.slice(1); //a is a new array, copied from 1st->3rd of [1,2,3,4], which is [2,3,4].
      return arr;
    }
    console.log( dontChange( a ) ); //runs above function, logs the new array [2,3,4]
    console.log( a ); //logs the original, unchanged array [1,2,3,4]. We never touched it! Only copied.
    
    When you changed those lines of code, you changed that original array, and broke the program. I hope that helped! :-)
  • +
  • 1
  • -
  • First: a huge thanks to you for taking the time out to write out that detailed explanation. I have not studied C, but your explanation is clear and was very helpful to my understanding. Initially, I was thrown off by my use of .shift() because I had thought that using that would only modify the local "array" within the function. I thought that within function(array) {...}, any changes to array would keep any changes to "array" within the function. However, your explanation of pointers has given me a better understanding of what's actually happening. This particular part was very helpful:
    //This is OK. You've made a new array, 
                                        // and pointed the local variable "array" at it.
                                        // The original array is still alive and well and unharmed
                                        //  somewhere outside of this function! :-)
    
    Also, this stackoverflow link helped me understand reference data types in JS a bit more. There is a visual aide in the chosen answer: stackoverflow.com/questions/8318357/javascript-pointer-reference-craziness-can-someone-explain-this
    Log in to write an answer.