如何在不使用eval的情况下使不存在(非成员,非全局)方法可调用?

时间:2013-09-30 18:45:26

标签: javascript

让我们从代码开始:

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一起不存在,但我们可以调用它,因为eval中存在say(name)

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

所以..让我重新提出问题:

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

4 个答案:

答案 0 :(得分:2)

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

你不能。

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

不要那样做。

答案 1 :(得分:1)

简短的回答:你没有。

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

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);  
});

答案 2 :(得分: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不能以任何方式重新上下文或别名。

答案 3 :(得分:0)

我很难通读你的代码并弄清楚你要用它来完成什么,但看起来你正试图将一个变量引入当前范围,以便你可以调用它。您不能使用您演示的方法在javascript中执行此操作。范围只会“流下来”。我的意思是,函数中定义的变量或函数只能用于该函数和其中定义的任何其他函数。无论何时评估该函数,您的名为ghost的函数将只在定义它的函数中可用。

然而,您可以做的是编写一个返回函数的函数。然后,您可以调用该函数并将结果分配给要公开功能的作用域中的变量。这样做会是这样的。

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

var newlyDefinedMethod = defineSpecialAlert();

newlyDefinedMethod("Baal");