這是幾乎不可能恰當地比較這些功能。人們只能比較它們在特定語言中的實現。我主要使用Java和nodejs語言收集了我的經驗。
我發現這些差異:
- 可以使用
require
不僅僅是爲了使其他模塊提供給您的模塊的更多。例如,您可以使用它來解析JSON文件。
- 您可以在代碼中使用
require
無處不在,而import
只能在文件的頂部。
require
實際執行所需的模塊(如果尚未執行),而import
有着更爲聲明性特性。這對所有語言來說可能都不是這樣,但這是一種趨勢。
require
可以從子目錄加載私有依賴項,而import
通常對所有代碼使用一個全局名稱空間。再說一遍,這也不是真的,而只是一種傾向。
責任
正如你所看到的,require
方法有多重責任:聲明模塊依賴和讀取數據。這更好地與導入方法分開,因爲import
應該只處理模塊依賴關係。我猜想,您可以使用require
方法讀取JSON,它爲程序員提供了一個非常簡單的界面。我同意擁有這種簡單的JSON閱讀界面非常好,但是不需要將它與模塊依賴關係機制混合使用。可以有另一種方法,例如readJson()
。這將分離關注點,因此require
方法僅用於聲明模塊依賴關係。
位置在代碼
現在,我們只使用require
爲模塊依賴關係,這是一個不好的做法,使用其他地方比在您的模塊的頂部。當您在代碼中的任何地方使用它時,都很難看到模塊依賴關係。這就是爲什麼您只能在代碼頂部使用import
語句的原因。
我看不到導入創建全局變量的地步。它僅爲每個依賴項創建一致的標識符,該標識符僅限於當前文件。正如我上面所說的,我建議只在文件的頂部使用require
方法。它確實有助於提高代碼的可讀性。
它是如何工作
執行代碼加載一個模塊,也可以是一個問題的時候,尤其是在大項目。您可能會遇到一個循環,其中一個模塊需要傳遞自己。這可能很難解決。據我所知,的NodeJS處理這種情況,像這樣:當A需要B和B要求A和您的要求,然後開始:
- 模塊系統會記住它目前加載
- 它執行代碼在一個
- 它會記住當前正在加載乙
- 其B中執行代碼
- 它會嘗試加載A,但A已經加載
- 一個尚未完成加載
- 它返回的一半裝A到B
- B不指望能在半載
這可能是一個問題。現在,人們可以爭辯說,應該避免循環依賴,我同意這一點。但是,循環依賴只能在程序的不同組件之間避免。組件中的類通常具有循環依賴性。現在,模塊系統可以用於兩個抽象層:類和組件。這可能是一個問題。
接下來,require
方法通常會導致單例模塊,它們不能在同一個程序中多次使用,因爲它們存儲全局狀態。然而,這不是系統的錯誤,但程序員錯誤地錯誤地使用系統。不過,我的觀察是,require
方法誤導了特別是新程序員這樣做。
依賴管理
的依賴管理是底圖不同的辦法確實是一個有趣的問題。例如,Java在當前版本中仍然錯過了正確的模塊系統。再次,它宣佈了下一個版本,但誰知道這是否會成爲現實。目前,您只能使用OSGi獲取模塊,這遠非易於使用。
下層nodejs的依賴管理非常強大。但是,這也不完美。例如,通過模塊API公開的非私有依賴性(通常是一個問題)是通過模塊API公開的依賴性。但是,這是依賴管理的常見問題,因此它不限於nodejs。
結論
我想兩者都沒有那麼糟糕,因爲每個成功使用。然而,在我看來,import
比require
有一些客觀優勢,如責任分離。因此,import
可以被限制在代碼的頂部,這意味着只有一個地方可以搜索模塊依賴關係。此外,import
可能更適合編譯語言,因爲這些不需要執行代碼來加載代碼。
您要查找的功能究竟是什麼,區分這兩個系統的功能是什麼? – svick
@svick主要是require函數,它返回一個函數或其他結構化數據。 與'從x導入x'隱式創建全局可訪問屬性相反,只能在文件頂部完成。 – ISNIT