0

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

这是它在概念上的工作方式。

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

我怎样才能使这种模式起作用?

4

3 回答 3

1

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

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

换句话说,在浏览器环境中沙箱化 JavaScript 是不可能的。

于 2012-04-19T15:03:49.083 回答
1

在您的第一个示例中, window 的唯一原因undefined是因为您传入了一个空对象并调用了参数window,所以它隐藏了真实的window.

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

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

因此,即使您以某种方式设法阻止window,再次将其取回也是微不足道的。

于 2012-04-19T15:05:14.153 回答
0

如果您在沙箱之外定义函数,则上下文将是当前上下文,否则您将无法真正做到。

如果你真的想做一些沙盒,那么你应该使用 iframe 来实现。看看https://github.com/substack/vm-browserify它是vmnode 模块的浏览器版本,你应该能够提取一些好的工作,并避免eval哪些对你来说不是很干净想要做。

于 2012-04-19T15:05:09.763 回答