论坛首页 Web前端技术论坛

JavaScript内核系列 第1章 前言及概述

浏览 21552 次
该帖已经被评为精华帖
作者 正文
   发表时间:2010-04-01   最后修改:2010-04-28

前言

从2006年第一次接触JavaScript至今,算来也有四年时间了。上大学的时候,有一段时间沉迷于函数式编程,而那时候对JavaScript的理解仅仅局限在这是用来做网页的一种脚本,那些很恶心的弹出窗口和不断在页面上漂浮的黄色广告就是用JavaScript做出来的。工作之后,由于我们产品本身就是基于WEB展现的,而这个时候Ajax已经复兴数年了,但是于我,则只有“Ajax可以实现页面的局部刷新”这样一个概念。在实际的应用中,我才有机会面对真正的JavaScript,早期关于函数式编程的概念开始在我的记忆力复苏,而真正将JavaScript比较熟练的应用在产品的开发中,那已经是09年年末了。

 

开始研究JavaScript,是从2008年的5月左右,我从当当上买了一本犀牛书,并下载到一本蝴蝶书,结合着实际工作的的要求,一步一步的开始了JavaScript的探索。刚开始也只是被陷入在DOM的泥潭中,慢慢的开始考虑更进一步的东西,比如JSON作为数据交换,window对象的一些特殊的方法如eval等等,事实上仍然是陷入在语法的细节中。当终于有一天,理解了变量的作用域,理解了闭包,理解了函数的一等性,以往用来类比的来源于其他语言的所有概念则完全被颠覆了,当理解了JavaScript中的这些基本概念(虽然难以理解,但是它们的确是基本概念)之后,在回顾来时的路,则有些一览众山小的意思。

 

但是,这些看似基本的概念,在初学时如果混入了其他语言的概念以进行类比,则后患无穷,所以,学习JavaScript其实就一句话:“将JavaScript当成一门新的语言来学习”。鉴于我学习JavaScript的历程中,遇到了很多问题,但是最终都一一克服了,在这个过程中,有些心得,有些体会,就分节贴出来,做成一个系列,以方便初学JavaScript的朋友们。

 

 

 

第一章 概述

1.1 Javascript简史

在20世纪90年代,也就是早期的WEB站点上,所有的网页内容都是静态的,所谓静态是指,除了点击超链接,你无法通过任何方式同页面进行交互,比如让页面元素接受事件,修改字体等。人们于是迫切的需要一种方式来打破这个局限,于是到了1996年,网景(Netscape)公司开始研发一种新的语言Mocha,并将其嵌入到自己的浏览器Netscape中,这种语言可以通过操纵DOM(Document Object Model,文档对象模型)来修改页面,并加入了对鼠标事件的支持。Mocha使用了C的语法,但是设计思想上主要从函数式语言Scheme那里取得了灵感。当Netscape 2发布的时候,Mocha被改名为LiveScript,当时可能是想让LiveScript为WEB页面注入更多的活力。后来,考虑到这个脚本语言的推广,网景采取了一种宣传策略,将LiveScript更名为JavaScript,目的是为了跟当时非常流行的面向对象语言Java发生暧昧的关系。这种策略显然颇具成效,以至于到现在很多初学者还会为JavaScript和Java的关系而感到困惑。

Javascript取得成功了之后,确实为页面注入了活力,微软也紧接着开发自己的浏览器脚本语言,一个是基于BASIC语言的VBScript,另一个是跟Javascript非常类似的Jscript,但是由于Javascript已经深入人心,所以在随后的版本中,微软的IE几乎是将Javascript作为一个标准来实现。当然,两者仍然有不兼容的地方。1996年后期,网景向欧洲电脑厂商协会(ECMA)提交了Javascript的设计,以申请标准化,ECMA去掉了其中的一些实现,并提出了ECMAScript-262标准,并确定Javascript的正式名字为ECMAScript,但是JavaScript的名字已经深入人心,故本书中仍沿用Javascript这个名字。

1.1.1动态网页

WEB页面在刚开始的时候,是不能动态修改其内容的,要改变一个页面的内容,需要先对网站上的静态HTML文件进行修改,然后需要刷新浏览器。后来出现的JSP,ASP等服务器端语言可以为页面提供动态的内容,但是如果没有JavaScript则无法在服务器返回之后动态的在前端修改页面,也无法有诸如鼠标移上某页面元素则高亮该元素之类的效果,因此JavaScript的出现大大的丰富了页面的表现,提高了用户体验。

而当AJAX流行起来之后,更多的非常绚丽的WEB应用涌现了,而且呈越来越多的趋势,如Gmail,Google Map,Google Reader,Remember the milk,facebook等等优秀的WEB2.0应用,都大量的使用了JavaScript及其衍生的技术AJAX。

1.1.2浏览器之战
1.1.3标准
1.2 JavaScript语言特性

JavaScript是一门动态的,弱类型,基于原型的脚本语言。在JavaScript中“一切皆对象”,在这一方面,它比其他的OO语言来的更为彻底,即使作为代码本身载体的function,也是对象,数据与代码的界限在JavaScript中已经相当模糊。虽然它被广泛的应用在WEB客户端,但是其应用范围远远未局限于此。下面就这几个特点分别介绍:

1.2.1动态性

动态性是指,在一个Javascript对象中,要为一个属性赋值,我们不必事先创建一个字段,只需要在使用的时候做赋值操作即可,如下例:

 

//定义一个对象
var obj = new Object();
//动态创建属性name
obj.name = "an object";
//动态创建属性sayHi
obj.sayHi = function(){
return "Hi";
}
obj.sayHi();
 

 

加入我们使用Java语言,代码可能会是这样:

 

class Obj{
String name;
Function sayHi;
public Obj(Sting name, Function sayHi){
this.name = name;
this.sayHi = sayHi;
}
}
Obj obj = new Obj("an object", new Function());
 

 

动态性是非常有用的,这个我们在第三章会详细讲解。

1.2.2弱类型

与Java,C/C++不同,Javascript是弱类型的,它的数据类型无需在声明时指定,解释器会根据上下文对变量进行实例化,比如:

 

//定义一个变量s,并赋值为字符串
var s = "text";
print(s);
//赋值s为整型
s = 12+5;
print(s);
//赋值s为浮点型
s = 6.3;
print(s);
//赋值s为一个对象
s = new Object();
s.name = "object";
print(s.name);
 

 

结果为:

 

text
17
6.3
Object
 

 

可见,Javascript的变量更像是一个容器,类似与Java语言中的顶层对象Object,它可以是任何类型,解释器会根据上下文自动对其造型。

弱类型的好处在于,一个变量可以很大程度的进行复用,比如String类型的name字段,在被使用后,可以赋值为另一个Number型的对象,而无需重新创建一个新的变量。不过,弱类型也有其不利的一面,比如在开发面向对象的Javascript的时候,没有类型的判断将会是比较麻烦的问题,不过我们可以通过别的途径来解决此问题。

1.2.3解释与编译

通常来说,Javascript是一门解释型的语言,特别是在浏览器中的Javascript,所有的主流浏览器都将Javascript作为一个解释型的脚本来进行解析,然而,这并非定则,在Java版的Javascript解释器rhino中,脚本是可以被编译为Java字节码的。

解释型的语言有一定的好处,即可以随时修改代码,无需编译,刷新页面即可重新解释,可以实时看到程序的结果,但是由于每一次都需要解释,程序的开销较大;而编译型的语言则仅需要编译一次,每次都运行编译过的代码即可,但是又丧失了动态性。

我们将在第九章和第十章对两种方式进行更深入的讨论。

1.3 Javascript应用范围

当Javascript第一次出现的时候,是为了给页面带来更多的动态,使得用户可以与页面进行交互为目的的,虽然Javascript在WEB客户端取得了很大的成功,但是ECMA标准并没有局限其应用范围。事实上,现在的Javascript大多运行与客户端,但是仍有部分运行于服务器端,如Servlet,ASP等,当然,Javascript作为一个独立的语言,同样可以运行在其他的应用程序中,比如Java版的JavaScript引擎Rhino,C语言版的SpiderMonkey等,使用这些引擎,可以将JavaScript应用在任何应用之中。

1.3.1客户端Javascript

客户端的JavaScript随着AJAX技术的复兴,越来越凸显了Javascript的特点,也有越来越多的开发人员开始进行JavaScript的学习,使用Javascript,你可以使你的WEB页面更加生动,通过AJAX,无刷新的更新页面内容,可以大大的提高用户体验,随着大量的JavaScript包如jQuery, ExtJS,Mootools等的涌现,越来越多的绚丽,高体验的WEB应用被开发出来,这些都离不来幕后的JavaScript的支持。


图JavaScript实现的一个WEB幻灯片

 

浏览器中的JavaScript引擎也进行了长足的发展,比如FireFox 3,当时一个宣传的重点就是速度比IE要快,这个速度一方面体现在页面渲染上,另一方面则体现在JavaScript引擎上,而Google的Chrome的JavaScript引擎V8更是将速度发展到了极致。很难想象,如果没有JavaScript,如今的大量的网站和WEB应用会成为什么样子。

我们可以看几个例子,来说明客户端的JavaScript的应用程度:


图 ExtJS实现的一个网络相册,ExtJS是一个非常优秀的JavaScriipt库


图 ExtJS实现的一个表格,具有排序,编辑等功能

 

当然,客户端的JavaScript各有侧重,jQuery以功能见长,通过选择器,可以完成80%的页面开发工作,并且提供强大的插件机制,下图为jQuery的UI插件:


总之,随着Ajax的复兴,客户端的JavaScript得到了很大的发展,网络上流行着大量的优秀的JavaScript库,现在有一个感性的认识即可,我们在后边的章节会择其尤要者进行详细讲解。

1.3.2服务端Javascript

相对客户端而言,服务器端的JavaScript相对平淡很多,但是随着JavaScript被更多人重视,JavaScript在服务器端也开始迅速的发展起来,Helma, Apache Sling等等。在服务器端的JavaScript比客户端少了许多限制,如本地文件的访问,网络,数据库等。

一个比较有意思的服务端JavaScript的例子是Aptana的Jaxer,Jaxer是一个服务器端的Ajax框架,我们可以看这样一个例子(例子来源于jQuery的设计与实现这John Resig):

 

<html>
<head>
<script src="http://code.jquery.com/jquery.js" runat="both"></script>
<script>
jQuery(function($){
$("form").submit(function(){
save( $("textarea").val() );
return false;
});
});
</script>
<script runat="server">
function save( text ){
Jaxer.File.write("tmp.txt", text);
}
save.proxy = true;
function load(){
$("textarea").val(
Jaxer.File.exists("tmp.txt") ? Jaxer.File.read("tmp.txt") : "");
}
</script>
</head>
<body onserverload="load()">
<form action="" method="post">
<textarea></textarea>
<input type="submit"/>
</form>
</body>
</html>
 

runat属性说明脚本运行在客户端还是服务器端,client表示运行在客户端,server表示运行在服务器端,而both表示可以运行在客户端和服务器端,这个脚本可以访问文件,并将文件加载到一个textarea的DOM元素中,还可以将textarea的内容通过Form表单提交给服务器并保存。

再来看另一个例子,通过Jaxer对数据库进行访问:

 

<script runat="server">
var rs = Jaxer.DB.execute("SELECT * FROM table");
var field = rs.rows[0].field;
</script>
 

通过动态,灵活的语法,再加上对原生的资源(如数据库,文件,网络等)操作的支持,服务器端的JavaScript应用将会越来越广泛。

当Google的JavaScript引擎V8出现以后,有很多基于V8引擎的应用也出现了,其中最著名,最有前景的当算Node.js了,下面我们来看一下Node.js的例子:

var sys = require('sys'),
http = require('http');
http.createServer(function (req, res) {
setTimeout(function () {
res.sendHeader(200, {'Content-Type': 'text/plain'});
res.sendBody('Hello World');
res.finish();
}, 2000);
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000/');
 

 

 

 

 

保存这个脚本为sayHello.js,然后运行:

node sayHello.js

程序将会在控制台上打印:

Server running at http://127.0.0.1:8000/

访问http://127.0.0.1:8000,两秒钟之后页面会响应:Hello, World。

再来看另一个官方提供的例子:

var tcp = require('tcp');
var server = tcp.createServer(function (socket) {
socket.setEncoding("utf8");
socket.addListener("connect", function () {
socket.send("hello\r\n");
});
socket.addListener("receive", function (data) {
socket.send(data);
});
socket.addListener("eof", function () {
socket.send("goodbye\r\n");
socket.close();
});
});
server.listen(7000, "localhost");
 

 

 

 

 

访问localhost的7000端口,将建立一个TCP连接,编码方式为utf-8,当客户端连接到来时,程序在控制台上打印

hello

当接收到新的数据时,会将接收到的数据原样返回给客户端,如果客户端断开连接,则向控制台打印:

goodbay

Node提供了丰富的API来简化服务器端的网络编程,由于Node是基于一个JavaScript引擎的,因此天生的就具有动态性和可扩展性,因此在开发网络程序上,确实是一个不错的选择。

1.3.3其他应用中的Javascript

通过使用JavaScript的引擎的独立实现,比如Rhino,SpliderMonkey,V8等,可以将JavaScript应用到几乎所有的领域,比如应用程序的插件机制,高级的配置文件分析,用户可定制功能的应用,以及一些类似与浏览器场景的比如Mozilla的ThunderBrid,Mozilla的UI框架XUL,笔者开发的一个Todo管理器sTodo(在第十章详细讨论)等。


图 sTodo 一个使用JavaScript来提供插件机制的Java桌面应用

 

Java版的JavaScript引擎原生的可以通过使用Java对象,那样将会大大提高JavaScript的应用范围,如数据库操作,服务器内部数据处理等。当然,JavaScript这种动态语言,在UI方面的应用最为广泛。

著名的Adobe reader也支持JavaScript扩展,并提供JavaScript的API来访问PDF文档内容,可以通过JavaScript来定制Adobe Reader的界面以及功能等。

 

app.addMenuItem({
cName: "-",
// menu divider
cParent: "View",
// append to the View menu
cExec: "void(0);"
});
app.addMenuItem({
cName: "Bookmark This Page &5",
cParent: "View",
cExec: "AddBookmark();",
cEnable: "event.rc= (event.target != null);"
});
app.addMenuItem({
cName: "Go To Bookmark &6",
cParent: "View",
cExec: "ShowBookmarks();",
cEnable: "event.rc= (event.target != null);"
});
app.addMenuItem({
cName: "Remove a Bookmark",
cParent: "View",
cExec: "DropBookmark();",
cEnable: "event.rc= (event.target != null);"
});
app.addMenuItem({
cName: "Clear Bookmarks",
cParent: "View",
cExec: "ClearBookmarks();",
cEnable: "event.rc= true;"
});
 

为Adobe Reader 添加了4个菜单项,如图:


另一个比较有意思的JavaScript实例为一个在线的遗传算法的演示,给定一个图片,然后将一些多边形(各种颜色)拼成一个图片,拼图的规则为使用遗传算法,使得这些多变形组成的图片与目标图片最为相似:


可见,JavaScript在其他方面的也得到了广泛的应用。

 

附:由于作者本身水平有限,文中难免有纰漏错误等,或者语言本身有不妥当之处,欢迎及时指正,提出建议,参与讨论,谢谢大家!

 

  • 大小: 145.9 KB
  • 大小: 187.8 KB
  • 大小: 37.9 KB
  • 大小: 14 KB
  • 大小: 50.1 KB
  • 大小: 6.4 KB
  • 大小: 256.5 KB
   发表时间:2010-04-02  
举报一个通假字

在1.3.1

"现在有一个感性的‘人是’即可"
0 请登录后投票
   发表时间:2010-04-02  
congdepeng 写道
举报一个通假字

在1.3.1

"现在有一个感性的‘人是’即可"


呵呵,谢谢了,是错别字,我改下!
0 请登录后投票
   发表时间:2010-04-02  
这个系列值得期待.
在web版块好久没有这么好的帖子了.

楼主 能不能先列个目录或大纲  让大家了解一下你这个系列的一个概况
0 请登录后投票
   发表时间:2010-04-02   最后修改:2010-04-02
fins 写道
这个系列值得期待.
在web版块好久没有这么好的帖子了.

楼主 能不能先列个目录或大纲  让大家了解一下你这个系列的一个概况


谢谢支持,下面是目前的大纲计划:

第一章 概述
1.1 Javascript简史
1.1.1动态网页
1.1.2浏览器之战
1.1.3标准
1.2 JavaScript语言特性
1.2.1动态性
1.2.2弱类型
1.2.3解释与编译
1.3 Javascript应用范围
1.3.1客户端Javascript
1.3.2服务端Javascript
1.3.3其他应用中的Javascript

基础部分

第二章 基本概念
2.1数据类型
2.1.1 基本数据类型
2.1.2 对象类型
2.1.3 两者之间的转换
2.1.4类型的判断
2.2 变量
2.2.1基本类型和引用类型
2.2.2变量的作用域
2.3运算符
2.3.1中括号运算符([])
2.3.2点运算符(.)
2.3.3 == 和 === 以及 != 和 !==

第三章 对象与JSON
3.1 Javascript对象
3.1.1 对象的属性
3.1.2属性与变量
3.1.3原型对象
3.1.4 this指针
3.2使用对象
3.3 JSON及其使用

第四章 函数
4.1函数对象
4.1.1 创建函数
4.1.2 函数的参数
4.2函数作用域
4.3函数上下文
4.4 call和apply

第五章 数组
5.1数组的特性
5.2使用数组

第六章 正则表达式
6.1 元字符与规则
6.2 RegExp对象与String
6.3 实例:JSFilter

第七章 闭包
7.1闭包的特性
7.2闭包的用途
7.3应该注意的问题

第八章 面向对象的Javascript
8.1 原型继承
8.1.1引用
8.1.2 new操作符
8.2封装与继承
8.3 工具包Base
8.4实例:事件分发器

第九章 函数式的Javascript
9.1匿名函数
9.2高阶函数
9.3闭包与Currying
9.4一些例子

0 请登录后投票
   发表时间:2010-04-02  
写完可以出版了,我一定买,LZ让我想起自己最初用JS写ASP的时候了。
0 请登录后投票
   发表时间:2010-04-02  
不知道楼主大纲计划里的东西 跟内核系列有个什么样的联系?
0 请登录后投票
   发表时间:2010-04-02  
谢谢大家的关注!

说下这个系列的名字为什么叫《JavaScript内核》啊,内核并不是讲一个JavaScript引擎的设计与实现(有兴趣的朋友可以直接参考V8,Rhino等的实现,这里暂不考虑),这里的内核意思是对JavaScript核心概念的解释/讨论。

所谓的核心是指诸如作用域,上下文,对象(函数,数组),闭包等概念,尽量不涉及比如DOM之类外部对象,也就是JavaScript语言中难以理解,又与外部关联最少的部分。

如果这个名字实在容易引起误解,欢迎大家为其命名,集思广益。
0 请登录后投票
   发表时间:2010-04-02  
没看出来与别的JS书有什么区别
0 请登录后投票
   发表时间:2010-04-02  
抛出异常的爱 写道
没看出来与别的JS书有什么区别


我的目标是:没有DOM!至少在10章之内尽量不涉及DOM,那样反而不容易掌握JavaScript的精髓,呵呵。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics