你手中的这本《JavaScript王者归来》不仅是一本传播知识的书,更是一本求道的书。
本书分为五个部分循序渐进地与读者讨论了JavaScript的方方面面,从简单的语言基础到丰富的实际应用再到深入剖析语言本质的高级话题,字里行间包含着作者多年工作中对JavaScript实践乃至程序设计思想的深入思考和总结。
本书揭开了JavaScript的面纱,绕过误解和虚幻的表象,引领你探索程序王国的奥妙。它既是一本为初学者准备的入门级教程,又是一本探寻程序设计思想本源的“魔法典籍”,也是一本Web开发工程师们需要的案头参考书。
本书是你进入脚本王国的一把钥匙,引导你领略脚本魔法的神奇魅力。它还是一本着眼于未来改变互联网的启蒙读物,在它的引领下,你将在互联网的世界里获得你所希望得到的知识、智慧、成就和快乐。
吴亮(网名月影)早年曾在微软亚洲研究员做过访问学生、在金蝶软件有限公司先后担任过核心开发工程师、设计师和项目经理,现任百度电子商务事业部Web开发项目经理。多年来致力于JavaScript技术和Web标准的推广,活跃于国内极有影响力的JavaScript专业网站——无忧脚本(www.51js.com),并担任JavaScript版的版主。平时热爱文学、写作和围棋。
第一部分 概论 19 第一章 从零开始 19 1.1为什么选择JavaScript? 19 1.1.1 用户的偏好:B/S模式 19 1.1.2 在什么情况下用JavaScript 20 1.1.3 对JavaScript的一些误解 20 1.1.4 警惕!脚本诱惑 22 1.1.5 隐藏在简单表象下的复杂度 22 1.1.6 令人迷惑的选择:锦上添花还是雪中送炭 23 1.1.7回到问题上来 23 1.2 JavaScript的应用范围 24 1.2.1客户端的JavaScript 24 1.2.2服务器端的JavaScript 25 1.2.3其他环境中的JavaScript 26 1.3 JavaScript的版本 26 1.3.1 浏览器中的JavaScript版本 26 1.3.2 其他版本 27 1.4 一些值得留意的特性 27 1.4.1 小把戏:神奇的魔法代码 27 1.4.2 为客户端服务 30 1.4.3 数据交互 32 1.4.4 表面上的禁忌 32 1.5 安全性和执行效率 35 1.5.1 数据安全:永远的敏感话题 35 1.5.2 实战!攻击与防范 35 1.5.3 不容马虎:时刻关注性能 38 1.6 一个例子——JavaScript编写的计算器 40 1.6.1 从需求分析开始:什么是计算器? 40 1.6.2 系统设计:如何实现计算器? 41 1.6.3 系统实现:计算器的最终实现 46 1.6.4 持续改进:迭代的软件开发过程 55 1.7 学习和使用JavaScript的几点建议 56 1.7.1 像程序员一样地思考 57 1.7.2 吝惜你的代码 59 1.7.3 学会在环境中调试 59 1.7.4 警惕小缺陷 59 1.7.5 思考先于实践 60 1.7.6 时刻回头 60 1.8 关于本书的其余部分 60 第二章 浏览器中的JavaScript 61 2.1 嵌入网页的可执行内容 61 2.1.1 在什么地方装载代码 61 2.1.2 代码的Script标签 63 2.1.3 我的代码什么时候被执行 63 2.1.4 拿来主义:引入外部文件 65 2.2 赏心悦目的特效 69 2.2.1 生命在于运动 69 2.2.2 换一种风格 69 2.2.3 我的地盘我做主 70 2.3 与用户交互 73 2.3.1 悄悄地告诉你 73 2.3.2 填错了哦 77 2.4 绕开脚本陷阱 77 2.4.1 现实并不总是完美的 77 2.4.2 不能完全相信你所见到的 78 2.5 总结 78 第三章 开发环境和调试方法 79 3.1 我能用什么来编写脚本 79 3.1.1 适合编写JavaScript的文本编辑器 79 3.2 来自浏览器的支持 82 3.2.1 主流浏览器 82 3.2.2 非主流浏览器 82 3.3 集成开发环境 83 3.3.1 什么是集成开发环境 83 3.3.2 我需要集成开发环境吗 83 3.3.3 适合JavaScript的集成开发环境 83 3.4 调试工具:提升开发效率的利器 84 3.4.1 什么是调试 84 3.4.2 原始的调试方法 84 3.4.3 适合JavaScript的调试工具 87 3.5 定位代码和调用堆栈 89 3.5.1 Step by Step:单步和断点 89 3.5.2 监视内存 89 3.5.3 追踪问题的源头:查看调用堆栈 90 3.5.4 遇到麻烦了:为什么我跟踪不到代码 91 3.6 浏览器捕获异常 91 3.6.1 异常处理机制 91 3.6.2 异常的种类 93 3.6.3 应该在什么时候“吃掉”异常 94 3.7 总结 94 第二部分 JavaScript核心 95 第四章 语言结构 95 4.1基本文法 95 4.1.1 字符集 95 4.1.2 大小写敏感 96 4.1.3 分隔符 97 4.1.4 词、句子和段落 97 4.1.5 分号 98 4.1.6 标记 99 4.1.7 注释 99 4.1.8 保留字 99 4.2常量和变量 100 4.2.1 常量和变量 100 4.2.2 变量的标识符 101 4.2.4 变量的声明 101 4.2.5 变量的作用域 102 4.3表达式和运算符 106 4.3.1 表达式 106 4.3.2 运算符概述 106 4.3.3 算术运算符 108 4.3.4 关系运算符 109 4.3.5 逻辑运算符 111 4.3.6 位运算符 112 4.3.7 赋值运算符 113 4.3.8 其他运算符 114 4.4控制语句 118 4.4.1 表达式语句 118 4.4.2 语句块 119 4.4.3 条件语句 119 4.4.4 循环语句 123 4.4.5 跳转语句 126 4.4.6 异常处理语句 129 4.4.7 其他语句 130 4.5总结 131 第五章 数据类型 132 5.1基本数据类型 132 5.1.1数值 133 5.1.2字符串 134 5.1.3布尔型 136 5.2数组和对象 137 5.2.1数组 137 5.2.2对象 138 5.3函数类型 141 5.3.1函数 141 5.4null和undefined 143 5.4.1 null 143 5.4.2 undefined 143 5.5正则表达式 144 5.5.1正则表达式常量 144 5.5.2正则表达式对象 144 5.6值类型和引用类型 144 5.6.1什么是值和值的引用 144 5.6.2使用值和使用引用 145 5.7类型识别与类型转换 148 5.7.1运行时类型识别 148 5.7.2类型的自动转换 150 5.7.3强制类型转换 151 5.7.4高级用法 154 5.8警惕数值陷阱 155 5.8.1困惑:浮点数的精度问题 155 5.8.2误差的修正 156 5.9总结 157 第六章 函数 158 6.1函数定义和函数调用 158 6.1.1 函数的定义 158 6.1.2 函数的调用 161 6.2函数的参数 162 6.2.1 形参与实参 162 6.2.2 Arguments对象 164 6.2.3 参数类型匹配 168 6.3函数的调用者和所有者 171 6.3.1 函数的调用者 171 6.3.2 函数的所有者 171 6.3.3 动态调用:外来的所有者 173 6.4函数常量和闭包 175 6.4.1 匿名的函数 175 6.4.2 函数引用 175 6.4.3 函数参数和函数返回值 176 6.4.4 高级用法 177 6.5高级抽象: Function类型和函数模版 179 6.5.1 动态创建函数 179 6.5.2 模式:函数工厂 180 6.6总结 183 第七章 对象 183 7.1什么是对象 184 7.2对象的属性和方法 184 7.2.1 对象的内置属性 184 7.2.2 为对象添加和删除属性 186 7.2.3 反射机制:枚举对象属性 188 7.3对象的构造 188 7.3.1 构造函数 188 7.3.2 缺省构造和拷贝构造 190 7.3.3 对象常量 192 7.4对象的销毁和存储单元回收 192 7.5 JavaScript内置对象 193 7.5.1 Math对象 193 7.5.2 Date对象 194 7.5.3 Error对象 196 7.5.4 其他内置对象 196 7.5.5 特殊的对象:全局对象与调用对象 196 7.6总结 197 第八章 集合 197 8.1数组和数组元素 198 8.1.1 数组的构造 198 8.1.2 数组常量 199 8.1.3 数组元素 199 8.2数组对象和方法 199 8.2.1 查找元素 199 8.2.2 添加和删除元素 200 8.2.3 集合操作 201 8.3哈希表 202 8.2.1什么是哈希表 203 8.2.2 哈希表的构造 203 8.2.3 实现HashTable类型 203 8.4高级用法 206 8.4.1 集合操作和闭包 206 8.5总结 210 第九章 字符串 211 9.1字符串的构造 211 9.1.1 字符串常量 211 9.1.2 转义序列 211 9.1.3 字符串构造函数 212 9.2字符串的使用 212 9.2.1 比较字符串 212 9.2.2 抽取和检索子串 212 9.2.3 连接拆分 213 9.2.4 模式匹配 214 9.2.5 其他方法 216 9.3字符串与字符数组 216 9.4字符串与文本处理 216 9.4.1 JavaScript棋谱阅读器(一) 217 9.5总结 221 第十章 正则表达式 222 10.1什么是正则表达式 222 10.1.1 正则表达式的概念 222 10.1.2 JavaScript中的正则表达式 222 10.2正则表达式的规则 223 10.2.1直接量字符 223 10.2.2 字符类和布尔操作 224 10.2.3 重复 224 10.2.4 选择、分组和引用 224 10.2.5 指定匹配的位置 225 10.2.6标志 225 10.3模式匹配 226 10.3.1 用于模式匹配的String方法 226 10.3.2 用于模式匹配的RegExp方法 229 10.4正则表达式包装对象 231 10.4.1 RegExp对象 231 10.4.2 RegExp的实例属性 233 10.5强大的正则表达式 233 10.5.1 分析正则表达式的局部 233 10.5.2 一个例子——强大的在线编辑器 233 10.5.3 构造新的文法 236 10.6高级用法 238 10. 7 用正则表达式处理文本 239 10.7.1 计价公式编辑器 239 10.7.2 同步滚动歌词播放器 243 10. 8 总结 247 第三部分 浏览器与DOM 248 第十一章 浏览器对象 248 11.1 Window对象 248 11.1.1 Window对象概览 248 11.1.2 Window对象的生命周期 249 11.1.3 Window属性和方法 251 11.2 Document对象 253 11.2.1 Document对象概览 253 11.2.2 动态生成的文档 254 11.2.3 Document对象的基本信息 257 11.2.4 Document对象的外观属性 258 11.2.5 子对象接口 260 11.3 对话框和状态栏 262 11.3.1 简单对话框 263 11.3.2其他类型的对话框 264 11.3.3 状态栏 274 11.4 框架 274 11.4.1 多框架应用 274 11.4.2 框架之间的关系 275 11.4.3 框架的命名 276 11.4.4 子框架中的JavaScript 276 11.4.5 框架的应用——多页签显示 277 11.5 表单和表单对象 279 11.5.1 Form对象 279 11.5.2客户端表单校验 282 11.5.3通用的客户端表单校验组件 287 11.6 其他内置对象 296 11.6.1 Navigator对象 296 11.6.2 Screen对象 297 11.6.3 Location对象 299 11.6.4 History对象 301 11.7 总结 301 第十二章 文档对象模型 301 12.1 什么是DOM 302 12.1.1 把文档表示为树 302 12.1.2 树的节点 302 12.1.3 DOM对象的通用属性和方法 304 12.1.4 HTML结构和DOM对象的关系 304 12.2 DOM与浏览器实现 306 12.2.1 DOM HTML API 306 12.2.2 DOM的级别和特性 309 12.2.3 DOM的一致性 309 12.2.4 差异性:浏览器的DOM方言 310 12.3一组“盒子”:DOM元素 310 12.3.1嵌套的“盒子” 311 12.3.2“盒子”和“盒子”内容的分类 311 12.4创建和删除节点 312 12.4.1 构造全新的节点 312 12.4.2 平面展开:通过文档元素直接创建 314 12.4.3 回收空间:删除不用的节点 316 12.5访问和操纵 DOM节点 316 12.5.1 打开每一个盒子:遍历节点 317 12.5.2 弄清层级关系:父子与兄弟 318 12.5.3 搜索特定节点 319 12.5.4 克隆节点 322 12.5.5移动节点 324 12.5.6 小技巧 327 12.6读写数据 329 12.6.1 添加、修改和删除属性 330 12.7外观与行为 331 12.7.1 DOM样式属性 331 12.7.2 显示与隐藏 331 12.7.3 改变颜色和大小 332 12.7.4 改变位置 334 12.7.5 编辑控制 335 12.7.6 改变样式 337 12.8 XML DOM 338 12.8.1 什么是XML DOM 339 12.8.2 如何使用XML DOM 339 12.9总结 341 第十三章 事件处理 342 13.1 什么是事件 342 13.1.1 消息与事件响应 342 13.1.2 浏览器的事件驱动机制 343 13.2 基本事件处理 344 13.2.1 事件和事件类型 344 13.2.2 事件的绑定 345 13.2.3 直接调用事件处理函数 345 13.2.4 事件处理函数的返回值 347 13.2.5 带参数的事件响应 347 13.2.6“this”关键字 348 13.3标准事件模型 349 13.3.1 起泡和捕捉:浏览器的事件传播 349 13.3.2 事件处理函数的注册 350 13.3.3 把对象注册为事件处理程序 351 13.3.4 事件模块和事件类型 351 13.3.5 Event接口 352 13.3.6 混合事件模型 354 13.3.7 合成事件 354 13.4浏览器的事件处理模型实现 355 13.4.1 Internet Explorer 事件模型 355 13.4.2 Netscape 4 事件模型 357 13.5回调与用户自定义事件 360 13.5.1 事件处理模式 361 13.5.2 用户事件接口的定义 363 13.5.3 事件代理和事件注册 363 13.5.4 标准模式:事件分派和接收 367 13.6一个例子——增强数据表格 370 13.6.1 什么是增强数据表格 370 13.6.2 固定表头 371 13.6.3 可变列宽 373 13.6.4 标记列 375 13.6.5 小技巧:将代码添加到样式表 377 13.7总结 378 第十四章 级联样式表 379 14.1什么是级联样式表 379 14.1.1 CSS样式和样式表 379 14.1.2 CSS的标准化 379 14.1.3 浏览器支持的CSS 383 14.2 JavaScript与CSS 383 14.2.1 CSS和DOM 383 14.2.2 CSS和IE 385 14.2.3浏览器的CSS兼容性 386 14.3 总结 386 第十五章 脚本化数据存储 386 15.1什么是cookie 387 15.1.1 浏览器和客户端cookie 387 15.1.2 cookie的属性 388 15.2 cookie的客户端存取 388 15.2.1 cookie的存储 388 15.2.2 cookie的读取 389 15.3 cookie的限制 389 15.4 cookie示例 389 15.5 cookie对象封装 392 15.5什么是userData 394 15.5.1 浏览器和客户端userData 394 15.5.2 userData的声明 394 15.5.3 userData的属性和方法 395 15.6 userData的客户端存取 395 15.6.1 userData的存储和读取 395 15.6.2 userData的安全性 396 15.7 userData的限制 396 15.8 userData与cookie的对比 396 15.9 userData示例 396 15.10总结 400 第四部分 数据交互 400 第十六章 同步和异步 400 16.1什么是同步和异步 401 16.2超时设定和时间间隔 401 16.3定时器使用——侦听与拦截 403 16.3.1 标准模式:监视器 403 16.3.2 应当注意的问题 405 16.4一个例子——漂亮的Web时钟 406 16.4.1什么是Web时钟? 406 16.4.2 最简单的Web时钟 407 16.4.3 Web时钟的设计 408 16.4.4 完整的Web时钟源代码 408 16.5总结 412 第十七章XML DOM和XML HTTP 412 17.1 什么是XML DOM对象 413 17.1.1 XML DOM简介 413 17.1.2 浏览器支持的XML DOM接口 414 17.2 XMLDOM的版本兼容性 418 17.2.1 XMLDOM的跨浏览器应用 418 17.3 错误处理 423 17.3.1 ParseError对象 423 17.3.2 包含错误信息的文档 424 17.4 XML DOM操作XML文档 424 17.4.1 访问节点 424 17.4.2 创建新节点 425 17.4.3移动和修改节点 426 17.4.4 读写节点属性和读写数据 428 17.4.5 保存文档 428 17.5 一个例子——JavaScript棋谱阅读器(二) 428 17.5.1 用XML描述棋谱 428 17.5.2 将XML棋谱转换为SGF棋谱 429 17.6 什么是XML HTTP对象 430 17.6.1 XML HTTP 对象简介 431 17.6.2 浏览器支持的XML HTTP对象 431 17.7发送请求 431 17.7.1 建立连接 432 17.7.2发送请求 432 17.8 读取和设定HTTP头 432 17.8.1 什么是HTTP头 432 17.9 服务器应答 433 17.9.1 同步和异步应答 433 17.9.2 ResponseText 和ResponseXML 435 17.10 总结 435 第十八章 Ajax简介 436 18.1什么是Ajax 436 18.1.1 Ajax并不神秘 436 18.1.2 Ajax的应用场景 436 18.1.3 Ajax的竞争对手:其他替代技术 437 18.2 Ajax初探:我的第一个Ajax程序 438 18.2.1 从常规应用开始 438 18.2.2 讨厌的页面刷新 439 18.2.3 无刷新解决方案 440 18.2.4 异步工作 441 18.3 Ajax原理剖析 442 18.3.1 XmlHttp实时通信 442 18.3.2 数据动态显示 445 18.3.3 发挥XML的能力 448 18.3.4 JavaScript绑定一切 448 18.3.5 应用背后的标准 448 18.4 Ajax范例——实时聊天工具 449 18.4.1什么是实时聊天工具 449 18.4.2需求分析:实时聊天功能的实现要点 450 18.4.3系统实现:实时聊天功能的实现 450 18.4.4小结 451 18.5 总结 451 第十九章 标准和兼容性 452 19.1标准化组织 452 19.1.1 W3C和 DOM标准 452 19.1.2 ECMA 和 JavaScript标准 452 19.1.3 互联网标准 452 19.2平台和浏览器的兼容性 453 19.2.1 最小公分母法 453 19.2.2 防御性编码 453 19.2.3 客户端探测器 453 19.2.4 特性检测 454 19.2.5 实现标准 454 19.3语言版本的兼容性 455 19.3.1 language属性 455 19.3.2 版本测试 455 19.4如何实现跨浏览器应用 456 19.4.1 取舍:划定支持范围 456 19.4.2 基础模块设计:独立兼容性检测 457 19.4.3 划分运行级别 458 19.4.4 给出正确的信息 458 19.4.5 充分的应用测试 459 19.4.6 靠近标准和就近原则 460 19.5展望未来 460 19.6总结 461 第二十章 信息安全 461 20.1用户的隐私信息 461 20.1.1 Web应用中的隐私信息 461 20.2禁止和受限制的操作 462 20.2.1 受限制的属性 462 20.2.2 受限制的操作 463 20.2.3 脚本安全级别 464 20.2.4 脚本调试 464 20.3警惕幕后的攻击者 465 20.3.1 攻击的手段 465 20.3.2 隐匿的数据流 466 20.3.3 页面伪装 466 20.3.4 发现蛛丝马迹 466 20.3.5 防范的手段 467 20.4同源策略 468 20.4.1 什么是同源策略 468 20.4.2 同源策略的利弊 469 20.4.3 突破同源策略 469 20.5安全区和签名脚本 470 20.5.1 可配置的安全策略方案 470 20.5.2 Internet Explorer的安全区 470 20.5.3 Netscape的签名脚本 470 20.6代码本身的安全:加密和混淆 470 20.6.1 为什么要加密和混淆 470 20.6.2 客户端的加密技术 471 20.6.3 代码混淆原理 472 20.6.4 JavaScript代码混淆工具 472 20.6.5 加密和混淆的结合使用 475 20.7总结 476 第五部分 超越JavaScript 477 第二十一章 面向对象 477 21.1什么是面向对象 477 21.1.1 类和对象 478 21.1.2 公有和私有:属性的封装 479 21.1.3 属性和方法的类型 480 21.2神奇的prototype 482 21.2.1 什么是prototype 482 21.2.2 prototype使用技巧 484 21.2.3 prototype的实质 492 21.2.4 prototype的价值与局限性 494 21.3继承与多态 495 21.3.1 什么是继承 495 21.3.2 实现继承的方法 496 21.3.3 单继承与多重继承 505 21.3.4 接口 507 21.3.5 多态 508 21.4构造与析构 510 21.4.1构造函数 510 21.4.2多重构造 511 21.4.3析构 512 21.5疑团!“this”迷宫 513 21.5.1 无数个陷阱:令人困扰的“this”谜团 513 21.5.2 偷梁换柱:不好的使用习惯 517 21.5.3 异步调用:谁动了我的“this” 518 21.5.4 揭开真相:JavaScript的“this”本质 518 21.5.5 困难不再:利用闭包修正“this”引用 518 21.6包装对象 519 21.6.1 区分值和引用 520 21.6.2 装箱与拆箱 521 21.7元类,类的模板 523 21.7.1 什么是元类 523 21.7.2 元类:构造类的类 523 21.7.3 为什么要用元类 525 21.7.4 类工厂 526 21.8谁才是造物主 526 21.8.1 万物适用的准则 526 21.8.2 抽象的极致 527 21.8.3 返璞归真,同源架构 529 21.9总结 530 第二十二章 闭包与函数式编程 530 22.1动态语言与闭包 530 22.1.1动态语言 530 22.1.2语法域和执行域 531 22.1.2 JavaScript的闭包 532 22.2闭包的特点与形式 533 22.2.1 闭包的内在:自治的领域 533 22.2.2 访问外部环境 535 22.2.3 闭包和面向对象 536 22.2.4 其他形式的闭包 537 22.3闭包使用的注意事项 538 22.3.1 不适合使用闭包的场合 538 22.4函数式编程 539 22.4.1 什么是函数式编程 539 22.4.3 函数式编程的优点 545 22.4.4 函数式编程的缺点 547 22.5闭包与面向对象 547 22.5.1 私有域 548 22.5.2 名字空间管理 549 22.5.3 友元 550 22.6 Python风格 551 22.6.1 最简约代码 552 22.6.2 轻量级重用 552 22.6.3 模块管理 557 22.7 总结 558 第二十三章 模块级管理 558 23.1模块化管理 558 23.1.1 模块化:代码的重用 559 23.1.2 JavaScript的模块管理 559 23.2开放封闭原则和面向接口 561 23.2.1 开放封闭原则 561 23.2.2 面向接口 561 23.3名字空间管理 562 23.3.1 什么是名字空间 562 23.3.2 为什么要用名字空间 562 23.3.3 JavaScript的名字空间管理 562 23.4调用依赖 565 23.4.1 模块的依赖性 566 23.4.2 模块依赖的管理 566 23.5用代码管理代码 567 23.5.1 运行时环境的管理 567 23.5.2 托管代码 567 23.5.3 完整的代码管理容器 568 23.6总结 571 第二十四章 动态构建 571 24.1让代码去写代码 572 24.1.1 脚本的动态解析 572 24.1.2 语法扩展:创造属于自己的语言 572 24.2 “发明”语法 573 24.2.1 正则表达式和语法解析 574 24.2.2 一个简单的语法解析器实现 577 24.3 实现自己的方言——LispScript 580 24.3.1 从JavaScript到Lisp 580 24.3.2 最初的工作 580 24.3.3 公理,表达式 582 24.3.4 七条基本公设 582 24.3.5 函数文法 586 24.3.6 定义新函数 588 24.3.7一个惊喜——_eval 590 24.3.8其他的扩展 591 24.3.9小结 591 24.3.10运行环境和代码容器 592 24.4 总结 595 第二十五章 执行效率 595 25.1为什么要讨论执行效率 595 25.1.1 来自客户的抱怨:JavaScript能有多慢 595 25.1.2 代码慢下来是谁的错 598 25.2封闭的代价 599 25.2.1 过度封装的性能问题 599 25.2.2 信息隐藏的利弊 602 25.2.3构造对象的开销 604 25.3盒子里的流火 606 25.3.1 DOM的内存开销 606 25.3.2 浏览器的内存管理 607 25.3.3 看清一个事实:内存泄漏的存在 608 25.3.4 注意:及时关闭你的“盒子” 608 25.3.5 一些误会的澄清 609 25.4 动态:魔鬼与天使 610 25.4.1 动态解析的性能分析 610 25.4.2开发效率与执行效率:永远的困难选择 612 25.4.3 优美与适用:学会经受魔鬼的诱惑 612 25.4.4 扮演客户眼中的天使 613 25.5 让代码轻舞飞扬 613 25.5.1 简单就是美:为代码瘦身 613 25.5.2 最完美的运用是不用 614 25.5.3 高度抽象是为了简化问题 614 25.5.4 逻辑和表达同样重要 615 25.5.5 保持代码的严谨 616 25.5.6 漂亮的书写风格:让阅读者心情愉快 616 25.6 总结 617 第二十六章 应用框架 617 26.1应用框架概览 617 26.1.1 什么是应用框架 618 26.1.2 应用框架的组成部分 618 26.2为什么要设计应用框架 620 26.2.1 应用框架的适用范围 620 26.2.2 应用框架的利弊 620 26.3如何设计应用框架 621 26.3.1 把握设计的目标 621 26.3.2 应用框架的设计准则 622 26.3.3 什么样的应用框架才是成熟的应用框架 622 26.3.4 应用框架的设计方法 623 26.3.5 实战!设计一个简单的应用框架 623 26.4框架的实际应用 639 26.5已存在的应用框架 647 26.5.1 Prototype 647 26.5.2 JQuery 649 26.5.3 Dojo 650 26.5.4 JSVM2 653 26.5.5 其他框架 654 26.6 总结 656
你好,很高兴你能翻开这本书——《JavaScript王者归来》。
书名中的“王者”,并不是指我这个作者,而是指你们——偶然地停下来,饶有兴趣地翻阅这本书的每一位读者。正是你们对JavaScript和Web开发的浓厚兴趣和热情,使得Web领域发生了和正在发生着翻天覆地的变化,也使得我有信心和毅力去完成这样一本厚厚的书。所以,这本书,是献给你们的,现在的和将来的JavaScript王者们!
这是一本什么样的书呢?作为作者,我很希望它能成为一本带着神奇力量的魔法书,能够将你对技术的兴趣,转化为神奇的魔力,帮助你在Web应用中写出不可思议的奇迹般的漂亮代码。当然,也许这只是我的一个美好的愿望,但是如果你是带着兴趣和热情来读这本书,并且愿意和我一起探寻JavaScript王国的奥秘,那么,这本书中一定有着能让你着迷的东西。
JavaScript是一位美丽而又难以捉摸的丛林女神,她干净利落而又变化多端,她的美丽能够带给你喜悦和幸福感,她的善变,却又让你深深地陷入困惑之中。有时候,你本能地想逃避她,内心里又离不开她。你觉得她单纯,可是你看不透她,你觉得她难以捉摸,可是她却偏偏又有着简单乖巧的一面。这样的一种语言,是充满魅力的魔法精灵,难道你就不想看清她的真面目,读懂她,让她帮助你创造出激动人心的神迹吗?来吧,翻开这本书,你的愿望能够实现。
如果你是一位刚刚接触到丰富多彩的Web世界,希望自己也能够制作出那些美丽多彩的页面的人,那么请相信我,这本书是为你准备的,通过阅读它,能够使你具备创建和驾驭属于你自己的Web国度的能力。 如果你是一位偶然地在浏览器页面代码中发现一小段包含在<script>标记之间的小脚本,并且希望弄明白它的人,那么请相信我,这本书是为你准备的,如果你有耐心读完它,你将能够自由地让你的意志在<script>标记之间飞扬。
如果你是一位迷失在无数脚本和特效之间的旅行者,那么请相信我,这本书是为你准备的。来和我一起在Web的湖泊中畅游吧,我必将带你离开迷宫和陷阱,让你看到脚下的这个王国是多么的美好,你将成为一位英明的王,而不再是无助的迷路人。
如果你是一位饱受脚本困扰的程序员,那么请相信我,这本书是为你准备的,请和我一起打开缠绕在你心头的枷锁,你会发现你手中握着的是一把神奇的利刃,这把神兵将不再割伤你自己,而是被你支配,成为在Web世界里助你开拓疆土的神器。
如果你是一位在脚本泥潭中挣扎的项目经理,那么请相信我,这本书也是为你准备的,我发誓我有能力带你离开我自己曾经挣扎过的地方,当你离开了陷阱,你将发现以前你无暇顾及的世界,原来是那么的美好。
所有翻开了这本书并喜爱着JavaScript的读者们,愿脚本神力与你们同在!
本书中的部分内容来自于网络上公开的文章,所有有出处的文字都尽量标注出原始的出处,包括原文作者、首发网址和译者。引用为例子的代码在尽可能的情况下得到作者本人的同意。如果对这部分内容有任何疑义,请及时与作者联系。
本书中的部分文字参考或者直接引用了《JavaScript权威指南》第四版,作者David Flanagan,译者张铭泽等,O’REILLY授权机械工业出版社2006年9月出版。凡是明确引用此书内容和参考此书内容的部分,笔者也在书中尽量注明(正文中统一用【1】来表示),如果因为引用原文内容而产生的任何问题,请及时与作者联系。
书中相关章节的表格(表 XX.AA)大多数来源于《JavaScript权威指南》和互联网,在正文里不再做一一说明,如果对此有任何疑义,请及时与作者联系。
虽然这几年来我一直致力于推广JavaScript技术和Web标准,但是如果离开了时时刻刻支持和鼓励着我的朋友们,这样一本涉及到JavaScript方方面面的书,以我个人微不足道的力量是不可能完成的。这本书的面市凝聚着无数关心我的朋友们的心血,他们中的一些人是我的同事,另一些人是我在无忧脚本(www.51js.com)结识的伙伴,还有许许多多通过网络联系的未曾谋面的朋友。他们的每一分鼓励、每一个思想、和每一点意见都是我创作的灵感和力量的源泉,没有他们,就永远也不会有这样一本出自我手的书,在此我要向他们表示由衷的感谢。
我在金蝶工作的同事在我写这本书的时候,不但为我提出了各种建议,而且毫无怨言地分担了我的工作,体贴地为我留出足够的创作时间。在这里我要感谢jimi、张锦、小陆、阿日、建新、大琴、老丁、谢汀以及其他的和我共同奋斗的金蝶MOP团队的兄弟姐妹,谢谢你们的努力工作,谢谢你们对我的默默支持。
我创作这本书的大量灵感来源于我和无忧脚本以及CSDN论坛上的朋友们的交流。我们总是一起探讨关于脚本的深入话题,有时候达成一致意见,也有时候产生分歧甚至激烈的争执。灵感的火花总是在思维碰撞中产生的,和你们的讨论让我学到了很多东西,也直接地决定了这本书的内容组织和观点形成。在此,我要感谢所有在无忧脚本和CSDN结识的JS高手们,感谢幻宇、宝玉、梅花雪、周爱民、万常华、海浪、梅雪香、dron、stone、aoao、biyuan、泣红亭、winter和asfman以及其他所有和我一起讨论共同进步的JSers们,谢谢你们。
我在04年从学校里毕业的时候,还对JavaScript一无所知,我自学JavaScript使用的第一本教材就是David Flanagan的《JavaScript权威指南》,如果没有这本出色的教材,我可能永远也不会对JavaScript有今天这种程度的理解。本书的基础部分的许多基本概念、观点和结论,也和《JavaScript权威指南》保持一致。在此感谢David Flanagan、Brendan Eich和《JavaScript权威指南》,没有你们的帮助,也许我现在还是一位JavaScript的门外汉。
这是我写的第一本技术类的书,在此之前,我完全没有创作教程的经验,是我的编辑陈冰鼓励我创作这本书。而且在我撰写这本书的一年里,他耐心细致地阅读了我每一章节的稿件,提出了许多意见和建议,并一次又一次地督促我改进稿件,直至最终完成。如果没有陈冰的耐心指导和帮助,我永远也写不出这样一本书。
Web技术的飞速发展使得JavaScript这门脚本语言日渐被人们所重视,Web标准化工作的推进,也使得JavaScript变得越来越完善和优美,也变得越来越神奇。在这里我要感谢所有为Web技术发展做出贡献的技术人员,没有你们的努力,就没有JavaScript生存和发展的土壤。感谢W3C和ECMA组织孜孜不倦地进行的标准化工作,如果没有这些努力,JavaScript也许到今天仍然只是Web舞台一个不起眼的角落里的小配角。
最后,我要感谢我亲爱的父母,没有你们对我的爱,今天的我就不可能拥有我喜欢的事业,写出我喜欢的书,我也要将我的这本书献给你们。我永远爱着你们。吴亮 2008年1月10日
emu:这是我多年来最期盼的一本JS的书。月影式的思考问题的方式和角度,总是让人耳目一新。
我首先想说的是,作者不是个正常人来着。如果说像我这样的正常人看一个问题,可以构造出来一个数学模型,用一个函数来描述它fn(a,b,c,d...)={do sth.},在确定了n个参数后,问题就可以解决;那么到了月影手里,这个问题就变成了n维的问题空间,在只确定了部分条件的时候,就可以把这个n维空间在一个n-m维空间上做一个投影,转化为另一个问题来看待(22.4节关于Currying的内容,是我看过的最精彩的关于函数式编程的讲解之一)。
一个脚本开发的问题,到了月影手里,也许实质上是个滤波器的问题(见本书第一章),也许和波粒二像性有关(看月影以前的博文),也许实质上是受到测不准原理的限制,也许和多维时空有密不可分的关系(都是某次和月影聊天时的话题),也许背后更有不可捉摸的“道”。月影看待问题的目光,总是这样穿透表象,深入实质,并升华了问题本身,最后不但可以解决这一个问题,还可以解决相关的一系列问题,而且在解决问题的过程中,我们可能已经解决了一系列的问题。这种月影式的风格,让我们每每击案叫绝。
这些年来,在JavaScript和DOM上面基于对象和函数式编程,网友们有过无数的尝试和探索。但是这样的探索之路是如此艰难,限于精力和能力,我们往往只能在得到零星小小的突破后便折返。我们也一直期待有达人可以穿透那些荆棘后把沿途的这些风景整理出来给后人分享,但是我们都知道这些风景只要看一眼已经是如此之难,要什么样的人,才能攀下这么多的高峰,并把它们一一系统的整理出来,呈现在大家面前?
aoao:是不是看到书的文字过于华丽,是不是认为这不是技术人员写的书?别急~华丽的语言并不与技术冲突,虽然很难想像得到有一本技术类的书读起来可以用舒服来形容,很不巧,刚好这本书就是。 是不是找不到有专门介绍IE或Firefox兼容的一章,是不是正想放弃这本书?别急~这不是一本只专注解决特定问题的书,而是一本让您看到JavaScript真相的书,当你了解了事实的真相时,问题自然迎刃而解。
dh20156:许久不曾买书,嗷嗷和月影的书是我至今为止最为期待的两本! 月影的这本书从开篇便用经验及趣味的脚本来吸引读者,加上引人入胜的描述方式,让人心痒不止,不睹不快!
再谈谈本书的设计,理论知识由浅到深的推进,实战则从最简单的应用直到当前最流行应用的深入分析,更值得一提的是,作者无时无刻不在引导着读者朝着一个真正的程序员的方向去看待问题、思考问题、解决问题!可以说,本书是一本“老少皆宜”的JavaScript参考手册!无论是新手还是已从事JavaScript工作多年的人,都可以从中获得巨大的帮助!
希望本书能够帮到更多的人,为Web开发带来更多新突破!
winter:这是一本求“道”的书。市面上关于JavaScript的书极多,且不乏精品,然而多执著于“术”。若讲JavaScript的语法,ECMA262标准的文档已经足够,若讲JavaScript与DOM应用,MSDN和W3C上的DOM参考也足够。
JavaScript是一门很有趣的语言,每取得一点更深入的理解,我便以为自己已经彻悟。从最初的函数使用、面向对象、原型继承、函数对象到后来作用域链、functional、预解析、表达式解析机制、动态语言特性,每在此道路上前进一步,我都曾以为自己到达了顶峰。然而,事实上是,简单的语法也能承载深刻的思想。巧妙的设计让JavaScript成为一门兼有元类(meta-class)、类(class-based)、原型(prototype-based)三种面向对象特性和functional特性的动态语言。回忆起来,对这样的语言,说我已到达顶峰,是十分可笑的。
这本书虽然已经详细到足可以代替参考手册来查阅,但是,它是一门讲思想的书。她将以优美的文字和同样优美的代码向你展示JavaScript的独特魅力。读过这本书,你不但能了解JavaScript,还会对整个编程的思想有一个新的认识,对于面向对象语言、函数式语言、动态语言有全新的理解。
从另一个角度说,思想也并非作者所追求的“道”的终极。透漏一下,除了项目经理/资深程序员外,作者还有很多身份:论坛版主、文学爱好者(写的小说挺不错、就是更新慢了点)、理论物理爱好者(是的,你将会看到他经常把程序跟理论物理联系起来)。读过这本书,你也许能理解作者所追求的“道”。
多说无益,赶紧弄一本回家看吧。..
92页,表4.1,Break、Case、New等,首字母小写,应为break、case、new等
101页,表4.3,运算符In,应为in
225页,“9.2.5 其他方法” 一节中的String.fromCharAt 应该是 String.fromCharCode
264页,表11.1,属性方法名Alert、AttachEvent、Blur、ClearInterval、ClearTimeout的首字母应小写
363页,表13.1,标准事件类型中OnXxx首字母大写的均应为首字母小写onXxx
370页,表13.2,事件模块和事件接口中的事件类型首字母大写的均应为首字母小写
501页,Ttop.location = self.location应为top.location = self.location
574页,GroupTempl@te应为GroupTemplate
89页,getElementsByTagName('BUTTON')举例有误,该方法对大小写并不敏感
95页,对于未声明也未赋初值的变量,如果直接使用,会抛出一个系统级别的Error,唯一的例外是typeof操作 —— typeof并不是“唯一的例外”,除了typeof外还有delete操作
97页,代码var c=step(20)重复
164页,return语句不一定只执行一次,有一种特殊情况,就是当用了try...catch...finally...的时候,读者可以自行验证:)