Previous articleIn this article, we introduce the monitoring of defineProperty on objects. In this article, we will look at the monitoring of defineProperty on arrays.
Changes in arrays
Let us first understand the tracking of array changes ():
var a={}; bValue=1; (a,"b",{ set:function(value){ bValue=value; ("setted"); }, get:function(){ return bValue; } }); ;//1 =[];//setted =[1,2,3];//setted [1]=10;//No output(4);//No output=5;//No output;//[1,10,3,4,undefined];
You can see,When set to an array, as long as a new array object is not reassigned, any modifications to the internal array will not trigger the execution of the setter method.. This is very important because data bidirectional binding implemented by modern front-end frameworks based on the () method also cannot recognize such array changes. Therefore, the first point is that if you want to trigger bidirectional binding of data, we should not use arr[1]=newValue; to implement it; the second point is that the framework also provides many methods to implement bidirectional binding of arrays.
For how the framework implements monitoring of array changes, in most cases, the framework will rewrite the method and generate a new array to assign value to the data, so that the two-way binding of the data will be triggered.
Implement simple listening to changes in arrays
var arrayPush = {}; (function(method){ var original = [method]; arrayPush[method] = function() { // This pointer can be seen through the test below (this); return (this, arguments) }; })('push'); var testPush = []; testPush.__proto__ = arrayPush; // Through the output, you can see that this mentioned above points to testPush// [] (1); // [1] (2);
In the official documentation, only 7 methods need to be monitored: push(), pop(), shift(), unshift(), splice(), sort(), and reverse(). We can go through it:
var arrayProto = var arrayMethods = (arrayProto) ;[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ].forEach(function(item){ (arrayMethods,item,{ value:function mutator(){ //Cache native method and call it later ('array is visited'); var original = arrayProto[item] var args = (arguments) (this,args) // (this); }, }) })
Complete code
function Observer(data){ = data; (data); } var p = ; var arrayProto = var arrayMethods = (arrayProto) ;[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ].forEach(function(item){ (arrayMethods,item,{ value:function mutator(){ //Cache native method and call it later ('array is visited'); var original = arrayProto[item] var args = (arguments) (this,args) // (this); }, }) }) = function(obj){ var value; for(var key in obj){ // Filter out the properties owned by an object through hasOwnProperty if((key)){ value = obj[key]; // Recursive call loops out all objects if(typeof value === 'object'){ if ((value)) { var augment = value.__proto__ ? protoAugment : copyAugment augment(value, arrayMethods, key) observeArray(value) } new Observer(value); } (key, value); } } }; = function(key, value){ (, key, { enumerable: true, configurable: true, get: function(){ (key + 'Accessed'); return value; }, set: function(newVal){ (key + 'Modified, new' + key + '=' + newVal); if(newVal === value) return ; value = newVal; } }) }; var data = { user: { // name: 'zhangsan', age: function(){(1)} }, apg: [{'a': 'b'},2,3] } function observeArray (items) { for (var i = 0, l = ; i < l; i++) { observe(items[i]) } } //Dull data Observerfunction observe(value){ if(typeof(value) != 'object' ) return; var ob = new Observer(value) return ob; } //Auxiliary methodfunction def (obj, key, val) { (obj, key, { value: val, enumerable: true, writable: true, configurable: true }) } // Compatible with methods that do not support __proto__//Reassign the __proto__ attribute of Arrayfunction protoAugment (target,src) { target.__proto__ = src } //Do not support __proto__'s direct modification of related attributes methodfunction copyAugment (target, src, keys) { for (var i = 0, l = ; i < l; i++) { var key = keys[i] def(target, key, src[key]) } } var app = new Observer(data); // [2] = 111; (5); // [0].a = 10; // ();
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.