Deleting array elements in JavaScript - delete vs splice

后端 未结 27 3675
予麋鹿
予麋鹿 2020-11-21 05:31

What is the difference between using the delete operator on the array element as opposed to using the Array.splice method?

For example:

myArray = [\         


        
相关标签:
27条回答
  • 2020-11-21 06:11

    splice will work with numeric indices.

    whereas delete can be used against other kind of indices..

    example:

    delete myArray['text1'];
    
    0 讨论(0)
  • 2020-11-21 06:12

    Performance

    There are already many nice answer about functional differences - so here I want to focus on performance. Today (2020.06.25) I perform tests for Chrome 83.0, Safari 13.1 and Firefox 77.0 for solutions mention in question and additionally from chosen answers

    Conclusions

    • the splice (B) solution is fast for small and big arrays
    • the delete (A) solution is fastest for big and medium fast for small arrays
    • the filter (E) solution is fastest on Chrome and Firefox for small arrays (but slowest on Safari, and slow for big arrays)
    • solution D is quite slow
    • solution C not works for big arrays in Chrome and Safari
      function C(arr, idx) {
        var rest = arr.slice(idx + 1 || arr.length);
        arr.length = idx < 0 ? arr.length + idx : idx;
        arr.push.apply(arr, rest);
        return arr;
      }
      
      
      // Crash test
      
      let arr = [...'abcdefghij'.repeat(100000)]; // 1M elements
      
      try {
       C(arr,1)
      } catch(e) {console.error(e.message)}

    Details

    I perform following tests for solutions A B C D E (my)

    • for small array (4 elements) - you can run test HERE
    • for big array (1M elements) - you can run test HERE

    function A(arr, idx) {
      delete arr[idx];
      return arr;
    }
    
    function B(arr, idx) {
      arr.splice(idx,1);
      return arr;
    }
    
    function C(arr, idx) {
      var rest = arr.slice(idx + 1 || arr.length);
      arr.length = idx < 0 ? arr.length + idx : idx;
      arr.push.apply(arr, rest);
      return arr;
    }
    
    function D(arr,idx){
        return arr.slice(0,idx).concat(arr.slice(idx + 1));
    }
    
    function E(arr,idx) {
      return arr.filter((a,i) => i !== idx);
    }
    
    myArray = ['a', 'b', 'c', 'd'];
    
    [A,B,C,D,E].map(f => console.log(`${f.name} ${JSON.stringify(f([...myArray],1))}`));
    This snippet only presents used solutions

    Example results for Chrome

    0 讨论(0)
  • 2020-11-21 06:13

    delete will delete the object property, but will not reindex the array or update its length. This makes it appears as if it is undefined:

    > myArray = ['a', 'b', 'c', 'd']
      ["a", "b", "c", "d"]
    > delete myArray[0]
      true
    > myArray[0]
      undefined
    

    Note that it is not in fact set to the value undefined, rather the property is removed from the array, making it appear undefined. The Chrome dev tools make this distinction clear by printing empty when logging the array.

    > myArray[0]
      undefined
    > myArray
      [empty, "b", "c", "d"]
    

    myArray.splice(start, deleteCount) actually removes the element, reindexes the array, and changes its length.

    > myArray = ['a', 'b', 'c', 'd']
      ["a", "b", "c", "d"]
    > myArray.splice(0, 2)
      ["a", "b"]
    > myArray
      ["c", "d"]
    
    0 讨论(0)
  • 2020-11-21 06:13

    The difference can be seen by logging the length of each array after the delete operator and splice() method are applied. For example:

    delete operator

    var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
    delete trees[3];
    
    console.log(trees); // ["redwood", "bay", "cedar", empty, "maple"]
    console.log(trees.length); // 5
    

    The delete operator removes the element from the array, but the "placeholder" of the element still exists. oak has been removed but it still takes space in the array. Because of this, the length of the array remains 5.

    splice() method

    var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
    trees.splice(3,1);
    
    console.log(trees); // ["redwood", "bay", "cedar", "maple"]
    console.log(trees.length); // 4
    

    The splice() method completely removes the target value and the "placeholder" as well. oak has been removed as well as the space it used to occupy in the array. The length of the array is now 4.

    0 讨论(0)
  • 2020-11-21 06:13

    Others have already properly compared delete with splice.

    Another interesting comparison is delete versus undefined: a deleted array item uses less memory than one that is just set to undefined;

    For example, this code will not finish:

    let y = 1;
    let ary = [];
    console.log("Fatal Error Coming Soon");
    while (y < 4294967295)
    {
        ary.push(y);
        ary[y] = undefined;
        y += 1;
    }
    console(ary.length);
    

    It produces this error:

    FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.
    

    So, as you can see undefined actually takes up heap memory.

    However, if you also delete the ary-item (instead of just setting it to undefined), the code will slowly finish:

    let x = 1;
    let ary = [];
    console.log("This will take a while, but it will eventually finish successfully.");
    while (x < 4294967295)
    {
        ary.push(x);
        ary[x] = undefined;
        delete ary[x];
        x += 1;
    }
    console.log(`Success, array-length: ${ary.length}.`);
    

    These are extreme examples, but they make a point about delete that I haven't seen anyone mention anywhere.

    0 讨论(0)
  • 2020-11-21 06:13

    OK, imagine we have this array below:

    const arr = [1, 2, 3, 4, 5];
    

    Let's do delete first:

    delete arr[1];
    

    and this is the result:

    [1, empty, 3, 4, 5];
    

    empty! and let's get it:

    arr[1]; //undefined
    

    So means just the value deleted and it's undefined now, so length is the same, also it will return true...

    Let's reset our array and do it with splice this time:

    arr.splice(1, 1);
    

    and this is the result this time:

    [1, 3, 4, 5];
    

    As you see the array length changed and arr[1] is 3 now...

    Also this will return the deleted item in an Array which is [3] in this case...

    0 讨论(0)
提交回复
热议问题