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 modifySymbo
  • 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.