This is the 28th day of my participation in the August Text Challenge.

The array methods are push, POP, Slice, Map, and Reduce

Push the implementation of the

Array.prototype.push = function(. items) {
        let O = Object(this); Ecma refers to converting to objects first
        let len = this.length >>> 0;
        let argCount = items.length >>> 0;
        // 2 ^ 53-1 is the largest positive integer that JS can represent
        if (len + argCount > 2六四屠杀53 - 1) {
        throw new TypeError("The number of array is over the max value")}for(let i = 0; i < argCount; i++) {
            O[len + i] = items[i];
        }
        let newLength = len + argCount;
        O.length = newLength;
        return newLength;
}
Copy the code

As can be seen from the above code, the key point is to add a new element item to the loop of the array itself, and then adjust the length of the array to the latest length to complete the low-level implementation of push.

The length part needs to be unsigned, which you’ll see in a lot of source code. You can do your own research on why some variables are unsigned, for example, there are some high-vote answers on Stack Overflow that won’t take up space here. Let’s look at the implementation of POP again.

The low-level implementation of the POP method

Array.prototype.pop = function() {
    let O = Object(this);
    let len = this.length >>> 0;
    if (len === 0) {
        O.length = 0;
        return undefined;
    }
    len --;
    let value = O[len];
    delete O[len];
    O.length = len;
    return value;
}
Copy the code

The idea is to delete the len length of the array itself, update the len length, and return the value of the element. In addition, when the length is 0, if the pop operation returns undefined, you need to do something special.

Having looked at the pop implementation, let’s look at the underlying logic of the Map method.

The underlying implementation of the Map method

Array.prototype.map = function(callbackFn, thisArg) {
    if (this= = =null || this= = =undefined) {
    throw new TypeError("Cannot read property 'map' of null");
    }
    if (Object.prototype.toString.call(callbackfn) ! ="[object Function]") {
    throw new TypeError(callbackfn + ' is not a function')}let O = Object(this);
    let T = thisArg;
    let len = O.length >>> 0;
    let A = new Array(len);
    for(let k = 0; k < len; k++) {
    if (k in O) {
      let kValue = O[k];
      // Pass this, the current item, the current index, the entire array
      letmappedValue = callbackfn.call(T, KValue, k, O); A[k] = mappedValue; }}return A;
}
Copy the code

The mappedValue is assigned to A newly defined array A, and the new array A is returned without changing the value of the original array.

The low-level implementation of the Reduce method

Array.prototype.reduce = function(callbackfn, initialValue) {

// Exception handling, similar to map

if (this= = =null || this= = =undefined) {
throw new TypeError("Cannot read property 'reduce' of null");
}

// Handle callback type exceptions

if (Object.prototype.toString.call(callbackfn) ! ="[object Function]") {
throw new TypeError(callbackfn + ' is not a function')}let O = Object(this);
let len = O.length >>> 0;
let k = 0;
let accumulator = initialValue; // The second argument to the reduce method is the initial value of the accumulator
if (accumulator === undefined) {
  throw new Error('Each element of the array is empty');
  // The initial value is not passed
for(; k < len ; k++) {
  if (k in O) {
    accumulator = O[k];
    k++;
    break; }}}for(; k < len; k++) {if (k in O) {
  // Note the core accumulator of Reduce
  accumulator = callbackfn.call(undefined, accumulator, O[k], O); }}return accumulator;

}
Copy the code