在Javascript中围绕函数()制作沙盒

在Javascript中围绕函数()制作沙盒,javascript,scope,sandbox,Javascript,Scope,Sandbox,我是否可以将字符串生成函数的访问权限(使用函数构造函数)限制为父/全局作用域 例如:由于函数正在窗口中存储/修改变量,因此下面的代码打印为false window.a = 4; Function("a=3;")() console.log(a === 4); 我可以限制对窗口/父范围的访问并将其打印为“true”吗?我不这么认为。您可以在参数中命名要保护的全局对象,使其成为阴影: window.a = 4; Function("a", "a=3;")() console.log(a === 4

我是否可以将字符串生成函数的访问权限(使用函数构造函数)限制为父/全局作用域

例如:由于函数正在窗口中存储/修改变量,因此下面的代码打印为false

window.a = 4;
Function("a=3;")()
console.log(a === 4);

我可以限制对窗口/父范围的访问并将其打印为“true”吗?

我不这么认为。您可以在参数中命名要保护的全局对象,使其成为阴影:

window.a = 4;
Function("a", "a=3;")()
console.log(a === 4);
但是不管你怎么尝试,这个函数都将访问全局。。。这就是为什么它被称为全球


根据您正在尝试做什么,还有其他解决方法,例如web workers。。。和往常一样,.

@Esailija的答案是正确的。此外,我建议首先限制必须保护的全局变量的数量。将通常放在全局命名空间中的任何内容放在您控制的
应用程序
范围中:

var APP = (function() {
    return {
        a: 4
    };
}());

没有办法完全限制对全局范围的访问,但至少这样你只需要保护一个对象:
APP

这里有一个额外的想法,它可能与Esailija的建议结合在一起非常强大(请参阅他回答中的评论以了解讨论内容)

您可以创建虚拟iframe并使用其
函数
函数。默认情况下,使用该函数创建的函数只能访问iframe的作用域,尽管它仍可能脱离iframe。幸运的是,以赛利娅建议,预防这种情况很容易

我可以想象函数是这样的:

function sandboxed(code) {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);

    var F = frame.contentWindow.Function,
        args = Object.keys(frame.contentWindow).join();

    document.body.removeChild(frame);

    return F(args, code)();
}

(可选)您可能希望在
前面加上“使用strict”到代码


这至少在Chrome中有效。以这种方式创建的函数是否可以访问iframe的全局范围或页面的全局范围,可以通过以下方法轻松测试:

(function() {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    var same = window === frame.contentWindow.Function('return window;')();
    alert(same ? ':(' : ':)');
    document.body.removeChild(frame);
}());

这是我的修改后的
沙盒
函数。它需要代码和一个可选字典以及函数的参数

函数沙盒(代码,args={}){
var frame=document.createElement('iframe');
document.body.appendChild(框架);
var F=frame.contentWindow.Function;
document.body.removeChild(框架);
返回F(…Object.keys(args),“'use strict';”+code)(…Object.values(args));
}
log(沙盒('returna-10;',{'a':34}));
// 24

好吧,您可以将
窗口
文档
定义为参数,以防止直接访问它们(正如您已经说过的),然后预先设置
使用strict
添加到代码以防止全局变量的隐式定义。那可能行得通。但当然,只要不通过参数“隐藏”现有全局变量,它就不会阻止对它们的访问。也许有人可以迭代所有
窗口
属性并自动创建参数列表。@FelixKling听起来很不错,我将尝试一些技巧,看看我是否仍然可以访问它global@FelixKling这是我现在的,如果你对
函数进行阴影处理
窗口创建参数
的属性似乎可以工作:。@FelixKling即使有一个阴影处理的
函数
,我们仍然有
(函数(){})。构造函数
非常有创意:D+1我得到
:)
除了IE8,它抛出的
不支持属性或方法函数
@Esailija:感谢您的测试(我没有IE)。可能iframe的源代码必须在IE中显式设置(
frame.src='about:blank'
应该这样做),或者该属性的名称不同(而不是
contentWindow
)。如果必须设置源代码,可能需要等待
加载
事件,然后才能访问该窗口,但当然,让
沙盒
接受对结果的回调是没有问题的:)