Summary of the content

  • Object.defineproperty intercepts tests
  • Proxy interception test
  • conclusion

If you’re familiar with Vue and curious, you’ll want to know how reactive Vue is implemented. To understand how reactive Vue works, you need to understand the Object.defineProperty and Proxy apis. Write test examples for both apis and see what happens.

Object.defineproperty intercepts tests


Common code

let hero = {
        name: 'zhaoyun'.hp: 100.sp: 100.equipment: ['the horse'.'long']}Object.keys(hero).forEach(key= > {
        let internalValue = hero[key]
        Object.defineProperty(hero, key, {
            get() {
                console.log(`getting key "${key}": ${internalValue}`)
                return internalValue
            },
            set(newValue) {
                console.log(`setting key "${key}": ${internalValue} -> ${newValue}`)
                internalValue = newValue
            }
        })
})
Copy the code

Test 1: Modify object -string field to intercept test

  • Code:

    console.log("------ modified: object -string field, intercept test ------");
    hero.name = "吕布"
    console.log('Result after change:${hero.name}`);
    Copy the code
  • Output result:

  • Conclusion: Object-plain field modifications can be intercepted by get sets

Test 2: Modify object – array type field, add element, intercept test

  • Code:

    console.log("------ Modified: Object - array type field, new element, interception test ------");
    hero.equipment.push("Armor");
    console.log('Result after change:${hero.equipment}`);
    Copy the code
  • Output result:

  • Conclusion: Object – array field new element, can be intercepted by GET, cannot be intercepted by set

Test 3: Modify objects – Add fields, intercept tests

  • code

    console.log("------ Modified: Object - Add field, intercept test ------");
    hero.age = 23;
    console.log('Result after change:${hero.age}`);
    Copy the code
  • The output

  • Conclusion: Object – add field, cannot be intercepted by get set

Test 4: Modify objects – Remove fields and intercept tests

  • code

    console.log("------ Modify: object - Delete field, intercept test ------");
    delete hero.name;
    console.log('Result after change:${hero.name}`);
    Copy the code
  • The output

  • conclusion

Test 5: Modify array type fields, add elements, intercept tests

  • code

    Object.defineProperty(hero.equipment, 'push', {
            value() {
                console.log(`value The ${this} -  The ${arguments[0]}`)
                this[this.length] = arguments[0]}});console.log("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- part 2: object - array value to intercept test -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
    console.log("------ Modified: Array type field, new element, interception test ------");
    console.log('Current equipment:${hero.equipment}`);
    hero.equipment.push("Armor");
    console.log('Added [armor] after equipment:${hero.equipment}`);
    Copy the code
  • The output

  • Conclusion: You can use value interception to object – array field element subtraction

Proxy interception test


Common code:

let hero = {
        name: 'zhaoyun'.hp: 100.sp: 100.equipment: ['the horse'.'long']}let handler = {
    get: function (target, key, receiver) {
        let value = Reflect.get(target, key, receiver)
        console.log(`getting key "${key}": ${value}`)
        return value;
    },
    set: function (target, key, value, receiver) {
        let oldValue = Reflect.get(target, key, receiver);
        const result = Reflect.set(target, key, value, receiver);
        console.log(`setting key "${key}": ${oldValue} -> ${value}  result:${result}`)
        return result
    }
}

let heroProxy = new Proxy(hero, handler);
Copy the code

Test 1: Modify the object string field to intercept the test

  • code

    console.log("------ Modified: Object string field, intercept test ------");
    heroProxy.name = "吕布"
    console.log('Result after change:${heroProxy.name}`);
    Copy the code
  • The output

  • Conclusion: Object-plain field modifications can be intercepted by get sets

Test 2: Modify object array type field, add element, intercept test

  • code

    console.log("------ Modified: Object array type field, new element, interception test ------");
    heroProxy.equipment.push("Armor");
    console.log('Result after change:${heroProxy.equipment}`);
    Copy the code
  • The output

  • Conclusion: Object – array field new element, can be intercepted by GET, cannot be intercepted by set

Test 3: Modify objects – Add fields, intercept tests

  • code

    console.log("------ Modified: Object - Add field, intercept test ------");
    heroProxy.age = 23;
    console.log('Result after change:${heroProxy.age}`);
    Copy the code
  • The output

  • Conclusion: Object – add field, can be intercepted by set

Test 4: Modify objects – Remove fields and intercept tests

  • code

    console.log("------ Modify: object - Delete field, intercept test ------");
    delete heroProxy.name;
    console.log('Result after change:${heroProxy.name}`);
    Copy the code
  • The output

  • Conclusion: Object-deleted fields can be intercepted by GET

Test 5: Modify: object array type field

  • code

    let heroProxyArray = new Proxy(hero.equipment, handler);
    console.log("------ Modified: Object array type field, new element, interception test ------");
    console.log('Current Equipment:');
    console.log(heroProxyArray);
    
    heroProxyArray.push("Knife");
    
    console.log(Added [Dagger] after Equipment: ');
    console.log(heroProxyArray);
    Copy the code
  • The output

  • Conclusion: You can easily intercept array changes using proxy


Demo source: vue-principle-learn

In the future, I will update the learning materials and demo related to vUE principle to this warehouse. Welcome star to collect ~

Conclusion:

  • Object.defineProperty
    • Disadvantage 1: Only existing attributes of the object can be traversed and get set interception cannot be performed for new or deleted elements
    • Disadvantage 2: Array interception requires interception of push, shift, POP, and unshift, which is complicated
  • Proxy
    • Advantage 1: New and deleted fields can be easily intercepted
    • Advantage 2: Array interception is the same as object property GET set interception. No special processing is required

reference

  • Practice ES6 Proxy & Reflect
  • how-to-watch-for-array-changes

Above: If you find any problems, welcome to point out the message, I timely correction