【问题标题】:How to detect native browser/engine objects in javascript [closed]如何在javascript中检测本机浏览器/引擎对象[关闭]
【发布时间】:2013-12-01 15:35:07
【问题描述】:

如果给定的变量名称已经由 javascript 引擎或浏览器定义,我需要一个函数来返回 true。

例如

isNative('window') //true;
isNative('Math') //true;
isNative('myVar') //false
isNative('navigator') //true
isNative('document') //true

【问题讨论】:

  • 您要解决什么问题?到目前为止,您尝试过什么?
  • 为什么需要区分原生和自定义?而且,不,我认为这是不可能的。
  • 我相信没有“原生”JS 对象这样的东西。有些函数包含本机代码,仅此而已。
  • 我需要在调用 eval() 之前解析一个 javascript 字符串并覆盖非原生变量来拦截它们。
  • 是否可以在没有任何额外库或 js 代码的情况下拥有一个“新鲜”“窗口”javascript 引擎变量命名空间,然后在该窗口中检查这些变量名称?

标签: javascript browser native javascript-engine


【解决方案1】:

好的,我找到了解决方案。

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;
}

【讨论】:

  • 是的,iframe 借用。顺便说一句,您可以使用document.body 而不是document.getElementsByTagName('body')[0]
【解决方案2】:

我认为这不是你想要的。第一件事;全局变量不好。因此,您应该拥有自己的命名空间,其中您拥有所有自己的逻辑/模块/功能;

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

现在,本地对象/函数和自定义对象/函数之间没有区别。它们都有对象原型在原型链之上,没有办法区分。但是,您可以检查的内容是,如果您的对象本身具有属性,或者它是否在原型链上“继承”,例如 toString 将始终存在但不属于您的对象(除非您已定义并覆盖它)。您可以使用以下代码进行检查

for (var prop in obj) {
    if( obj.hasOwnProperty( prop ) ) {
        console.log("own property", prop, obj[prop]);
    } 
}

【讨论】:

    【解决方案3】:

    这是可能的,但我不知道你能做些什么,而且效率也不高。

    您需要做的就是首先准备一个变量来克隆窗口。

    // 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
    

    【讨论】:

    • 这样做的问题是,如果在此代码运行之前加载了一些库,那么它会将它们的全局变量视为本机。但这是一种巧妙的方法。
    • 是的,所以它必须首先加载和运行。另外我相信你真正的问题可以用另一种更好的方式解决,不需要解决窗口的原生属性。
    【解决方案4】:

    查看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
    

    【讨论】:

    • 但是如果我定义了一个全局变量,它会将其检测为 Native,但事实并非如此。例如,如果我有 window.myVar = 10; jsfiddle.net/na65y/1
    【解决方案5】:

    'document' 对象不是原生的。

    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;
    

    看看能不能帮到你:http://jsfiddle.net/na65y/2/

    【讨论】:

    • 你能解释一下为什么文档对象不是原生的吗?
    • 不知道。一个用外语写的网站提到了这一点。
    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    相关资源
    最近更新 更多