“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:
- First save the Array prototype, then create a new object __proto__ pointing to the Array prototype
- 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
- 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