[英]Function scope in anonymous functions
我剛剛配置了gulp / bower來最小化並捆綁我的JavaScript文件,並且我創建了一些遵循自執行匿名函數格式的單個JS文件。 例如,假設我有一個名為“ mobile-functions.js”的文件,其中包含一個名為“ isViewportInMobile”的函數。
mobile-functions.js
(function ($) {
function isViewportInMobile(mobileWidthOverride) {
var widthToCheckAgainst = mobileWidthOverride || 768;
return window.innerWidth < widthToCheckAgainst;
}
})(jQuery);
如何從其他Javascript文件調用該函數(該文件也遵循自動執行的匿名函數格式)? 當我嘗試在其他文件中使用該函數時,它說isViewportInMobile是未定義的。
根據對相關文件的訪問量,可以對其稍加修改,以將自調用函數的范圍傳遞給變量。 但是,我假設如果您具有這樣的訪問權限,則可能不需要創建此線程,但是盡管如此,這是您可以執行的操作...
var something = (function($) {
this.isViewportInMobile(mobileWidthOverride) {
var widthToCheckAgainst = mobileWidthOverride || 768;
return window.innerWidth < widthToCheckAgainst;
};
return this;
})(jQuery);
然后,您可以像這樣調用該函數:
something.isViewportInMobile(params);
我希望這是有用的。
無法直接訪問該功能,它是在另一個功能的范圍內定義的,因此對於外部世界是不可見的。 但是,有一種非常好的方法,您可以在不膨脹全局范圍或通過某些全局對象訪問它們的 同時訪問該函數。
TL; DR這是可行的,可以使用匿名包裝程序和一些技巧。 無法縮短。 為文字牆做好准備。
我將嘗試舉一個示例,說明如何在不暴露全局變量的情況下如何巧妙地執行此操作,但這需要一些時間。
上面是一個小提琴示例,我將其制作為1個小提琴,但代表了您文件的4個,我將在此處將它們作為獨立文件發布。 另外,請確保您已仔細閱讀注釋,因為其中有些行“僅顯示”有效。 在制造產品時,應將其刪除。 要測試它是否確實有效,請閱讀第113行。
這個怎么運作:
您創建的所有模塊以及放入匿名JS函數的模塊,都需要在初始化之前將其Hooks賦予使用的方法。 然后在初始化時,將鈎子捕獲到匿名函數作用域的this
對象中供您使用。
模塊的模式非常簡單,您需要具備以下條件:
(function() {
var wrapper = this;
function InitializeModule(hookObject) {
var hooks = Object.keys(hookObject);
var i;
for (i = 0; i < hooks.length; i++) {
wrapper[hooks[i]] = hookObject[hooks[i]];
}
delete window['methodRegistrationName-config.js'];
}
//MAKE YOUR FUNCTIONS BELOW
//------------------------------------------------------------------
//------------------------------------------------------------------
function InitializeHooks(hooksObject) {
//REGISTER YOUR FUNCTIONS LIKE THIS:
hooksObject.addHook('globalyUniqueID', functionName)
window['methodRegistrationName-config.js'] = InitializeModule;
}
window['methodRegistrationName-config.js'] = InitializeHooks;
window['activeModules']--;
})();
所有模塊都遵循完全相同的模式,您可以自由創建和引用在任何其他模塊中創建的任何功能(只要已加載)。 您需要做的就是使config.js和fileHandler.js如我在下面指定的那樣,並根據需要添加任意數量的模塊。 所有配置都在config.js中完成。
我制作了兩個模塊(module1.js和module4.js),並將其發布在下面,以便您可以看到它的工作原理。 查看開頭鏈接的小提琴。
制作一個config.js像這樣:
//CONFIG.js
(function() {
//User manually configures which modules he wants to use
var config = {
// Name : [ load? , path, methodRegistrationName ]
Module1: [true, 'js/module1.js', 'InitializeModule1'],
Modele2: [false, 'js/module2.js', 'InitializeModule2'],
Module3: [false, 'js/module3.js', 'InitializeModule3'],
Module4: [true, 'js/module4.js', 'InitializeModule4']
}
Initialize();
//-------------------------
// DO NOT TOUCH BELOW (a note for your users)
//-------------------------
function Initialize() {
//Required module to make all of this work (this one always has to be added);
config['fileHandler'] = [true, 'js/filehandler.js'];
//-----------------------------------------------------------------------------
var modules = Object.keys(config);
var activeModules = 0;
var i;
var bodyElement = document.getElementsByTagName('body')[0];
var scriptString = "";
for (i = 0; i < modules.length; i++) {
if (config[modules[i]][0]) {
scriptString = "<script type=\"text/javascript\" scr=\"" + config[modules[i]][1] + "\">";
// Now this next line is going to be commented because we dont want fiddle to use it,
// instead we will alert. In your project however you want to add these and NOT alert.
// bodyElement.innerHTML += scriptString;
activeModules++;
console.log(scriptString);
//These scripts will be added to the body;
}
}
window['activeModules'] = activeModules;
var interval = setInterval(scriptsLoadedCheck, 500)
function scriptsLoadedCheck() {
if (window['activeModules'] === 0) {
//all scripts loaded, clear interval you are ready to continue
clearInterval(interval);
delete window['activeModules'];
InitializeFileHandler(config);
}
}
}
})();
現在使fileHandler.js像這樣(這是唯一不能包裝的文件,盡管它可以與config合並,在這種情況下可以包裝):
//FILEHANDLER.js
function InitializeFileHandler(configObject) {
var moduleHooks = {
addHook: function(id, callback) {
if (this.checkHook)
moduleHooks[id] = callback;
else
console.error("Hook already registered.")
},
checkHook: function(id) {
if (this[id] !== undefined)
return true;
return false;
}
}
initializeActiveModules();
function initializeActiveModules() {
var modules = Object.keys(configObject);
var i;
for (i = 0; i < modules.length; i++) {
if (modules[i] === 'fileHandler')
continue;
if (configObject[modules[i]][0]) {
console.log(configObject[modules[i]]);
window[configObject[modules[i]][2]](moduleHooks);
}
}
//------------------------------------------------------------HOOKS INITIALIZED, NOW REAL
for (i = 0; i < modules.length; i++) {
if (modules[i] === 'fileHandler')
continue;
if (configObject[modules[i]][0]) {
window[configObject[modules[i]][2]](moduleHooks);
}
}
}
}
window['activeModules']--;
現在,您可以制作您的模塊,例如module1.js :
//MODULE1.js
(function() {
var wrapper = this;
function InitializeModule(hookObject) {
var hooks = Object.keys(hookObject);
var i;
for (i = 0; i < hooks.length; i++) {
wrapper[hooks[i]] = hookObject[hooks[i]];
}
delete window['InitializeModule1'];
//This next line should NOT be here, it is here just to test/show it works
Module1Function1();
}
function Module1Function1() {
//Change the arguement to 'Module4Function1ID' to simulate a call from Module4;
console.log(Module1Function2ID());
}
function Module1Function2() {
return "Worked!";
}
function InitializeHooks(hooksObject) {
hooksObject.addHook('Module1Function1ID', Module1Function1)
hooksObject.addHook('Module1Function2ID', Module1Function2)
//Once hooks are initialized, the initialization process switches to the module
window['InitializeModule1'] = InitializeModule;
}
window['InitializeModule1'] = InitializeHooks;
window['activeModules']--;
})();
例如, module4.js像這樣:
//MODULE4.js
(function() {
var wrapper = this;
function InitializeModule(hookObject) {
var hooks = Object.keys(hookObject);
var i;
for (i = 0; i < hooks.length; i++) {
wrapper[hooks[i]] = hookObject[hooks[i]];
}
delete window['InitializeModule4'];
}
function Module4Function1() {
return "Function from module4";
}
function InitializeHooks(hooksObject) {
hooksObject.addHook('Module4Function1ID', Module4Function1)
//Once hooks are initialized, the initialization process switches to the module
window['InitializeModule4'] = InitializeModule;
}
window['InitializeModule4'] = InitializeHooks;
window['activeModules']--;
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.