[英]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.