This is the fifth day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021
Responsive system is a well-known important feature in Vue, and some problems are also talked about by developers. For example, the special handling of arrays is a typical problem. When asked why Vue needs special handling of arrays, some people answer: Object.defineproperty can only hijack objects and cannot touch arrays, so arrays need to be handled specially
Before we reveal the answer, let’s take a look at a simple version of the reactive implementation
Object.defineProperty
It is well known that one of the cores of responsiveness in Vue is Object.defineProperty, which directly defines a new property on an Object or modifies an existing property of an Object and returns the Object
Grammar:
Object.defineProperty(obj, prop, descriptor)
Copy the code
- Obj: Object for which attributes are to be defined
- Prop: The name or name of the property to define or modify
Symbo
- Descriptor: Property descriptor to define or modify
The data was hijacked
Next go directly to the code, the core code has been commented
/** * data hijacking */
const defineReactive = (data, key, value) = > {
// Recursive hijacking of data
observe(value);
Object.defineProperty(data, key, {
get() {
console.log("get");
return value;
},
set(newValue) {
console.log("set");
// If the data does not change, no processing
if (newValue === value) return;
// Recursive hijacking of data: Continue hijacking if the newly assigned data is an objectobserve(newValue); value = newValue; }}); };/** * is used to process data */
const observe = (data) = > {
// No objects need to be processed
if (typeofdata ! = ="object"| |! data) {return data;
}
// Iterate over the object
Object.keys(data).forEach((key) = > {
defineReactive(data, key, data[key]);
});
};
Copy the code
Next you define the data to hijack
const obj = {
arr: [1.2.3].name: "nordon".info: {
age: 12,}};Copy the code
Hijacking of data
observe(obj);
Copy the code
First verify the effect of hijacking regular data
obj.name;
obj.name = "wy";
obj.info.age = 18
Copy the code
The console outputs get, set, get, set
Let’s see if we have a hijacking effect on the array
obj.arr.unshift(4);
Copy the code
The above code changes the length of the ARR, adds a bit of data to its header, and fires multiple GET and set sets. This proves that object.defineProperty can be used to jack the data of an array. Therefore, for the special processing of arrays in Vue, Not because Object.defineProperty cannot hijack arrays, but because it overwrites the methods of seven arrays for performance reasons.