[JS奇怪的世界]No.21 框架小叮嚀:預設值
第一個框架的小叮嚀
接下來將針對框架做一個小觀念叮嚀,這邊課程講解的是 jQuery,為什麼會拿 jQuery 來講解呢呢?以前最熱門的框架非 jQuery 莫屬,舉凡動畫效果等等都是由 jQuery 一手包辦,並不用說瀏覽器適應問題,所以這章節拿 jQuery 來作範例再適合不過了。
所以這次課程將結合前面學的參數預設值,還有執行環境、全域環境等觀念,試著去了解 jQuery 程式碼。
課程建立了三個檔案做範例,假設 lib1 及 lib2 都是由別人所撰寫的第三方套件。
- lib1.js
- lib2.js
- app.js // 我們自己的核心 js
lib1.js 內容是 ↓
1 | var libraryName = 'Lib1'; |
lib2.js 內容是 ↓
1 | var libraryName = 'Lib2'; |
那如果同時載入時會發生什麼事情?
1 |
|
我們試著在 all.js
寫入 console.log(libraryName);
,這時候它會吃到誰?
答案是吃到 lib2.js,為什麼?首先在 HTML 中 lib1.js 是第一個載入 var libraryName = 'Lib1';
的,後來第二行 lib2.js 載入了 var libraryName = 'Lib2';
,而 var libraryName
目前所建立的環境是全域執行環境,所以代表著 libraryName
是全域變數,所以當 lib2 的 libraryName 建立時才會導致蓋掉原本的 lib1.js 的 libraryName
。
那該如何解決?其中一個方法使用 ES6 中的 let
↓
lib1.js 內容是 ↓
1 | var libraryName = 'tomy'; |
lib2.js 內容是 ↓
1 | var libraryName = 'jack'; |
結果會變什麼?
結果會是 tomy
,而且還會出現一個錯誤 SyntaxError: redeclaration of let libraryName
,這句錯誤是在說 libraryName
被重複命名了,也就是說因為 ES6 let
的特性,所以才不會因為 lib2.js 後加載導致 libraryName
被覆蓋掉。
另外課程上也有寫另一種不使用 ES6 的方式
lib2.js 內容 ↓
1 | window.libraryName = window.libraryName || 'lib2'; |
意思是在檢查當全域環境下是否已經有了 libraryName
這個變數,如果有那麼就不做任何動作,若沒有在建立新的 libraryName
叫 lib2
。
結果呢?
這樣就可以知道當若我們不使用 ES6 的時候可以這樣做,避免衝突問題,這也是人家所謂的全域變數汙染,而這個做法在課程上也有一個專有名詞「**檢查全域命名空間 (global namespace)**」,當然我是比較頃向使用 ES6。