Splice knows the basics

Array provides a lot of methods to use in JavaScript, and splice is one of the methods we use most often.

To implement a splice method, let’s first look at the splice definition and usage

Define vs usage: the splice() method adds and deletes items from an array, and then returns the deleted items.

Grammar arrayObject. Splice (index, howmany, item1,… ,itemX)

parameter describe
index A necessity. Integer to specify where items are added/removed, and negative numbers to specify positions from the end of the array.
howmany A necessity. Number of items to delete. If set to 0, the project will not be deleted.
item1, … , itemX Optional. The new item added to the array.
The return value describe
Array Contains a new array of deleted items, if any.

Tips: The splice() method is different from the slice() method in that splice() directly makes changes to the array.

With the basic concepts of the Splice method clear, let’s first try to implement a simplified version

  1. Copy the deleted element
  2. Moves the element after the deleted element
  3. Insert new elements
      //splice
      Array.prototype.splice = function (startIndex, deleteCount, ... addElements) {
        let argumentLen = arguments.length;
        let array = Object(this);
        let len = array.length;
        let deleteArr = new Array(deleteCount);

        // Copy the deleted element
        sliceDeleteElements(arra, startIndex, deleteCount, deleteArr);
        // Move the element after the deleted element
        movePostElements(array, startIndex, len, deleteCount, addElements);
        // Insert a new element
        for (let i = 0; i < addElements.length; i++) {
          array[startIndex+i] = addElements[i];
        }
        array.length = len - deleteCount + addElements.length;
        return deleteArr;
      };
Copy the code

Copy the deleted element

    const sliceDeleteElements = (array, startIndex, deleteCount, deleteArr) = > {
        for(let i = 0; i<deleteCount; i++){let index = startIndex + i
          if(index in array) {
            letcurrent = array[index]; deleteArr[i] = current; }}}Copy the code

Moves the element after the deleted element

  • The number of elements added is equal to the number of elements removed
  • The number of added elements is greater than that of deleted elements
  • The number of added elements is smaller than that of deleted elements
// Move the element after the deleted element
      / / is equal
      const movePostElements = (array, startIndex, len, deleteCount, addElements) = > {
        if (deleteCount === addElements.length) return;
      };
      / / less than
      const movePostElements = (array, startIndex, len, deleteCount, addElements) = > {
        if (deleteCount > addElements.length) {
          // More elements are deleted than added, and the following elements are moved forward
          // We need to move len-startindex-deletecount
          for (let i = startIndex + deleteCount; i < len; i++) {
            let formIndex = i;
            // The target position to be moved
            if (formIndex in array) {
              array[toIndex] = array[formIndex];
            } else {
              deletearray[toIndex]; }}}// The current length is len + addElements -deletecount
        for (let i = lem - 1; i > len + addElements.length - deleteCount; i--) {
          deletearray[i]; }};// Add is greater than delete
      const movePostElements = (array, startIndex, len, deleteCount, addElements) = > {
        if (deleteCount < addElements.length) {
          // The number of deleted elements is smaller than the number of new elements
          for(let i = len - 1; i>=startIndex+deleteCount; i--){let formIndex  = i;
            // The target position to be moved
            let toIndex = i + (addElements.length -deleteCount);
            if(formIndex in apply){
              array[toIndex] = array[formIndex];
            } else{
              delete array[toIndex]
            }
          }
        }
Copy the code

Preventing incorrect array boundary values (arguments) from being passed by the user

      // Handle unsolicited startIndex, deletecount from the user.
      const computeStartIndex = (startIndex, len) = > {
        if (startIndex < 0) {
          return startIndex + len > 0 ? startIndex + len : 0
        }
        return startIndex >= len ? len : startIndex
      }
      // Delete numeric processing
      const computeDeleteCount = (startIndex,len,deleteCount,argumentLen) = > {
        if(arguments.length === 1) {return len - startIndex
        }
        if(deleteCount < 0) return 0;
        if(deleteCount > len - deleteCount) return len - startIndex;
        return deleteCount
      }
Copy the code

Do this if the array is read-only or immutable

  • Sealed object: an object that is non-extensible and can be modified without any additional or deleted mode. The property of the object is false
  • Frozen object: Property values cannot be modified on the basis of sealed objects
    if(Object.isSealed(array) && deleteCount ! == addElements.length){throw new Error ('this object is a sealed object')}else if(Object.isFrozen(array) && (deleteCount > 0 || addElements.length > 0)) {throw new Error ('this object is a Frozen object')}Copy the code

Enter the front end door, a cabbage, record their learning path, hope to inspire themselves, hope we can lightly spray, there are wrong places can be pointed out that will be changed in time to Ao! Thank you for your attention

Reference: Sanyuan Dashen blog (highly recommended)

V8 array splice source code

w3 School JavaScript plice

MDN document Array Splice