function getObject(s) {
var pieces = s.split("."), i = 0, length = pieces.length, object = window;
for (i; i < length; i++) {
if (object[pieces[i]]) {
object = object[pieces[i]];
}
else {
throw new Error("No object found for " + s);
}
}
return object;
}
window.foo = {
bar: {}
};
var o = getObject("foo.bar");
alert(o === window.foo.bar); // should alert true
a string contains system object name, which may be:
"window", "document" etc.
is it possible to obtain system object from its name-string?
yes. it's built-in and it's called eval.
Code:
var n = eval("window");
//to let n = object window.
the code toicontien posted work only on browsers, and only finds globals, which good programmers do not use.
eval works anywhere in the current execution scope, even in non-browsers like pdf, asp, node.js, jsc.exe, etc...
var getObject = function(name) {
return this[name];
}
Granted, I haven't tested this in node or a PDF, but my understanding is that if getObject() is defined in the global scope, referring to "this" inside the function will refer to the "global object" -- window, in the case of a browser.
And thankfully, the "global" window scope contains a reference to itself. So, given the trivial getObject() function above, you can do this:
PHP Code:
var w = getObject('window');
Or this:
PHP Code:
var C = function() {
this.getWindow = function() {
return getObject('window');
}
}
var x = new C();
var w = x.getWindow();
.. and expect that w now holds a copy of the window object either way, if it exists.
But, if you're writing your code for the browser, which I think is the general assumption for most questions posted in a web-dev forum, window['objectname'] is a simpler way to go.
It's my opinion that eval() introduces a performance hit that's almost never necessary.
But, if you're writing your code for the browser, which I think is the general assumption for most questions posted in a web-dev forum, window['objectname'] is a simpler way to go.
It's my opinion that eval() introduces a performance hit that's almost never necessary.
w/ getObject:
Code:
var getObject = function(name) {
return this[name];
}
function test(){
function bob(){return "ok";}
alert( getObject("bob") );
}
w/ eval:
Code:
function test(){
function bob(){return "ok";}
alert( eval("bob") );
}
your code shows "undefined" while eval shows the function object source.
tacking globals onto the global scope, no matter what it's called, is surely misguided at best and fragile at worse...
If the OP were following good organizational practices, the correct answer even more-so be, "use the array syntax."
PHP Code:
var o = myObjectCollection['objectname'];
or
PHP Code:
var other_o = this['localobjectname']
The answer to this question is not, and should not be, "use eval()." It's just an unnecessary pair of [potentially insecure] parsing and compilation steps. And we frankly have no idea where the "variable name" is coming from. Perhaps it's user input, or worse, perhaps it's derived from another users's input -- something that should *not* be passed to eval()!
It's a very clever looking solution, to be sure. But, I maintain it's not the right one. Particularly in light of the philosophy, which you appear also to endorse, wherein most, if not all, variables are out of the global scope, and presumably well-organized. In such a case, you'll almost always have a "scope object" you can refer to directly.
But yes, the purpose of the getObject() function was to fetch an object from the global namespace, which is quite clearly what the OP was attempting to do!
It's a very clever looking solution, to be sure. But, I maintain it's not the right one.
no wonder eval's parsing is "insecure"; you're trash talking it up and down :P
i don't believe in right and wrong; just working and not-working.
Ideally, one would write code where such late assessments are not used at all.
the problem i have with using raw array syntax is that it only goes straight up to the top, skipping over the middle of the scope chain. This implies the need for left-over variables, which is generally considered poor practice.
i guess if you use globals, window[x] works, but i encourage anyone using eval('x') or window['x'] to write more robust code that requires neither syntax. Grabbing an instance early is all that needs to happen to use obj.x...
no wonder eval's parsing is "insecure"; you're trash talking it up and down :P
98% sure that statement doesn't make any sense. Again, I'm claiming ignorance of context here -- ignorance of the origins noted "object name." And in any case, it's not my intention to "trash talk" eval() here -- only it's use in this context.
Originally Posted by rnd me
i don't believe in right and wrong; just working and not-working.
Well, if you want philosophy, I'd say working and not-working are more subjective than right and wrong. In my experience, it's much easier to look at someone's code and say, "this is wrong" than it is to say, "this doesn't do what it should." You typically only learn that something doesn't do what it should after it's pounded on by your users.
When I first started at my current place of employment, for instance, I inherited a set of web applications that were clearly coded very very wrongly. My supervisors sensed this, and it was obvious to me after a few minutes with the code. The apps "worked," (they met the specifications) but they were horrendously slow in certain scenarios and utterly un-maintainable. Every seemingly minor change resulted in a errors elsewhere in the application. It was very easy to determine that they were coded wrong, in an great number of respects, even though they seemingly "worked."
Noting the presence of eval(name) in place of something like this[name] or someobject[name], for instance, is a very good indicator that something somewhere is wrong -- beyond the mere presence of eval() for purposes better suited by other means. (Eval() 30% slower, by the by, than using the array syntax) The problems eval() tends to indicate are what actually what you've been suggesting: poor variable/object organization and un-robust code. If you know where your objects are, there's no need to eval() anything.
This makes it all the more confusing that, having properly identified the fundamental design issues that correlate with using eval(), one would suggest using eval().
The two good reasons to eval(), that I can think of offhand, are executing JSONP responses and dynamically (re)writing functions -- for neat tricks like magic "base" variable insertions into class constructors and so forth.
Originally Posted by rnd me
Ideally, one would write code where such late assessments are not used at all.
the problem i have with using raw array syntax is that it only goes straight up to the top, skipping over the middle of the scope chain. This implies the need for left-over variables, which is generally considered poor practice.
i guess if you use globals, window[x] works, but i encourage anyone using eval('x') or window['x'] to write more robust code that requires neither syntax. Grabbing an instance early is all that needs to happen to use obj.x...
I disagree with you 98% here. I'll give you 2%, because all "core" objects should be known at coding time and can be referred to using the dot-notation. There is no reason, however, to suggest that the array syntax is poor form. It provides an efficient mechanism for the iteration and manipulation of unknown objects, objects with optional properties, and elegant references to object properties based on user input -- and if you're writing your script to work on data in a variety of settings, with respect to user input, which most of us are, this is the norm.
But, it's wise to avoid hasty maxims. The array syntax is not bad in and of itself, and it facilitates many things that simply can't be done otherwise. But, I would agree that a great lack of dot-syntax property references in an allegedly OO script is an indicator that someone somewhere is in unfamiliar water ...
And please note again, I don't intend to "bash" the eval() function. I named two distinct cases for which eval() and generally only eval() should be used. Finding variables/objects is not one of them. And I think you'd be hard pressed to find any other convincing reasons to use eval().
Bookmarks