本喵又來給大家送來新鮮的讀書筆記啦.
大家感不感動? ( ´థ౪థ)
今天文章主要是來說一下,在工作中書寫 JS 時的團隊協作以及如何一些小技巧.
新的文章正在撰寫中,諸君可以回頭看看之前的文章
最後,求點贊,求分享,如果是女孩紙的話,哼哼,求抱抱! (づ。◕‿‿◕。)づ
以下爲正文
1.養成良好的編程習慣
1.1 團隊合作——如何避免 JS 衝突
我們進入公司之後,我們可能會從新開發一個網站.這種情況,我們定義什麼參數,使用什麼名字全部都是隨自己的想法,自己維護也可能會很正常.
但是假如我們進入公司接手的是別人的代碼呢?和其他同事一起同事合作開發呢?
這時候我們很多之前不注意的小習慣就可能會造成巨大的災難.
<script type="text/javascript">
var a = "li";
var b = "peng";
...
</script>
可以看到,我們在編寫 JS 的時候直接定義了兩個變量,他們的作用域都是直接在 Window 作用域下的,但是假如我們的另外一個工程師,也去直接定義了兩個變量,而且名字相同呢?
這樣會直接造成代碼的衝突,引起某些不知名的錯誤.
那我們該如何去解決呢?
我們可以使用匿名函數去對腳本進行包裹,讓變量的作用域控制於匿名函數中.
<script type="text/javascript">
(function(){
var a = "li";
var b = "peng";
...
})();
</script>
可以看見,我們在上的代碼中使用了一個匿名函數 (function(){})();
.
執行代碼的時候,包裹在這個匿名函數中的變量,它的作用域就不是 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>
除此之外,我們在團隊合作中,還可以將自己的名字縮寫也放在變量命名中,而且還應該去適當的寫明註釋,這些都是可以大大加快團隊合作進程的工作方式.
具體操作可以參考我之前的文章: 編寫高質量的 HTML 代碼
1.2 給程序一個統一的入口 —— window.onload 和 DOMReady
大家都知道,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 框架去使用.
如 JQ.
<!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();
}
這樣就可以有效的避免上述問題了.
1.3 CSS 放頁頭, JS 放頁尾
CSS 放在頁頭,在載入 HTML 元素之前先載入,這樣可以避免 HTML 出現無樣式狀態.
JS 放在頁尾,可以避免 JS 阻塞網頁的呈現,減少頁面空白的時間.
1.4 文件壓縮
在之前的文章中曾經說明過,css 發佈前需要進行壓縮.
可以參考我之前的文章: 編寫高質量的 HTML 代碼
同樣的, JS 部分我們也可以去進行一下壓縮,這裏推薦兩個工具
Packers: packer
YUI Compressor: Compressor
需要注意 YUI 需要下載 jar 文件到本地,之後通過命令行調用,
好處是 YUI 不僅僅可以壓縮 JS,還可以壓縮 css.
下期預告:
JavaScript 的分層概念和 JavaScript 庫