Reputation:
Probably not the correct word. But I want to create a new type in JavaScript. It would have the simple property that one could do this:
var inst = new SomeType();
inst.key1.key2 = 'something';
inst.key1.key1.key3 = 'something';
Basically you wouldn't have to declare an object literal to extend further. It would create one automatically.
This would allow me to build complex structures without having to worry about checking for the existence of a property to extend off of.
Instead of doing
inst.key1 = {};
inst.key1.key2 = 'data';
one could just do
inst.key1.key2 = 'data';
and the
inst.key1 = {};
would be automatic, i.e. would happen internally.
This does have a practical purpose. Particularly I have a registry pattern which I would use this new type to organize data using a more hierarchical approach.
Also, I see a pattern, common in libraries, that tests for the existence of an object literal and then creates one if it does not exist.
This is a common idiom it seems.
Upvotes: 6
Views: 259
Reputation:
Because javascript does not support operator overloading, one could create a really ugly fake operator called ._
as such. If someone wants to implement ._
please edit answer.
var Obj = function () {
this.hold = {};
};
Obj.prototype._ = function (key) {
//implement here;
return this;
};
var obj = new Obj();
obj._('key1')._('key2')._('key3') = 'barbarella';
console.log(test);
Upvotes: 0
Reputation: 348992
What you'd like to get can easily be achieved with Harmony proxies (MDN). However, this API is not yet stable, so it's fine to use it in non-critical hobby code, but don't use it in production code (yet).
Here's an extremely simple example:
function getFreeChain(object) {
var handler = {
get: function(target, name) {
if (name in target)
return target[name];
var newTarget = target[name] = {};
return new Proxy(newTarget, handler);
}
};
return new Proxy(object, handler);
}
// Usage:
var obj = {};
var magicalObj = getFreeChain(obj);
magicalObj.a.b.c.d.e.g = 1;
console.log(magicalObj.a.b.c.d.e.g); // 1
console.log(obj.a.b.c.d.e.g); // 1
obj.x.y.z = 1; // TypeError: obj.x is undefined
Note: My example is an implementation of the latest Proxy
specification, which is only supported by Firefox .
Chrome only supports an old, significantly different version of the API, which can be enabled by turning on "Experimental JavaScript" at chrome://flags/
. This old API is ugly, and implementing the previous would require significantly more lines of code, so I'll leave this as an exercise to the reader.
Oh, there's a library called DirectProxies.js
(superseded by harmony-reflect) which brings the simple Proxy API to Chrome. After including the this library, the previous code will work in Firefox and Chrome (with experiments enabled): http://jsfiddle.net/PAhYL/
Upvotes: 7