犀牛書讀書筆記-01

第一章,概述


這章是綜述性質的,做者隨意的給出了一些例子。javascript

1. visibility = hidden, display = none。html

function hide (e, reflow) {
        if (reflow) {
            e.target.style.display = "none";
        } else {
            e.target.style.visibility = "hidden";
        }
}

這段代碼展現了兩種隱藏節點的方式,以前在項目中接觸最多的是display=none,對visibility=hidden的方式沒用過,還不知道這種方式和display = none有什麼區別。
visibility = "hidden",元素會隱藏,可是不會把元素從渲染樹種拿掉,它依然會部分渲染,只是不可見而已(變成徹底透明,只會觸發repaint)。
display = "none",那麼元素就不會渲染,整個從渲染樹中拿掉了。會觸發reflow與repaint。
好比 java

block one
block two
block three

中間的元素visibility = hiddennode

block one
hidden block
block three

中間的元素display = nonegit

block one
hidden block
block three

其實我想問爲何中間那個所謂只會觸發repaint的隱藏方式會傲嬌的多出來一截。。。。。。顯然這種狀況下瀏覽器會reflow的。想一想多是由於我用了自動寬度。果真,這樣就和諧多了。
使用固定寬度 github

block one
block two
block three
block one
block two
block three

2. Bind events with DOM node's "on" attributes。正則表達式

給DOM元素定義事件最簡單的方法是,給DOM節點以"on"爲前綴的屬性綁定一個回調。出於頁面維護性的考慮,這種代碼和HTML節點寫一起玩法正常狀況下不多會用到。 編程

<div style = "border: 1px solid gray" onmousedown="(function(node){node.textContent = new Date().toString();})(this);">點擊我文字會改變</div>
<div style = "border: 1px solid gray" onmouseup="(function(event){event.target.textContent = new Date().toString();})(event);">點擊我文字會改變</div>

3. addEventListener。數組

玩的更多的應該仍是addEventListener。瀏覽器

<div id = "click_node">點擊我看看</div>
<script>
    window.onload = function() {
        var node = document.getElementById('click_node');
        if (node && node.addEventListener) {
           node.addEventListener('mousedown', function(){
               node.textContent = "mouse down on node";
           }, false);
           node.addEventListener('mouseup', function(event){
               node.textContent = "mouse up on node";
           }, false);
        }
    }
</script>

注意幾個小問題,好比addEventListener的第一個參數是須要綁定的事件名,全小寫的,並且沒有」on」前綴。(若是兼容老版IE用attachEvent的話則須要加上on前綴)。第三個參數是用來指定是否把linstener註冊在事件的capture階段,通常都是false,也是使用element.onclick = function(){}這種綁定方式的的默認行爲。

關於DOM事件的生命週期,能夠參考一下這篇文章。這裏插一句,文章中提到經過阻止不必的事件冒泡能夠提高性能,不過做者提到的event.cancelBubble這種方式並不被提倡(參考),應該使用event.stopPropagation()來替代這種方式。

 

第二章,詞法結構


這章主要內容是JS程序的詞法構成,並無什麼須要特別注意的。

1. JavaScript會認爲它正在解析的程序代碼已是這種標準格式,不會再對標示符、字符串、正則表達式作標準化處理。

關於JavaScript與Unicode,我準備專門再寫一篇總結文章。這個Normalization問題有時候挺煩人的,特別是要對字符串作細緻處理的時候。ES6已經添加一個新方法String.prototype.normalize來提供這個功能,在此以前可使用一些庫來完成,好比unorm (https://github.com/walling/unorm)(by Bjarke Walling).

2. 在return、break、continue語句和隨後的表達式之間不能有換行。

不然會出現難以調試的程序問題。正常人應該都不會這麼寫的。

3. 「++」與「--」做爲後綴的時候要與表達式在同一行。

同上,正常人不會另起一行寫++--的。

 

第三章,類型、值和變量


1. JavaScript的數據類型分爲兩類:原始類型(primitive type)與對象類型。簡單(原始)類型(simple types)有numbers、strings、booleans、null 和 undefined。剩下的其餘的都是對象類型。

注意一下number、string、boolean是類對象(object-like)由於他們有一些預約義的方法,但它們是immutable的。

2. JS不區分整數和浮點數。全部的數字都是雙精度浮點數,採用IEEE 754標準。JS中實際的操做(好比數組索引、位操做)則是基於32位整數。

因爲是雙精度浮點數,因此有喜聞樂見的 0.1 + 0.2 != 0.3。任何採用二進制浮點數的編程語言都會有這個問題。
關於實際操做,好比位操做時使用32位整數, 寫代碼時能夠利用這個特性來把小數轉換成整數,參考我這篇文章,《javascript中小數轉換爲整數》
IEEE 754 中關於雙精度浮點數的規定是1位數符、11位階碼再加上52位的有效數位。因爲規範要求小數必須是標準形式,即小數點左邊爲1,因此用52位有效數字表示了53位的  信息。其所能精確表示的整數範圍就是 2^53 ~ -2^53。

3. JS中的NaN有一點特殊:它和任何值都不相等,包括自身。

因此看到dojo庫中有這樣的equals,也是爲了讓兩個NaN可以「相等」。

function equals(a, b){
    return (a === b) || ( a !== a && b !== b);
}
4. JS中字符串是Immutable的,相似replace、toUpperCase都是返回新串。

其實前面第一條講類型時已經說過了。

5. JS中有「包裝對象」的存在,前面提到的使用簡單類型的方法其實是經過建立臨時的包裝對象,而後再使用包裝對象的方法。null和undefined沒有包裝對象,試圖引用他們的任何屬性都會拋錯。

簡單對象雖然看起來有一些屬性,好比"123".length, 可是試圖給它賦值屬性(如"123".attr = 4)會被忽略掉 ("123".attr is still undefined)。

6. JS會在必要的時候把包裝對象轉換成原始值。如「==」認爲原始值與其包裝對象相等(包裝對象會向原始值轉換),可是「===」不會進行任何轉換,因此不等。

對象原始值的比較(==)會試圖把對象的原始值求出來再比較,若是是兩個對象比較,則比較他們是否引用同一個對象。

var  a = 'a',
     b = 'a',
     c = new String('a');
     d = new String('a');
a == b // true
a === b // true   a == c // true, 會轉換
a === c // false, 全等不轉換 c == d // false, 兩個對象的比較
c === d // false, 沒懸念

7. 對象向原始值的轉換有些複雜。顯示轉換最簡單,好比 Number("3"), Object(3)。

有一些經常使用的簡單寫法

+x //把x轉換成Number, 至關於Number(x), 也能夠寫成 x - 0,不過沒+x看起來好看
!!x //估計你們見得多了,至關於Boolean(x)

8. Object to Boolean 全部的對象類型都會轉成true。

因此別太驚訝,new Boolean(false)其實是會轉換成true。

if(new Boolean(false))
   console.info("yes, new Boolean(false) is truthy");

9. Object to Number/String, 涉及到toString(), valueOf()這兩個方法,通常狀況下轉成string,toString會先調用,不行就valueOf;轉成number則順序顛倒。

10. 「-「會把它的兩個操做數都轉換成數字。而對於」+「,不少時候+的操做數會被轉換成字符串。

[1] + 1; // 」11「
[1] - 1; //0
new Date() + 1; //"Sun Aug 10 2014 00:20:41 GMT+0800 (China Standard Time)1"
new Date() - 1; //1407601216775

11. 關於變量,JS中沒有塊級做用域,JS是函數做用域。因此有一種」聲明提早「的非正式稱謂(hoisting)。

實際上JS腳本雖然是解釋執行,可是在逐行執行以前還有一個」預編譯「的過程,這個過程會把context中聲明的變量放入」棧「中,並未他們賦值爲undefined,而後再開始逐條執行語句。

體會一下這個例子

a();
function a() { console.info(1);}
a();
function a() {console.info(2);}
a();
a = function () { console.info(3);}
a();
//輸出:
//2 2 2 3

12. 使用var 聲明的變量沒法被delete刪除,而做爲對象的屬性能夠。

刪除一個你本身聲明的變量確實沒有什麼必要。

(function() {
    var a = '123';
    console.info(a);
    delete a;
    console.info(a);
})();
//輸出兩個」123「

13. 做用域鏈與閉包。

這個我決定再單獨開一個坑。

相關文章
相關標籤/搜索