天天看點

用純Javascript打造類似NodeJS的子產品載入系統

用純Javascript打造類似NodeJS的子產品載入系統

 http://www.2cto.com/kf/201111/111190.html

nodejs的子產品系統有兩個重要的特點:

1. 子產品中直接用var定義的變量是僅作用與目前子產品的,而不是全局。

2. 每個子產品中都可以使用require和module這兩個“全局變量”。之是以打上引号,因為它們其實是每個子產品都有的通用執行個體,不同子產品中的執行個體是不一樣的。

javascript中除了用function func(){}來定義一個函數之外,還可以用new function()來建立一個函數。function是javascript中所有函數的prototype,即所有函數的基類。通過給function.prototype增加屬性可以給所有的函數執行個體增加屬性,這也是大家相對常用的一個做法。今天要給大家介紹的是通過直接new function()來建立一個函數,盡管這被認為性能不好,但在某些特殊場景能做到一些很有用的功能。

new function()的詳細文法格式是:

new function(args, body) 

這裡的args是一個字元串,表示函數的參數,參數之間用逗号隔開,而body則是函數體本身。比如:

var add = new function('x, y', 'return x + y;');

這樣建立的函數就等價于:

var add = function(x, y){ 

     return x + y; 

這兩者效果沒有任何差別,通常我們也隻會用第二種做法,因為有更好的可讀性。

現在我們來看new function的兩種潛在應用場景:

1. 避免命名沖突

大家知道通過<script>标簽引入的javascript檔案是全局的,每個檔案中定義的變量都是全局的,這時為了避免命名沖突,可以通過如下的小技巧:

(function(){ 

     var x = 0; 

     //my code 

})(); 

通過外包一個函數并立刻調用,可以做成一個閉包,其中的變量的作用域就隻局限于函數體之内。進而避免了與其它的檔案之間的命名沖突。但是在有些情況下,我們需要使用一個第三方的javascript檔案或者因為某些原因而無法修改的檔案,它完成某個獨立的任務,但是其中定義了一些全局變量。這些檔案無法被修改成使用上面提到的方法來避免命名沖突。這時我們的new function()就可以發揮作用了。這時我們不是通過<script>引入javascript檔案,而是通過xmlhttprequest獲得javascript檔案的内容,然後用如下的方式來執行這個javascript:

var result = (new function('', jscode + '; return {x: x}'))(); 

這樣,我們相當于也是在jscode外面包裝了一層function,并且,我們把需要用的的結果作為傳回值傳回出來,供外面程式使用。當然,對于大部分獨立的檔案,我們并不一定需要傳回值,而隻是需要執行一下即可。下面來看下一個應用場景。

2. 打造自己的子產品載入系統

這也是上一種應用場景的一個延伸,既然我們通過這種方式來載入javascript檔案,何不将其做成一個通用的子產品載入系統,供自己的項目使用。進而不用每個檔案都外包一層function來避免命名沖突。其實如果大家用過nodejs,就也許知道,nodejs中的每個子產品中定義的變量都是局限于目前子產品的,不會被其它子產品直接使用。而且每個子產品中還有一個預設的require和module變量,這兩個每個子產品中都可以像使用全局變量一樣使用,但它們卻又不是全局變量,nodejs文檔中寫的也很清楚,它們在各個子產品中都是不同的執行個體。這樣,一個子產品都它們進行的修改并不會影響到其它子產品。你也許會認為這一定是nodejs的native環境提供的特殊功能,但實際上,我們完全可以用純javascript打造出一個同樣的子產品機制,隻需對上面提到的例子做一點修改,比如這個loader是有類似如下的代碼:

var require = getrequireinstance(); 

var module = getmoduleinstance(); 

 //通過xmlhttprequest獲得要載入的javascript檔案的代碼 

var moduletext = getmoduletext();   

//執行子產品代碼,并“注入”require和module變量。 

(new function('require, module', moduletext))(require, module); 

怎麼樣,是不是很簡單?new function()雖然是一個很少用的功能,但是确實非常靈活,更多應用場景就靠大家繼續挖掘了

摘自 dojo中文部落格-

繼續閱讀