TASK 0002 已經發布,初級班的任務時間是從 4 月 24 日至 5 月 7 日,中級班為 4 月 18 日至 4 月 25 日。
TASK 0002 內容:https://github.com/baidu-ife/ife/tree/master/task/task0002
我做的:https://github.com/DIYgod/ife-work/tree/master/task0002
在線 Demo: https://www.anotherhome.net/file/ife/task0002/task0002_1.html
本次任務累計花費時間 17 天(4.19-5.6 )
下面是我做 TASK 0002 過程中的一些記錄。
**1. JavaScript 的性能優化 **(參考 JavaScript 的性能優化:加載和執行)
・Web 開發人員一般習慣在 <head> 中加載外鏈的 JavaScript,接著用 <link> 標籤用來加載外鏈的 CSS 文件或者其他頁面信息。然而這種常規的做法卻隱藏著嚴重的性能問題 —— 腳本會阻塞頁面其他資源的下載。因此推薦將所有 < script > 標籤儘可能放到 < body > 標籤的底部,以儘量減少對整個頁面下載的影響。
・由於每個 <script> 標籤初始下載時都會阻塞頁面渲染,所以減少頁面包含的 < script > 標籤數量有助於改善這一情況。
・ 減少 JavaScript 對性能的影響其他方法見參考。
2. ==
與 ===
(參考 Javascript 中雙等號 “==” 和三等號 “===” 的區別 JavaScript 裡面三個等號和兩個等號的區別 JavaScript 編碼規範)
==
:等於運算,但是不比較值的類型;
===
:完全等於運算,不僅比較值,而且還比較值的類型,只有兩者一致才為真。
百度 JavaScript 編碼規範也規定:在 Equality Expression 中強制使用類型嚴格的 ===
。僅當判斷 null 或 undefined 時,允許使用 == null
。因為使用 ===
可以避免等於判斷中隱式的類型轉換。
3. 類型檢測 (參考 JavaScript 編碼規範 Javascript 數組類型檢測:編寫更強壯的 isArray 函數 Javascript 判斷函數類型完美解決方案)
通用的簡易做法:類型檢測優先使用 typeof
。對象類型檢測使用 instanceof
。null 或 undefined 的檢測使用 == null
判斷數組類型:得到對象的字符串表示,然後對比此字符串是否是 '[object Array]'
9.20 更新:下面這樣也可以
判斷函數類型:首先保證測試的對象存在,並將其序列化成含有 “function” 的字符串,這個是我們檢測的基礎 (fn.constructor != String,fn.constructor != Array, and fn.constructor != RegExp)。另外,我們需要保證聲明的函數不是一個 DOM 節點(fn.nodeName)。然後,我們就可以作 toString 測試。如果我們將一個函數轉換成字符串,在一個瀏覽器中(fn+"")給我們的結果就像這樣 “function name (){...}”。現在,判斷它是否為函數就很簡單,僅僅只需要判斷字符串中是否包含單詞 “function”。這很神奇,對於任何有問題的函數,在所有瀏覽器中都能得到我們所需要的結果。這個函數較之於傳統的方法,運行速度有些不盡人意,作者(John Resig)建議我們保守使用。
9.20 更新:上面那種太麻煩,可以類似 Array 那樣判斷
複製 Array 的簡單做法:
4. 類型轉換 (參考 JavaScript 編碼規範)
number -> string:
string -> number:
-> boolean:
number 去除小數點:
5. 對有序集合進行遍歷時,緩存 length (參考 JavaScript 編碼規範)
雖然現代瀏覽器都對數組長度進行了緩存,但對於一些宿主對象和舊舊瀏覽器的數組對象,在每次 length 訪問時會動態計算元素個數,此時緩存 length 能有效提高程序性能。
6. document.body.scrollTop 與 document.documentElement.scrollTop 獲取滾動條滾動的距離的坑 (參考 document.body.scrollTop 與 document.documentElement.scrollTop 兼容 用 Javascript 獲取頁面元素的位置 火狐、谷歌、IE 關於 document.body.scrollTop 和 document.documentElement.scrollTop 以及值為 0 的問題)
參考阮一峰的教程寫了下面一段:
沒想到遇到了坑,結果 elementScrollLeft 總是 0,調試結果如下:
好坑啊,說好的如果有文檔聲明(即網頁第一句的 docType)的情況下,document.compatMode 的值等於 "CSS1compat",標準瀏覽器是只認識 documentElement.scrollTop 的啊。
另外試了一下 IE 和 Firefox,均可認 documentElement.scrollTop,chrome 的錯!
還好 document.body.scrollTop 與 document.documentElement.scrollTop 兩者有個特點,就是同時只會有一個值生效。比如 document.body.scrollTop 能取到值的時候,document.documentElement.scrollTop 就會始終為 0;反之亦然。所以可以這樣寫:
7. 獲取所有 DOM 元素
突然腦洞大開想到的
8. 真假判斷
對象總為 true,基礎類型看是否為空
容易把空數組誤以為是 false!
容易把空數組誤以為是 false!
容易把空數組誤以為是 false!
重要的事情要說三遍!
9. 遞歸獲取所有子元素
這個是有問題的,只能獲取到下級的子元素:
但如果改成這樣就能獲取所有子元素了:
第一段代碼出現問題的原因未知,已經想一晚上了,並無進展。
另外調試過程中發現的詭異現象:
解釋下:遞歸調用時返回值 allchilds 是正確的,但返回到上一層時並沒有加到上一層的 allchilds 中。
月月 告訴我這句話有問題!
w3school 如是說:concat () 方法用於連接兩個或多個數組。
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。僅僅會返回被連接數組的一個副本。僅僅會返回被連接數組的一個副本。
一切都說通了。。
所以根本不關 allchilds 聲明位置的事,debug 的方向一直都不對,要這樣改:
萬萬沒想到,在 月月 李勝 蛋炒飯 的幫助下千辛萬苦終於完成了這個小函數。。。
後續:突然想到這樣就能輕易獲取到
已吐血
10. 數組合併 (參考 JavaScript concat () 方法)
重要的事情要另外單獨說。因為被坑慘了。
concat () 方法用於連接兩個或多個數組。
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。
錯誤用法:
正確用法:
11. 事件代理 (參考 javascript 事件代理)
在編程中,如果我們不想或不能夠直接操縱目標對象,我們可以利用 delegate 創建一個代理對象來調用目標對象的方法,從而達到操縱目標對象的目的。毋庸置疑,代理對象要擁有目標對象的引用。
可以用事件代理的方法來優雅地用一個函數代理另一個函數,比如:
這樣就能優雅地用 on un 函數代理 addEvent removeEvent 函數了。這樣實現了目標對象的隱藏,這對於我們保護一些核心對象是非常有用的。
我錯了,直接這樣就行了。。
12. Object 相關 (參考 js 的 Object 到底是什麼呢?)
Array、Boolean、Date、Function、Number 等等對象,其實都是從 Object 來的,它們的祖先都是 Object。它們表現不同的語言特性,比如 Array 有被自動管理的 length 屬性,Boolean 只有 true 或 false 取值,Date 表示時間結構,Function 可以被運行,都是它們的原始類型 (valueOf) 賦予它們的能力。
所以有些有趣的東西:
可以給函數設置一個也是函數的屬性。
13. JavaScript 正則表達式分組 (參考 JavaScript 正則表達式 选择、分組和引用)
例:
其中 re.exec (document.cookie) 是一個數組,第一個元素是正則式所有匹配出的字符,第二個元素是匹配的第一個分組,即第一個括號裡的內容:(.*?)
分組就就是正則表達式中的子表達式,可以用來獲取正則式匹配出的字符串中的特定部分。
9.20 更新:當使用構造函數創造正則對象時,需要常規的字符轉義規則(在前面加反斜杠 \)。比如,以下是等價的:
14. JavaScript 跨域 (參考 JavaScript 跨域總結與解決辦法)
JavaScript 出於安全方面的考慮,不允許跨域調用其他頁面的對象。但在安全限制的同時也給注入 iframe 或是 ajax 應用上帶來了不少麻煩。
具體限制及解決辦法見參考。
15. JavaScript 月份多出一 (參考 JS 中 new Date 怎麼就多一個月了? JavaScript—— 搞甘特圖使用 Date 對象時遇到的問題)
明明設置的是 5 月,結果卻是 6 月。
實際中,我們數月份不是從 0 開始,但是 JavaScript 卻是從 0 開始。JS 中的 0 月是我們的 1 月,JS 中的 1 月是我們的 2 月...
所以設置月份時記得減一,獲取月份時記得加一。。
15. 計時器不會阻塞代碼執行
我的本意是執行完 a () 再輸出 b,沒想到 b 先輸出了,從這裡也可以推測出,計時器並不會阻塞後面語句的執行。
☆ミ(o*・ω・)ノ完結散花 等待 review