簡體   English   中英

將function的變量scope改成Javascript

[英]Change variable scope of function in Javascript

我對致電或申請更改this參考資料不感興趣。 出於我自己的興趣,我正在研究 javascript 的另一種 require 技術,這將使定義更清晰,目標是不必傳遞 arrays 或為我的定義重復引用模塊名稱。

我有一個在 function 上使用 toString 和 eval 的示例解決方案(只是概念證明),但我想知道是否有更安全或更有效的方法來執行此操作。

// 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 指出這會完全破壞主函數的 scope,這通常是不可接受的。 理想情況下,我希望看到模塊變量被添加到函數的 scope 而不會破壞其其他作用域變量(模塊名稱除外——程序員必須知道不要對兩件事使用相同的名稱)。 我敢打賭這可能是不可能的,但我仍然希望看到一些想法。

另一個目標是靈活地做到這一點,而不必為每個模塊添加 arguments 到主 function。否則我們將回到 CommonJS styles 的正方形(我不是想打架,只是對 scope 感到好奇。)。

我傾向於說“你做錯了”。 使用未聲明的變量從來都不是一個好主意,即使你可以。

這是另一個將模塊寫入全局 object 的 hack。但是,這可能會對從主 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 ,它似乎不起作用。

我想不出任何其他方式來做你所追求的。 我還懷疑這可能是少數幾個非惡意eval用例之一。 但請記住,模塊可能依賴於它們的作用域,這可能會破壞它們。

像這樣的東西怎么樣:

someModules = { 
  testModule: {test: function(){console.log("test from someModule")}},
  anotherModule: { doStuff: function(){console.log("Doin stuffs!");}}
};

function requireModules() {
  var all = [];
  for (var i = 0, l = arguments.length; i<l; i++) {
    all.push(someModules[i]);
  }
  return all;
}

(function(testModule,anotherModule){
  testModule.test();
  anotherModule.doStuff();
}).apply(null,requireModules('testModule','anotherModule'));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM