“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

The title

Recently, my friend met several video interviews in Dachang, which required handwritten pen questions. The first time was quick hand, and the topic required: decorate the array push method, requiring that the original function cannot be changed, and print the “push” example:

let arr = [1.2.3]
console.log(arr.push(4))

// Console print:
/ / "push"
/ / 4
Copy the code

Train of thought

The goal of this problem is to get you to rewrite the native Array push method and add some custom logic. The first reaction is to implement the push method on the Array prototype and override the native push method.

Array.prototype.push = function() {
    console.log("push");
    for( let i = 0; i < arguments.length; i++){
	this[this.length] = arguments[i] ;
    }
    return this.length;
}

let arr = [1.2.3]
console.log(arr.push(4))
Copy the code

Results after printing in browser:

It can be seen that although the effect is achieved, the original push function is destroyed, and there is an unexpected infinite loop. Push will print all the time. At this moment, the interviewer asks whether the original push function can be achieved without changing

So I came up with the idea of storing a copy of the original push method:

let _push = Array.prototype.push
Array.prototype.push = function() {
    console.log('push')
    return _push.apply(this.arguments)}var a = [1.2.3]
a.push(1)
Copy the code

Although this is also implemented, the same endless loop as above occurs, printing push frantically

Suddenly, I understood what the interviewer meant

In fact, the interviewer wants to investigate is vUE source code on the array method of responsive processing we can be based on the idea of processing the array method to achieve

The following is the correct solution:

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);

['push'.'pop'.'shift'.'unshift'].forEach(function(method) {
    arrayMethods[method] = function() {
        console.log('push') // Print push to update the view
        return arrayProto[method].apply(this.arguments)}})let a = [1.2.3]
a.__proto__ = arrayMethods  / / key

console.log(a.push(44));
Copy the code

Ideas:

  1. First save the Array prototype, then create a new object __proto__ pointing to the Array prototype
  2. The second step is to give a new method called push to the new object and do whatever you want in the new method, like update the view. Then go back and execute the native push and other methods that you just stored
  3. Finally, we can point __proto__ of our array to the new object

So when we do the push method, along the prototype chain is the push method in our new object, for decoration

Github vue2. X handles array methods with a few dozen lines of code: observer/array.js

conclusion

Often read source code, you will have a different harvest, but also learn more advanced way of thinking