1.1 JavaScript语言核心
本节是JavaScript语言的一个快速概览,也是本书第一部分的快速概览。在本章之后,我们将着重关注JavaScript的基础知识:第2章讲解JavaScript注释、分号和Unicode字符集;第3章会更加有意思,主要讲解JavaScript变量和赋值。这里有一些示例代码来说明这两章的重点内容:
//所有在双斜线之后的内容都属于注释
//仔细阅读这里的注释:它们对JavaScript代码做了解释
//变量是表示值的一个符号名字
//变量是通过var关键字声明的
var x;//声明一个变量x
//值可以通过等号赋值给变量
x=0;//现在变量x的值为0
x//=>0:通过变量获取其值
//JavaScript支持多种数据类型
x=1;//数字
x=0.01;//整数和实数共用一种数据类型
x="hello world";//由双引号内的文本构成的字符串
x='JavaScript';//单引号内的文本同样构成字符串
x=true;//布尔值
x=false;//另一个布尔值
x=null;//null是一个特殊的值,意思是"空"
x=undefined;//undefined和null非常类似
JavaScript中两个非常重要的数据类型是对象和数组。第6章介绍对象,第7章介绍数组,对象和数组在JavaScript中是如此之重要,以至于你在本书中处处都能看到它们的身影。
//JavaScript中的最重要的类型就是对象
//对象是名/值对的集合,或字符串到值映射的集合
var book={//对象是由花括号括起来的
topic:"JavaScript",//属性"topic"的值是"JavaScript"
fat:true//属性"fat"的值是true
};//右花括号标记了对象的结束
//通过"."或"[]"来访问对象属性
book.topic//=>"JavaScript"
book["fat"]//=>true:另外一种获取属性的方式
book.author="Flanagan";//通过赋值创建一个新属性
book.contents={};//{}是一个空对象,它没有属性
//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 points=[//具有两个元素的数组
{x:0,y:0},//每个元素都是一个对象
{x:1,y:1}
];
var data={//一个包含两个属性的对象
trial1:[[1,2],[3,4]],//每一个属性都是数组
trial2:[[2,3],[4,5]]//数组的元素也是数组
};
上段代码中通过方括号定义数组元素和通过花括号定义对象属性名和属性值之间的映射关系的语法称为初始化表达式(initializer expression),第4章有专门的介绍。表达式是JavaScript中的一个短语,这个短语可以通过运算得出一个值。通过“.”和“[]”来引用对象属性或数组元素的值就构成一个表达式。比如,请看一下上述代码中独占一行的表达式,其后的注释中箭头(=>)后的值就是表达式的运算结果。这种写法是本书中的一种约定表述方式。
JavaScript中最常见的表达式写法是像下面代码这样使用运算符(operator):
//运算符作用于操作数,生成一个新的值
//最常见的是算术运算符
3+2//=>5:加法
3-2//=>1:减法
3*2//=>6:乘法
3/2//=>1.5:除法
points[1].x-points[0].x//=>1:更复杂的操作数也能照常工作
"3"+"2"//=>"32":+可以完成加法运算也可以作字符串连接
//JavaScript定义了一些算术运算符的简写形式
var count=0;//定义一个变量
count++;//自增1
count—;//自减1
count+=2;//自增2:和"count=count+2;"写法一样
count=3;//自乘3:和"count=count3;"写法一样
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)//=>true:false和false相等
//逻辑运算符是对布尔值的合并或求反
(x==2)&&(y==3)//=>true:两个比较都是true,&&表示"与"
(x>3)||(y<3)//=>false:两个比较不都是true,||表示"或"
!(x==y)//=>true:!求反
如果JavaScript中的“短语”是表达式的话,那么整个句子就称做语句(statement),第5章会详细讲解。在上述代码中,以分号结束的行均是一条语句(下面的代码中,会看到省略分号的多行语句)。实际上,语句和表达式之间有很多共同之处,粗略地讲,表达式仅仅计算出一个值但并不作任何操作,它并不改变程序的运行状态。而语句并不包含一个值(或者说它包含的值我们并不关心),但它们改变程序的运行状态。在上文中已经见过变量声明语句和赋值语句。另一类语句是“控制结构”(control structure),比如条件判断和循环。在介绍完函数之后,我们给出相关的示例代码。
函数是带有名称(named)[2]和参数的JavaScript代码段,可以一次定义多次调用。第8章会正式详细地讲解函数。与对象和数组一样,在本书的很多地方都会提到函数。这里是一些简单的示例代码:
//函数是一段带有参数的JavaScript代码端,可以多次调用
function plus1(x){//定义了名为plus1的一个函数,带有参数x
return x+1;//返回一个比传入的参数大的值
}
//函数的代码块是由花括号包裹起来的部分
plus1(y)//=>4:y为3,调用函数的结果为3+1
var square=function(x){//函数是一种值,可以赋值给变量
return x*x;//计算函数的值
};//分号标识了赋值语句的结束
square(plus1(y))//=>16:在一个表达式中调用两个函数
当将函数和对象合写在一起时,函数就变成了“方法”(method):
//当函数赋值给对象的属性,我们称为
//"方法",所有的JavaScript对象都含有方法
var a=[];//创建一个空数组
a.push(1,2,3);//push()方法向数组中添加元素
a.reverse();//另一个方法:将数组元素的次序反转
//我们也可以定义自己的方法,"this"关键字是对定义方法
//的对象的引用:这里的例子是上文中提到的包含两个点位置信息的数组
points.dist=function(){//定义一个方法用来计算两点之间的距离
var p1=this[0];//通过this获得对当前数组的引用
var p2=this[1];//并取得调用的数组前两个元素
var a=p2.x-p1.x;//X坐标轴上的距离
var b=p2.y-p1.y;//Y坐标轴上的距离
return Math.sqrt(a*a+//勾股定理
我们称为b*b);//用Math.sqrt()来计算平方根
};
points.dist()//=>1.414:求得两个点之间的距离
现在,给出一些控制语句的例子,这里的示例函数体内包含了最常见的JavaScript控制语句:
//这些JavaScript语句使用该语法包含条件判断和循环
//使用了类似C、C++、Java和其他语言的语法
function abs(x){//求绝对值的函数
if(x>=0){//if语句…
return x;//如果比较结果为true则执行这里的代码.
}
//子句的结束.
else{//当if条件不满足时执行else子句
return-x;
}
//如果分支中只有一条语句,花括号是可以省略的
}
//注意if/else中嵌套的return语句
function factorial(n){//计算阶乘的函数
var product=1;//给product赋值为1
while(n>1){//当()内的表达式为true时循环执行{}内的代码
product=n;//"product=productn;"的简写形式
n—;//"n=n-1;"的简写形式
}
//循环结束
return product;//返回product
}
factorial(4)//=>24:143*2
function factorial2(n){//实现循环的另一种写法
var i,product=1;//给product赋值为1
for(i=2;i<=n;i++)//将i从2自增至n
product*=i;//循环体,当循环体中只有一句代码,可以省略{}
return product;//返回计算好的阶乘
}
factorial2(5)//=>120:12345
JavaScript是一种面向对象的编程语言,但和传统的面向对象又有很大区别。第9章将详细讲解JavaScript中的面向对象编程,这一章有大量的示例代码,是本书中最长的一章。这里有一个简单的示例,这段代码展示了如何在JavaScript中定义一个类来表示2D平面几何中的点。这个类实例化的对象拥有一个名为r()的方法,用来计算该点到原点的距离:
//定义一个构造函数以初始化一个新的Point对象
function Point(x,y){//按照惯例,构造函数均以大写字母开始
this.x=x;//关键字this指代初始化的实例
this.y=y;//将函数参数存储为对象的属性
}
//不需要return
//使用new关键字和构造函数来创建一个实例
var p=new Point(1,1);//平面几何中的点(1,1)
//通过给构造函数的prototye对象赋值
//来给Point对象定义方法
Point.prototype.r=function(){
2
return Math.sqrt(//返回x
+y2的平方根
this.x*this.x+//this指代调用这个方法的对象
this.y*this.y);
};//Point的实例对象p(以及所有的Point实例对象)继承了方法r()
p.r()//=>1.414…
第9章是第一部分的精华所在,后续的各章做了一些零星的延伸,将我们对JavaScript语言核心的探索带向尾声。第10章主要讲解了正则表达式的语法,并演示了如何使用这些“正则表达式”进行文本的模式匹配。第11章介绍JavaScript语言核心的子集和超集。最后,在进入客户端JavaScript的内容之前,第12章介绍两种在Web浏览器之外的两种JavaScirpt运行环境。
[1]F12用来唤醒/关闭Firebug操作面板,Ctrl+Shift+J用来唤醒错误控制台(Error Console)。
[2]这里“名称”含义是指函数具有固定标识,并不是指函数变量名称。