2017-10-18 57 views
0

我有一個JavaScript模塊,它看起來是這樣的:在node.js中,爲什麼`require`一個IIFE會在全局空間中創建一個閉包?

const Tools = {}; 
Tools.log = (function { 
    var logPath = ''; 
    // ... and all the stuff that is returned below 
    return { 
     setLogPath: setLogPath, 
     trace: trace, 
     debug: debug, 
     info: info, 
     warn: warn, 
     error: error 
    }; 
})(); 
module.exports = Tools; 

我這個模塊中的兩個文件使用要求:

var log = require(path/to/module).log; 

我本來期望每個需要語句來創建一個單獨關閉,但我發現如果我在一個文件中調用setLogPath方法,那麼另一個文件中的日誌路徑也會改變。

這實際上對我很好。但我不明白爲什麼只有一個關閉正在創建。

我期待在每次使用require語句時運行Tools.log函數,在使用require語句的文件中創建Tools.log函數的單獨關閉。這顯然不是這種情況。在這些文件中,const Tools = require(path/to/Tools/).log位於全局名稱空間中,如果這有所幫助。

require語句是如何工作的?

這段代碼顯示了我所期待的:

const A = function() { 
    var closureVal = 'a' 

    function changeVal(val) { 
     closureVal = val; 
    }; 

    function printVal() { 
     console.log(closureVal); 
    }; 
    return { 
     changeVal: changeVal, 
     printVal: printVal 
    }; 
}; 
var x = A(); 
x.printVal(); // a 
x.changeVal('x'); 
x.printVal(); // x 
var y = A(); 
y.printVal(); // a 
y.changeVal('y') 
y.printVal(); // y 
x.printVal(); // x 

回答

0

其實如果我改變上面的測試代碼,使用這樣的IIFE:

const A = (function() { 
    var closureVal = 'a' 

    function changeVal(val) { 
     closureVal = val; 
    }; 

    function printVal() { 
     console.log(closureVal); 
    }; 
    return { 
     changeVal: changeVal, 
     printVal: printVal 
    }; 
})(); 
var x = A; 
x.printVal(); // a 
x.changeVal('x'); 
x.printVal(); // x 
var y = A; 
y.printVal(); // x 
y.changeVal('y') 
y.printVal(); // y 
x.printVal(); // y 

然後我看到同樣的事情,與要求聲明。我期望這樣做,因爲在這個測試中A函數只運行一次,然後vars x,y作爲指針分配給結果對象。

但我仍然沒有看到爲什麼require語句會發生同樣的情況,我期望在每次模塊加載時運行該函數

相關問題