首页 > 代码库 > Professional JavaScript for Web Developers 3rd Edition ---读书笔记

Professional JavaScript for Web Developers 3rd Edition ---读书笔记

1. DOMContentLoaded DOM树构建完成时触发该事件

   load 页面加载完毕触发

原生js

document.addEventListener(‘DOMContentLoaded‘, function(){
    //code.....
}, false);

document.addEventListener(‘load‘, function(){
     //code...
}, false);

jquery

//DOMContentLoaded
$(document).ready(function(){
   //code...
});

//load
$(document).load(function(){
  //code...
});

2. XHTML中的用法

小于号(<)再xhtml中会被当做开始一个新标签来解析, 作为标签后面不能根空格。

技术分享

不兼容xhtml

技术分享

3. 区分大小写

变量名test和Test表示两个不同的变量

4. 注释

//单行注释

/**/多行注释

5. 严格模式

"use strict";

技术分享

6.  ECMAScriptz中有5中简单的数据类型  Undefined、Null、Boolean、Number、String

和    1中复杂数据类型 Object(Object实际上是一组无序的名值对组成)

7. typeof操作符

技术分享

typeof null 返回object, 因为特殊值null被认为是一个空的对象引用

8. Undefined类型

该类型只有一个值, 即undefined;

使用var声明变量但未初始化时, 这个变量的值就是undefined。var message; alert(message);//undefined alert(message == undefined);//true

如果变量未声明, 使用会出错,如alert(age); ReferenceError: age is not defined; typeof age //undefined 使用var声明或没声明都返回undefined

技术分享

9.Null类型

该类型只有一个值null

如果定义的变量在将来用于保存对象, 那么最好将它初始化为null。

undefined派生自null alert(null == undefined)//true, (==)相等操作符属于比较的目的会转换其操作数

10. Boolean类型

该类型只有两个字面量值 true和false

要将一个值转换为其对应的Boolean值, 可以调用转型函数Boolean().

Boolean("hello world");//true 非空字符串

Boolean("");//false 空字符串

技术分享

这些转换规则对流控制语句(if)自动执行相应的Boolean转换非常重要

var message = "hello world";

if(message){alert}

11. Number类型

11.1   8进制  在数字前面加0 如 071表示 57; 如果字面值超过了范围, 则前导0将被忽略 如 079 表示79

          在严格模式下无效

16进制  在字面量0x a-f 可以大小写

11.2  浮点数  科学计数法 e  , e前面的数值乘以10的指数次幂 var a = 3.123e3// 3123

最小值 Number.MIN_VALUE

最大值 Number.MAX_VALUE

NaN (Not a Number) b任何数值除以0 都会返回NaN

特点: 1. NaN/10 //NaN 任何操作返回NaN

         2. NaN == NaN //false

11.3 isNan(param)函数     某些不是数值的值会被转换为数值,然后返回false, 如 "10"或者 true(被转换为1); 不能  被转换为数值的值返回true

技术分享

11.4 数值转换

 有3个函数可以把非数值转换为数值 Number(), parseInt(), parseFloat

技术分享

例子

技术分享

parseInt函数在转换字符串时,更多的是看其是否符合数值模式, 他会忽略字符串前面的空格, 直到第一个非空格字符

技术分享

例子

技术分享

注意

技术分享

消除困惑, 提供第二个参数(转换时使用的基数 进制)

var num1 = parseInt(‘AF‘, 16);//175

var num2 = parseInt(‘AF‘);//NaN

建议:无论在什么情况下都明确指明基数

parseFloat的典型示例

技术分享

12. String类型

技术分享

转换为字符串

技术分享

 注意 null 和 undefined值没有这个方法; 默认十进制, 可以输出其他进制的字符串

技术分享

String()函数

技术分享

另一种转换成字符串的方式  (x + "")

13. Object类型

技术分享

3.5 操作符

3.5.1 一元操作符

1. 递增 递减 操作符

技术分享

示例

技术分享

2. 有符号整数

技术分享

3.5.3 布尔操作符

001 逻辑非

技术分享

同时使用两个逻辑非操作符(!!)就会模拟Boolean()转型函数的行为

例子

技术分享

002 逻辑与(&&)

技术分享

注意 : 逻辑与是一个短路操作符

003 逻辑或

技术分享

 

 3.5.4 乘性操作符

技术分享

001 乘法

技术分享

002 除法

技术分享

003 求模

技术分享

3.5.5 加性操作符

001 加法

技术分享

002 减法

技术分享

几个例子

技术分享

3.5.6 关系操作符

技术分享

大写字母的字符编码全部小于小写字母的字符编码

任何操作数与NaN比较 结果都是false

var result1 = NaN < 3; //false

var result2 = NaN >= 3; //false

 3.5.7 相等操作符

001 相等和不相等( == 和 !=)

 比较之前转换操作数

技术分享

比较时的规则

技术分享

002 全等和不全等

比较之前不转换操作数

var result1 = "55" == 55;//true

var result2 = ("55" ===55); //false

技术分享

3.5.8 条件操作符

3.5.9 赋值操作符

复合赋值操作符 +=之类

3.5.10 逗号操作符

在用于赋值时, 逗号运算符总是返回最后一项

var num = (5, 1, 3, 4, 0);//0

3.6.2 do-while语句

var i=0;

do{

  i+=2;

}while(i<10);

alert(i);

3.6.4 for语句

由于ECMAScript 中不存在块级作用
域(第4 章将进一步讨论这一点),因此在循环内部定义的变量也可以在外部访问到。

即使i 是
在循环内部定义的一个变量,但在循环外部仍然可以访问到它。

3.6.5 for-in语句

技术分享

这个过程会一直持续到对象中的
所有属性都被枚举一遍为止。与for 语句类似,这里控制语句中的var 操作符也不是必需的。但是,
为了保证使用局部变量,我们推荐上面例子中的这种做法。
ECMAScript 对象的属性没有顺序。因此,通过for-in 循环输出的属性名的顺序是不可预测的。

但是,如果表示要迭代的对象的变量值为null 或undefined,for-in 语句会抛出错误。
ECMAScript 5 更正了这一行为;对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的

兼容性,建议在使用for-in 循环之前,先检测确认该对象的值不是null 或undefined

3.6.6 label语句

技术分享

3.6.7 break和 continue语句

outermost : for(){};

break:outermost 从outermost后开始执行

continue: outermost 从outermost开始执行

 3.7 函数

ECMAScript 中的函数在定义时不必指定是否返回值 实际上,任何函数在任何时候都可以通过
return 语句后跟要返回的值来实现返回值

另外,return 语句也可以不带有任何返回值。在这种情况下,函数在停止执行后将返回undefined
值。这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下

3.7.1理解参数

技术分享

这个事实说明了ECMAScript 函数的一个重要特点:命名的参数只提供便利,但不是必需的。另
外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但
在ECMAScript 中,没有这些条条框框,解析器不会验证命名参数。

虽然这个特性算不上完美的重载,但也足够弥补ECMAScript 的这一缺憾了。

技术分享

关于arguments 的行为,还有一点比较有意思。那就是它的值永远与对应命名参数的值保持同步。

,这并不是说读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步。

另外还要记住,如果只传入了一个参数,那么为arguments[1]设置的值不会反应到
命名参数中。这是因为arguments 对象的长度是由传入的参数个数决定的,不是由定义函数时的命名
参数的个数决定的。

4.1 基本类型和引用类型的值

基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。

4.1.1 动态的属性

var person = new Object();

person.name = "zhangsan";

4.1.2 复制变量值

技术分享

4.1.3 传递参数

 技术分享

4.1.4 检测类型

typeof 检测基本类型

知道某个值是什么类型的对象 instanceof

var result = variable instanceof constructor

如果变量是给定引用类型的实例, 那么instanceof就返回true

如果使用instanceof检测基本类型的值, 则该操作符始终返回false, 因为基本类型不是对象

4.2 没有块级作用域

任何位于局部变量color 的声明之后的代码,如果不使用window.color 都无法访问全局color变量

4.3.2 引用计数

技术分享

消除循环引用

myObject.element = null;

element.someObject = null;

为了解决上述问题,IE9 把BOM 和DOM 对象都转换成了真正的JavaScript 对象。这样,就避免了
两种垃圾收集算法并存导致的问题,也消除了常见的内存泄漏现象。

5.1 Object对象

创建Object对象的两种方式:

001 new 操作符

var person = new Object();

person.name = "zhangsan";

002 对象字面量

var person = {

          name : "zhangsan",

          age : 19

};

可以使用方括号来访问对象的属性

person["first name"]

5.2 Array类型

创建数组的基本方式有两种

001 Array 构造函数

var color = new Array();

002 使用数组字面量

var color = ["red", "blue", "green"];

数组的项数保存在length属性中( 0+)  通过设置这个属性, 可以从数组的末尾移除项 或向数组中添加新项

var colors = ["red", "blue", "green"];

colors.length = 2;

alert(colors[2]);//undefined

colors.length = 4;

alert(colors[3]);//undefined

利用这个特性可以方便的添加新项

colors[colors.length] = "gray";

colors[colors.length] = "yellow";

5.2.1 检测数组

技术分享

5.2.2 转换方法

所有对象都有 toLocaleString(), toString(), valueOf()方法

var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
alert(colors.toString()); // red,blue,green
alert(colors.valueOf()); // red,blue,green
alert(colors); // red,blue,green

如果使用join() 方法, 可以使用不同的分隔符来创建这个字符串

colors.join("&");// red&blue&green

技术分享

5.2.3  栈方法

push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而
pop()方法则从数组末尾移除最后一项,减少数组的length 值,然后返回移除的项。

var colors = new Array();

var count = colors.push("green", "blue");

alert(count);//2

var  item = colors.pop();

alert(item);//blue

5.2.4 队列方法

因此要模拟队列只需一个从数组前端取得项的方法。实现这一操作的数组方法就是shift(),它能够移
除数组中的第一个项并返回该项,同时将数组长度减1。结合使用shift()和push()方法,可以像使
用队列一样使用数组。

var item = colors.shift();

alert(item);//green

unshift()与shift()的用途相反:
它能在数组前端添加任意个项并返回新数组的长度。因此,同时使用unshift()和pop()方法,可以
从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项

5.2.5 重排序

数组中有两个重排序方法

reverse() 反转数组项的顺序

sort() 即使数组中的每一项都是数值, sort() 方法比较的也是字符串(调用每一项的toString()方法 然后比较字符串)

var values = [0, 1, 5, 10, 15];
values.sort();
alert(values); //0,1,10,15,5

sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。
比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等
则返回0,如果第一个参数应该位于第二个之后则返回一个正数

function compare(value1, value2) {//升序
if (value1 < value2) {
return -1;//return 1 降序
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); //0,1,5,10,15

5.2.6 操作方法

001  concat()方法

技术分享

002 slice() 方法

技术分享

003 splice()方法

技术分享

splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何
项,则返回一个空数组)

5.2.7 位置方法

indexOf()

lastIndexOf()  

var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4,4));
alert(numbers.lastIndexOf(4, 4));

5.2.8 迭代方法

技术分享

var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return (item > 2);
});
alert(everyResult); //false
var someResult = numbers.some(function(item, index, array){
return (item > 2);
});
alert(someResult); //true

var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]

var mapResult = numbers.map(function(item, index, array){
return item * 2;
});

alert(mapResult); //[2,4,6,8,10,8,6,4,2]

最后一个方法是forEach(),它只是对数组中的每一项运行传入的函数。这个方法没有返回值,
本质上与使用for 循环迭代数组一样。来看一个例子。
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
//执行某些操作
});

5.2.9 归并方法

reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。

其中,reduce()方法从数组的第一项开始,逐个遍历到最后。

而reduceRight()则从数组的最后一项开始,向前遍历到第一项

给reduce()和reduceRight()的函数接收4 个参数:前一个值、当前值、项的索引和数组对象。这
个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第
一个参数是数组的第一项,第二个参数就是数组的第二项

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15

reduceRight()的作用类似,只不过方向相反而已

5.3 Date类型

var now = new Date();不传递参数的情况下,新创建的对象自动获得当前日期和时间

001 Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数。

如果直接将表示日期的字符串传递给Date 构造函数,也会在后台调用Date.parse()

var someDate = new Date(Date.parse("May 25, 2004"));等价于

var someDate = new Date("May 25, 2004");

 

002 Date.UTC()  日期和时间都基于本地时区而非GMT 来创建

// GMT 时间2005 年5 月5 日下午5:55:55
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));

// 本地时间2005 年5 月5 日下午5:55:55
var allFives = new Date(2005, 4, 5, 17, 55, 55);

003 Data.now()

//取得开始时间
var start = Date.now();

使用+操作符把Data 对象转换成字符串,也可以达到同样的目的。

//取得开始时间
var start = +new Date();

5.3.1 继承的方法

Date 类型也重写了toLocaleString()、toString()和valueOf()方法;

5.3.3 日期/时间组件方法  p120

5.4 RegExp类型

创建正则表达式 var expression = /pattern/flags;

其中的模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类、限定符、分组、向前查找以及反向引用

正则表达式的匹配模式支持下列3 个标志。
? g:表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即
停止;
? i:表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写;
? m:表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模
式匹配的项。

因此,一个正则表达式就是一个模式与上述3 个标志的组合体。不同组合产生不同结果

001 以字面量形式来定义的正则表达式

/*
* 匹配所有".at",不区分大小写
*/
var pattern4 = /\.at/gi;

002 RegExp 构造函数创建正则表达式

/*
* 与pattern1 相同,只不过是使用构造函数创建的
*/
var pattern2 = new RegExp("[bc]at", "i");

ECMAScript 5 明确规定,使用正则表达式字面量必须像直接调用RegExp 构造函数一样,每次都创
建新的RegExp 实例。

5.5 Function类型

函数实际上是对象

每个函数实际上都是Function类型的实例

p128

Professional JavaScript for Web Developers 3rd Edition ---读书笔记