javascript沙箱模块,以防止引用窗口

javascript沙箱模块,以防止引用窗口,javascript,sandbox,Javascript,Sandbox,我试图创建一个沙盒模块,该模块可以获取一个对象并阻止该对象对窗口的代码引用 下面是它的工作原理 var sand = function(window) { var module = { say: function() { console.log(window.location); } }; return module; } sand({}).say(); // window.location is undefine 如果对象已传入,则此操作不起作用 var

我试图创建一个沙盒模块,该模块可以获取一个对象并阻止该对象对窗口的代码引用

下面是它的工作原理

var sand = function(window) {
var module = {
    say: function() {
        console.log(window.location);
    }   
};
return module;
}
sand({}).say(); // window.location is undefine
如果对象已传入,则此操作不起作用

var $sand = (function(){
return function(obj, context) {
    return (function(obj, window) {
        window.module = {};
        // doesn't work even copy object
        for (p in obj) {
            window.module[p] = obj[p];
        }
        console.log(window.location); // undefine
        return window.module;
    }(obj, context));
};
}());

var module = {
say: function() {
    console.log(window.location);
}
};

$sand(module, {}).say(); // still reference to window.location

如何使此模式工作?

只要您的函数范围内没有变量阴影
窗口
,函数就可以访问
窗口
。即使您有一个名为
window
的变量,代码仍然可以通过省略
window来访问属性。

(function(window) {
    console.log(window.location); //undefined
    console.log(location); //this will still work
})({ });

换句话说,在浏览器环境中沙盒JavaScript是不可能像这样的。

如果在沙盒外部定义函数,则上下文将是当前上下文,否则就无法执行


如果您真的想做一些沙箱,那么应该使用iframe来实现这一点。看看它是node的
vm
模块的浏览器版本,您应该能够提取一些好的工作,并避免
eval
,这对于您想要做的事情来说不是很干净。

在您的第一个示例中,窗口
未定义的唯一原因是,您传入一个空对象并调用参数
窗口
,因此它隐藏了真正的
窗口

此外,通过在闭包内提升
变量,始终可以访问窗口对象,如下所示:

console.log ( ( function () { return this; } )() );

因此,即使您设法阻止了
窗口
,重新获取它也很简单。

我有点不清楚,您的意思是:
var sand=function(window){var module={say:function(){alert(typeof window.location);}};return module;}sand(未定义)。say()这将使“窗口”不是内部定义的对象?换句话说,这将返回“true”
警报(null==window)坏消息:算了吧。阻止访问全局对象是不可能的-“隐藏”名称是不够的。谢谢所有的答案。我发现Dean Edward从2006年起就这么做了。。。