2012-07-19 24 views
2

說我有以下模塊,跨多個文件分割既能夠延伸skillet是否有可能讓變量只顯示「模塊」及其擴展名?

File1.js:

(function(){ 
var privateVar1 = 0; 

var privateFunction1 = function() { 
    //function definiton 
}; 

skillet.fry() = function() { 
    //fry it 
    //matchbox.light(); 
}; 

})(window.skillet = window.skillet || {}); 

File2.js:

(function(){ 
var privateVar2 = 0; 

var privateFunction2 = function() { 
    //some private function 
}; 

skillet.grillIt = function() { 
    //grill It 
    //matchbox.strike(); <-- Shared with File1.js 
}; 

})(window.skillet = window.skillet || {}); 

是否有可能共享變量/對象如matchbox由兩個模塊共享沒有綁定到window.matchboxwindow.skillet.matchbox?即知名度matchbox應該只適用於File1.js和File2.js,並且不能在其他地方訪問。我懷疑是否有可能,但有沒有辦法在JavaScript中實現這樣的行爲?如果不是,這方面的最佳做法是什麼?

(它更像具有共享事件總線一組相關模塊中,而不暴露全局該總線)

回答

3

不。

「私有」變量只能在JS中使用,因爲函數聲明的範圍。無法與在完全不同範圍內聲明的函數共享該範圍。範圍一旦創建,就是功能不可改變的屬性。

這就是爲什麼這種事通常與_foo樣式屬性完成。

skillet._matchbox = { strike: function() { ... } }; 

下劃線前綴是「內部」的約定,並作爲一個提示,不要弄亂它。


你也可以發揮創意與您如何通過matchbox雖然身邊,雖然在所有的情況下,這將意味着提供一種方式來獲得matchbox出它的原始範圍。也許也許,製作一個skillet.extend方法,將火柴盒傳遞給它的參數?

(function() { 
    var matchbox = { strike: function() { ... } } 
    window.skillet = { 
    extend: function(fn) { 
     fn(matchbox); 
    } 
    }; 
})(); 

skillet.extend(function(matchbox) { 
    var privateVar2 = 0; 
    var privateFunction2 = function() {}; 

    skillet.grillIt = function() { 
    //grill It 
    matchbox.strike(); 
    }; 
} 

它允許您以受控方式在原始範圍之外使用matchbox。但它也允許任何人得到matchbox,這可能不應該。

var stolenMatchbox; 
skillet.extend(function(matchbox) { 
    stolenMatchbox = matchbox; 
}); 
while (stolenMatchbox.count > 0) { stolenMatchbox.strike(); } 
alert("Now you are outta matches, sucker!"); 
2

由於您已將代碼劃分爲多個文件,因此您可以使用模塊加載器(如require.js)進行研究。您可以爲火柴盒定義第三個模塊,然後將它作爲參數傳遞給上面示例中的兩個skille。採用這種方法,您不必通過窗口全局公開火柴盒。

File1.js與require.js應該是這樣的:

define(['matchbox'], function(matchbox){ 
(function(){ 
    var privateVar1 = 0; 

    var privateFunction1 = function() { 
    //function definiton 
    }; 

    skillet.fry() = function() { 
     //fry it 
     matchbox.light(); 
    }; 

})(window.skillet = window.skillet || {}); 
}); 

火柴盒。js看起來像這樣:

define([], function() { 
    function light() { 
    //light implementation 
    } 

    function strike() { 
    //strike implementation 
    } 

    return { 
    light: light, 
    strike: strike 
    } 
} 
+0

我還沒有使用requirejs之前。你能否詳細說明前兩行的含義?封裝是如何實現的? – PhD 2012-07-19 20:06:29

+1

Require.js是一個JavaScript模塊加載器,它遵循[異步模塊定義(AMD)範例](http://requirejs.org/docs/whyamd.html)。通俗地說,這是一種在javascript的#include/import/using類型語法中定義模塊依賴關係的方法。 我包裝了File1.js的define()調用指定它取決於模塊的「火柴盒」,一旦它完成非同步加載,它將作爲參數「火柴盒」傳遞給函數。使用這種方法,不需要將您的火柴盒模塊註冊到全局名稱空間。 – GreatTall1 2012-07-20 16:16:21

相關問題