购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 句法基础

句法定义了JavaScript的逻辑结构,包括词、句和段的基本规则和特性。本节将介绍JavaScript语言的句法基础,了解JavaScript的代码结构。

3.2.1 认识词、句和段

JavaScript语法体系体现了一种词、句、段的层次结构,简单说明如下。

☑ 词:表示表达式。

☑ 句:表示语句,一行执行特定任务的命令。

☑ 段:包含多行命令的逻辑结构。

1.段

在JavaScript程序中,常用大括号来划分段落结构,大括号拥有封装代码和逻辑的功能,由此形成一个独立的段落结构。

【示例1】 下面这些结构都可以形成独立的段落。

段落结构包含的内容可以是一个或多个句子。段落起始标记({)前面可以添加修饰词,如域谓词(with)、逻辑谓词(if、while、for、switch等)、函数谓词(function fn(arg))等。

2.句

句子就是由词构成的完整的可执行命令。在JavaScript中,常用分号(;)来划分句子,有时也可以省略分号,此时会使用换行符表示完整的句子。

☑ 一个句子可以包含一个或多个词

【示例2】 在下面两个句子中,第一个句子只有一个词,这是一个指令词,该指令只能够位于循环体内或switch结构体内。第二个句子包含3个分词,alert函数名,小括号表示运算符,而“"提示信息"”表示字符串直接量。

☑ 一个句子也可以包含一个或多个段落

【示例3】 在下面的句子中,直接调用一个匿名函数。

【示例4】 可以把函数包含在另一个函数中形成嵌套结构,这个嵌套结构体就构成了一个复杂的句子。

句子也可以什么都不包含,仅由一个分号进行标识,这样的句子称之为空句子,空句子常用作占位符。

【示例5】 在下面这个循环体内就包含了一个空句子。

3.词

词是JavaScript句法中最小语义单位,包括指令、变量、直接量、运算符、表达式等。在JavaScript中,词语之间必须使用分隔符进行分隔,否则JavaScript就会错误解析。

【示例6】 下面代码块是一个简单的求两个数的平均值方法。

其中var、function、return是指令,这些指令也是JavaScript默认的关键字。a、b、c、d、aver、alert为变量,34、56是数值直接量,=、(、)、{、}、/、+、,是运算符。

3.2.2 分号

分号是JavaScript语句分隔符,用来分隔不同的语句。

【示例1】 下面的代码虽在同一行内显示,但通过分号被分为3个语句。

     var a=1; var b=2; var c=3;

由于JavaScript默认独立一行的代码为一个语句,所以可以省略分号,但是如果把多句代码写在一行内显示,则必须增加分号。

【示例2】 对于上面代码可以按如下方式进行书写:

     var a=1;
     var b=2;
     var c=3;

或者:

     var a=1
     var b=2
     var c=3

考虑到JavaScript程序可能会被压缩为一行显示,为了避免错误,建议大家养成好的习惯,不管一行内语句是否完整,只要是完整的语句都必须增加分号以表示句子的结束。

注意: 在程序结尾或大括号}之前的分号也可以省略。

在长句中可以分行显示,以方便阅读。在分行时应确保一行内不能形成完整的逻辑语义,避免JavaScript解析器自动增加分号。

【示例3】 下面的代码是一个连续赋值的语句,通过分行显示可以更清楚地查看它们的关系。这种分行显示,由于一行内不能形成独立的逻辑语义,所以JavaScript解析器不会把每一行视为独立的句子,从而不会产生歧义。

如果在一行内显示则如下所示:

     var a=b=c=4;  //单行显示的一个句子

【示例4】 下面这个语句定义一个变量i,然后为其赋值,如果变量a为true,则赋值为1,否则就判断变量b,如果为true,则赋值为2,否则就判断变量c,如果为true,则赋值为3,否则赋值为4。

     var i=a ? 1 : b ? 2 : c ? 3 : 4;

下面的分行显示就是错误的,因为表达式a ? 1: b能够形成独立的逻辑语义,所以JavaScript解析器会自动在其后添加分号来表示一个独立的句子。

安全的方法应该按如下所示分行显示。这样每一行都不能形成独立的语义。

提示: JavaScript并不是在所有换行处都自动填补分号,只有在缺少了分号就无法正确解析代码时,JavaScript才会填补分号。因此,如果当前语句和随后的非空格字符不能当成一个整体来解析,JavaScript就在当前语句行结束处填补分号。

例如,如果第一行语句以(、[、/、+或-结束,那么它极有可能和第二行语句合在一起解析。类似的还有return、break和continue语句。

也有例外:在涉及++和--运算符时,这些运算符可以作为表达式的前级,也可以当作表达式的后缀。如果将其用作后缀表达式,它和表达式应当在同一行。否则,行尾将自动填补分号,同时++和--将会作为下一行代码的前级操作符并与之一起解析。例如:

     x
     ++
     y

将被解析为x;++y;,而不是x++;y;。

3.2.3 大括号

大括号是语句的分段标识,它也可以构建数据结构(在对象章节将详细讲解)。

【示例1】 下面的代码使用大括号定义一个对象直接量,其中包含多个“名/值”对,名称与值之间通过冒号分隔,每个“名/值”对之间通过逗号分隔。

【示例2】 下面代码定义一个函数,在函数中嵌套了一个switch条件结构。

JavaScript不支持使用大括号定义块状作用域,不过支持函数作用域,不允许外界直接访问函数内变量。在循环结构和条件结构中,大括号允许循环语句和条件语句包含更多的执行语句。 7Dyu99khlgYR0bcF1UWJ9HCTAwuwM7nt2p9uAYmAN5NXpfeyRkDL6cS6ZJ4yxRE8



第4章

数据、类型和变量

视频讲解:109分钟)

一般在运行程序时,都需要对值进行操作,这些值的类型被称为数据类型,数据类型是编程语言最基本的特性。当需要将值保存起来以备将来使用时,可以将其赋值给一个变量。变量是一个值的符号名称,程序可以通过这个符号名称获得值的具体内容,变量也是编程语言的一个基本特性。本章将详细讲解JavaScript数据类型、值和变量的基本概念、基本规则和使用技巧。

【学习重点】

▲ 了解数据和类型的关系

▲ 理解JavaScript值类型数据

▲ 理解引用类型数据

▲ 能够正确检测数据类型

▲ 能够灵活转换数据类型

▲ 正确使用变量 7Dyu99khlgYR0bcF1UWJ9HCTAwuwM7nt2p9uAYmAN5NXpfeyRkDL6cS6ZJ4yxRE8



4.1 JavaScript数据类型概述

ECMAScript中有5种简单的数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String,还有一种复杂的数据类型:Object。由于ECMAScript数据类型具有动态性,所以不支持任何创建自定义类型的机制,而所有值最终都将是上述6种数据类型之一。

4.1.1 JavaScript数据类型的特点

JavaScript是弱类型语言,对于数据类型的规范比较松散。具体表现如下:

☑ 分类简单,且不明确细分。

☑ 声明变量时,不用指定数据类型。

☑ 使用不严格,可根据需要自动转换数据类型。

☑ 数据类型检查比较简单,也比较混乱。

优点:使用限制少,应用灵活,入门门槛比较低。

缺点:开发复杂的程序存在瓶颈,执行效率与强类型语言相比较低。

4.1.2 JavaScript的基本数据类型

JavaScript定义了6种基本数据类型,如表4-1所示。

表4-1 JavaScript定义的6种基本数据类型

【示例】 使用typeof运算符可以检测数据的基本类型。下面代码使用typeof运算符分别检测常用直接量的值的类型。

注意: typeof运算符以字符串的形式返回上述6种基本类型之一。但是,JavaScript把null归为object数据类型,而function(){}归为function类型。把函数视为一种基本数据类型,而不是object的一种特殊类型。

提示: 在JavaScript中,函数是一个比较复杂、特殊的数据结构,它可以是函数类型,又可以是对象类型,也可以是类(构造函数、构造器),用法比较灵活,用户应该在具体环境中灵活把握。

4.1.3 值类型和引用类型

4.1.2节从形态角度对数据进行归类,下面从用法角度对其进行概括。任何数据都可以分为两大类:值类型和引用类型。

☑ 值类型:也称为原始数据、原始值。值类型是简单的数据,值可以直接赋值给变量,并存储在变量中。

☑ 引用型:也称为复合型数据。引用型数据不会直接传递给变量,变量与值之间相互分离,它们之间是引用关系。

在JavaScript中,Number、String、Boolean和Undefined型数据都是值类型,而object、Function和Array等都是引用型数据。

提示: 其他编程语言都把字符串视为引用型数据,而不是值类型,因为字符串的长度是可变的。但是JavaScript把字符串作为值类型进行处理,不过字符串在复制和传递运算中,是以引用型数据的方法来处理的。

【拓展1】 值和类型是两个不同的概念。例如,null是Null类型的唯一值,undefined是Undefined类型的唯一值,而true和false是Boolean类型仅有的两个值等。

在任何语言中,值的操作都可以归纳为以下3个方面。

☑ 复制值:把值赋予给变量,或者通过变量把值赋值给另一个变量、属性或数组元素。

☑ 传递值:把值作为参数传递给函数或方法。

☑ 比较值:通过逻辑运算符,把值与另一个值进行比较,看是否相等。

由于值类型数据和引用型数据的值存在形式不同,它们的操作方法和运算结果也是不同的。

1.使用原始值

对于原始值来说,其操作的3个层面说明如下。

(1)复制值

在赋值语句中,操作的过程将会产生一个值的副本,副本与实际值之间没有任何联系。

【示例1】 在本示例中,分别把值123复制3份给变量a、数组b和对象c,虽然它们的值是相等的,但它们之间是相互独立的。

(2)传递值

当把值传递给函数或方法时,传递的值仅是副本,而不是值本身。

【示例2】 当在函数中修改传递进来的值时,结果只能够影响这个参数值,并不会影响到原来的值。

(3)比较值

当对原始值进行比较时,比较的是值本身,而不是值所处的位置,比较结果可能会相等,这只能说明它们所包含的字节信息是相同的。

2.使用引用值

对于引用值来说,其操作的3个层面说明如下。

(1)复制值

在赋值语句中,所赋的值是对原值的引用,而不是原值副本。赋值之后,变量保存的是对原值的引用。当在多个变量、数组元素或对象属性中间复制时,它们都会与原始值保持引用关系。

【示例3】 所有引用都具有相同的功能,通过编辑其中的引用变量的值,这种修改将会在原值及其他相关引用中体现出来。

但是,如果给变量b重新赋予新值,则新值不会影响原值内容。

重复赋值实际上是覆盖变量对原值的引用,变为另一个值的副本或对其引用,所以不会对原值产生影响。

(2)传递值

当使用引用将数据传递给函数时,传递给函数的也是对原值的一个引用,函数可以使用这个引用来修改原值本身,任何修改在函数外部都是可见的。

【示例4】 在下面代码中,把数组a作为参数传递给函数f,则在函数体内可以修改函数体外数组的元素值。

在函数内可以使用外部引用的值,但是如果在函数内部使用一个新的值覆盖原来的引用,那么在函数内部的修改就不会影响原来引用的值。

(3)比较值

当比较两个引用值时,比较的是两个引用地址,看它们引用的原值是否为同一个副本,而不是比较它们的原值字节是否相等。

【示例5】 在下面代码中,当对两个不同值进行引用时,尽管它们由相同的字节构成,但是这两个引用的值却是不相等的。

【拓展2】 使用值和使用引用都是数据操作的两种基本方法。在操作数据时,要采用什么方法进行处理,主要看数据的类型。值类型和引用型数据参与运算的方式不同,值类型数据通过使用值来操作数据,而引用型数据使用引用来操作数据。

【示例6】 在下面代码中,值类型数据是以实际值参与函数内部运算,因此与原值没有直接关系,而引用型数据是以引用地址参与运算,计算的结果会影响到引用地址所关联的原值。 gXZdwj4Uc5CeSWiu5fwdfiwVL3VrCG2eAShxY9vsVeAeAGd1ouRt127aTRopOFcK

点击中间区域
呼出菜单
上一章
目录
下一章
×