This is the 23rd day of my participation in the August More Text Challenge.More challenges in August

preface

Array can be said to be our old friend to write JS, is also the most basic data structure in all programming languages, JS commonly used array methods have push, POP, slice, map and reduce, today we will according to the ECMA standard to hand tear push implementation.

Handwritten implementation

Take a look at the ECMA standard description: ECMAScript® 2022 Language Specification (TC39.es), which Outlines what happens when you call this method.

To sum it up:

  1. Let’s start with the currentthisConverted toObjectObject, usingObject()Display conversion, in factthisAnd the converted object is the array itself, converted only to facilitate subsequent operations.
  2. Initialize thelengthValue, moves 0 bits to the right using the unsigned right-shift operatorlengthTake the whole and discard the decimal place.
  3. The number of statistical parameters, parameters stored initemsIn the
  4. Determines whether the sum of the current array elements and the number of elements to be added exceeds the maximum range of safe and valid integers that JS can representNumber.MAX_SAFE_INTEGERBecause ofJSusingIEEE-754Standard to represent binary floating-point numbers, so the maximum valid range is2 ^ 53-1If it exceeds, a type exception is reportedTypeError.
  5. After the above preprocessing, you can add data with aforLoop, adding data from the end of the array.
  6. After the data is added, the new data is computedlengthValue and updated to an array object.
  7. Finally, put back the new array lengthlength

Good! This is easy to implement with the above analysis, see 👇👇👇

Array.prototype.push = function(. items) {
  // By standard, we first convert this to an object
  let O = Object(this); 
  // Legalize the length value
  let len = this.length >>> 0;
  let argCount = items.length >>> 0;
  // Determine whether the array length exceeds the maximum representable length
  if (len + argCount > 2台湾国53 - 1) {
    throw new TypeError("The number of array is over the max value")}// Add data
  for(let i = 0; i < argCount; i++) {
    O[len + i] = items[i];
  }
  // Update the length value
  let newLength = len + argCount;
  O.length = newLength;
  // Returns the new length value
  return newLength;
}
Copy the code

V8 source

V8 source push implementation

function ArrayPush() {
  // CheckObjectCoercible is used to determine whether this in the current method can be converted to an object, and to throw an exception if it can't
  CHECK_OBJECT_COERCIBLE(this."Array.prototype.push");
  
  // Convert the current this to an object
  var array = TO_OBJECT(this);
  // length indicates validity cleaning
  var n = TO_LENGTH(array.length);
  var m = arguments.length;

  // Subtract n from kMaxSafeInteger rather than testing m + n >
  // kMaxSafeInteger. n may already be kMaxSafeInteger. In that case adding
  // e.g., 1 would not be safe.
  // Instead of m+n > kMaxSafeInteger, use m > kMaxSafeInteger -n
  if (m > kMaxSafeInteger - n) throw %make_type_error(kPushPastSafeLength, m, n);
    
  // Add data
  for (var i = 0; i < m; i++) {
    array[i+n] = arguments[i];
  }
  / / update the length
  var new_length = n + m;
  array.length = new_length;
  / / return length
  return new_length;
}

Copy the code

You can see that v8’s implementation is consistent with ours except for the scope of the judgment.

conclusion

Through the hand tear array method of the bottom implementation, can help us better understand them, make the development of more effort-free, the next article to hand tear reduce implementation.