更改Javascript中的变量功能范围 [英] Change variable scope of function in Javascript

查看:98
本文介绍了更改Javascript中的变量功能范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对致电不感兴趣,也不想申请更改this参考.只是出于我自己的利益,我正在研究另一个需要JavaScript的需求技术的想法,该技术可以使一些更简洁的定义成为可能,并且目标是不必为我的定义传递数组或加倍引用模块名称.

I'm not interested in call or apply to change the this reference. Just for my own interest, I'm playing with an idea for another require technique for javascript that would make for some cleaner definitions, and the goal was to not have to pass arrays or doubly reference module names for my definitions.

我有一个在函数上使用toString和eval的示例解决方案(只是概念证明),但我想知道是否存在更安全或更有效的方法.

I have a sample solution (just a proof of concept) using toString and eval on a function but I'm wondering if there is a safer or more efficient way to do this.

// Sample module libraries (would probably be in their own files)
someModules = { 
    testModule: {test: function(){console.log("test from someModule")}},
    anotherModule: { doStuff: function(){console.log("Doin stuffs!");}}
};

sampleRequire = function() {

    // Load the modules
    for (var i=arguments.length-2; i>=0; --i){

        // Create a local variable reference to the module
        eval ('var '+arguments[i]+' = someModules.'+arguments[i].toString());
    }

    // Redefine the programmer's function so that it has my local vars in its scope
    eval("var fn = "+arguments[arguments.length-1]);

    return fn;
}

// Main code...
sampleRequire( 'testModule', 'anotherModule',
    function(){ 
        testModule.test();
        anotherModule.doStuff();
    }
)();

Pointy提出了一个极好的观点,即这将完全破坏主函数的作用域,这通常是不可接受的.理想情况下,我希望看到模块变量被添加到函数的作用域中,而不会破坏其其他作用域变量(模块名称除外-程序员必须知道在两件事上不要使用相同的名称).我敢打赌这可能是不可能的,但我仍然很乐意看到一些想法.

Pointy made an excellent point that this would completely destroy the main function's scope, which would often times be unacceptable. Ideally I'd like to see the module variables being added to the function's scope without clobbering its other scoped variables (with the exception of the module names--the programmer must know not to use the same name for two things). I'm betting this is probably impossible, but I would still love to see some ideas.

另一个目标是灵活地执行此操作,而不必在每个模块的主函数中添加参数.否则,我们将回到CommonJS样式的第一位(我不打算与之抗争,只是对范围感到好奇!).

Another goal is to do this flexibly without having to add arguments per module to the main function. Otherwise we're back to square one with CommonJS styles (which I'm not trying to fight, just curious about scope!).

推荐答案

我倾向于说您做错了".即使可以,使用未声明的变量也不是一个好主意.

I tend to say "you're doing it wrong". Using undeclared variables is never a good idea, even though you can.

这是另一个将模块写入全局对象的黑客.但是,这可能会对从主函数调用的方法产生副作用.

Here's another hack which writes the modules to the global object. However, this may have side effects on the methods called from the main function.

sampleRequire = function() {

    var cache = {};
    var moduleNames = [].slice.call(arguments);
    var fn = moduleNames.pop();

    return function () {
        var result, name, i;
        // export modules to global object
        for (i = 0; i < moduleNames.length; i++) {
            name = moduleNames[i];
            cache[name] = window[name]; // remember old values
            window[name] = someModules[name];
        }
        result = fn.apply(null, arguments);
        // restore original global stuff
        for (i = 0; i < moduleNames.length; i++) {
            name = moduleNames[i];
            window[name] = cache[name];
        }
        return result;
    };
}

我还尝试了with关键字,这基本上是为您想要的内容而设计的.但是,在这种情况下,如果没有eval,它将无法正常工作.

I also tried some magic with the with keyword, which was basically made for precisely what you want. However, it looks like it doesn't work without eval in this case.

这篇关于更改Javascript中的变量功能范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆