I'm wondering if it's possible to have a setter for a dynamic property in Javascript ?
So this:
var myobj = new MyObj();
myobj.a_custom_prop = 'something';
Would call a function being able to retrieve 'a_custom_prop' and 'something'
To be clear, I would like a function similar to:
MyObj.property.define = function (prop, value) { };
to be called like this:
myobj.prop = value;
instead of:
myobj.define('prop', value);
Knowing that the name of the property is not static relative to myobj
, otherwise I would have used:
Object.defineProperty(MyObj.prototype, 'a_custom_prop', {
set: function (value) { /*...*/ }
});
What you want is similar to method missing
in Ruby, where you define a function that will handle calls to undefined methods.
As you can read here: Does Javascript have something like Ruby's method_missing feature? JavaScript doesn't have something similar yet, but there is a proposal for ES6: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
As Yoshi stated in a comment, it could be possible using Object.observe()
from the ES7 draft.
However it's not exactly a "catch-all setter" because it will only be triggered after the property changed, not before. So, if for example you want to store the property somewhere else, you will have to delete
it. Since the observe
callback is asynchronous, it will be ran after the current callstack, meaning the new value can be immediately used before being altered.
Also, Chrome only for now.
The following snippet does some manipulations on the object through native setting and using Object.observe
. It logs in the following order:
Here goes:
var foo = {};
Object.observe(foo, function(changes) {
var lastChanges = changes[changes.length - 1],
newValue = lastChanges.object[lastChanges.name];
console.log('The callback retrieves: ' + newValue);
delete lastChanges.object[lastChanges.name];
}, ['add']);
foo.bar = 'foobar'; //Log n°2
console.log('I added this value: ' + foo.bar); //Log n°1
setTimeout(function() {
console.log('Value of foo.bar after deletion: ' + foo.bar); //Log n°3
}, 0); //Execute after the observe callback
Due to the fact that it's in the ES7 draft, the previous might be completely wrong depending on when you read this.
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