【问题标题】:Javascript: making the global eval() behave like object.eval()Javascript:使全局 eval() 表现得像 object.eval()
【发布时间】:2011-11-03 22:15:30
【问题描述】:

好的——我有一个非常特殊的情况,我需要使用 eval()。在人们告诉我根本不应该使用 eval() 之前,让我透露一下我知道 eval 的性能问题、安全问题和所有这些问题。我在一个非常狭窄的情况下使用它。问题是这样的:

我寻找一个函数,它将向传递给它的任何范围写入变量,允许这样的代码:

function mysteriousFunction(ctx) {
//do something mysterious in here to write
//"var myString = 'Oh, I'm afraid the deflector shield will be 
//quite operational when your friends arrive.';"
}

mysteriousFunction(this);
alert(myString);

我尝试使用全局 eval() 来执行此操作,使用闭包、'with' 关键字等来伪造执行上下文。我无法使其工作。我发现唯一有效的是:

function mysteriousFunction(ctx) {
ctx.eval("var myString = 'Our cruisers cant repel firepower of that magnitude!';");
}

mysteriousFunction(this);
alert(myString); //alerts 'Our cruisers cant repel firepower of that magnitude!'

但是,上述解决方案需要 object.eval() 函数,该函数已被弃用。它有效,但它让我紧张。有人愿意对此进行破解吗?感谢您的宝贵时间!

【问题讨论】:

  • 我只想说我喜欢你对示例代码的品味。
  • @Alex:将其称为this.myString 是否有问题?有关详细讨论,请参阅我的答案中的 cmets。

标签: javascript eval


【解决方案1】:

jsFiddle

编辑:正如@Mathew 所指出的,我的代码毫无意义!所以一个使用字符串的工作示例:

function mysteriousFunction(ctx) {
    eval(ctx + ".myString = 'Our cruisers cant repel firepower of that magnitude!';");
}
var obj = {};
mysteriousFunction("obj");
alert(obj.myString);

【讨论】:

  • 这没有任何意义。如果您只是分配给窗口(不是最窄的范围),为什么还要使用eval
【解决方案2】:

你可以这样说:

function mysteriousFunction(ctx) {
   ctx.myString = "[value here]";
}

mysteriousFunction(this);
alert(myString);     // catch here: if you're using it in a anonymous function, you need to refer to as this.myString (see comments)

演示:http://jsfiddle.net/mrchief/HfFKJ/

你也可以这样重构它:

function mysteriousFunction() {
   this.myString = "[value here]";   // we'll change the meaning of this when we call the function
}

然后call(双关语)你的函数在不同的上下文中是这样的:

var ctx = {};
mysteriousFunction.call(ctx);
alert(ctx.myString);

mysteriousFunction.call(this);
alert(myString);

演示:http://jsfiddle.net/mrchief/HfFKJ/4/

【讨论】:

  • @Matthew:如果你要声明一个匿名函数,那么你必须调用alert(this.myString)。不过,这是一个不错的选择,我在答案中对其进行了更新。 jsfiddle.net/mrchief/cgKnF/1
  • 对,但我认为关键是他不想写this.myString
  • @Matthew:在他的 OP 中,他也没有在匿名函数中使用它。如果您要更改范围,那么 this.myString 不会造成任何伤害。无论如何,它比使用 eval 要好得多。
  • @Alex,你永远不会在那里创建对象,所以 thiswindowmyString 是全局的。
  • @Alex:我觉得你把我和马修搞糊涂了!
【解决方案3】:

我很确定如果没有eval,就不可能从另一个函数写入函数范围(即模拟var)。

请注意,当您传递this 时,您要么传递窗口,要么传递一个对象。两者都不标识函数(非全局var 的范围)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多