【发布时间】:2013-07-06 18:08:26
【问题描述】:
鉴于我的插件可以在任何 JS 引擎上运行(无论是否在浏览器中),
-
如何知道某个变量实际上是浏览器
window对象。比如我怎么知道
someVar是否引用了浏览器window对象。window中有什么东西可以让我检查它是否真的是浏览器window对象? -
以及如何检查浏览器
window对象是否确实存在,而不仅仅是一些包含对象的window变量。假设您无法判断
someVar本身是否为window,并且您想将其与真实 浏览器window对象(如someVar === window)进行匹配,您如何获得window,您确定它是浏览器window,而不是来自名为window的外部范围的其他对象,或者来自其他环境的其他全局对象?
只是为了澄清一点:
- 我不是在寻找全局环境。我正在寻找浏览器
window对象。 - 我没有检查脚本是否在浏览器上运行。
我不能做像if(!window) 这样的事情,因为window 可能只是在范围之外的某个地方声明的另一个对象。
function someFunction(){
var window = {foo:'bar'};
(function(){
console.log(window); //{foo:'bar'}
}());
}
我无法检查if(window.window === window),因为我也可以进行自引用,并且如前所述,window 可能是来自外部范围的对象:
var bar = {};
bar.bar = bar;
bar.bar.bar.bar.bar.bar === bar; //true
以下可能不起作用,因为脚本可能会被包装或连接到全局空间以外的其他地方。 this 也可以通过 call()、apply() 或 bind() 等调用进行修改。
//Stand-alone, I can assume window is global since "this" is the global in global space
(function(window){
//window may not be window
}(this));
//But when this happens
someNamespace.someFunction = function(){
(function(window){
//window may not be window
}(this));
}
//or this:
someNamespace.someFunction.call({});
我感觉这是复制品,但我找不到第一次看到它的地方。
【问题讨论】:
-
听起来您想通过检查窗口是否存在来确定您的代码是否在浏览器中运行。您可以尝试寻找浏览器可能作为窗口的一部分实现的功能,例如 window.location.href,但当然即使这样也不是故障安全的。如何确定是否可以返回有效的 userAgent 字符串?
-
(function(){return this}).call(null)总是有效吗? -
@JanDvorak:不。在 ES3 环境中它会,但是 ES5 更改了规则,说当显式传递
null时,thisArg不会更改为全局对象。例如,这将返回 null:(function () { "use strict"; return (function(){return this}).call(null); })(). -
@AndyE 什么时候改成
thisArg呢?可以使用类似的方法吗?
标签: javascript