Reputation: 2352
Is there a technique / framework, which creates and stores a new object into an undefined variable when it is handled as an object?
F.e. writing
some.thing = 7;
Gives an error describing, that undefined's ( some's ) property could not be set.
So now, we have to go back, and write
some = {};
some.thing = 7;
which looks almost unnecessary to me, since it is obvious, that I'd like to use some as an object.
It would be very comfortable this way:
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ].age = 32;
This looks way more efficient, and simple than
hospitals = {};
hospitals.sectors = {};
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
Upvotes: 0
Views: 124
Reputation: 708
If you are trying to assign 7
to some.thing
and some
should not be declared at all beforehand, use Cory's suggestion of var some = { thing: 7 };
.
If you are trying to assign 7
to some.thing
and some
might be declared/defined already (or even if it is declared, may or may not be set to undefined
), use
(some = (some || {})).thing = 7;
or (a more readable solution, though not a one liner)
some = (some || {});
some.thing = 7;
The one caveat with my solution is that you might get undesired scoping on some
if it isn't declared ahead of time. An example of where it would be undefined but still declared (and thus the scope would be what is expected):
function assignThing(some) {
(some = (some || {})).thing = 7; /* one liner solution */
return some;
}
var foo = assignThing(); /* the parameter 'some' is undefined, but declared */
var bar = assignThing({}); /* the parameter 'some' is defined
* (though empty) and declared */
(baz = (baz || {})).thing = 7; /* Unless you have this declared
* elsewhere this *should* be the
* global scope */
var foobar; /* declared, not defined */
(foobar = (foobar || {})).thing = 7; /* now defined */
Edit: Created a namespace solution like what anddoutoi suggested.
First example of usage (hospitals
) uses the optional nature of the third parameter, which defaults to "undefined".
Second example (hospitals2
) passes undefined.
Third example (hospitals3
) passes another object (I happened to create it inline).
For the example you (the OP) provided, my hospitals
example is the closest to an exact match. I don't know of a way to auto-magically create an object hierarchy besides using a canonical name string + a function.
function create(canonicalPropertyName, value, root) {
root = (root || {});
var names = canonicalPropertyName.split(".");
var current = root;
for (var i = 0; i < names.length; i++) {
/* Ensure the property exists */
current[names[i]] = (current[names[i]] || (i < names.length - 1 ? {} : []));
/* We're recursing down the object tree */
current = current[names[i]];
}
return root;
}
var hospitals = create("sectors.doctors", []);
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
console.log(hospitals);
var hospitals2 = create("sectors.doctors", [], undefined);
hospitals2.sectors.doctors[ 0 ] = {};
hospitals2.sectors.doctors[ 0 ].age = 32;
console.log(hospitals2);
var hospitals3 = create("sectors.doctors", [], { name: "City Hospital" });
hospitals3.sectors.doctors[ 0 ] = {};
hospitals3.sectors.doctors[ 0 ].age = 32;
console.log(hospitals3);
Upvotes: 1
Reputation: 10111
Many frameworks have a namespace()
method/function that helps you achieve what you want.
Example:
Ext.ns('hospitals.sectors.doctors') = [];
var doctors = Ext.ns('hospitals.sectors.doctors');
doctors[0] = {
age : 32
};
I myself don't like this pattern as it adds unnecessary dependencies and work.
Upvotes: 1
Reputation: 5639
you could write an own handler to do the job
function createObjectProperty(objNameString, objPropertyString, objValueString) {
window[objNameString] = {};
window[objNameString][objPropertyString] = objValueString;
return window[objNameString];}
var test = createObjectProperty("some", "thing", 7);
alert(test.thing);
the call would look like:
createObjectProperty("some", "thing", 7);
and it alerts "7".You also could check before creating the new object, if it exists. I would iterate over the object and gather all attributes, check for duplicate and append my new attribute + value if you need such functionality. Otherwise the new object will overwrite the old one. Hope this is what you are searching for
working fiddle (update):
https://jsfiddle.net/a922bopj/1/
Upvotes: 0