咱們進入公司以後,咱們可能會重新開發一個網站.這種狀況,咱們定義什麼參數,使用什麼名字所有都是隨本身的想法,本身維護也可能會很正常.javascript
可是假如咱們進入公司接手的是別人的代碼呢?和其餘同事一塊兒同事合做開發呢?html
這時候咱們不少以前不注意的小習慣就可能會形成巨大的災難.java
<script type="text/javascript"> var a = "li"; var b = "peng"; ... </script>
能夠看到,咱們在編寫 JS 的時候直接定義了兩個變量,他們的做用域都是直接在 Window 做用域下的,可是假如咱們的另一個工程師,也去直接定義了兩個變量,並且名字相同呢?jquery
這樣會直接形成代碼的衝突,引發某些不知名的錯誤.ajax
那咱們該如何去解決呢?編程
咱們可使用匿名函數去對腳本進行包裹,讓變量的做用域控制於匿名函數中.瀏覽器
<script type="text/javascript"> (function(){ var a = "li"; var b = "peng"; ... })(); </script>
能夠看見,咱們在上的代碼中使用了一個匿名函數 (function(){})();
.bash
執行代碼的時候,包裹在這個匿名函數中的變量,它的做用域就不是 window 了,而是侷限在函數內部,這樣也就不會引發代碼衝突了.服務器
可是這樣並非就一勞永逸了,假如說咱們在不一樣的腳本之間互相通訊呢?框架
咱們須要在網頁中添加新功能,在新功能中須要使用到以前定義的函數中的某一個變量,這時候該怎麼辦?
最簡單的解決方案:直接把新的代碼也放在以前的匿名函數中,可是,這樣並不符合咱們的代碼規範,
並且加入以前的功能是已經離職的員工寫的呢?
你還須要首先去閱讀他以前寫的程序,去避開每個衝突.
其次,你還須要將本身書寫的內容去進行封裝,這樣會逼死人的
(PS: 別問我我是怎麼知道的 ╮(;´༎ຶД༎ຶ`)╭ )
那麼如何去解決這個問題呢?
咱們能夠在 window 做用域下定義一個全局變量,把它做爲一個橋樑,完成各匿名函數之間的通訊.
<script type="text/javascript"> var str; </script> <script type="text/javascript"> (function(){ var a = "li"; str = b = "peng"; ... })(); </script> <script type="text/javascript"> (function(){ var a = "li"; var b = str; ... })(); </script>
可是咱們有多個變量呢?難道須要一個個去定義麼?
咱們可使用一個 { } 對象類型的變量做爲全局變量,若是匿名函數之間須要多個變量做爲通訊橋樑,能夠將這些變量都做爲全局變量的屬性,這樣能夠保證全局變量不多,並且拓展性很好.
<script type="text/javascript"> var GLOBAL = {}; </script> <script type="text/javascript"> (function(){ var a = "li"; var b = "peng"; GLOBAL.str = a; GLOBAL.str2 = b; ... })(); </script> <script type="text/javascript"> (function(){ var a = GLOBAL.str; var b = GLOBAL.str2; ... })(); </script>
除此以外,咱們在團隊合做中,還能夠將本身的名字縮寫也放在變量命名中,並且還應該去適當的寫明註釋,這些都是能夠大大加快團隊合做進程的工做方式.
你們都知道,JS 是中腳本語言,咱們的瀏覽器下載到哪裏,就會執行到哪裏.
這種特性會爲編程帶來很大的便利,可是同時也會形成代碼過於零散,四處分佈.
爲了解決這種問題,咱們首先須要從功能上對程序進行職能的劃分.
網頁中的 JS 從功能上應該分爲兩大部分 ------ 框架部分 和 應用部分.
1. 框架部分提供對 JS 代碼的組織做用的代碼,其中應該包括 定義全局變量, 定義命名空間等方法.它和應用無關,每一個頁面都須要包括相同的框架,因此框架部分的代碼在每一個頁面都相同.
2. 應用部分提供的是頁面功能邏輯,不一樣頁面會有不一樣的功能,不一樣的頁面應用部分的代碼也不相同.
<script type="text/javascript"> function init(){ (function(){ ... }()); (function(){ ... }()); (function(){ ... }()); (function(){ ... }()); } </script>
能夠看見,咱們將全部應用部分的代碼都集中到 init 函數內了,全部的初始化工做都在這裏,這裏就是網頁程序的入口.
可是須要注意,若是程序控制某個 DOM 節點,而該 DOM 節點當時尚未被載入,程序會直接報錯.
有兩種解決方案,第一種最簡單的解決方案,直接把腳本放在後面.
可是有時候,咱們但願咱們的程序可以無視這種放置規則,可讓程序的位置在 DOM 節點以前或者以後.
這時候咱們能夠去 監聽 window 對象的 onload 事件,當 window 觸發 onload 事件以後去調用腳本.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript"> function init(){ alert(document.getElementById("test").innerHTML); } window.onload = init; </script> </head> <body> <div class="test">MR_LP</div> </body> </html>
這樣,咱們的腳本不會當即執行,而是在 window.onload 以後纔去執行.
而 window 對象會在頁面內元素所有加載完成以後纔去觸發 onload 事件,而這時候咱們的 test 已經加載完畢,因此並不會報錯.
你覺得如今就能夠萬事大吉了麼? 固然不是. ٩(๑˃̌ۿ˂̌๑)۶
若是頁面加載的時候,存在某張超級大的圖片呢?
window.onload 會等所有加載完成纔會觸發,難度這期間就讓用戶等着?
這時候就要說到 DOMReady
了.
DOMReady 只判斷頁面內全部的 DOM 節點 是否已經所有生成,至於節點中的內容是否已經加載,並不會檢查.
因此 DOMReady 會 比 window.onload 加載速度要快不少.
可是須要注意, DOMReady 並非原生 JS 支持的事件,通常咱們都是結合 JS 框架去使用.
如 jQuery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" scr="http://ajax.googleAPIs.com/ajax/libs/jquery/1.3/jquery.min.js"></script> <script type="text/javascript"> function() init{ alert(document.getElementById("test").innerHTML); } $(document).ready(init); </script> </head> <body> <div class="test">MR_LP</div> </body> </html>
固然咱們也能夠本身去模擬 DOMReady ,即咱們去定義了 init 函數,以後等<body>
以前的時候去調用一下 init 函數,這時候雖然 DOM 節點不必定都所有加載完成了,可是卻必定都生成了,經過這種方式,能夠去簡單模擬一下 DOMReady.
完事了? 固然沒有 (இдஇ) .
在實際工做中,網站的頭部和尾部常常會作成獨立的文件,用服務器端語言 include 到網頁中,因此咱們的網頁常常會拆散成三個文件,頭部,主體和尾部三個文件.
通常來講,頭尾文件都很是穩定.由於全站公用的統一結尾,這部分不會常常修改,而主體部分是每一個頁面各不相同的,若是有的頁面不須要 JS, 這時候咱們的主體中可能就沒有 init 函數了,這時候調用就確定會報錯了.
這時咱們固然能夠去作一個規範,讓每一個頁面都去書寫一次,可是這並不合理.
正確的處理方式是咱們在書寫 init 以前能夠先去判斷一下 init 是否存在.
if(init){ init(); }
這樣就能夠有效的避免上述問題了.
做者:MR_LP___李鵬連接:https://www.jianshu.com/p/92a41e9b4a1b來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。