I have this code in js bin:
var validator = {
set (target, key, value) {
console.log(target);
console.log(key);
console.log(value);
if(isObject(target[key])){
}
return true
}
}
var person = {
firstName: "alfred",
lastName: "john",
inner: {
salary: 8250,
Proffesion: ".NET Developer"
}
}
var proxy = new Proxy(person, validator)
proxy.inner.salary = 'foo'
if i do proxy.inner.salary = 555;
it does not work.
However if i do proxy.firstName = "Anne"
, then it works great.
I do not understand why it does not work Recursively.
http://jsbin.com/dinerotiwe/edit?html,js,console
Nested objects are objects that are inside another object. You can create nested objects within a nested object. In the following example, Salary is an object that resides inside the main object named Employee . The dot notation can access the property of nested objects.
Creating Nested Objects in JavaScript Dynamically In ES6, Objects can be created with computed properties. To use a “dynamic” key, you have to use bracket notation: Iterate through the elements of basis . Use the keys to find the corresponding element in nested , and use that as the key in the new object being created.
The Proxy object allows you to create an object that can be used in place of the original object, but which may redefine fundamental Object operations like getting, setting, and defining properties. Proxy objects are commonly used to log property accesses, validate, format, or sanitize inputs, and so on.
A proxy allows you to perform meta-programming operations such as intercepting a call to inspect or change an object's property. The original object the proxy will virtualize.
You can add a get
trap and return a new proxy with validator
as a handler:
var validator = { get(target, key) { if (typeof target[key] === 'object' && target[key] !== null) { return new Proxy(target[key], validator) } else { return target[key]; } }, set (target, key, value) { console.log(target); console.log(key); console.log(value); return true } } var person = { firstName: "alfred", lastName: "john", inner: { salary: 8250, Proffesion: ".NET Developer" } } var proxy = new Proxy(person, validator) proxy.inner.salary = 'foo'
A slight modification on the example by Michał Perłakowski with the benefit of this approach being that the nested proxy is only created once rather than every time a value is accessed.
If the property of the proxy being accessed is an object or array, the value of the property is replaced with another proxy. The isProxy
property in the getter is used to detect whether the currently accessed object is a proxy or not. You may want to change the name of isProxy
to avoid naming collisions with properties of stored objects.
Note: the nested proxy is defined in the getter rather than the setter so it is only created if the data is actually used somewhere. This may or may not suit your use-case.
const handler = { get(target, key) { if (key == 'isProxy') return true; const prop = target[key]; // return if property not found if (typeof prop == 'undefined') return; // set value as proxy if object if (!prop.isProxy && typeof prop === 'object') target[key] = new Proxy(prop, handler); return target[key]; }, set(target, key, value) { console.log('Setting', target, `.${key} to equal`, value); // todo : call callback target[key] = value; return true; } }; const test = { string: "data", number: 231321, object: { string: "data", number: 32434 }, array: [ 1, 2, 3, 4, 5 ], }; const proxy = new Proxy(test, handler); console.log(proxy); console.log(proxy.string); // "data" proxy.string = "Hello"; console.log(proxy.string); // "Hello" console.log(proxy.object); // { "string": "data", "number": 32434 } proxy.object.string = "World"; console.log(proxy.object.string); // "World"
I published a library on GitHub that does this as well. It will also report to a callback function what modifications have taken place along with their full path.
Michal's answer is good, but it creates a new Proxy
every time a nested object is accessed. Depending on your usage, that could lead to a very large memory overhead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With