Sometimes, we want to add getters and setters dynamically to a JavaScript object.
In this article, we’ll look at how to implement dynamically getters and setters with JavaScript.
Use a Proxy
JavaScript comes with the Proxy
constructor to let us create an object that is a facade on another object.
For instance, we can add a dynamic getter to it by writing:
const original = {
"foo": "bar"
};
const proxy = new Proxy(original, {
get(target, name, receiver) {
let rv = Reflect.get(target, name, receiver);
if (typeof rv === "string") {
rv = rv.toUpperCase();
}
return rv;
}
});
console.log(original.foo)
console.log(proxy.foo);
We create the original
object with the foo
property.
Then we use the Proxy
constructor to create a proxy with the original
object.
And we pass it an object with the get
method to get the property we want to modify the return value for with the Reflect.get
method.
Ir returns the value from the original
object with the property name set to name
.
And we return rv
as upper case if the rv
return value is a string.
Therefore, the first console log logs 'bar'
, but the second one logs 'BAR'
.
We can add a setter by adding the set
method into the object we pass in as the 2nd argument of the Proxy
constructor.
For instance, we can write:
const original = {
"foo": "bar"
};
const proxy = new Proxy(original, {
get(target, name, receiver) {
let rv = Reflect.get(target, name, receiver);
if (typeof rv === "string") {
rv = rv.toUpperCase();
}
return rv;
},
set(target, name, value, receiver) {
if (!Reflect.has(target, name)) {
console.log(`Setting non-existent property '${name}', initial value: ${value}`);
}
return Reflect.set(target, name, value, receiver);
}
});
proxy.baz = 'abc'
console.log(original.foo)
console.log(proxy.foo);
We add the set
method that lets us modify how the properties of the original
object is modified.
We call the Reflect.has
method to check if the original
object has the property name
.
If it doesn’t, we log a message.
Otherwise, we call Reflect.set
to set the name
property to the given value
and return the result.
Therefore, when we try to set the proxy.baz
property, we get:
'Setting non-existent property ‘baz’, initial value: abc’
And the rest of the console logs are the same as before.
Conclusion
We can use JavaScript proxies to modify getters and setters the way we want.