views:

865

answers:

3

I have a method, that perfectly works in Firefox, with which I can determine the name of an instance of a particular javascript object (please don't ask why I need it...). Fr example:

var temp = new String("hello!");
var theName = getVarName(temp); //returns "temp"

This method uses "window.hasOwnProperty()" which doen't work in Internet Explorer: any suggestions?

A: 

Do not use global variables. Always put them in namespaces so that you don't run into such problems.

If I understood correctly, you want the global variable name when given the value under any scope. For example, the following should work too

var temp = "hello";
function foo(x) {
     alert(getVarName(x)); //returns "temp" as well.
}
foo(temp);

This is sort of reverse hash lookup on Window object which is not only expensive, since you need to iterate over all the properties of window object each time, but also unreliable (two variables can have a same value).

Chetan Sastry
this.hasOwnProperty has issues in IE in closures (namespaces) as well. Lawrence has the workaround.
Fraser Harris
@Fraser Harris: What issues?
Chetan Sastry
Depending on how you instantiate the object / namespace, the object context differs. Try this on Chrome and IE (my results: Chrome "true", IE "Object doesn't support this property or method"): (function c() {this.x = true;alert(this.hasOwnProperty('x'));})()
Fraser Harris
`this` in your example still refers to global Window object, not a namespace - try `(function c() { alert(this === window); })();`. So it is the same problem. `hasOwnProperty` in IE (<9 at least) fails on DOM objects because they are implemented differently than regular javascript objects.
Chetan Sastry
+2  A: 

I have a method, that perfectly works in Firefox, with which I can determine the name of an instance of a particular javascript object

I don't think you do, because that's not possible in JavaScript. JS is a call-by-value language; when you write:

var temp= 'hello';
getVarName(temp);

that's exactly the same as saying:

getVarName('hello');

At which point the reference to ‘temp’ as a variable is lost. What I'm guessing your getVarName function does is basically this:

function getVarName(value) {
    for (var name in window) {
        if (window[name]===value)
            return name;
    }
}

This will work on IE and other browsers without Object.hasOwnProperty(); it will simply return the name of any global variable that matches the argument. The hasOwnProperty() call can be added to this function to refine it a little by only allowing direct properties of window (which act as global variables, including the ones you set explicitly), and not of any of its prototypes. I'm guessing that's what your version of the function is doing, but in practice it has very little effect since almost nothing inherits into ‘window’ by prototype.

You're confusing things a little bit by boxing your 'hello' in an explicit String object (which is very unusual and rarely a good idea), which makes it possible to have two different 'hello' objects that are disinguishable using the === identity comparator, so this will work:

var a= new String('hello!');
var b= new String('hello!');
getVarName(a); // 'a'
getVarName(b); // 'b' - distinguishable object from a

But that still doesn't stop you from doing:

var a= new String('hello!');
var b= a;
getVarName(a); // 'a' or 'b', depending on implementation
getVarName(b); // the same 'a' or 'b' as in the previous call

So, whilst you can fairly harmlessly lose the hasOwnProperty() call as above, what you're doing can't really work properly and you should probably look at a better way of achieving whatever it is you're up to.

bobince
You've clarified a bit my problem. Anyway I know I will use a single global variable, so this is perfectly what I need. Moreover I don't need to use it with a simple string variable or boolen or whatevet, but with a complex object and actually I call kinda getVarName(this) inside the class
Enreeco
+3  A: 

If for whatever reason you do need to use window, use:

Object.prototype.hasOwnProperty.call(obj, p)

Lawrence Pit