diff --git a/grammar/basic.md b/grammar/basic.md index 8989d23d..b0215f8b 100644 --- a/grammar/basic.md +++ b/grammar/basic.md @@ -14,41 +14,37 @@ JavaScript程序的执行单位为行(line),也就是一行一行地执行 语句(statement)则是以完成某种任务为主要目的的操作,不一定有返回值。比如下面就是一个赋值语句: -{% highlight javascript %} -var a = 1 + 3 ; -{% endhighlight %} +`var a = 1 + 3 ;` + 这条语句将 1+3 的运算结果赋值给变量a。它是没有返回值的,因为主要目的不是为了得到返回值。 语句以分号结尾,一个分号就表示一个语句结束。多个语句可以写在一行内。 -{% highlight javascript %} - -var a = 1 + 3 ; var b = "abc"; +`var a = 1 + 3 ; var b = "abc";` -{% endhighlight %} 分号前面可以没有任何内容,解释器将其视为空语句。 -{% highlight javascript %} + ;;; -{% endhighlight %} + 上面的代码就表示3个空语句。(关于分号的更多介绍,请看后文《结尾的分号》一节。) 表达式不需要分号结尾。一旦在表达式后面添加分号,则解释器就将表达式视为语句,这样会产生一些没有任何意义的语句。 -{% highlight javascript %} -1 + 3; -"abc"; +`1 + 3;` + +`"abc";` + -{% endhighlight %} 上面两行语句有返回值,但是没有任何意义,因为没有使用这个返回值,也没有任何其他操作。 @@ -56,7 +52,7 @@ var a = 1 + 3 ; var b = "abc"; Javascript提供两种注释:一种是单行注释,用//起头;另一种是多行注释,放在/* 和 */之间。 -{% highlight javascript %} + // 单行注释 @@ -67,69 +63,72 @@ Javascript提供两种注释:一种是单行注释,用//起头;另一种 释 */ -{% endhighlight %} + ## 变量 变量是对“值”的引用,使用变量等同于引用一个值。每一个变量都有一个变量名。 -{% highlight javascript %} -var a = 1; -{% endhighlight %} +`var a = 1;` + + 上面的代码先声明a,然后在变量a与数值1之间建立引用关系,也称将数值1“赋值”给变量a。以后,引用a就会得到数值1。最前面var,是变量声明命令。它表示通知解释器,要创建一个变量a。 变量的声明和赋值,是分开的两个步骤,上面的代码将它们合在了一起,实际的步骤是下面这样。 -{% highlight javascript %} -var a; -a = 1; + var a; + + a = 1; + -{% endhighlight %} JavaScript允许省略var,也就是说,省略上面的第一行命令,直接对未声明的变量赋值,效果完全相同。由于这样的做法很容易不知不觉地创建全局变量(尤其是在函数内部),所以建议总是使用var命令声明变量。 但是,如果一个变量也没有声明和赋值就使用,JavaScript会报错,告诉你变量未定义。 -{% highlight javascript %} -console.log(x) -// ReferenceError: x is not defined -{% endhighlight %} +`console.log(x)` +`// ReferenceError: x is not defined ` + + 可以在同一条var命令中声明多个变量。 -{% highlight javascript %} -var a,b; -{% endhighlight %} +`var a,b;` + + ### 变量提升 JavaScript解释器的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升。 -{% highlight javascript %} -alert(a); -var a = 1; -{% endhighlight %} +`alert(a);` + +`var a = 1;` + + 上面的代码等同于下面的写法,所以解释器不会报错,但是结果不会得到1,而是undefined。 -{% highlight javascript %} -var a; -alert(a); -a = 1; -{% endhighlight %} +`var a;` + +`alert(a);` + +`a = 1;` + + ## 区块 @@ -137,18 +136,18 @@ JavaScript使用大括号,将相关的语句组合在一起,称为“区块 与大多数编程语言不一样,JavaScript的区块不构成单独的作用域(scope)。也就是说,区块中的变量就是全局变量。 -{% highlight javascript %} -{ - var a; - a = 1; -} + { + var a; + a = 1; + + } + + a + // 1 -a -// 1 -{% endhighlight %} ## 数据类型 @@ -170,25 +169,25 @@ Javascript的值的类型分成两大类:原始类型(primitive type)和 undefined表示“未定义”,即还没有确定数据类型。如果一个变量只是被声明,没有被赋值,那么它的值默认就是undefined。 -{% highlight javascript %} -var v; -v -// undefined + var v; + + v + // undefined + -{% endhighlight %} null表示空对象。它不是一种单独的数据类型,而是包含在对象类型(object)之中的一种特殊值。 -{% highlight javascript %} -var v = null; -v -// null + var v = null; + + v + // null + -{% endhighlight %} 这里需要明确的是,Javascript的所有数据,都可以视为对象,数组和函数只不过是特殊的对象而已,就连数值、字符串、布尔值都可以用对象方式调用。 @@ -198,103 +197,103 @@ v (1)如果值的类型是布尔值,返回boolean。 -{% highlight javascript %} -typeof false -// boolean -{% endhighlight %} + typeof false + // boolean + + (2)如果值的类型是数值,返回number。 -{% highlight javascript %} -typeof 123 -// number -{% endhighlight %} + typeof 123 + // number + + (3)如果值的类型是字符串,返回string。 -{% highlight javascript %} -typeof "123" -// string -{% endhighlight %} + typeof "123" + // string + + (4)如果值的类型是函数,返回function。 -{% highlight javascript %} -typeof print -// function -{% endhighlight %} + typeof print + // function + + (5) 如果值的类型是undefined: 返回undefined。 -{% highlight javascript %} -> typeof undefined + + typeof undefined "undefined" -{% endhighlight %} + 利用这一点,typeof可以用来检查一个没有声明的变量,而不报错。其他语法结构都没有这个功能。 -{% highlight javascript %} -v -// ReferenceError: v is not defined -typeof v -// undefined + v + // ReferenceError: v is not defined + + typeof v + // undefined + -{% endhighlight %} (6)如果值的类型是null,返回object。 -{% highlight javascript %} -typeof null -// object -{% endhighlight %} + typeof null + // object + + (7)如果值的类型不属于上面任何一种情况,返回object。 -{% highlight javascript %} -typeof window -// object -typeof {}; -// object + typeof window + // object -typeof []; -// object + typeof {}; + // object + + typeof []; + // object + + typeof null; + // object -typeof null; -// object -{% endhighlight %} 考虑到typeof对数组(array)和对象(object)的显示结果,都是object。因此,可以使用instanceof运算符进一步区分。 -{% highlight javascript %} -var o = {}; -var a = []; + var o = {}; + + var a = []; -o instanceof Array -// false + o instanceof Array + // false + + a instanceof Array + // true -a instanceof Array -// true -{% endhighlight %} ## 字符串 @@ -304,41 +303,41 @@ a instanceof Array 字符串的连接,可以使用加号(+)运算符。 -{% highlight javascript %} -"a" + "b" -// "ab" -{% endhighlight %} + "a" + "b" + // "ab" + + 在一个字符串的结尾添加一个字符串,可以使用+=运算符。 -{% highlight javascript %} -a += b; -// 等同于 + a += b; + + // 等同于 + + a = a + b; -a = a + b; -{% endhighlight %} 另一种方法是使用数组的连接方法。 -{% highlight javascript %} -var arr = []; -arr.push("Hello"); + var arr = []; + + arr.push("Hello"); + + arr.push(" "); -arr.push(" "); + arr.push("World"); -arr.push("World"); + arr.join("") + // "Hello World" -arr.join("") -// "Hello World" -{% endhighlight %} JavaScript引擎对“+”运算做过优化,所以上面两种方法,在速度方面没有太大区别。 @@ -346,33 +345,33 @@ JavaScript引擎对“+”运算做过优化,所以上面两种方法,在速 在浏览器环境中,JavaScript原生提供btoa方法,将字符串或二进制值转化为Base64编码;以及atob方法,将Base64编码转化为原来的编码。 -{% highlight javascript %} -window.btoa("Hello World") -// "SGVsbG8gV29ybGQ=" -window.atob("SGVsbG8gV29ybGQ=") -// "Hello World" + window.btoa("Hello World") + // "SGVsbG8gV29ybGQ=" + + window.atob("SGVsbG8gV29ybGQ=") + // "Hello World" + -{% endhighlight %} 这两个方法不适合Unicode字符串,浏览器会报错。必须中间插入一个浏览器转码的环节,再使用这两个方法。 -{% highlight javascript %} -function utf8_to_b64( str ) { - return window.btoa(unescape(encodeURIComponent( str ))); -} + + function utf8_to_b64( str ) { + return window.btoa(unescape(encodeURIComponent( str ))); + } -function b64_to_utf8( str ) { - return decodeURIComponent(escape(window.atob( str ))); -} + function b64_to_utf8( str ) { + return decodeURIComponent(escape(window.atob( str ))); + } // 使用方法 -utf8_to_b64('你好'); // "5L2g5aW9" -b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "你好" + utf8_to_b64('你好'); // "5L2g5aW9" + b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "你好" + -{% endhighlight %} ## 布尔值 @@ -384,42 +383,42 @@ Javascript将下面的值,都视为false。 - 0 - "" -{% highlight javascript %} + if (""){ console.log(true);} // 没有任何输出 -{% endhighlight %} + 需要特别注意的是,空数组([])和空对象({})对应的布尔值,都是true。 -{% highlight javascript %} -if ([]){ console.log(true);} -// true -if ({}){ console.log(true);} -// true + if ([]){ console.log(true);} + // true + + if ({}){ console.log(true);} + // true + -{% endhighlight %} ## 条件语句 ### if 结构 -{% highlight javascript %} - if (myvar === 3) { - // then - } else { - // else - } -{% endhighlight %} + if (myvar === 3) { + // then + } else { + // else + } + + ### switch结构 -{% highlight javascript %} + switch (fruit) { case "banana": @@ -432,7 +431,7 @@ if ({}){ console.log(true);} // ... } -{% endhighlight %} + ## 循环语句 @@ -440,13 +439,13 @@ if ({}){ console.log(true);} While语句包括一个循环条件,只要该条件为真,就不断循环。 -{% highlight javascript %} -while (condition){ - // some code here -} -{% endhighlight %} + while (condition){ + // some code here + } + + ### for循环 @@ -458,25 +457,25 @@ for语句分成三步: 它的格式如下: -{% highlight javascript %} + for(初值; 循环条件; 下一步) -{% endhighlight %} + 用法: -{% highlight javascript %} + for (var i=0; i < arr.length; i++) { console.log(arr[i]); } -{% endhighlight %} + 所有for循环,都可以改写成while循环。 -{% highlight javascript %} + var i = 0; @@ -485,19 +484,19 @@ for(初值; 循环条件; 下一步) i++; } -{% endhighlight %} + ### do...while循环 do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。 -{% highlight javascript %} + do { // ... } while(condition); -{% endhighlight %} + ### break语句和continue语句 @@ -513,51 +512,51 @@ break用于在循环体中跳出循环,continue用于不再进行本次循环 (1)for和while循环。 -{% highlight javascript %} -for(;;){} // 没有分号 -while(true){} // 没有分号 +`for(;;){} // 没有分号` + +`while(true){} // 没有分号` + -{% endhighlight %} 需要注意的是do...while循环是有分号的。 -{% highlight javascript %} -do { - a--; - } while(a > 0); // 分号不能省略 -{% endhighlight %} + do { + a--; + } while(a > 0); // 分号不能省略 + + (2)分支语句:if, switch, try。 -{% highlight javascript %} -if (true) {} // 没有分号 -switch () {} // 没有分号 +`if (true) {} // 没有分号` + +`switch () {} // 没有分号` + +`try {} catch {} // 没有分号` -try {} catch {} // 没有分号 -{% endhighlight %} (3)函数的声明语句 -{% highlight javascript %} -function f() {} // 没有分号 -{% endhighlight %} +`function f() {} // 没有分号` + + 但是函数表达式仍然要使用分号。 -{% highlight javascript %} -var f = function f() {}; -{% endhighlight %} +`var f = function f() {};` + + 在以上三种不使用分号结尾的情况下,如果使用了分号,并不会出错。因为,解释器会把这个分号解释为空语句。 @@ -565,107 +564,102 @@ var f = function f() {}; 在一行的结尾,有时没有写分号,解释器会自动添加。 -{% highlight javascript %} -var a = b + c -{% endhighlight %} +`var a = b + c` + + 解释器会自动在 b+c的后面添加分号。 但是,如果下一行的开始可以与本行的结尾连在一起解释,解释器就不会自动添加分号。 -{% highlight javascript %} -"abc" -.length -{% endhighlight %} + "abc" + .length + + 解释器会把上面两行解释为 -{% highlight javascript %} -"abc".length -{% endhighlight %} +`"abc".length` + + 以下例子都不会自动添加分号。 -{% highlight javascript %} -var a = b + c -(d+e).toString(); -// 解释为c(d+e),即先进行乘法运算 -a = b -/hi/g.exec(c).map(d); -// 解释为 a = b / hi / g.exec(c).map(d),即把正则表达式的斜杠当作除法运算符 + var a = b + c + (d+e).toString(); + // 解释为c(d+e),即先进行乘法运算 + + a = b + /hi/g.exec(c).map(d); + // 解释为 a = b / hi / g.exec(c).map(d),即把正则表达式的斜杠当作除法运算符 -var = "b" -[ "red", "green" ].foreach(function(c) { console.log(c) }) -// 解释为"b"["red", "green"],即把字符串当作一个数组,按索引取值 + var = "b" + [ "red", "green" ].foreach(function(c) { console.log(c) }) + // 解释为"b"["red", "green"],即把字符串当作一个数组,按索引取值 -var a = 0; -var f = function(x) { return x } -(a++) -// f等于0,因为(a++)被视为匿名函数的调用 + var a = 0; + var f = function(x) { return x } + (a++) + // f等于0,因为(a++)被视为匿名函数的调用 -return a + -b; + return a +b; -return (a -+ b) + return (a+ b) -obj.foo(arg1, -arg2) + obj.foo(arg1,arg2) + -{% endhighlight %} 一般来说,在没有分号结尾的情况下,如果下一行起首的是(、 [ 、+、-、/这五个字符中的一个,分号不会被自动添加。只有下一行的开始与本行的结尾,无法放在一起解释,JavaScript引擎才会自动添加分号。 -{% highlight javascript %} -if (a < 0) a = 0 -console.log(a) -// 等同于下面的代码,因为0console没有意义 + if (a < 0) a = 0 + console.log(a) + + // 等同于下面的代码,因为0console没有意义 + + if (a < 0) a = 0; + console.log(a) -if (a < 0) a = 0; -console.log(a) -{% endhighlight %} 另外,如果一行的起首是“自增”(++)或“自减”(--)运算符,则它们的前面会自动添加分号。 -{% highlight javascript %} -a = b = c = 1 -a -++ -b --- -c -console.log(a, b, c) -// 1 2 0 + a = b = c = 1 + a++ + b-- + c + + console.log(a, b, c) + // 1 2 0 + -{% endhighlight %} 之所以会得到“1 2 0”的结果,原因是自增和自减运算符前,自动被加上了分号。上面的代码实际上等同于下面的形式: -{% highlight javascript %} -a = b = c = 1; -a; -++b; ---c; -{% endhighlight %} + a = b = c = 1; + a; + ++b; + --c; + + 如果continue、break、return和throw这四个语句后面,直接跟换行符,则会自动添加分号。这意味着,如果return语句返回的是一个对象的字面量,起首的大括号一定要写在同一行,否则得不到预期结果。 -{% highlight javascript %} + return { first: "Jane" }; @@ -674,7 +668,7 @@ a; return; { first: "Jane" }; -{% endhighlight %} + 由于解释器自动添加分号的行为难以预测,因此编写代码的时候不应该省略行尾的分号。 diff --git a/grammar/number.md b/grammar/number.md index 6f304034..a167307b 100644 --- a/grammar/number.md +++ b/grammar/number.md @@ -10,50 +10,50 @@ modifiedOn: 2013-02-13 JavaScript内部,所有数字都是以64位浮点数形式储存。由于浮点数不是精确的值,所以涉及浮点数的比较和运算要特别小心。 -{% highlight javascript %} +```javascript -0.1 + 0.2 === 0.3 -// false + 0.1 + 0.2 === 0.3 + // false -0.3 / 0.1 -// 2.9999999999999996 + 0.3 / 0.1 + // 2.9999999999999996 +``` -{% endhighlight %} 根据国际标准IEEE 754,储存数值的64个二进制位中,第0位到第51位储存有效数字部分,第52到第62位储存指数部分,第63位是符号位,0表示整数,1表示负数。 因此,JavaScript提供的有效数字的精度为53个二进制位(IEEE 754规定有效数字第一位默认为1,再加上后面的52位),也就是说,小于2的53次方的整数都可以精确表示。 -{% highlight javascript %} +```javascript -Math.pow(2, 53) // 54个二进制位 -// 9007199254740992 + Math.pow(2, 53) // 54个二进制位 + // 9007199254740992 -Math.pow(2, 53) + 1 -// 9007199254740992 + Math.pow(2, 53) + 1 + // 9007199254740992 -Math.pow(2, 53) + 2 -// 9007199254740994 + Math.pow(2, 53) + 2 + // 9007199254740994 -Math.pow(2, 53) + 3 -// 9007199254740996 + Math.pow(2, 53) + 3 + // 9007199254740996 -Math.pow(2, 53) + 4 -// 9007199254740996 + Math.pow(2, 53) + 4 + // 9007199254740996 -{% endhighlight %} +``` 大于等于2的53次方的数值,都无法保持精度。 -{% highlight javascript %} -Math.pow(2, 53) -// 9007199254740992 +```javascript + Math.pow(2, 53) + // 9007199254740992 -9007199254740992111 -// 9007199254740992000 + 9007199254740992111 + // 9007199254740992000 +``` -{% endhighlight %} 另一方面,指数部分的长度是11,意味着指数部分的最大值是2047(2的11次方减1)。所以,JavaScript能够表示的数值范围为(-2^2048, 2^2048),超出这个范围的数无法表示。 @@ -61,115 +61,115 @@ Math.pow(2, 53) 数值可以字面形式直接表示,也可以采用科学计数法表示。 -{% highlight javascript %} -123e3 -// 123000 +```javascript + 123e3 + // 123000 -123e-3 -// 0.123 + 123e-3 + // 0.123 +``` -{% endhighlight %} 除了以下两种情况,所有数值都采用直接表示。 (1)小数点前的数字多于21位。 -{% highlight javascript %} +```javascript -1234567890123456789012 -// 1.2345678901234568e+21 + 1234567890123456789012 + // 1.2345678901234568e+21 -123456789012345678901 -// 123456789012345680000 + 123456789012345678901 + // 123456789012345680000 -{% endhighlight %} +``` (2)小数点后的零多于5个。 -{% highlight javascript %} +```javascript -0.0000003 -// 3e-7 + 0.0000003 + // 3e-7 -0.000003 -// 0.000003 + 0.000003 + // 0.000003 +``` -{% endhighlight %} ## NaN NaN表示“非数字”(not a number),主要用于将字符串解析成数字出错的场合。 -{% highlight javascript %} -Number("xyz") -// NaN +```javascript + Number("xyz") + // NaN +``` -{% endhighlight %} 它数据类型属于Number。 -{% highlight javascript %} +```javascript typeof NaN // 'number' +``` -{% endhighlight %} 它不等于任何值,包括它本身。 -{% highlight javascript %} +```javascript NaN === NaN // false +``` -{% endhighlight %} 0除以0会得到NaN。 -{% highlight javascript %} +```javascript 0 / 0 // NaN +``` -{% endhighlight %} isNaN方法可以用来判断一个值是否为NaN。 -{% highlight javascript %} +```javascript isNaN(NaN) // true +``` -{% endhighlight %} 但是,这个方法只对数值有效,如果传入其他值,会被先转成数值。传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别引起注意。 -{% highlight javascript %} +```javascript isNaN("Hello") // true // 相当于 isNaN(Number("Hello")) // true +``` -{% endhighlight %} 出于同样的原因,对于数组和对象,isNaN也会返回true。 -{% highlight javascript %} +```javascript isNaN({}) // true isNaN(["xzy"]) // true +``` -{% endhighlight %} 由于NaN是唯一不等于自身的值,可以利用这一点判断一个值是否为NaN。 -{% highlight javascript %} +```javascript function myIsNaN(value) { return value !== value; } @@ -179,15 +179,15 @@ function myIsNaN(value) { function myIsNaN2(value) { return typeof value === 'number' && isNaN(value); } +``` -{% endhighlight %} ## Infinity Infinity表示“无穷”。任意数除以0(0本身除外),会得到Infinity。它有正负之分。 -{% highlight javascript %} +```javascript 1 / -0 // -Infinity @@ -202,84 +202,84 @@ Math.pow(+0, -1) Math.pow(-0, -1) // -Infinity +``` -{% endhighlight %} 超出JavaScript表示范围的数值,也会得到无穷。 -{% highlight javascript %} +```javascript Math.pow(2, 2048) // Infinity -Math.pow(2, 2048) // -Infinity +``` -{% endhighlight %} Infinity的四则运算,符合无穷的数学计算规则。 -{% highlight javascript %} +```javascript Infinity + Infinity // Infinity 5 * Infinity // Infinity 5 - Infinity // -Infinity Infinity / 5 // Infinity 5 / Infinity // 0 +``` -{% endhighlight %} Infinity减去或除以Infinity,得到NaN。 -{% highlight javascript %} +```javascript Infinity - Infinity // NaN Infinity / Infinity // NaN +``` -{% endhighlight %} ## parseInt方法 该方法可以将字符串或小数转化为整数。 -{% highlight javascript %} +```javascript parseInt("123") // 123 parseInt(1.23) // 1 +``` -{% endhighlight %} 如果字符串的第一个字符不能转化为数字,返回NaN。 -{% highlight javascript %} +```javascript parseInt("abc") // NaN parseInt(".3") // NaN +``` -{% endhighlight %} 如果被解析的值是以0开头的整数,表示该数字为八进制;如果以0x或0X开头,表示该数字为十六进制。 -{% highlight javascript %} +```javascript parseInt(010) // 8 parseInt(0x10) // 16 +``` -{% endhighlight %} 该方法还可以接受第二个参数(2到36之间),表示被解析的值的进制。 -{% highlight javascript %} +```javascript parseInt(1000, 2) // 8 @@ -289,7 +289,7 @@ parseInt(1000, 6) parseInt(1000, 8) // 512 -{% endhighlight %} +``` ## 参考链接 diff --git a/grammar/object.md b/grammar/object.md index 5d6a2ef2..57f61e99 100644 --- a/grammar/object.md +++ b/grammar/object.md @@ -10,7 +10,7 @@ modifiedOn: 2013-04-30 对象(object)是一种数据结构,由若干个“键值对”(key-value)构成。 -{% highlight javascript %} +```javascript var o = { @@ -18,13 +18,13 @@ var o = { }; -{% endhighlight %} +``` 上面代码中,大括号就代表一个对象,被赋值给变量o。这个对象内部包含一个键值对(又称为“成员”),p是“键”(成员的名称),“Hello World”是“值”(成员的值)。 “键”又称为“属性”(property),它的“值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”。 -{% highlight javascript %} +```javascript var o = { @@ -35,18 +35,18 @@ var o = { o.p(1) // 2 -{% endhighlight %} +``` 属性之间用逗号分隔,最后一个属性后面可以加逗号(trailing comma),也可以不加。 -{% highlight javascript %} +```javascript var obj = { foo: 123, bar: function () { ... }, } -{% endhighlight %} +``` 上面的代码中bar属性后面的那个逗号,有或没有都不算错。 @@ -54,7 +54,7 @@ o.p(1) 对象用大括号{}表示。生成一个对象,可以直接用{},可以用new Object()命令。 -{% highlight javascript %} +```javascript var o = {}; @@ -62,13 +62,13 @@ var o = {}; var o = new Object(); -{% endhighlight %} +``` ### 读取属性 读取一个属性,有两种方法,一种是点结构,还有一种是方括号。 -{% highlight javascript %} +```javascript var o = { @@ -82,20 +82,20 @@ console.log(o.p); // Hello World // 方括号 console.log(o["p"]); // Hello World -{% endhighlight %} +``` 这两种方法,不仅可以引用到该属性对应的值,还可以用来赋值。 -{% highlight javascript %} +```javascript o.p = "abc"; o["p"] = "abc"; -{% endhighlight %} +``` 查看一个对象本身的所有属性,可以使用Object.keys方法。 -{% highlight javascript %} +```javascript var o = { key1: 1, @@ -105,13 +105,13 @@ var o = { Object.keys(o); // ["key1", "key2"] -{% endhighlight %} +``` ### 属性的增加与删除 JavaScript允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。 isExtensible -{% highlight javascript %} +```javascript var o = { p:1 }; @@ -120,11 +120,11 @@ var o = { p:1 }; var o = {}; o.p = 1; -{% endhighlight %} +``` delete命令可以删除属性。 -{% highlight javascript %} +```javascript var o = { p:1 }; @@ -133,13 +133,13 @@ delete o.p o.p // undefined -{% endhighlight %} +``` ### 对象的引用 如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。 -{% highlight javascript %} +```javascript var v1 = {}; @@ -150,11 +150,11 @@ v1.a = 1; v2.a // 1 -{% endhighlight %} +``` 这种引用只局限于对象,对于原始类型的数据,则是传值引用,也就是说,都是值的拷贝。 -{% highlight javascript %} +```javascript var x = 1; @@ -167,7 +167,7 @@ x = 2; y // 2 -{% endhighlight %} +``` 上面的代码中,当x的值发生变化后,y的值并不变,这就表示y和x并不是指向同一个内存地址。 @@ -179,16 +179,16 @@ y 它的格式如下,其中的括号不是必需的: -{% highlight javascript %} +```javascript with (object) statement -{% endhighlight %} +``` 作用是当操作同一个对象的多个属性时,提供一些书写的方便。 -{% highlight javascript %} +```javascript o.p1 = 1; o.p2 = 2; @@ -200,11 +200,11 @@ with (o){ p2 = 2; } -{% endhighlight %} +``` 这里需要注意的是,在with区块内部依然是全局作用域。 -{% highlight javascript %} +```javascript with ({}){ var x = "abc"; @@ -213,11 +213,11 @@ with ({}){ x // "abc" -{% endhighlight %} +``` with语句有很大的弊病,主要问题是绑定对象不明确,会产生意想不到的结果,并且在浏览器编译时无法优化。 -{% highlight javascript %} +```javascript var x = 1; @@ -228,11 +228,11 @@ with (o) { } // 1 -{% endhighlight %} +``` 上面代码的with区块中的x,表面上应该属于o对象,但是实际上属于全局对象,这非常不利于代码的除错和模块化。因此,建议不要使用with语句,可以考虑用一个临时变量代替。 -{% highlight javascript %} +```javascript with(o1.o2.o3) { console.log(p1 + p2); @@ -243,7 +243,7 @@ with(o1.o2.o3) { var b = o1.o2.o3; console.log(b.p1 + b.p2); -{% endhighlight %} +``` ## 属性模型 @@ -253,7 +253,7 @@ ECMAScript 5对于对象的属性,提出了一个更精确的模型。 除了直接定义值以外,属性还可以用存取函数(accessor)定义。其中,存值函数称为setter,使用set关键字;取值函数称为getter,使用getter关键字。 -{% highlight javascript %} +```javascript var o = { @@ -266,11 +266,11 @@ var o = { } } -{% endhighlight %} +``` 定义存取函数之后,引用该属性时,取值函数会自动调用;赋值该属性时,存值函数会自动调用。 -{% highlight javascript %} +```javascript o.p // getter @@ -278,7 +278,7 @@ o.p o.p = 123; // setter: 123 -{% endhighlight %} +``` ### 属性的attributes对象 @@ -295,7 +295,7 @@ attributes对象包含如下属性: 有了attributes对象,就可以描述其对应的属性。 -{% highlight javascript %} +```javascript { value: 123, @@ -304,21 +304,21 @@ attributes对象包含如下属性: configurable: false } -{% endhighlight %} +``` ### Object.defineProperty方法 该方法允许通过定义attributes对象,来定义一个属性,然后返回修改后的对象。它的格式是 -{% highlight javascript %} +```javascript Object.defineProperty(object, propertyName, attributesObject) -{% endhighlight %} +``` 比如,定义o对象的p属性可以这样写: -{% highlight javascript %} +```javascript var o = Object.defineProperty({}, "p", { value: 123, @@ -335,11 +335,11 @@ o.p // 123 // 因为writable为false,所以无法改变该属性的值 -{% endhighlight %} +``` 如果一次性定义多个属性,可以使用Object.defineProperties方法。 -{% highlight javascript %} +```javascript var o = Object.defineProperties({}, { p1: { value: 123, enumerable: true }, @@ -352,13 +352,13 @@ o.p1 o.p2 // "abc" -{% endhighlight %} +``` ### 控制对象的可写性 (1) Object.preventExtensions方法,可以使得一个对象无法再添加新的属性。 -{% highlight javascript %} +```javascript var o = new Object(); @@ -368,11 +368,11 @@ Object.defineProperty(o, "t", { value: "hello" }); // TypeError: Cannot define property:t, object is not extensible. -{% endhighlight %} +``` Object.isExtensible方法用于检查一个对象是否使用了preventExtensions方法。 -{% highlight javascript %} +```javascript var o = new Object(); @@ -381,11 +381,11 @@ Object.preventExtensions(o); Object.isExtensible(o) // false -{% endhighlight %} +``` (2) Object.seal方法,可以使得一个对象即无法添加新属性,也无法删除旧属性,处于被封闭状态。 -{% highlight javascript %} +```javascript var o = {t:"hello"}; @@ -394,13 +394,13 @@ Object.seal(o); delete o.t; // false -{% endhighlight %} +``` Object.isSealed()用于检查一个对象是否使用了Object.seal方法。 (3) Object.freeze方法,可以使得一个对象无法添加新属性、无法删除旧属性、也无法改变属性的值,使得这个对象实际上变成了常量。 -{% highlight javascript %} +```javascript var o = {t:"hello"}; @@ -411,13 +411,13 @@ o.t = "world"; console.info(o.t); // hello -{% endhighlight %} +``` Object.isFrozen方法用于检查一个对象是否使用了Object.freeze()方法。 需要注意的是,即使使用上面这些方法锁定对象的可写性,我们依然可以通过改变该对象的原型对象,来为它增加属性。 -{% highlight javascript %} +```javascript var o = new Object(); @@ -430,21 +430,21 @@ proto.t = "hello"; o.t // hello -{% endhighlight %} +``` ### Object.getOwnPropertyDescriptor方法 该方法返回属性的attributes对象,格式如下 -{% highlight javascript %} +```javascript Object.getOwnPropertyDescriptor(object, property) -{% endhighlight %} +``` 使用方法如下: -{% highlight javascript %} +```javascript > var o = Object.defineProperty({}, "p", { value: 123, @@ -459,7 +459,7 @@ Object.getOwnPropertyDescriptor(object, property) writable: false } -{% endhighlight %} +``` ### 可枚举性 @@ -467,18 +467,18 @@ Object.getOwnPropertyDescriptor(object, property) 假定,对象o有两个属性p1和p2,可枚举性分别为true和false。 -{% highlight javascript %} +```javascript var o = Object.defineProperties({}, { p1: { value: 1, enumerable: true }, p2: { value: 2, enumerable: false } }); -{% endhighlight %} +``` 那么,for-in操作和Object.keys操作的返回结果,将不包括p2。 -{% highlight javascript %} +```javascript > for (var x in o) console.log(x); p1 @@ -486,20 +486,20 @@ var o = Object.defineProperties({}, { > Object.keys(o) ["p1"] -{% endhighlight %} +``` 除了上面两个操作,其他操作都不受可枚举性的影响。 -{% highlight javascript %} +```javascript > Object.getOwnPropertyNames(o) ["p1", "p2"] -{% endhighlight %} +``` 一般来说,系统原生的属性(即非用户自定义的属性)都是不可枚举的。 -{% highlight javascript %} +```javascript > Object.keys([]) [] @@ -519,36 +519,36 @@ var o = Object.defineProperties({}, { 'propertyIsEnumerable', 'toString' ] -{% endhighlight %} +``` for...in循环会列出对象自身的可枚举属性,以及对象继承的可枚举属性。 -{% highlight javascript %} +```javascript for (name in object) { if (object.hasOwnProperty(name)) { .... } } -{% endhighlight %} +``` Object.keys则只会列出对象自身的可枚举属性。 -{% highlight javascript %} +```javascript Object.keys(obj).forEach( function(key) { console.log(key); }); -{% endhighlight %} +``` propertyIsEnumerable方法用来判断一个属性是否可枚举。 -{% highlight javascript %} +```javascript Object.prototype.propertyIsEnumerable("toString") // false -{% endhighlight %} +``` ## 参考链接 diff --git a/grammar/operator.md b/grammar/operator.md index e1ee5ade..8de72b2d 100644 --- a/grammar/operator.md +++ b/grammar/operator.md @@ -12,25 +12,25 @@ modifiedOn: 2013-06-13 加法运算符(+)用于数字的相加或者字符串的连接。如果两个运算子都是数值,则返回它们的和;如果两个运算子都是字符,则返回连接后的字符串。 -{% highlight javascript %} -1 + 1 // 2 -"1" + "1" // "11" + 1 + 1 // 2 + + "1" + "1" // "11" + -{% endhighlight %} 其他情况下,则需要将运算子转为数值或字符串类型。转化的基本规则是,如果有一个运算子是字符串,则将另一个也转成字符串,返回两者连接的结果;否则就将两个运算子都转为数值,返回两者的和。 -{% highlight javascript %} -true + 1 -// 2 -true + "1" -// "true1" + true + 1 + // 2 + + true + "1" + // "true1" + -{% endhighlight %} 更详尽的转化规则参见《数据类型转化》一节。 @@ -38,17 +38,17 @@ true + "1" 如果一个运算子是数值类型,另一个是其他类型,那么除了加法运算符,在其他运算符的情况下,另一个运算子都会被转化成数值类型。 -{% highlight javascript %} -// 加法运算符的情况 -1 + "1" -// "11" -// 减法运算符的情况 -1 - "1" -// 0 + // 加法运算符的情况 + 1 + "1" + // "11" + + // 减法运算符的情况 + 1 - "1" + // 0 + -{% endhighlight %} ## 圆括号运算符 @@ -56,52 +56,52 @@ true + "1" 对表达式使用圆括号,返回表达式的值。 -{% highlight javascript %} -(1) -// 1 -('a') -// a + (1) + // 1 + + ('a') + // a + + (1+2) + // 3 -(1+2) -// 3 -{% endhighlight %} 如果对某个对象使用圆括号,则等同于调用该对象的valueOf方法。 -{% highlight javascript %} -var o = {p:1}; -(o) -// 等同于o.valueof() + var o = {p:1}; + + (o) + // 等同于o.valueof() + -{% endhighlight %} 调用函数的时候,在尾部添加一对圆括号,就表示对函数求值。如果将函数放在圆括号中,则会返回整个函数,因为这相当于调用函数对象的valueOf方法。 -{% highlight javascript %} -function f(){return 1;} -f() -// 1 + function f(){return 1;} + + f() + // 1 + + (f) + // function f(){return 1;} -(f) -// function f(){return 1;} -{% endhighlight %} 由于圆括号的作用是求值,如果对语句使用圆括号,就会报错,因为语句没有返回值。 -{% highlight javascript %} -(var a =1) -// SyntaxError: Unexpected token var -{% endhighlight %} + (var a =1) + // SyntaxError: Unexpected token var + + ## 方括号运算符 @@ -109,25 +109,25 @@ f() 对于数组,就是按照数组的下标取值。 -{% highlight javascript %} -var a = ["a", "b", "c"]; -a[1] -// "b" + var a = ["a", "b", "c"]; + + a[1] + // "b" + -{% endhighlight %} 对于对象,就是按照对象的属性名取值。 -{% highlight javascript %} -var o = { p1:"a", p2:"b"}; -o["p1"] -// "a" + var o = { p1:"a", p2:"b"}; + + o["p1"] + // "a" + -{% endhighlight %} 需要注意的是,取值的时候,属性名排p1必须放在引号中,否则会被JavaScript当作变量名解释。 @@ -137,45 +137,44 @@ void运算符的作用是执行一个表达式,然后返回undefined。 它可以写成 -{% highlight javascript %} -void expr -{% endhighlight %} +`void expr` + + 或者 -{% highlight javascript %} -void(expr) -{% endhighlight %} +`void(expr)` + -建议采用后一种形式,即总是使用括号。因为void运算符的优先性很高,如果不使用括号,容易造成错误的结果。比如,void 4+7 实际上等同于 (void 4) +7 。 + +建议采用后一种形式,即总是使用括号。因为void运算符的优先性很高,如果不使用括号,容易造成错误的结果。比如,`void 4+7` 实际上等同于 `(void 4) +7` 。 这个运算符号主要是用于书签工具(bookmarklet)或者用于在超级链接中插入代码,目的是返回undefined可以防止网页跳转。以书签工具为例,下面的代码会导致直接在当前窗口打开新链接。 -{% highlight javascript %} -javascript:window.open("http://www.whitehouse.gov/"); -{% endhighlight %} +`javascript:window.open("http://www.whitehouse.gov/");` + + 使用void运算符后,就会跳出一个新窗口打开链接。 -{% highlight javascript %} -javascript:void(window.open("http://www.whitehouse.gov/")); -{% endhighlight %} +`javascript:void(window.open("http://www.whitehouse.gov/"));` + + 写入超级链接,就是下面这样: -{% highlight html %} - Compute + `Compute` + -{% endhighlight %} ## 比较运算符 @@ -200,40 +199,40 @@ javascript:void(window.open("http://www.whitehouse.gov/")); (1)undefined和null两者,与自身或互相比较时,结果为true,与其他类型的值比较时,结果都为false。 -{% highlight javascript %} -null == null // true -undefined == undefined // true -undefined == null // true + null == null // true + undefined == undefined // true + + undefined == null // true + + false == null // false + 0 == null // false -false == null // false -0 == null // false -{% endhighlight %} (2)原始类型的数据会转换成数值类型再进行比较。 -{% highlight javascript %} -1 == true // true -0 == false // true -"true" == true // false + 1 == true // true + 0 == false // true -'' == 0 // true + "true" == true // false -'' == false // OK -'1' == true // OK + '' == 0 // true -"2" == true // false -2 == true // false -2 == false // false + '' == false // OK + '1' == true // OK + + "2" == true // false + 2 == true // false + 2 == false // false + + '\n 123 \t' == 123 // true + // 因为字符串转为数字时,省略前置和后置的空格 -'\n 123 \t' == 123 // true -// 因为字符串转为数字时,省略前置和后置的空格 -{% endhighlight %} (3)对象与字符串或数值比较时,对象转化成原始类型的值,再进行比较。 @@ -249,70 +248,70 @@ false == null // false (3)数字与数字比较时,看它们的值是否相同。同时,NaN与任何值都不相等(包括其自身),以及正0等于负0。 -{% highlight javascript %} + NaN !== _ // 任何值包括其自身 +0 === -0 -{% endhighlight %} + (4)两个复合类型的量比较时(包括对象、数组、函数),不是比较它们的值是否相等,而是比较它们是否指向同一个对象。 -{% highlight javascript %} -{} === {} -// false -[] === [] -// false + {} === {} + // false + + [] === [] + // false + + (function (){}) === (function (){}) + // false -(function (){}) === (function (){}) -// false -{% endhighlight %} 如果两个变量指向同一个复合类型的值,则它们相等。 -{% highlight javascript %} -var v1 = {}; -var v2 = v1; -v1 === v2 -// true + var v1 = {}; + var v2 = v1; + + v1 === v2 + // true + -{% endhighlight %} (5)如果两个变量的值都是undefined或null,它们是相等的。 -{% highlight javascript %} -var v1 = undefined; -var v2 = undefined; -v1 === v2 -// true + var v1 = undefined; + var v2 = undefined; -var v1 = null; -var v2 = null; + v1 === v2 + // true + + var v1 = null; + var v2 = null; + + v1 === v2 + // true -v1 === v2 -// true -{% endhighlight %} 因为变量声明后默认类型是undefined,因此两个只声明未赋值的变量是相等的。 -{% highlight javascript %} -var v1; -var v2; -v1 === v2 -// true + var v1; + var v2; + + v1 === v2 + // true + -{% endhighlight %} ## 布尔运算符 @@ -320,13 +319,13 @@ v1 === v2 取反运算用于将一个布尔值变为相反值。 -{% highlight javascript %} -!true // false -!false // true + !true // false + + !false // true + -{% endhighlight %} 对于非布尔值的数据,布尔运算会自动将其转为布尔值。以下六个值取反后为true,其他都为false。 @@ -337,15 +336,15 @@ v1 === v2 - NaN - "" -{% highlight javascript %} -!undefined // true -!null // true -!0 // true -!NaN // true -!"" // true -{% endhighlight %} + !undefined // true + !null // true + !0 // true + !NaN // true + !"" // true + + 这种自动转为布尔值的规则,对下面几种布尔运算都成立。 @@ -353,39 +352,39 @@ v1 === v2 如果第一个运算子为true,则返回第二个运算子;如果第一个运算子为false,则直接返回第一个运算子,且不再对第二个运算子求值。 -{% highlight javascript %} -"t" && "" // "" -"t" && "f" // "f" -"" && "f" // "" -"" && "" // "" -{% endhighlight %} + "t" && "" // "" + "t" && "f" // "f" + "" && "f" // "" + "" && "" // "" + + (3) OR(||) 或运算 如果第一个运算子为true,则返回第一个运算子,且不再对第二个运算子求值;如果第一个运算子为false,则返回第二个运算子。 -{% highlight javascript %} -"t" || "" // "t" -"t" || "f" // "t" -"" || "f" // "f" -"" || "" // "" -{% endhighlight %} + "t" || "" // "t" + "t" || "f" // "t" + "" || "f" // "f" + "" || "" // "" + + (4) 三元运算符 ? : 三元运算符用问号(?)和冒号(:),分隔三个表达式。如果第一个表达式为true,则返回第二个表达式,否则返回第三个表达式。 -{% highlight javascript %} -"t" ? true : false // true -0 ? true : false // false + "t" ? true : false // true + + 0 ? true : false // false + -{% endhighlight %} ## 位运算符 @@ -401,77 +400,77 @@ v1 === v2 位运算有一些特殊运用。比如,连续对a和b进行三次异或运算,aˆ=b, bˆ=a, aˆ=b,可以互换两个变量的值(详见[维基百科](http://en.wikipedia.org/wiki/XOR_swap_algorithm)),因此使用位运算可以在不引入临时变量的前提下,互换两个变量的值。 -{% highlight javascript %} -var a = 10; -var b = 99; -a^=b, b^=a, a^=b; + var a = 10; + var b = 99; + + a^=b, b^=a, a^=b; + + a // 99 + b // 10 -a // 99 -b // 10 -{% endhighlight %} 又比如,由于位运算只对整数有效,会将运算子先转成32位整数,所以将一个数与0进行或运算,等同于对该数调用Math.floor方法。 -{% highlight javascript %} -2.2352524535 | 0 -// 2 -{% endhighlight %} + 2.2352524535 | 0 + // 2 + + 连续进行两次否运算,也能达到同样效果。 -{% highlight javascript %} -~~2.2352524535 -// 2 -{% endhighlight %} + ~~2.2352524535 + // 2 + + 但是,一般来说,这些位运算的例子只对正数有效,且运算子不能超过32位整数的最大值2147483647。 -{% highlight javascript %} -Math.floor(2147483647.4); // 2147483647 -2147483647.4 | 0; // 2147483647 -Math.floor(2147483648.4); // 2147483648 -2147483648.4 | 0; // -2147483648 + Math.floor(2147483647.4); // 2147483647 + 2147483647.4 | 0; // 2147483647 + + Math.floor(2147483648.4); // 2147483648 + 2147483648.4 | 0; // -2147483648 + -{% endhighlight %} ### 左移运算<< 该运算符表示将一个数的二进制形式向前移动,尾部补0。 -{% highlight javascript %} -4 << 1 -// 8 -// 因为4的二进制形式为100,左移一位为1000(即十进制的8) --4 << 1 -// -8 + 4 << 1 + // 8 + // 因为4的二进制形式为100,左移一位为1000(即十进制的8) + + -4 << 1 + // -8 + -{% endhighlight %} ### 右移运算>> 该运算符表示将一个数的二进制形式向后移动,头部补0。 -{% highlight javascript %} -4 >> 1 -// 2 -// 因为4的二进制形式为100,右移一位得到10(即十进制的2) --4 >> 1 -// -2 + 4 >> 1 + // 2 + // 因为4的二进制形式为100,右移一位得到10(即十进制的2) + + -4 >> 1 + // -2 + -{% endhighlight %} ### 不带符号位的右移运算>>> @@ -479,15 +478,15 @@ Math.floor(2147483648.4); // 2147483648 这对正数的运算结果与>>运算符完全一致,区别主要在于负数的符号位。 -{% highlight javascript %} -4 >>> 1 -// 2 --4 >>> 1 -// 2147483646 + 4 >>> 1 + // 2 + + -4 >>> 1 + // 2147483646 + -{% endhighlight %} -4带符号位右移一位,得到2147483646。这主要是因为在JavaScipt内部,-4以10000000000000000000000000000100的32位形式保存,最前面的1表示负值。带符号位右移一位时,这个值变成01000000000000000000000000000010,等于十进制的2147483646。 diff --git a/index.md b/index.md index 9a3ccae2..774d7f4b 100644 --- a/index.md +++ b/index.md @@ -7,112 +7,112 @@ modifiedOn: 2013-07-05

导论

-- [为什么学习JavaScript?](introduction/why.html) -- [Javascript的历史](introduction/history.html) -- [使用说明](introduction/instruction.html) -- [参考书目](introduction/bibliography.html) +- [为什么学习JavaScript?](introduction/why.md) +- [Javascript的历史](introduction/history.md) +- [使用说明](introduction/instruction.md) +- [参考书目](introduction/bibliography.md)

基本语法

-- [概述](grammar/basic.html) -- [运算符](grammar/operator.html) -- [数值](grammar/number.html) -- [对象](grammar/object.html) -- [数组](grammar/array.html) -- [函数](grammar/function.html) -- [数据类型转换](grammar/conversion.html) -- [编程风格](grammar/style.html) -- [严格模式](grammar/strict.html) +- [概述](grammar/basic.md) +- [运算符](grammar/operator.md) +- [数值](grammar/number.md) +- [对象](grammar/object.md) +- [数组](grammar/array.md) +- [函数](grammar/function.md) +- [数据类型转换](grammar/conversion.md) +- [编程风格](grammar/style.md) +- [严格模式](grammar/strict.md)

标准库

-- [Object对象](stdlib/object.html) -- [Array 对象](stdlib/array.html) -- [原始类型的包装对象](stdlib/wrapper.html) -- [Boolean对象](stdlib/boolean.html) -- [Number对象](stdlib/number.html) -- [String对象](stdlib/string.html) -- [Math对象](stdlib/math.html) -- [Date对象](stdlib/date.html) -- [Regex对象](stdlib/regex.html) -- [JSON对象](stdlib/json.html) -- [Error对象](stdlib/error.html) +- [Object对象](stdlib/object.md) +- [Array 对象](stdlib/array.md) +- [原始类型的包装对象](stdlib/wrapper.md) +- [Boolean对象](stdlib/boolean.md) +- [Number对象](stdlib/number.md) +- [String对象](stdlib/string.md) +- [Math对象](stdlib/math.md) +- [Date对象](stdlib/date.md) +- [Regex对象](stdlib/regex.md) +- [JSON对象](stdlib/json.md) +- [Error对象](stdlib/error.md)

面向对象编程

-- [概述](oop/basic.html) -- [封装](oop/encapsulation.html) -- [继承](oop/inheritance.html) -- [ECMAscript 6 介绍](oop/ecmascript6.html) +- [概述](oop/basic.md) +- [封装](oop/encapsulation.md) +- [继承](oop/inheritance.md) +- [ECMAscript 6 介绍](oop/ecmascript6.md)

DOM

-- [dataset](dom/dataset.html) -- [classList](dom/classlist.html) -- [样式表操作](dom/stylesheet.html) +- [dataset](dom/dataset.md) +- [classList](dom/classlist.md) +- [样式表操作](dom/stylesheet.md)

浏览器对象

-- [JavaScript运行原理](bom/engine.html) -- [History对象](bom/history.html) -- [CSS](bom/css.html) -- [Ajax](bom/ajax.html) -- [Web Storage](bom/webstorage.html) -- [WebSocket](bom/websocket.html) -- [Geolocation](bom/geolocation.html) -- [MatchMedia](bom/matchmedia.html) -- [WebRTC](bom/webrtc.html) +- [JavaScript运行原理](bom/engine.md) +- [History对象](bom/history.md) +- [CSS](bom/css.md) +- [Ajax](bom/ajax.md) +- [Web Storage](bom/webstorage.md) +- [WebSocket](bom/websocket.md) +- [Geolocation](bom/geolocation.md) +- [MatchMedia](bom/matchmedia.md) +- [WebRTC](bom/webrtc.md)

HTML网页的API

-- [Canvas](htmlapi/canvas.html) -- [SVG图像](htmlapi/svg.html) -- [File对象和二进制数据](htmlapi/file.html) -- [Web Worker](htmlapi/webworker.html) -- [服务器端发送事件](htmlapi/eventsource.html) -- [Page Visiblity](htmlapi/pagevisibility.html) -- [FullScreen](htmlapi/fullscreen.html) -- [Web Speech](htmlapi/webspeech.html) -- [requestAnimationFrame](htmlapi/requestanimationframe.html) +- [Canvas](htmlapi/canvas.md) +- [SVG图像](htmlapi/svg.md) +- [File对象和二进制数据](htmlapi/file.md) +- [Web Worker](mhtmlpi/webworker.md) +- [服务器端发送事件](htmlapi/eventsource.md) +- [Page Visiblity](htmlapi/pagevisibility.md) +- [FullScreen](htmlapi/fullscreen.md) +- [Web Speech](htmlapi/webspeech.md) +- [requestAnimationFrame](htmlapi/requestanimationframe.md)

jQuery

-- [选择器](jquery/selector.html) -- [Utility方法](jquery/utility.html) -- [deferred对象](jquery/deferred.html) -- [如何做到jQuery-free?](jquery/jquery-free.html) +- [选择器](jquery/selector.md) +- [Utility方法](jquery/utility.md) +- [deferred对象](jquery/deferred.md) +- [如何做到jQuery-free?](jquery/jquery-free.md)

函数库

-- [Underscore.js](library/underscore.html) -- [Modernizr](library/modernizr.html) -- [Datejs](library/datejs.html) +- [Underscore.js](library/underscore.md) +- [Modernizr](library/modernizr.md) +- [Datejs](library/datejs.md)

开发工具

-- [console对象](tool/console.html) -- [Chrome开发工具](tool/chrome.html) -- [性能测试(Benchmark)](tool/benchmark.html) -- [PhantomJS](tool/phantomjs.html) -- [Grunt任务管理工具](tool/grunt.html) -- [RequireJS和AMD规范](tool/requirejs.html) -- [移动端开发](tool/mobile.html) -- [Google Closure](tool/closure.html) -- [Source map](tool/sourcemap.html) +- [console对象](tool/console.md) +- [Chrome开发工具](tool/chrome.md) +- [性能测试(Benchmark)](tool/benchmark.md) +- [PhantomJS](tool/phantomjs.md) +- [Grunt任务管理工具](tool/grunt.md) +- [RequireJS和AMD规范](tool/requirejs.md) +- [移动端开发](tool/mobile.md) +- [Google Closure](tool/closure.md) +- [Source map](tool/sourcemap.md)

Node.js

-- [概述](nodejs/basic.html) -- [CommonJS规范](nodejs/commonjs.html) +- [概述](nodejs/basic.md) +- [CommonJS规范](nodejs/commonjs.md)

模式

-- [设计模式](pattern/designpattern.html) -- [异步编程](pattern/asynchronous.html) +- [设计模式](pattern/designpattern.md) +- [异步编程](pattern/asynchronous.md)

算法

-* [排序](algorithm/sorting.html) +* [排序](algorithm/sorting.md) {% comment %} @@ -131,7 +131,7 @@ modifiedOn: 2013-07-05 ## 最新页面 {% for page in site.pages limit:5 %} -{% if page.url !='/index.html' %} +{% if page.url !='/index.md' %} * [{{ page.title }}]( {{ page.url }})({{ page.date }}) {% endif %} {% endfor %}