Javascript 在沙箱中创建变量并执行代码

Javascript 在沙箱中创建变量并执行代码,javascript,Javascript,我如何管理它,通过run()在Sandbox()中放置变量并运行代码 请不要回答eval()是不安全的,我不应该使用它。 关于setter/getter的使用,请不要回答 谢谢你的阅读 您可以使用闭包 Sandbox.prototype.Run = function(src) { (function(_src){ eval.call(this, _src); })(src); }; 这应该起作用: ... Sandbox.prototype.run = fun

我如何管理它,通过run()在Sandbox()中放置变量并运行代码

请不要回答eval()是不安全的,我不应该使用它。 关于setter/getter的使用,请不要回答


谢谢你的阅读

您可以使用闭包

Sandbox.prototype.Run = function(src) {
    (function(_src){
        eval.call(this, _src);
    })(src);
};
这应该起作用:

...

Sandbox.prototype.run = function(src) {
    eval(src);
};

...

bx.run('this.x = 1;');

...

这可能不是您想要的,但如果您不向沙箱传递字符串,而是传递函数,会怎么样呢。这甚至允许对源文件使用
eval

您的代码的工作方式如下:

...

Sandbox.prototype.Run = function(fn){
    fn.call(this);
}

var bx = new Sandbox();
bx.run(function(){
    this.x = 1;
});
bx.getVar("x") // 1
然后,如果您想使用
eval
,您只需编写一个函数来附加函数语法

/* source.js */
this.x = 1;
this.blah = "Hello, World!";
与:

使用此方法,您还可以通过将沙盒代码对象和函数传递给将模拟全新伪环境的函数,从而传递要使用的沙盒代码对象和函数

编辑:我对你的问题的完美的答案做了一些研究,答案是

我可以迭代局部范围中声明的变量吗

答案是。目前看来这是javascript的一个限制。希望这样的东西会出现在新的规范中

目前我的想法是评估源代码,使所有的var语句都进入window对象,通过一些努力,可以手动迭代并添加到
沙盒
对象中

像这样警告:极度简化

(function(){
    var src = get_source_file();
    eval(src);
    iterate_over_each_newly_created_window_property(function(property, value){
         bx[property] = value;
         window[property] = undefined;
    });
})();
编辑2: 我的想法有效=)

编辑3:修复错误


现在我知道它有一些bug和一些函数可能会使它失控。现在,您的工作是清理代码以供实际使用。我给了你概念上的方法

我认为您在错误的范围内Eval只能在全局范围内运行。这是一个javascript限制。bx.getvar('x')将导致未定义。我不希望在Run()的表达式中使用“this”。如果希望它工作,则需要使用
this
var
创建一个与
Sandbox
实例不关联的局部变量。是的,这是有效的。非常感谢。但是我不能将它添加到每个表达式中,因为我不知道Run()每次使用的表达式的确切类型。但是,是否可以设置一个局部变量并使用getvar()返回局部变量?不,局部变量的作用域一结束就消失了。这个范围不是
getvar
方法的一部分。在我的情况下,这不是我可以使用的,但感谢您的支持!不,这些变量应该放在沙盒对象中。这没那么糟糕!:-)我正在考虑为此使用with()。我会的。看看这个方法,也许我们可以再微调一下。我不喜欢那个窗口。eval();-)
Sandbox.prototype.evaluate = function(src){
     return eval("function(){" + src + "}");
}

bx.Run(Sandbox.evaluate(src));
bx.getVar("x") // 1
bx.getVar("blah") // "Hello, World!"
(function(){
    var src = get_source_file();
    eval(src);
    iterate_over_each_newly_created_window_property(function(property, value){
         bx[property] = value;
         window[property] = undefined;
    });
})();
function Sandbox(){
    return this;
}
Sandbox.prototype.run = function(src){
    // Take a snapshopt of the window object before
    var before = {};
    var prop;
    for(prop in window){
        before[prop] = true;
    }
    // Then evaluate the source
    window.eval(src);
    // Then see what changed
    var changed = [];
    for(prop in window){
        if(!before[prop]){
            // Add to the sandbox object
            this[prop] = window[prop];
            delete window[prop];
        }
    }
}
var bx = new Sandbox();
bx.run("var x = 'Hello, World!';");
alert(bx.x);
function Sandbox(){
this.keys = [];
this.values = [];
    return this;
}
Sandbox.prototype.eval = function(src){
    var before = {}, prop, fn;
    // Take a snapshopt of the window object before
    src = "function(" + this.keys.join(",") + "){" + src + "}";
    src = src.replace(/var/g, "");
    /* I'm not a wisard at regex so a better one should be used avoid this bug
    var x, y, z; */
    for(prop in window){
        before[prop] = true;
    }
    // Then evaluate the source
    fn = window.eval(src);
    fn.apply(window, this.values);
    // Then see what changed
    for(prop in window){
        if(!before[prop]){
            // Add to the sandbox object
            this.keys.push(prop);
            this.values.push(window[prop]);
            this[prop] = window[prop];
            delete window[prop];
        }
    }
}
var bx = new Sandbox();
bx.eval("var x = 1;");
bx.eval("var y = x;");
alert(bx.x);
alert(bx.y);