4

In Vue2 and 3, defineProperty and Proxy are both used to implement reactive data binding. The functions implemented are similar, but the two APIs are essentially different.

  1. monitoring data

    1. defineproperty can only monitor a certain attribute but not the entire object.
    2. proxy does not need to set specific properties, and directly monitors the entire object.
    3. defineproperty listener needs to know which attribute of which object, while proxy only needs to know which object. That is, the for in cycle will be omitted to improve efficiency.
  2. monitoring on the original object

    1. Because defineproperty is a monitoring effect achieved by adding or modifying attributes to the original object to add descriptors, the original data will definitely be modified.
    2. And proxy is just a proxy of the original object, proxy will return a proxy object without changing the original object, and no pollution to the original data.
  3. realizes the monitoring of the array

    1. Because of the particularity of the length (length descriptors configurable and enumerable are false, and if you try to modify configurable to True, js will directly report an error: VM305:1 Uncaught TypeError: Cannot redefine property: length)
    2. defineproperty can’t monitor the array length change, Vue can only realize the monitoring effect by rewriting the array method. The rewriting array method still cannot solve the problem of monitoring when modifying the array index. You can only use the custom $set method.
    3. proxy because of its own characteristics, is to create a new proxy object instead of monitoring properties on the original data. When operating on the proxy object, all operations will be captured, including array methods and length operations. There is no need to rewrite array methods and self Define the set function. (Code example below)

    4. Monitoring range

    1. defineproperty can only listen to value of get set change.
    2. proxy can monitor all JS object operations [[getOwnPropertyNames]] (See the link below) The monitoring range is larger and more comprehensive.

Click to view the object operation methods supported by the proxy to monitor (except getOwnPropertyNames)

Proxy monitor array change example:

let array = ['1', '2']
let arrayProxy = new Proxy(array, {
    get(target, key) {
        console.log('(key:', key + ") 发生了get操作")
        return target[key]
    },
    set(target, key, value) {
        console.log('(key:', key + ") 发生了set操作, value= " + value)
        return target[key] = value
    }
})
arrayProxy.push('我是push函数push到数组中的值')

// (key: push) 发生了get操作
// (key: length) 发生了get操作
// (key: 2) 发生了set操作, value= 我是push函数push到数组中的值
// (key: length) 发生了set操作, value= 3

// 从log可以看出push length等操作都被捕捉了

海洋饼干
1.5k 声望191 粉丝