读此书之前,感谢淘宝技术团队对此javascript核心的翻译,感谢弗拉纳根写出此书。感谢你们无私的分享,仅以此笔记献给你们的辛勤付出。
一:javascript语言核心
本章之后,我们将主要关注javascript的基础知识。第二章我们讲解javascript的注释,分号和unicode字符集;第三章会更有意思,主要讲解javascript的变量和赋值
这里有一些实例代码说明前两章的重点内容。
<script type="text/javascript"> //双斜杠之后之后的内容都于属于注释 //仔细阅读这里的注释,它将会对javascript代码做解释 // 变量是表示值的一个符号名字 // 变量是通过var关键字声明 var x; //声明一个变量x //值可以通过符号赋值给变量 x = 0; //现在变量x的值为0 x //通过变量名获取其值。 //javascript支持多种数据类型 x = 1; //数字 x = 0.01; //整数和实数共用一种数据类型 x = "hello world"; //由双引号内的文本构成字符串 x = 'hello world'; //单引号同样构成字符串。 x = true; //布尔值 x = false; //另外一个布尔值 x = null; //null是一个特殊的值。意思是空 x = undefined; //undefined和null非常类似 </script>
在javascript中,最重要的类型就是对象和数组,第六章介绍对象,第7章介绍数组。对象和数组在 javascript是如此重要。以至于在本书中到处能看到他们的身影。
<script type="text/javascript"> //javascript中最重要的类型就是对象 //对象是名/值对的集合,或字符串值到映射值的集合。 var book = { //对象是由花括号括起来的 topic: "javascript", //属性"topic"的值是javascript fat: true //属性fat的值是true }; //右边的花括号结束。 //通过“.”或“[]”来访问对象属性。 book.topic //=>"javascript" book["fat"] //=>true另外一种获取属性的方式、 book.author = "ahthw"; //通过赋值创建一个新的属性 book.content = {}; //{}是一个空对象。它没有属性 //javascript同样支持数组(以数组为索引的列表) var primes = [2, 3, 5, 7]; //拥有4个值的组合,由“[”“]”划定边界 primes[0] //=>2:数组的第一个对象,索引为0 primes.length //=>4,数组中元素的个数 primes[primes.length-1] //=>7:数组中最后一个元素 primes[4] =9; //通过赋值来增加新的元素 primes[4] =11;//通过赋值来改变已有的元素 var empty = [];//空数组,有0个元素 empty.length //=>:0 //数组和对象中都可以包含另一个数组或者对象。 var point =[ //具有两个元素的数组 {x:0,y:0}, //每个元素都是一个对象 {x:1,y:1} ]; var data ={ //一个包含两个属性的对象 trial1:[[1,2],[3,4]], //每一个对象都是数组 trial2:[[2,3],[4,5]] //数组的元素也是数组 }; </script>
上面代码中通过方括号定义数组元素和通过花括号定义对象属性名和属性值之间的映射关系的语法陈伟初始化表达式(initalizer expression),第四章有专门介绍.表达式是javascript中的一个短语,这个短语可以通过运算得出一个值,通过","和"[]"来引用对象属性或数组元素的值构成一个表达式。
javascript中最常见的表达式写法是像下面 代码这样的运算符(oprartor)
//运算符作为操作符,生成一个新的值 //最常见的算术运算符 3+2 // =>5 加法 3-2 // =>减法 3*2 // =>乘法 3/2 // =>除法 point[1].x -point[0].x //=>复杂的运算也能照常工作 "3"+"2" // => 32.可以完成加法运算,也可以完成 字符串拼接。 //javascript定义了一些算术运算符作为简写形式 var count = 0; //定义一个变量 count++; //自增1 count--; //自减1 count +=2; //自增2 和 "count = count + 2;"写法一样 count *=3 //自乘3. 和"count = count*3; "写法一样 count //=> 6: 变量名本身也是一个表达式 //相等关系运算符用来判断两值是否相等 //不等,大于,小于运算符运算结果是true或false var x=2,y=3; //这里的等号是赋值的意思,不是比较相等 x == y; //=>false 相等 x != y; //=> true 不等 x < y; //=> true: 小于 x <= y; //true 小于等于 x > y; //false 大于 x >= y; //false 大于等于 "two"=="three"; //false 两个字符串不相等 "two" > "three"; //true "tw"在字母表中的索引大于"th" false == (x>y); //ture false =false; //逻辑运算符是对布尔值的合并或求反 (x == 2)&&(y==3); //=>true两个比较都为true.&&为"与" (x > 3)||(y<3); //=> false 两个比较都不是true. ||表示"或" !(x == y); //=>true !表示求反
如果javascript中的“短语”是表达式话,那么整个句子就称作语句(statement),第五章会详细讲解。
在上述代码中,以分号结束的行均是一条语句,粗略的讲,表达式仅仅计算出一个值(或者它包含的值我们并不关心)但他们改变程序运行状态。在上文中,已经见过变量声明语句和赋值语句。另一类语句是“控制结构”(control structure),比如条件判断和循环,在介绍完函数后,我们给出相关示例代码。
函数是带有名称和参数的javascript代码段,可一次定义多次使用。第8章会正式详细地讲解函数。与对象和数组一样,本书很多地方提到函数,这里给一些简单的示例代码。
//函数是一段待遇参数的javascript代码段,可以多次调运 function plus1(x) { //定义了一个名为plus1的函数,并带有参数x return x + 1; //返回一个比传入大1的值。 } //函数的代码块是由花括号包裹起来的部分 plus1(y) // var square =function(x){ //函数是一种值,可以赋值给变量 return x*x; //计算函数的值 }; //分号表示了赋值语句的结束 square(plus1(y)); //在一个表达式中石油两个函数
当将函数和对象和写在一起时,函数就编程了“方法”(method)
//当函数赋值给对象的属性,我们称为 //"方法",所有的javascript对象都包含方法 var a =[]; //创建一个空数组 a.push(1,2,3); //向push()方法向数组中添加对象 a.reverse(); //数据反转 // document.write(a) //我们可以定义子的方法,"this"关键字是对定义方法 //的对象的引用,这里的例子是上文中提到的包含两个点位置信息的数组。 points.dist =function(){ //定义一个方法计算两点之间的距离 var p1 =this[0]; //通过this关键字获得当前数组的引用 var p2 =this[1]; //并取得调用的数组前两个元素 var a =p2.x- p1.y; // x坐标轴上的距离 var b =p2.y - p1.y; //y坐标轴上的距离 return Math.sqrt(a * a + "我们称为" + b * b); //勾股定理 }; //Math.sqrt()计算平方根 points.dist() // =>求两个点之间的距离
现在,给出一些控制语句的例子,这里的示例函数体内包含了最常见的javascript的控制语句
//这里javascript语句使用该语法包含条件判断和循环 //使用了类似java c++和其它语言的语法 function abs(x) { //求绝对值函数 if (x >= 0) { //if return x; //如果true则执行这里代码 } else { //false执行 return -x; } } function factprial(n) { //计算阶乘 var product = 1; //给product赋值为1 while (n > 1) { //()值表达式为 true时循环执行{}内容 product *= n; //product = product * n的简写 n--; // n = n-1写法 } //循环结束 return product; //返回 product } factprial(4) // =>24 1*4*3*2 document.write(factprial(4)) function factorial2(n) { //实现循环的另外一种写法 var i, product = 1; // for (i = 2; i <= n; i++) //将i从2自增到n product *= i; //循环体,当循环体中只有一句代码,省略{} return product; //计算返回好的阶乘 } factorial2(5) //document.write(factorial2(5)) =>120 : 1*2*3*4*5
javascript是一种面向对象的编程语言,但和传统的页面对象有有很大的区别,第9章将详细讲解的javascript的面向对象,这章会有大量的示例代码,是本书最长的一章。
这里有一个简单的示例,这段代码展示了如何在javascript中定义一个类来表示2D面的几何中的点。这个类实例化的对象拥有一个名为r()的方法,用来计算改点到原点的距离。
//定义一个构造函数以初始化一个新的point对象 function Point(x, y) { //构造函数一般均以大写字母开始 this.x = x; //关键字this指代初始化的实例 this.y = y; //将函数参数存储为对象的属性 } //使用new关键字和构造函数来创建一个实例 var p = new Point(1, 1); //平面几何中的点1,1, //通过构造函数prototype对象赋值 //来给Point对象定义方法 Point.prototype.r = function() { return Math.sqrt( //返回x平方+y平方的平方根 this.x * this.x + //this指代调运这个方法的对象 this.y * this.y); }; //Point的实例对象p(以及所有的point实例对象)继承了方法r() p.r() // => 1.4142135623730951 /document.write(p.r())
第9章是第一部分的精华所在,后续的各章做了零星的延伸,将带领我们走向对javascript探索的尾声。
第十章主要讲正则表达式进行的文本匹配模式。
第11章主要护额石膏javascript的语言核心的子集和超集。
在进入客户端的javascript的内容之前,第12章我们只要介绍两种在web之外的javascript运行环境。
2.客户端javascript
javascript语言核心部分的内容知识点交叉引用比较多,且知识层次感不分明。在客户端javascript的内容编排有了很大的改变。依照本章学习,完全可以在web浏览器中使用javascript。(但你如果想通过阅读本书学习javascript的话,不能只将眼光放在第二部分) 第13章是第二部分的第一章,该章介绍如何让javascript在web浏览器中运行起来。 第14章讲解到web浏览器脚本技术,并涵盖客户端javascirpt的一席重要的全局函数。
例如:
function moveon() { //通过对话框询问一个问题 var answer = confirm("准备好了吗?"); //单击确定,浏览器会加载一个新的页面 if (answer) window.location = "http://www.baidu.com"; } //在1分钟(60000毫秒后执行这个函数) setTimeout(moveon,300);
第十五章会讲述javascript如何操纵html样式定义内容的展示方式.第十五章的内容将更加务实,通过脚本操作html文档内容,它将展示如何选取特定的网页元素,如何给html元素设置属性,如果修改元素的内容,以及如何给文档添加新的节点
以下实例函数展示了如果查找和修改基本的文章内容
//在document中的一个指定信息的区域树超调试信息 //如果document上不存在这个元素,则创建一个 function debug(msg) { //通过查看html元素的 id属性来查找文档的调试部分 var log = document.getElementById("debuglog");//如果元素不存在,则创建一个 if (!log) { log = document.createElement("div"); //创建一个新的div元素 log.id = "debuglog"; //为在各方元素的id赋值 log.innerHTML = "<h1>Debug Log</h1>"; //自定义初始内容 document.body.appendChild(log); //将其添加到文档末尾 } //将消息包含在<pre>中,并添加到log中 var pre = document.createElement("pre"); //创建pre元素 var text = document.createElement(msg); //将msg包含在一个文本节点上 pre.appendChild(text); //文本添加到pre log.appendChild(pre); //pre添加到log }
在第十六章会讲到如何使用javascript操作元素,这通常会使用到元素的style和class属性
function hide(e, reflow) { //通过jvascript操纵元素和隐藏元素e if (reflow) { //如果第二个参数为true e.style.display = "none" //隐藏这个元素,其占用的空间也销售 } else { e.style.visibility = "hidden"; //将e隐藏,保留其占用的空间 } }function highlight(e) { //通过设置css来高亮显示e if (!e.className) e.className = "highcss"; else e.className += "highcss"; }
可以通过javascript来控制元素的内容和css样式,同样也可以通过事件处理程序(event handler)来定义文档行为,事件处理辰星是一个在浏览器中心注册的javascript函数,当特定的事件发生时浏览器便可以调用这个函数。
通常我们关注的事件类型是鼠标点击和键盘按键事件(智能手机为各种触碰事件)。或者说当浏览器完成文档的加载,当用户改变窗口的大小或当用户向表单中输入数据时便会触发一个人事件。
第17章会详细描述如何定义,注册时间处理程序,以及在事件发生时浏览器是如何调用他们的。
自定义事件处理程序最简单的方法,给html的以on为前缀的属性绑定一个回调,当写一些简单的程序测试时,最实用的方法就是给“onclick”处理程序绑定回调。假设以上将上文的debug()和hide()这个函数保存至debug.js和hide.js的文件中,那么就可以简单些一个html测试文件,来给onclick的属性指定一个事件处理程序。如下
<script type="text/javascript"> //在document中的一个指定信息的区域树超调试信息 //如果document上不存在这个元素,则创建一个 function debug(msg) { //通过查看html元素的 id属性来查找文档的调试部分 var log = document.getElementById("debuglog"); //如果元素不存在,则创建一个 if (!log) { log = document.createElement("div"); //创建一个新的div元素 log.id = "debuglog"; //为在各方元素的id赋值 log.innerHTML = "<h1>Debug Log</h1>"; //自定义初始内容 document.body.appendChild(log); //将其添加到文档末尾 } //将消息包含在<pre>中,并添加到log中 var pre = document.createElement("pre"); //创建pre元素 var text = document.createElement(msg); //将msg包含在一个文本节点上 pre.appendChild(text); //文本添加到pre log.appendChild(pre); //pre添加到log } function hide(e, reflow) { //通过jvascript操纵元素和隐藏元素e if (reflow) { //如果第二个参数为true e.style.display = "none" //隐藏这个元素,其占用的空间也销售 } else { e.style.visibility = "hidden"; //将e隐藏,保留其占用的空间 } } function highlight(e) { //通过设置css来高亮显示e if (!e.className) e.className = "highcss"; else e.className += "highcss"; } </script> hello <button onclick="hide(this,true); debug('hide buttoon 1');">hide1</button> <button onclick="hide(this);debug('hide button 2');">hide2</butotn>
下面的这些客户端javascript用到了事件,它给了一个很重要的事件:“load”事件注册了一个事件处理辰星。同事也展示注册"click"事件处理函数更高级的一种方法
<script type="text/javascript"> //"load"事件在只有在文档加载后才能完成触发 //如通常需要等待load事件发生后才能执行javascript代码 window.onload = function() { //找到文档中所有的img标签 var images = document.getElementsByTagName("img");//遍历images,给每个节点的click事件添加处理程序 //在点击图片的时候将图片隐藏 for (var i = 0; i < images.length; i++) { var imge = images[i]; if (imge.addEventListener) //注册时间处理程序的另外一种方法 imge.addEventListener("click", hide, false); else //兼容ie8以前操作 imge.attachEvent("onclick", hide); } //这便是上面注册事件的处理函数 function hide(evnet) { event.target.style.visibility = "hidden"; } }; </script>
在15-17章讲述了如何使用javascript来控制网页的内容,样式以及行为(事件处理),这章讨论api多少有些复杂,而且至今有糟糕的浏览器兼容性,正是这个原因,很多javascript程序员选择使用"库"或“框架”来简化他们的编码工作,最流行的莫非jQuery,第19章介绍jQuery库
function debug(msg) { var log = $("#debuglog"); if (log.length == 0) { log = $("<div id='debuglog'><h1>debuglog</h1></div>"); log.appendTo(document.body); } document.write(log) log.append($("<pre/>").text(msg)); };
目前我们所提到的第二个部分的4章都是围绕网页展开讨论的,后续的4章将着眼店转向web应用,这几张内容不是讨论如何编写操控内容。样式和兴旺的脚本使用web浏览器来渲染文档;而是讲解如何将web浏览器作为应用平台。并描述了用于支持更复杂精细的客户端web应用和现代浏览器的api。
第18章讲解如何使用javascript来发起http请求。
第20章描述数据存储机制以及客户端应用的会话状态保持,第21章涵盖基于讲解html5所驱动的新一代应用api/网络 存储 图形,这些都是基于哪些支持新api的浏览器开发。浙江是你作为javascript程序员最激动人心的时刻。最后4章没有太多的示例代码。下面的例子使用了这些新的api.