犀牛书读书笔记-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. 做用域链与闭包。

这个我决定再单独开一个坑。

相关文章
相关标签/搜索