2

I need a function to return true if the given variable name is already defined by javascript engine or browser.

For example

isNative('window') //true;
isNative('Math') //true;
isNative('myVar') //false
isNative('navigator') //true
isNative('document') //true
danial
  • 4,058
  • 2
  • 32
  • 39
  • 2
    What problem are you trying to solve? What have you tried so far? – Pointy Dec 01 '13 at 15:36
  • 1
    Why do you need to distinguish native from user-defined? And, no, I don't believe it's reasonably possible. – Jonathan Lonowski Dec 01 '13 at 15:45
  • I believe there is no such thing as "native" JS objects. There are functions which contain of native code, but thats it. – Pavlo Dec 01 '13 at 15:47
  • I need to parse a javascript string before calling eval() and override non-native variables to intercept them. – danial Dec 01 '13 at 15:48
  • Is it possible to have a "fresh" "window" javascript engine variable namespace without any extra libraries or js code and then check those variable names in that window? – danial Dec 01 '13 at 15:55
  • Pointy Ears - is that you in the first comment? I recall dueling with you on the comp.lang.javascript group back in the day. FWIW, I think that isNative is useful and have incorporated it into my code. IMHO, this should not have been closed!! - JavascriptDude (LOL) – Timothy C. Quinn Oct 24 '22 at 15:21

5 Answers5

4

Ok I found the solution.

function isNative(variableName) {
    if (window['__emptyIframeRef__'] === undefined) {            
        window['__emptyIframeRef__'] = document.createElement('iframe');
        window['__emptyIframeRef__'].setAttribute('style', 'display:none');
        document.getElementsByTagName('body')[0].appendChild(window['__emptyIframeRef__']);
    }
    return window['__emptyIframeRef__'].contentWindow[variableName] !== undefined;
}

Additional code that can be added to the top to guard against edge condition of code running before document.body is available:

function isNative(variableName) {
    if(o===null||o===undefined)return true
    if(!document.body){
        if(o instanceof String) o = window[o]
        if(o===undefined) return false
        if(o.constructor.toString().indexOf('[native code]')>-1) return true
        return false
    }
    ...
}
Timothy C. Quinn
  • 3,739
  • 1
  • 35
  • 47
danial
  • 4,058
  • 2
  • 32
  • 39
  • 2
    Yeah, iframe borrowing. Btw, you can use `document.body` instead of `document.getElementsByTagName('body')[0]`. – Pavlo Dec 04 '13 at 21:55
  • The downside of this is where your code is executing in the sequence. If its before the body is declared, it will fail with 'document.body is null' in Firefox. Although this technique is great, it should be extended to handle this edge condition. – Timothy C. Quinn Oct 24 '22 at 15:05
1

I don't think this is what you want. First thing off; global variables are bad. So you should have your own namespace where you have all your own logic/modules/functions as in;

var danial={
    module1:{
        get:function(bla){...}
    },
    module2:(function(){
        ....
    }());
}

Now, there is no difference between a native object/function and a self defined one. They all have the object prototype on top of the prototype chain and there is no way to differentiate. What you can check on though, if your object has the property itself or if it is 'inherited' over the prototype chain, for instance toString will always be present but doesnt belong to your object (unless you've defined and overriden it). You can check that with following code

for (var prop in obj) {
    if( obj.hasOwnProperty( prop ) ) {
        console.log("own property", prop, obj[prop]);
    } 
}
japrescott
  • 4,736
  • 3
  • 25
  • 37
1

It's possible but I don't know any good you can do with that, and it's not efficient as well.

All you need to do is to prepare a variable to clone window at the very first.

// Borrowed from Coffeescript
// Similar functionality as underscore.js extend()
__extends = function(child, parent) { 
              for (var key in parent) { 
                if (__hasProp.call(parent, key)) child[key] = parent[key]; 
              } 
              function ctor() { this.constructor = child; } 
              ctor.prototype = parent.prototype; child.prototype = new ctor();
              child.__super__ = parent.prototype; return child; 
            };

var foo;
foo = __extends({}, window);

//Usage
foo.hasOwnProperty('console')
// true
window.hasOwnProperty('console')
// true

var bar = 'bar'
foo.hasOwnProperty('bar')
// false
window.hasOwnProperty('bar')
// true
Billy Chan
  • 24,625
  • 4
  • 52
  • 68
  • The problem with this would be if some libraries are loaded before this code runs then it would consider their global variables as native. But it's a neat approach. – danial Dec 01 '13 at 16:27
  • Yes, so it has to be very first to load and run. Also I believe your real problem has way to be solved in another nicer way, no need to work around window's native property. – Billy Chan Dec 01 '13 at 16:29
0

Check it on http://jsfiddle.net/7h3su/

function isNative(variableName){
    return window[variableName]!=undefined;
}
alert(isNative('window')) //true;
alert(isNative('Math')) //true;
alert(isNative('myVar')) //false
alert(isNative('navigator')) //true
alert(isNative('document')) //true
Tom Chung
  • 1,412
  • 9
  • 12
  • But if I define a global variable it would detect it as Native but it is not. For example if I have window.myVar = 10; http://jsfiddle.net/na65y/1/ – danial Dec 01 '13 at 15:45
-1

'document' object is not native though.

function isNative(variableName){
    return [Object,Function,Array,String,Boolean,Number,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError].some(function(element){return window[variableName]===element});
}
myVar = 10;
alert(isNative('Object')) //true;
alert(isNative('String')) //true;
alert(isNative('myVar')) //false;
alert(isNative('document')) //false;

Check to see if it can help you: http://jsfiddle.net/na65y/2/

Tom Chung
  • 1,412
  • 9
  • 12