2

让我们从代码开始:

function say(name) {
    var ghost=function () {
        function ghost() {
            alert('!');
        };

        return body;
    };

    eval("var body=''+"+name+';');
    eval(name+('=('+ghost).replace('body', body)+')();');
    eval(name+'();');
}

function Baal() {
    if ('undefined'===typeof ghost) {
        say('Baal');
        return;
    }

    ghost();
}

say('Baal'); // or just Baal();

看起来魔鬼的名字会唤起他的存在(好吧,也许他需要某人来获得精神财产)..

正如你所看到的,幽灵并不存在Baal,但我们可以调用它,因为evals 中有 s say(name)

say(name) 将其作为闭包重新分配Baal给其代码体并使其捕获ghost方法,这就是事情的工作方式。但我试图避免eval..

所以..让我改写这个问题:

如何在不使用的情况下使不存在的(而不是成员或全局)方法可以调用eval

4

4 回答 4

2

让我改写你的问题,只是为了确保我明白了。给定一个函数,您希望在其范围内放置一个新变量,而该范围不是全局范围或调用者和主题之间共享的范围,而不使用eval(或等效的new Function和其他黑客,取决于环境)。

你不能。

在您刚才提到的情况下,您可以定义一个函数 ,base()它使用arguments.callee.caller.

不要那样做。

于 2013-09-30T19:00:34.363 回答
1

简短的回答:你没有。

该范围不可用。如果您要附加范围,那么它将在使用的范围内可用。然后您可以访问方法句柄。我认为这不是您想要的,但这就是它的样子。演示

function say(name){
 var methods = {};   
 methods.Baal = function(){
  alert("!");  
 };

 return methods[name];//this could invoke as well: methods[name]()
}

var handle = say('Baal');
handle();

您的评估分解为这些方面的内容(尽管具有来自字符串构建的动态内容 - 这是最终结果)

function say(name) {
 var Baal = (function () {
    function ghost() {
        alert('!');
    };

    return function(){ 
     if ('undefined'===typeof ghost) {
      say('Baal');
      return;
     }
     ghost();
   }
 })();
 Baal();
}

say('Baal'); // or just Baal();

请注意,这里发生的内容来自函数Baal,即它调用硬编码ghost(),而硬编码又调用硬编码警报。为什么要经历所有这些麻烦来访问硬编码的函数?

更好的方法是将此函数作为回调注入,该回调需要注入一些参数。

jsFiddle Demo

function say(callback){
 var params = "!";
 if( typeof callback == "function" ){
  callback(params);   
 }
}

say(function(params){
 alert(params);  
});
于 2013-09-30T20:06:55.073 回答
0

It's very difficult for me to read through your code and figure out what you are trying to accomplish with it, but it appears that you are trying to introduce a variable into the current scope so that you can call it. You cannot do this in javascript with the method that you demonstrated. Scoping only ever "flows down". By that I mean that a variable or function defined within a function will only be available to that function and any other functions defined therein. Your function named ghost will only ever be available within the function where it is defined, regardless of when that function is evaluated.

What you can do, however, is write a function that returns a function. You can then call that function and assign the result to a variable in the scope where you want to expose functionality. Doing that would look something like this.

function defineSpecialAlert() {
    return function(name) {
        alert(name + "!");
    };
}

var newlyDefinedMethod = defineSpecialAlert();

newlyDefinedMethod("Baal");
于 2013-09-30T19:28:21.430 回答
0

因此,如果我理解,您似乎想创建 eval 的别名:类似于

#Note this code is not intended as a solution, but demonstrates
#an attempt that is guaranteed to fail.
#
function myAlias(ctx) {
eval.call(ctx, 'var ghost = 42');
}

myAlias(this);
alert(ghost);

Javascript 允许许多时髦的花招,尤其是在使用闭包时,但这可能是 javascript 无法做到的一件不可能的事情。我已经尝试过做同样的事情,我可以告诉你,你只会遇到来自浏览器的抱怨,说 eval 不能以任何方式重新设置上下文或别名。

于 2013-09-30T19:14:00.477 回答