Skip to main content

Why Vue3 uses Proxy instead of Object.defineProperty?

ยท 3 min read

As we all know, Vue3 uses Proxy instead of Object.defineProperty() to listen for property changes. so what's the difference between the two? Now let's compare the differences by coding.

Object.definePropertyโ€‹

Object.defineProperty() defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

Syntaxโ€‹

Object.defineProperty(obj, prop, descriptor);

Let's focus on the third parameter description. description allow us to intercept the get and set methods of object properties.

Take a simple example.

let o = {};
let bValue = "bValue";
Object.defineProperty(o, "b", {
// when `b` is accessed, return bValue
get() {
console.log("get o.b value");
return bValue;
},
set(newValue) {
console.log("set o.b value");
bValue = newValue;
},
enumerable: true,
configurable: true,
});
console.log(o.b); // get o.b value
o.b = "newValue"; // set o.b value

We can see that using the defineProperty() method, we successfully listen on the o.b property. But this method has the following disadvantages.

  • Cannot listen for array changes
  • Each property of the object must be traversed
  • Nested objects must be traversed deeply

Proxyโ€‹

The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.

Now we use the Proxy object to implement listening on the properties of the o object above.

let o = {};
const oProxy = new Proxy(o, {
get(target, property, receiver) {
console.log(`get ${property}`);
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log(`set ${property}`);
return Reflect.set(target, property, value, receiver);
},
});
const bVal = oProxy.b; // get b
oProxy.b = "newValue"; // set b

As you can see, using Proxy to intercept the get and set methods of objects is very simple, and we can intercept arbitrary properties of objects without using looping.

oProxy.otherProperty = "otherValue"; // set otherProperty

Now let's try using Proxy to listen for changes in the subscript values of the array.

let arr = [1, 2, 3];
const arrProxy = new Proxy(arr, {
get(target, property, receiver) {
console.log(`get ${property}`);
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log(`set ${property}`);
return Reflect.set(target, property, value, receiver);
},
});
arrProxy[0] = 10; // set 0
arrProxy[6] = 20; // set 6

Wow, very cool!!! Proxy makes it easy to listen for changes in array subscripts. ๐Ÿ‘

Summaryโ€‹

Vue3 use of Proxy is a step forward. It is a new improvement in performance. I'm sure you can't wait to upgrade Vue3, so just do it now!