JavaScript Dom编程艺术(第二版)读书笔记 第二章:JavaScript语法

118 阅读20分钟

第二章:JavaScript语法

2.1准备工作

用javaScript编写的代码必须通过HTML/XHTML文档才能执行。有两种发过誓可以做到这点。

第一种方式是将JavaScript代码放到文档标签中的

<Doctype html>
<html lang = "en">
<head>
    <meta charset="utf-8">
    <title>Example</title>
    <script>
    JavaScript goes here...
    </Script>
</head>
<body>
Mark-up goes here...
</body>
</html>

一种更好的方式是把JavaScipt代码作为一个扩展名为.js的独立文件。典型的作法是在问答ing的部分放到一个

<Doctype html>
<html lang = "en">
<head>
    <meta charset="utf-8">
    <title>Example</title>
    <script>
    JavaScript goes here...
    </Script>
</head>
<body>
Mark-up goes here...
</body>
</html>

但最好的做法是把标签之前:

<Doctype html>
<html lang = "en">
<head>
    <meta charset="utf-8">
    <title>Example</title>
</head>
<body>
    Mark-up goes here...
    <script>
    JavaScript goes here...
    </Script>
</body>
</html>

这样能使浏览器更快地加载页面。

2.2语法

如同书面的人类语言,每种程序设计语言也都有自己的语法。JavaScript与Java和C++语言的语法非常相似。

2.2.1语句

用JavaScript编写的脚本,与其他语言编写的脚本一样,都由一系列指令构成,这些存储指令叫做语句。只有按照正确的语法编写出来的语句才能得到正确的解释。

如下所示:

first statement
​
second statement

如果你想把多条语句放在同一行上,就必须像下面这样用分号哎隔开它们:

first statement;second statement

我们建议在每条语句的末尾都加上一个分号,这是一种良好的编程习惯:

first statement;
​
second statement;

2.2.2注释

不是所有的语句都需要JavaScript解释器去解释并执行。有时你需要在脚本中写一些进攻自己参考或提醒自己的信息,你希望JavaScript解释器能直接忽略掉这些信息。这些语句就是注释。

2.2.3变量

在日常生活中,有些东西是固定不变的,有些则会发生变化。

把值存入变量的操作称为赋值。

在JavaScript脚本中,如果程序员在冬季某个变量赋值之前未声明,赋值操作将自动声明该变量。四u然JavaScript没有强制要求程序员必须声明变量,但提前声明变量是一种良好的编程习惯。下面的语句对变量mood和age做出了声明:

var mood;
var age;

不必单独声明每个变量,你也可以用一条语句声明多个变量:

var mood,age;

你甚至可以一石二鸟:把声明变量和对该变量赋值一次完成:

var mood = "happy";
var age = 33;

甚至可以像下面这样:

var mood = "happy",age = 33;

像上面这样声明和赋值时最有效率的做法,这一条语句的效果相当于下面这些语句的总和:

var mood,age;
mood = "happy";
age = 33;

在JavaScript语言里,变量和爱他语法元素的名字都是区分字母大小写的。

JavaScript语法不允许变量名中包含空格或标签符号(美元符号"$"例外)。

JavaScript语法中允许包含字母、数字、美元符号和下划线(但第一个字符不允许是数字)。

通常驼峰格式是函数名、方法名和对象属性名命名的首选格式。

2.2.4数据类型

1.字符串

字符串由零个或多个字符构成。字符包括(但不限于)字母、数字、标点符号和空格。字符串必须在引号里,单引号或双引号都可以。下面这两条语句含义完全相同:

var mood = 'happy';
var mood = "happy";

你可以随意选用引号,但最好是根据字符串所包含的字符来选择。

var mood = "don`t ask";
2.数值

如果想给一个变量赋一个数值,不用限定它必须是一个证书。JavaScript允许使用带小数点的数值,并且允许任意位小数,这样的数成为浮点数;

var age = 33.25

也可以使用负数。在有关数值的前面再加上一个减号(-)表示它是一个负数;

var temperature = -20

JavaScript也支持负数浮点数:

var temperature = -20.3333333

以上就是数值数据类型的例子。

3.布尔值

另一种重要的数据类型是布尔类型。

布尔数据只有两个可选值——ture或false。

从某种那个意义上讲,为计算机设计程序就是与布尔值打交道。作为最基本的事实,所有的电子电路都只是识别和使用布尔数据。布尔值不是字符串,千万不要把布尔值用引号括起来。布尔值false与字符串false是两码事。

下面这条语句将把变量Married设置为布尔值ture;

var married = ture;

下面这条语句将把变量Married设置为布尔值ture;

var married = "ture"; 

2.2.5数组

字符串、数值和布尔值都是标量。如果某个变量是标量,它在任意时刻就只能有一个值。如果想用一个变量来存储一组值。就需要使用数组。

素组是指用一个变量来表示一个值的集合,集合中的每个值都是这个数组的一个元素。例如:我们可以用名为beatles的变量来保存,beatles乐队全体四位成员的姓名。

在JavaScript中,数组可以用关键字Array声明。声明数组的同时还可以来指定数组初始元素的个数,也就是这个数组的长度。

var beates = Array(4);

有时,我们无法预知某个数组有多少个元素。没有关系,JavaScrpt,根本不要求在声明数组时,必须给元素个数,我们完全建议在声明数组时不给出元素个数。

var beatles = Array();

向数组中添加元素的操作成为填充,。在填充数组时,不仅需要给出新元素的值,还需要给出新元素在数组中的存放位置,这个位置就是这个元素的下标。数组里一个元素配有一个下标。下标必须用方括号括起来:

array[index] = element;

JavaScript世界里的一条规则:用0而不是1作为第一个下标。

beatles[0] = "john";

下面是声明和填充beatles数组的全过程:

var beatles = Aarray(4);
beatles[0] = "john";
beatles[1] = "paul";
beatles[2] = "George";
beatles[3] = "Ringo";

可以通过下标值"2"(beatles[2])来获取"George"了。因beatles数组的长度是4,所以最后一个元素的下标是3。

如下是一种简单的方式:在声明数组的同时对它进行填充。这种方式需要逗号将各个元素隔开:

var beatles = Array("john","paul","George","Ringo");

上面这条语句会为每个元素自动分配一个下标:第一个下标是0,第二个是1,以此类推。因此,beatles[2]仍将对应"George"的元素。

我们甚至用不着明确地表明我们是在创建数组。事实上,只需用一对括号把各个元素的初始组括起来就可以了:

var beatles = ["john","paul","George","Ringo"];

数组元素不必非得是字符串。可以把一些布尔值存入一个数组,还可以一组数值存入一个数组:

var years = [1940,1941,1942,1943];

甚至可以把这三种数据类型混在一起存入一个数组:

var lemon = ["John",1940,false];

数组元素还可以是变量:

var name = "John";
beatles=[0] = name;

这将把beatles数组的第一个元素赋值为"John"。

数组元素的值还可以是另一个数组的元素。下面两条语句将把beatles数组的第二个元素赋值为"Paul":

var names=["Ringo","john","George","paul"];
beatles[1] = names[3];

事实上,数组还可以包含其他的数组!数组中的任何一个元素都可以把一个数组作为它的值:

var lemon = ["John",1940,false];
var beatles = [];
beatles[0] = lemon;

现在,beatles数组的第一个元素的值是另外一个数组。要想获得那个数组里的某个元素的值,需要使用更多的方括号。beatles[0] [0]的值是"John",beatles[0] [1]的值是1940,beatles[0] [2]的值是false。

这是一种相当强大的存储和获取信息的方式。还有集中办法可以填充数组,首先看看一种更可读的填充数组的方式,然后介绍存放数据的首选方式:将数据保存为对象。

  • 关联数组

可以通过填充数组时为每个新元素明确地给出下标来改变这种默认的行为。在为新元素给出下标时,不必局限于使用整数数字。可以用字符串:

var lenmon = Array();

lenmon["name"] = "John";

lenmon["year"] = 1940;

lenmon["living"] = false;

这样的数组叫做关联数组。可以使用字符串来代替数字值,因而代码更具有有可读性。在这个例子中,实际上是给lenmon数组添加了Name、year和Living三个属性。理想情况下,不应该修改Array对象的属性,而应该使用通用的对象(object)。

2.2.6对象

与数组类似,对象也是一个名字表示一组值。对象的每个值都是对象的一个属性。例如:前一节的lemon数组也可以创建成下面这个对象:

var lemon = object();
lemon.name = "John";
lemon.year = "1940";
lomon.living = "false";

创建对象还有一种更简洁的语法,即花括号语法:

{propertyName:value,propertyName:value}

比如,lemon对象也可以写成下面这样:

var lemon = {name:"John",year:1940,living:false};

2.3操作

此前给出的示例都非常简单,只是创建了一些不同类型的变量而已。要用JavaScript做一些有用的工作,还需要能够进行计算和处理数据。也就是需要完成一些操作。

  • 算术操作符

  • 加法是一种操作,减法、除法和乘法也是。分别是+、-、/、*、等。

    此处例子没有过多的举例,因为过于简单了。

    //此处没有做出举例,过于简单了。

2.4条件语句

最常见的语句是If语句。下面是if语句的基本用法:

if(condition){
statements;
}

条件必须放在If后面的圆括号中。条件的求职结果永远是一个布尔值即只能是ture或false。花括号中的语句——不管它们有都多少条,只有在给定条件的求职结果是ture的情况下才会执行。因此,在这个例子中,alert消息永远也不会出现:

if(1>2){
    alert("The world has gone mad!");
}

因为1不可能大于2,所以上面的这个条件的值永远是false。

是世行,if语句中的花括号本身并不是必不可少的。如果if语句中的花括号部分只包含着一条语句的话,那就可以不适用花括号,而且这条if语句的全部内容可以卸载同一行上:

if(1>2)alert("The world has gone mad!");

if语句可以有一个else子句。else子句中的语句会在给定条件为假时执行:

if(1>2){
    alert("the world has gone mad");
}else{
    alert("All is well with world");
}

因为给定条件"1>2"的值为false,所以我们可以得到All is well with the world;

2.4.1比较操作符

JavaScript还提供了许多几乎只能在条件语句里的操作符,其中包括诸如大于(>),小于(<),大于或等于(>=),等比较操作符。

下面是一个比较错误的例子:

var my_mood = "happy";
var your_mood = "sad";
if(my_mood = your_mood){
    alert("we both feel the same");
}

上面这条语句的错误指出在与,它是把变量your——mood赋值给变量my_mood,而不是在比较是否相当。下面时正确的做法:

var my_mood = "happy";
var your_mood = "sad";
if(my_mood == your_mood){
    alert("we both feel the same");
}

这次条件语句的结果时false。

JavaScript提供了不等于的比较操作符。(!=)。

if(my_mood!= your_mood){
    alert("we’re feeling different moods.")
}

相等操作符===并不表示严格相等,例如:

var a = false;
var b = "";
if(a == b){
    alert ("a equals b");
}

这个条件语句的求值结果时ture,因为相等操作符==认为空字符串与false的含义相同。要进行严格的比较,就要使用另外一种等号(===)。这个全等操作符会执行严格的比较,不仅比较直,而且会比较变量的类型:

var a = false;
var b = "";
if(a === b){
    alert("a equals b");
}

这一次,条件表达式的求职结果就是false了。因为即使可以认为false 与空字符串具有相同的含义,但Boolean和String可不是一种类型。

当然,对于不等操作符!=也是如此。如果像比较严格不相等,就要使用!==、

2.4.2逻辑操作符

JavaScript允许把条件语句里的操作组合在一起。例如,如果像检查某个变量,不妨假设这个变量的名字是num,它的值是不是在5~10之间,我将需要进行两次比较操作。首先,比较这个变量是否大于或等于5;然后比较这个容量是否小于或等于10。这两次你叫操作称为逻辑比较。下面是把两个逻辑比较组合在一起的具体做法:

if(num >= 5 && num <= 10){
    alert("The number is in the right range.");
}

这里使用了"逻辑与"操作符,它由两个"&",字符构成(&&),是一个逻辑操作符。

逻辑操作符的操作对象是布尔值。每个逻辑操作数返回一个布尔值true或者是false。"逻辑与"操作只有在它的两个操作数都是true时才会使true。

"逻辑或"操作符由两个垂直字符构成(||),只要它的操作数中有一个是true,"逻辑或"操作就将是true。如果它的两个操作数都是true,"逻辑或"操作也将是true。只有它们两个都是false时,"逻辑或"操作才会使false。

if( num > 10 || num < 5 ){
    alert("The number is not in the right range.");
}

"逻辑非"是由一个感叹号(!)单独构成。含义与上述基本相同。主要意义是取反。

if(!(1>2)){
    alert("All is well with the world");
}

可以用"逻辑非"操作符将整个条件语句的结果颠覆过来,在下面的例子中:使用了一堆括号来确保"逻辑非"操作符将作用于两个逻辑操作数的组合结果:

if (!(num > 10 || num < 5)){
    alert("The number is in the right range.");
}

2.5循环语句

2.5.1while循环

while循环与if语句非常相似,它们的语法几乎完全一样:

while(condition){
​
    sattements;
}

while循环与If语句唯一的区别是:只要给定条件的求值结果是true,包含在花括号里的代码就将反复地执行下去。下面是一个while循环的例子:

var count = 1;
while (count < 11){
    alert(count);
    count++
}

我们来仔细分析一下上面的这段代码。首先,创建数值变量count并赋值为1;然后,以count<11——意思是"只要变量count的值小于11,就重复执行这个循环"——为条件创建一个while循环。在while循环的内部,用"++"操作符对变量count的值执行加1操作。而这一操作将重复执行10此。如果用web浏览器来观察这段代码的执行情况,将会看到一个alert对话框闪烁10次。这条循环语句执行完毕后,变量count的值将是11。

  • do...while循环

类似于if语句的情况,while循环的花括号部分所包含的语句有可能不被执行,因为对循环控制条件的求值发生在每次循环之前。所以如果循环控制条件的首次结果是false,那些代码将一次也不会被执行。

在某些场合,我们希望那些包含在循环语句内部的代码至少执行一次。这是,do循环是我们的最佳选择。下面是do循环的语法:

do{
statements;
}while(condition);

这与刚才介绍的while循环非常相似,但是有个显而易见的区别:对循环控制条件的求值发生在每次循环结束之后,因此,即使循环控制条件的首次求值结果是false,包含在花括号里的语句也至少被执行一次。

我们可以把迁移小姐里的while循环改写成如下所示的do...while:

var count = 1;
do{
    alert(count);
    count++;
}while(count < 11);

这段代码的执行结果与while循环完全一样:alert消息将闪现10此;在玄幻结束后,变量count的值将是11.

再来看看下面这个变体:

var count = 1;
do {
    alert(count);
    count++;
}while (count < 1 );

在上面这个do循环里,循环控制条件的结果永远部位true:变量count的初始值是1,所以它在这里永远不会小于1.可是,因为do循环的循环控制条件出现在花括号部分之和,所以包含在这个do循环内部的代码还是执行了一次,也就是说,仍将看到一条alert消息。这些语句执行完毕后,变量count的值将是2,尽管循环控制条件的求值结果是false。

2.5.2 for循环

用for循环来重复执行一些代码也很方便,它类似于while循环。事实上for循环只是刚才介绍while循环的一种变体。如下所示:

initialize;
while(condition){
    statements;
    increment;
}

而for循环不过是进一步改写为如下所示的紧凑形式而已:

for(initial condition;test condition;alert condtion){
    statements;
}

用for循环来重复执行一些代码的好处是循环控制结构更加清晰、与循环有关的所有内容包含在for语句的圆括号部分。

可以把上一小节的例子改写为如下所示的for循环中:

for (var count =1;count<11;count++){
    alert(count)
}

for循环最常见的用途之一是对某个数组里的全体元素进行遍历处理。这往往需要用到array.length属性。这个属性告诉我们数字下标是从0而不是从1开始。下面的例子中,数组有4个元素。count变量对于数组中每个元素都是从0开始按1递增。数到4时,测试条件失败,循环终止,3是从数组中检索到的最后一个下标。

var beatles=Array("john","paul","George","Ringo");
for(var count =0;count<beatles,length;count++){
    alert(beatles[count]);
}
​

运行这段代码后,将会看到4条alert消息,它们分别对应这Beatles阅读的四位成员。

2.6 函数

如果需要多次使用同一段代码,可以把它们封装成一个函数。函数就是一组允许在你的代码里随时调用的语句。每个函数实际上就是一个短小的脚本。

  • 应该先对寒素定义后再调用它们。

下面是一个简单的实例函数:

function shoot(){
    var beatles = Array("John","Paul","George","Ringo");
    for (var count = 0; count < beatles.length;count++){
        alert(beatles[count]);
    }
}

这个函数里面的循环语句将一次弹出对话框来显示Beatles乐队的名字。现在如果你想在自己的脚本里执行这一动作,可以随时使用如下的语句来调用这个函数:

shout();

我们把可以传递给函数的数据称为参数。

定义一个函数的语法:

function name (arguments){
    statements;
}

JavaScript提供了许多内建函数,在前面多次出现过的alert就是一例。这个函数需要我们提供一个参数,它将弹出一个对话框来显示这个参数的值。

在定义函数时,你可以为它声明任意多个参数,只要用逗号把它们都分个开来就行,在函数的内部,你可以像是使用普通变量那样使用它的任何一个参数。

下面是一个需要传递两个参数的函数。如果把两个数值传递给这个函数,这个函数将对它们进行乘法运算:

function multiply(num1,num2){
    var total = num1*num2;
    alert(total);
}

在定义了这个函数的脚本里,我们可以从任意位置去调用这个函数,如下所示: multiply(10,2); 把数值10和2传递给multiply()函数的结果为20。

我们完全可以创建一个函数并让它返回一个数值,一个字符串一个数组或一个布尔值。这需要用到returan语句:

function multiply(num1,num2){
    var total = num1,num2;
    return total;
}

下面这个函数只有一个参数(一个华氏温度值),它将返回一个数值(同意温度的摄氏温度值):

function convertToCelsius(temp){
    var result = temp - 32;
    result = result / 1.8;
    return result;
}

函数的真正价值体现在,我们还可以将它们当作一种数据类型来使用,这意味着可以把一个函数的调用结果赋给一个变量:

var temp_fahrenheit = 95;
var temp_celsius = convertTocelsius(temp_fahrenheit);
alert(temp_celsius);

把华氏温度值95转换为摄制温度之值的结果为35; 在这个例子里,变量temp_celsius的值是35,这个数值由convertTocelsius函数返回;变量的作用域:

  • 全局变量:可以在将本中的任何位置被引用。一旦你在某个脚本里声明了一个全局变量,就可以从这个脚本中的任何位置——包括函数内部——引用它。全局变量的作用域是整个脚本。

  • 局部变量:只存在于声明它的那个函数的内部在那个函数的外部是无法引用它的,局部的作用域仅限于某个特定的函数。

    我们来看这个例子:

function square(num){
    total = num * num ;
    return total ;
}
var total = 50;
var number = square(20);
alert(total);

这些代码不可避免地将导致全局变量total的值发生变化。 全局变量total的值是400,本意是让square()函数只把它计算出来的平方值返回给变量number,但因为未把这个函数内部的total变量明确地声明为局部变量,这个函数把名字同样是total的那个全局变量的值也改变了。 把这个函数写成如下所示的样子才是正确:

function square(num){
    var total = num * num;
    return total;
}

现在,全局变量total变得安全了,再怎么调用square()函数也不会影响到它。

2.7对象

对象(object)是一种非常重要的数据类型,但此前我们还没有认真对待它。对象是自包含的数据集合,包含在对象里的数据可以通过两种形式访问——属性和方法: 属性是隶属于某个特定的那个对象的变量; 方法是只有某个特定对象才能调用的函数。 为给定对象创建一个新实例需要使用new关键字,如下所示: var jeremy = new person; 上面这条语句将创建出Person对象的一个新实例jeremy。我们就可以像下面这样利用Person对象的属性来检索关于jeremy信息了;

jeremy.age;
jeremy.mood;

2.7,1 内建对象

数组就是其中的一种,当我们使用new关键字去初始化一个数组时,其实是在创建一个Array的新实例了; var beatles = new Array(); 当你需要了解某个数组有多少个元素时,利用Array对象的length属性来获得这一信息:

beatles.length

Array对象只是诸多JavaScript内建对象中的一种。其他例子包括Math对象和Date对象,它们分别提供了许多非常有用的方法供人们处理数值和日期值。例如,Math对象的round方法可以把十进制数值舍入为一个最接近的整数:

var num = 7.561;
​
var num = Math.round(num);
​
alert(num);

Date对象可以用来存储和检索与特定日期和时间有关的信息。在创建Date对象的新实例时,JavaScript解释器将自动地使用当前日期和时间对它进行初始化:

var current——date = new Date();

Date对象提供了getDay(),getHours(),getMounth()等一系列的方法,以供人们用来检索与忒的那个日期有关的各种信息。例如,getDay()方法可以告诉我嗯给定日期是星期几:

var today = current_date.geDay();

2.7.2 宿主对象

除了内建对象,还可以在JavaScript脚本里使用一些预先定义好的其他对象。这些对象不是由JavaScript语言本身二十由它的运行环境提供的。具体到Web应用,这个环境就是浏览器。由浏览器提供的预定义对象被称为宿主对象。

宿主对象包括From,image和Element等。我们可以通过这些对象关于网页上的表单,图像和各种表单元素等信息。

2.8小结

在本章中,介绍了JavaScript语言的基础知识。子啊后续章节中,我们会用到这里介绍的很多术语:语句、变量、数组和函数等。