表达式与运算符是一个程序的基础,JavaScript中的表达式与运算符和C、C++、Java中的表达式与运算符十分相似,请看下面的介绍。
■JavaScript的表达式和常见运算符;
■JavaScript的一些比较高级的运算符,如逐位运算符;
■了解JavaScript的运算符优先级。
表达式(expression)就是JavaScript中的一个语句,这个语句可以是常量或变量,也可以是由常量、变量加上一些运算符组成的语句。因此,表达式可以分为以下3种。
■常量表达式:常量表达式就是常量本身,请看以下代码。
"JavaScript" //字符串常量表达式 1.2 //数字常量表达式 false //布尔常量表达式
■变量表达式:变量表达式就是变量的值,请看以下代码。
x //变量表达式 y //变量表达式
■复合表达式:复合表达式是由常量、变量加上一些运算符所组成的表达式,请看以下代码。
x + y //x是变量表达式,y是变量表达式,x+y是复合表达式 1 + 2 //1是常量表达式,2是常量表达式,1+2是复合表达式 (x + y) - (1 + 2) //这是由常量表达式和变量表达式共同组成的复合表达式
表达式按其运算结果又可以分为以下3种。
■算术表达式(arithmetic expression):运算结果为数字的表达式称为算术表达式。
■字符串表达式(string expression):运算结果为字符串的表达式称为字符串表达式。
■逻辑表达式(logical expression):运算结果为布尔值的表达式称为逻辑表达式。
操作数(Operant)是进行运算的常量或变量。例如以下代码中,常量1和常量2都是操作数。
1+2
以下代码中,变量x与常量100都是操作数。
x = 100
以下代码中,变量x、常量12和23都是操作数。
x = 12 + 23
在任何一种语言中,处理数据是必不可少的一个功能,而运算符就是处理数据中所不能缺少的一种符号。
运算符(Operator)是一种用来处理数据的符号,日常算数中所用到的“+”“-”“×”“÷”都属于运算符。在JavaScript中的运算符大多也是由这些符号表示,除此之外,还有一些运算符是使用关键字来表示的。根据处理对象数目的多少来分,JavaScript中的运算符可以分为以下3种。
■一元运算符(unary operator):如果运算符所处理的对象只有一个,就称为一元运算符。如在一个正数前加一个“-”号,将该正数变为负数,这个“-”就是一元运算符。一元运算符又称为单元运算符。
■二元运算符(binary operator):如果运算符所处理的对象有两个,就称为二元运算符。如加号(+)、减号(-)等运算符都是二元运算符。
■三元运算符(ternary operator):如果运算符所处理的对象有三个,就称为三元运算符。JavaScript中只有“?:”运算符是三元运算符。
根据运算符的功能来分,JavaScript中的运算符可以分为以下几种。
■算术运算符(arithmetic operator):返回结果为数字型的运算符。
■比较运算符(comparison operator):比较两个操作数,并返回布尔值的运算符。
■字符串运算符(string operator):返回结果为字符串的运算符。
■赋值运算符(assignment operator):可以将某个数值指定给变量的运算符。
■逻辑运算符(logical operator):返回结果为布尔型的运算符。
■位运算符(bitwise operator):按位操作的运算符。
■特殊运算符(special operator):以上所有运算符之外的其他运算符。
运算符所连接的是操作数,而操作数也就是变量或常量,变量和常量都有一个数据类型,因此,在使用运算符创建表达式时,一定要注意操作数的数据类型。每一种运算符都要求其作用的操作数符合某种数据类型。例如算术运算符中的乘号(*),要求其左右操作数的类型都是数字型,如果使用字符型("abc" * "def"),则会产生错误。
由于JavaScript可以隐式转换类型,因此对于“"123" * "456"”这个表达式,JavaScript会自动转换为“123 * 456”。事实上,隐式类型的转换,也恰恰是运算符对操作数类型要求的一种体现。
算术运算符所处理的对象都是数字类型的操作数。算术运算符对数字型的操作数进行处理之后,返回的还是一个数字型的值。
加法运算符(+)是一个二元运算符,可以对两个数字型的操作数进行相加运算,返回值是两个操作数之和。
【实例3.1】 请看以下代码。注意加粗的文字。
01 <html> 02 <head> 03 <title>加法运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 10; 07 var x = i + 2; 08 document.write(x); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为10。代码第7行定义了x变量,其值为一个二元运算“+”,则x的值为变量i与2的“和”。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample01.htm”里的内容,其运行结果为12。
减法运算符(-)是一个二元运算符,可以对两个数字型的操作数进行相减运算,返回第1个操作数减去第2个操作数的值。
【实例3.2】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>减法运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 10; 07 var x = i - 2; 08 document.write(x); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为10。代码第7行定义了x变量,其值为一个二元运算“-”,则x的值为变量i与2的“差”。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample02.htm”里的内容,其运行结果为8。
乘法运算符(*)是一个二元运算符,可以对两个数字型的操作数进行相乘运算,返回两个操作数之积。
【实例3.3】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>乘法运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 10; 07 var x = i * 2; 08 document.write(x); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为10。代码第7行定义了x变量,其值为一个二元运算“*”,则x的值为变量i与2的“积”。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample03.htm”里的内容,其运行结果为20。
除法运算符(/)是一个二元运算符,可以对两个数字型的操作数进行相除运算,返回第1个操作数除以第2个操作数的值。
【实例3.4】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>除法运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var x = i / 2; 08 document.write(x); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为10。代码第7行定义了x变量,其值为一个二元运算“/”,则x的值为二元运算的操作结果。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample04.htm”里的内容,其运行结果为5.5。JavaScript中的所有数字型的数据都是以浮点型表示的,所以就算是整数型数据相除,也能得到浮点型的数据。
在使用除法运算符进行除法运算时,如果除数为0(如2/0),得到的结果为Infinity;如果是0/0,得到的结果为NaN。
模运算符(%),又称为取余运算符。这也是一个二元运算符,可以对两个数字型的操作数进行取模操作,返回第1个操作数除以第2个操作数之后的余数。
【实例3.5】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>模法运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var x = i % 2; 08 document.write(x); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行定义了x变量,其值为一个二元运算“%”,则x的值为二元运算的操作结果。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample05.htm”里的内容,其运行结果为1。
模运算符的操作数通常是两个整数,但JavaScript中也支持使用浮点数,例如“-5.4 % 2.1”的结果是-1.2000000000000001。
负号运算符(-)是一个一元运算符,可以对一个数字进行取反操作,即将一个正数转换成相应的负数,也可以将一个负数转换成相应的正数。
【实例3.6】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>负号运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 i = -i; 08 document.write(i + "<br>"); 09 i = -i; 10 document.write(i + "<br>"); 11 --> 12 </script> 13 </head> 14 <body> 15 </body> 16 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行重新定义了i变量,其值为原来的i变量取负数。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample06.htm”里的内容,其运行结果为两行文字,第一行文字为-11,第二行文字为11。
(1)如果操作数为非数字型数据,负号运算符可以将其先转换为数字再进行取反操作。
(2)如果操作数为非数字型数据,并且该操作数不能转换为数字型数据,将返回NaN。
与负号运算符相对应,正号运算符(+)也是一个一元运算符,但该运算符不会对操作数产生任何影响,只会让源代码看起来更清楚。
【实例3.7】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>正号运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 i = +i; 08 document.write(i); 09 --> 10 </script> 11 </head> 12 <body> 13 </body> 14 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行重新定义了i变量,其值为原来的i变量进行正号运算,其实结果不变。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample07.htm”里的内容,其运行结果为11。
如果正号运算符的操作数是一个字符串型的数据,正号运算符可以将其转换为数字型的数据。如果该操作数是一个不能转换为数字型的数据,将返回NaN。
递增运算符(++)是一个一元运算符,该运算符可以对操作数进行递增操作,即每次增加1。递增运算符要求其操作数必须是变量、对象中的某个属性或数组中的某个元素,并且操作数的类型必须是数字型的,如果操作数类型不是数字型,递增运算符会将其先转换为数字型数据,再进行递增操作。
递增运算符根据其相对于操作数的位置有两种不同的递增方式。
(1)先使用后递增:当运算符在操作数之后时,JavaScript会先使用操作数的值之后,再对操作数做递增操作。
【实例3.8】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>先使用后递增</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = i++; 08 document.write(i + "<br>"); 09 document.write(j + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行定义了j变量,其值为i++。
图3.1 sample08.htm的运行结果
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample08.htm”里的内容,其运行结果如图3.1所示。在图3.1中可以看出,变量i的值为12,而变量j的值为11。在本例中,先是将变量i的值赋给变量j,再对i进行递增操作。所以本例中的关键代码相当于以下代码:
var i = 11; var j = i; i = i +1;
(2)先递增后使用:当运算符在操作数之前时,JavaScript会先对操作数做递增操作,再使用赋值后的操作数。
【实例3.9】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>先递增后使用</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = ++i; 08 document.write(i + "<br>"); 09 document.write(j + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行定义了j变量,其值为++i。
图3.2 sample09.htm的运行结果
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample09.htm”里的内容,其运行结果如图3.2所示。在该图中可以看出,变量i的值为12,而变量j的值也为12。在本例中,是对变量i进行递增操作后再将变量i的值赋给变量j。所以本例中的关键代码相当于以下代码:
var i = 11; i = i +1; var j = i;
递减运算符(--)也是一个一元运算符,该运算符可以对操作数进行递减操作,即每次减1。递减运算符要求其操作数必须是变量、对象中的某个属性或数组中的某个元素,并且操作数的类型必须是数字型的,如果操作数类型不是数字型,递减运算符会将其先转换为数字型数据,再进行递减操作。递减运算符根据其相对于操作数的位置有两种不同的递减方式。
当运算符在操作数之后时,JavaScript会先使用操作数的值,再对操作数做递减操作。
【实例3.10】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>先使用后递减</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = i--; 08 document.write(i + "<br>"); 09 document.write(j + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11,代码第7行定义了j变量,其值为i--。--和++的使用方式相似,是递减的意思。
图3.3 sample10.htm的运行结果
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample10.htm”里的内容,其运行结果如图3.3所示。从该图中可以看出,变量i的值为10,而变量j的值为11。在本例中,先是将变量i的值赋给变量j,再对i进行递减操作。所以本例中的关键代码相当于以下代码:
var i = 11; var j = i; i = i -1;
当运算符在操作数之前时,JavaScript会先对操作数做递减操作,再使用赋值后的操作数。
【实例3.11】 请看以下代码,注意加粗的文字:
01 <html> 02 <head> 03 <title>先递减后使用</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = --i; 08 document.write(i + "<br>"); 09 document.write(j + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行定义了i变量,并直接赋值为11。代码第7行定义了j变量,其值为--i。--i和++i的使用方式相似,是先执行递减操作的运算符。
图3.4 sample11.htm的运行结果
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample11.htm”里的内容,其运行结果如图3.4所示。从该图中可以看出,变量i的值为10,而变量j的值也为10。在本例中,是将变量i的进行递减操作后再将变量i的值赋给变量j。所以本例中的关键代码相当于以下代码:
var i = 11; i = i -1; var j = i;
关系运算符通常用于检查两个操作数之间的关系,即两个操作数之间是相等、大于还是小于关系等。关系运算符可以根据是否满足该关系来返回true或false。
相等运算符(==)是一个二元运算符,可以比较两个操作数是否相等。如果相等,则返回布尔值true;如果不相等,则返回布尔值false。
【实例3.12】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>相等运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 11; 08 var k = 12; 09 if (i==j) 10 { 11 document.write("i等于j<br>"); 12 } 13 else 14 { 15 document.write("i不等于j<br>"); 16 } 17 if (j==k) 18 { 19 document.write("j等于k<br>"); 20 } 21 else 22 { 23 document.write("j不等于k<br>"); 24 } 25 --> 26 </script> 27 </head> 28 <body> 29 </body> 30 </html>
【代码说明】 代码第9行和第17行分别进行了两个“==”的判断。在本例中,只有相等运算符左右两侧的操作数相等才会返回true,否则返回false。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample12.htm”里的内容,其运行结果如图3.5所示。
图3.5 sample12.htm的运行结果
值得注意的是:相等运算符并不要求两个操作数的类型是一样的,它会将字符串“11”与数字11认为是相等的两个操作数。即当字符串“11”与数字11比较时,将会返回true。相等运算符的比较原理如下。
■如果两个操作数的类型相同,则比较这两个操作数的值,如果值相等,则返回true,否则返回false。
■如果一个操作数是字符串,另一个操作数是数字,则把字符串转换成数字再判断两个操作数的值是否相等。如果值相等,返回true,否则返回false。
■如果一个操作数是布尔值,则把该操作数转换为数字再进行比较,其中true将转换为1,false将转换为0。
■如果一个操作数的值为undefined,另一个操作数的值为null,则返回true。
■如果一个操作数是对象,另一个操作数是数字或字符串,则使用valueOf()或toString()将对象转化为原始类型的值之后,再进行比较。
■如果操作数类型的组合与以上组合都不相同,则返回false。
等同运算符(===)与相等运算符类似,也是一个二元运算符,同样可以比较两个操作数是否相等。如果相等,则返回布尔值true;如果不相等,则返回布尔值false。请注意等同运算符与相等运算符在表示上的区别:相等运算符是两个等于号构成的,而等同运算符是三个等于号构成的。等同运算符对操作数是否相等的判断比相等运算符的判断更为严格,等同运算符只有在两个操作数类型相同,并且值也相同的情况下才会返回true。
【实例3.13】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>等同运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = "11"; 08 var k = "11"; 09 if (i==j) 10 { 11 document.write("i等于j<br>"); 12 } 13 else 14 { 15 document.write("i不等于j<br>"); 16 } 17 if (i===j) 18 { 19 document.write("i等同于j<br>"); 20 } 21 else 22 { 23 document.write("i不等同于j<br>"); 24 } 25 if (j===k) 26 { 27 document.write("j等同于k<br>"); 28 } 29 else 30 { 31 document.write("j不等同于k<br>"); 32 } 33 --> 34 </script> 35 </head> 36 <body> 37 </body> 38 </html>
【代码说明】 在本例中,代码6~8行定义了一个数字变量(i)和两个字符串变量(j和k),其中i的值为数字11,而j和k的值都为字符串“11”。在使用相等运算符进行比较时,JavaScript认为数字11与字符串“11”是相同的。而在使用等同运算符进行比较时,JavaScript认为数字11与字符串“11”是不相同的,只有值同样都是字符串“11”的j和k比较时,才认为它们是相同的。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample13.htm”里的内容,其运行结果如图3.6所示。
图3.6 sample13.htm的运行结果
等同运算符的比较原理如下。
■如果两个操作数的类型不相同,则返回false。
■如果两个操作数的类型相同,并且值相同,则返回true。
■NaN不会与任何值等同,包括它自己。
■字符串只有在长度与内容都相同的情况下才会返回true。
■当两个操作数的值都是true或都是false时,才会返回true。
■当两个操作数的值都是null或都是undefined时,才会返回true。
■两个操作数引用的是同一个对象、数组或函数时,才会返回true。如果两个操作数引用的不是同一个对象,哪怕这两个对象的属性完全相同,也会返回false。数组也是如此,只要两个操作数引用的不是同一个数组,哪怕两个数组的元素完全相同,也会返回false。
不等运算符(!=)也是一个二元运算符,可以比较两个操作数是否不相等。如果不相等,则返回布尔值true;如果相等,则返回布尔值false。
【实例3.14】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>不等运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 11; 08 var k = 12; 09 if (i!=j) 10 { 11 document.write("i与j不相等<br>"); 12 } 13 else 14 { 15 document.write("i与j相等<br>"); 16 } 17 if (j!=k) 18 { 19 document.write("j与k不相等<br>"); 20 } 21 else 22 { 23 document.write("j与k相等<br>"); 24 } 25 --> 26 </script> 27 </head> 28 <body> 29 </body> 30 </html>
【代码说明】 代码第9行和代码第17行执行了两个不等运算。在本例中,只有不等运算符左右两侧的操作数不相等才会返回true,否则返回false。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample14.htm”里的内容,其运行结果如图3.7所示。
图3.7 sample14.htm的运行结果
不等运算符与相等运算符检测的情况正好相反。
不等同运算符(!==)与不等运算符类似,也是一个二元运算符,同样可以比较两个操作数是否不相等。如果不相等,则返回布尔值true,否则返回布尔值false。请注意不等同运算符比不等运算符多一个等于号。不等同运算符对操作数是否不相等的判断比不等运算符的判断更为严格,不等同运算符只有在两个操作数类型相同,并且值也相同的情况下才会返回false。
【实例3.15】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>不等同运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = "11"; 08 var k = "11"; 09 if (i!=j) 10 { 11 document.write("i与j不相等<br>"); 12 } 13 else 14 { 15 document.write("i与j相等<br>"); 16 } 17 if (i!==j) 18 { 19 document.write("i与j不等同成立<br>"); 20 } 21 else 22 { 23 document.write("i与j不等同不成立<br>"); 24 } 25 if (j!==k) 26 { 27 document.write("j与k不等同成立<br>"); 28 } 29 else 30 { 31 document.write("j与k不等同不成立<br>"); 32 } 33 --> 34 </script> 35 </head> 36 <body> 37 </body> 38 </html>
【代码说明】 在本例中,代码第6~8行定义了一个数字变量(i)和两个字符串变量(j和k)。其中,i的值为数字11,而j和k的值都为字符串“11”。在使用不等运算符进行比较时,JavaScript认为数字11与字符串“11”是不相等的关系不成立,即数字11与字符串“11”是相等的。而在使用不等同运算符进行比较时,JavaScript认为数字11与字符串“11”是不等同的关系成立。只有在值同样都是字符串“11”的j和k比较时,才认为是不等同的关系不正立。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample15.htm”里的内容,其运行结果如图3.8所示。
图3.8 sample15.htm的运行结果
不等同运算符与等同运算符检测的情况正好相反。
小于运算符(<)是一个二元运算符,当第1个操作数小于第2个操作数时返回true,否则返回false。
【实例3.16】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>小于运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 12; 08 if (i<j) 09 { 10 document.write("i小于j"); 11 } 12 else 13 { 14 document.write("i不小于j"); 15 } 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 小于运算符也不要求两个操作数的类型相同,其比较原理如下。
■如果两个操作数都是数字型的,则按数字大小的方式来比较。
■如果两个操作数都是字符串型的,则逐个字符进行比较。字符的比较方式是采用字符在Unicode编码中的数值大小来进行比较。
■如果一个操作数是字符串型的,另一个操作数是数字型的,则将字符串型的操作数转换成数字型后再做比较。如果不能转换成数字,则返回false。
■如果操作数不能转换成字符串或数字,则返回false。
■如果一个操作数是NaN,则比较结果为false。
如果操作数是对象,并且该对象可以转换为数字或字符串,则将其转换为数字。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample16.htm”里的内容,其运行结果为“i小于j”。
大于运算符(>)也是一个二元运算符,与小于运算符相反,只有当第1个操作数大于第2个操作数时才返回true,否则返回false。
【实例3.17】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>大于运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 12; 08 if (i>j) 09 { 10 document.write("i大于j"); 11 } 12 else 13 { 14 document.write("i不大于j"); 15 } 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 代码第6~7行定义了两个变量,然后代码第8行比较两个变量,并根据不同的结果输出不同的值。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample17.htm”里的内容,其运行结果为“i不大于j”。
大于运算符的比较原理与小于运算符的比较原理相同。
小于或等于运算符(<=)是一个二元运算符,当第1个操作数小于第2个操作数,或者第1个操作等于第2个操作数时(即第1个操作数不大于第2个操作数时),都能返回true,否则返回false。
【实例3.18】 请看以下代码,注意加粗的代码。
01 <html> 02 <head> 03 <title>小于或等运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 11; 08 if (i<=j) 09 { 10 document.write("i小于或等于j"); 11 } 12 else 13 { 14 document.write("i大于j"); 15 } 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 代码第6~7行定义了两个变量,然后代码第8行比较两个变量,并根据不同的结果输出不同的值。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample18.htm”里的内容,其运行结果为“i小于或等于j”。
小于或等于运算符的比较原理与小于运算符的比较原理相同。
大于或等于运算符(>=)是一个二元运算符,当第1个操作数大于第2个操作数,或者第1个操作等于第2个操作数时(即第1个操作数不小于第2个操作数时),都能返回true,否则返回false。
【实例3.19】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>大于或等于运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var i = 11; 07 var j = 11; 08 if (i<=j) 09 { 10 document.write("i大于或等于j"); 11 } 12 else 13 { 14 document.write("i小于j"); 15 } 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 代码第6~7行定义了两个变量,然后代码第8行比较两个变量,并根据不同的结果输出不同的值。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample19.htm”里的内容,其运行结果为“i大于或等于j”。
大于或等于运算符的比较原理与小于运算符的比较原理相同。
in运算符虽然也是一个二元运算符,但是对运算符左右两个操作数的要求比较严格。in运算符要求第1个(左边的)操作数必须是字符串类型或可以转换为字符串类型的其他类型,而第2个(右边的)操作数必须是数组或对象。只有第1个操作数的值是第2个操作数的属性名,才会返回true,否则返回false。
【实例3.20】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>in运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个box对象 07 var box = {box_length:200,box_width:100}; 08 //定义一个数组 09 var arr = ["box_length",200,"200"]; 10 //定义变量 11 var x = "box_length"; 12 var y = 2; 13 if (x in box) 14 { 15 document.write("变量x包含在对象box之中<br>"); 16 } 17 else 18 { 19 document.write("变量x不包含在对象box之中<br>"); 20 } 21 if (y in box) 22 { 23 document.write("变量y包含在对象box之中<br>"); 24 } 25 else 26 { 27 document.write("变量y不包含在对象box之中<br>"); 28 } 29 if (x in arr) 30 { 31 document.write("变量x包含在数组arr之中<br>"); 32 } 33 else 34 { 35 document.write("变量x不包含在数组arr之中<br>"); 36 } 37 if (y in arr) 38 { 39 document.write("变量y包含在数组arr之中<br>"); 40 } 41 else 42 { 43 document.write("变量y不包含在数组arr之中<br>"); 44 } 45 --> 46 </script> 47 </head> 48 <body> 49 </body> 50 </html>
【代码说明】 本例代码中的关键点如下。
■代码7~9行定义了一个对象box和一个数组arr。其中,对象box包含了两个属性:box_length和box_width;数组arr一共包含3个元素。
■对于对象而言,in运算符比较的是对象的属性名。当变量x的值为“box_length”时,与对象box中的属性“box_length”相同,因此“x in box”返回true。而变量y的值与对象box中的所有属性名都不相同,因此“y in box”返回false。
■对于数组而言,in运算符比较的是数组的下标。当变量y的值为2时,属于数组arr的合法下标(arr的长度为3,所以合法下标为0~2),因此“y in arr”返回true。而变量x的值为“box_length”,虽然数组中有一个元素值也为“box_length”,但是这并不是数组arr的合法下标,因此“x in arr”返回false。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample20.htm”里的内容,其运行结果如图3.9所示。
图3.9 sample20.htm的运行结果
instanceof运算符用于判断对象与对象实例之间关系的运算符,或者判断对象是否由某个构造函数定义。这也是一个二元运算符,该运算符要求第1个操作数是一个对象或数组的名称,而第2个操作是对象类的名字。如果第1个操作数是第2个操作数的实例,instanceof运算符将会返回true,否则返回false。
【实例3.21】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>instanceof运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个Date对象 07 var myDate = new Date(); 08 //定义一个数组 09 var arr = ["box_length",200,"200"]; 10 if (myDate instanceof Date) 11 {document.write("myDate是Date类的实例<br>");} 12 else 13 {document.write("myDate不是Date类的实例<br>");} 14 if (myDate instanceof Object) 15 {document.write("所有对象都是Object类的实例<br>");} 16 else 17 {document.write("myDate不是Object类的实例<br>");} 18 if (myDate instanceof Number) 19 {document.write("myDate是Number类的实例<br>");} 20 else 21 {document.write("myDate不是Number类的实例<br>");} 22 if (arr instanceof Array) 23 {document.write("arr是Array类的实例<br>");} 24 else 25 {document.write("arr不是Array类的实例<br>");} 26 if (arr instanceof Object) 27 {document.write("所有对象都是Object类的实例<br>");} 28 else 29 {document.write("arr不是Object类的实例<br>");} 30 if (arr instanceof Number) 31 {document.write("arr是Number类的实例<br>");} 32 else 33 {document.write("arr不是Number类的实例<br>");} 34 --> 35 </script> 36 </head> 37 <body> 38 </body> 39 </html>
【代码说明】 本例代码中的关键点如下。
■代码第7~9行定义了一个名为myDate的Date对象和一个名为arr的数组。
■代码第10行使用“myDate instanceof Date”判断myDate是否是Date对象的实例,由于myDate是Date()定义的,所以返回true。
■代码第14行使用“myDate instanceof Object”判断myDate是否是Object类的实例,由于所有对象都是Object类的实例,所以返回true。
■代码第18行使用“myDate instanceof Number”判断myDate是否是Number类的实例,由于myDate不是Number对象,所以返回false。
■代码第22行使用“arr instanceof Array”判断arr是否是Array对象的实例,由于arr是一个数组,所以返回true。
■代码第26行使用“arr instanceof Object”判断arr是否是Object类的实例,由于所有对象都是Object类的实例,所以返回true。
■代码第30行使用“arr instanceof Number”判断arr是否是Number类的实例,由于arr不是Number对象,所以返回false。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample21.htm”里的内容,其运行结果如图3.10所示。
图3.10 sample21.htm的运行结果
字符串运算符比较简单,只有一个+运算符,该运算符的作用是连接两个字符串,并产生一个新的字符串。
【实例3.22】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>字符串运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = "JavaScript"; 07 var y = "字符串运算符"; 08 var z = x + y; 09 document.write(z); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 在本例中可以看出,字符串运算符的作用就是连接两个字符串。如果两个操作数中只有一个是字符串,则另一个操作数将会转换成字符串,再做连接操作,如以下代码返回的是字符串“1234”,而不是数字46:
"12" + 34
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample22.htm”里的内容,其运行结果为“JavaScript字符串运算符”。
如果运算符为“+”,而两个操作数都是数字,将执行相加运算,因为在这种情况下,JavaScript会将“+”看成是加法运算符,而不是字符串运算符。
赋值运算符(=)的作用是给一个变量赋值,即将某个数值指定给某个变量。这也是一个二元运算符,赋值运算符的左侧操作数应该是一个变量、数组的一个元素,或者是对象的一个属性,而右侧操作数可以是一个任意的数值。
【实例3.23】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>赋值运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x; 07 x = "JavaScript"; 08 var arr = new Array(); 09 arr[0] = "数组元素一"; 10 arr[1] = 1; 11 var pen = new Object(); 12 pen.color = "red"; 13 document.write("变量x的值为:" + x.toString() + "<br>"); 14 document.write("数组arr的值为:" + arr.toString() + "<br>"); 15 document.write("对象pen的color属性的值为:" + pen.color + "<br>"); 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 在本例中:
■代码第7行是为变量赋值;
■代码第9~10行是为数组元素赋值;
■代码第12行是为对象属性赋值。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample23.htm”里的内容,其运行结果如图3.11所示。
图3.11 sample23.htm的运行结果
逻辑运算符使用的是布尔操作数,在进行逻辑运算之后,返回的还是布尔值。逻辑运算符常与关系运算符结合使用,可以完成复杂的比较运算,而逻辑运算符的结果常用在if、while和for等语句中。
逻辑与运算符(&&)是一个二元运算符,要求左右两个操作数的值都必须是布尔值。逻辑与运算符可以对左右两个操作数进行AND运算,只有左右两个操作数的值都为真(true)时,才会返回true。如果其中一个或两个操作数的值为假(false),其返回值都为false。表3.1为逻辑与运算符返回的结果表。
表3.1 逻辑与运算符结果表
逻辑与运算符的运算过程比较复杂,通常JavaScript会对逻辑与运算符左边的操作数进行运算,如果左边的操作数的值为false,那么JavaScript就会直接返回false,而不再对右边的操作数进行运算。逻辑与运算符左边的操作数的值为true,JavaScript才会对逻辑与运算符右边的操作数进行运算。如果右边的操作数的值为true,JavaScript将返回true,否则返回false。请看以下代码:
if (x==y && y==z) { a = true; } else { a = false; }
在以上代码中,当x不等于y时,JavaScript不再去判断y是否等于z,而是直接将false值赋给变量a。只有当x等于y时,JavaScript才会去判断y是否等于z,并且只有在x等于y,y等于z两种情况同时成立时,才会将true值赋给变量a。请再看以下代码:
z = 2 if (x==y && (z++ == 3)) { a = true; } else { b = false; }
在以上代码中,“++”是一个递增运算符,可以将变量y的值加1。在x不等于y的情况下,JavaScript不会对逻辑与右侧的操作数进行运算,此时z的值还是等于2;而在x等于y的情况下,JavaScript才会对逻辑与右侧的操作数进行运算,此时z的值将会等于3。这种情况是必须要注意的。
逻辑或运算符(||)是一个二元运算符,要求左右两个操作数的值都必须是布尔值。逻辑或运算符可以对左右两个操作数进行OR运算,只有左右两个操作数的值都为假(false)时,才会返回false。如果其中一个或两个操作数的值为真(true),其返回值都为true。表3.2为逻辑或运算符返回的结果表。
表3.2 逻辑或运算符结果表
与逻辑与运算符类似,逻辑或运算符的运算过程也比较复杂,通常JavaScript会对逻辑或运算符左边的操作数进行运算,如果左边的操作数的值为true,那么JavaScript就会直接返回true,而不再对右边的操作数进行运算。如果逻辑或运算符左边的操作数的值为false,JavaScript才会对逻辑或运算符右边的操作数进行运算。如果右边的操作数的值为false,JavaScript将返回false,否则返回true。
逻辑非运算符(!)是一个一元运算符,要求操作数放在运算符之后,并且操作数的值必须是布尔型。逻辑非运算符可以对操作数进行取反操作,如果运算数的值为true,则取反操作之后的结果为false;如果运算数的值为false,则取反操作之后的结果为true。表3.3为逻辑非运算符返回的结果表。
表3.3 逻辑非运算符结果表
逐位运算符是一种比较复杂的运算符,可以分为逐位逻辑运算符(bitwise logical operator)与逐位位移运算符(bitwise shift operator)两种。无论是哪种逐位运算符,都必须先将操作数(要求是整型的操作数)转换成32位的二进制数值,然后再进行运算,运算完毕之后,再将结果转换成十进制数值。
逐位与运算符(&)是一个二元运算符,该运算符可以对左右两个操作数逐位执行AND操作,即只有两个操作数中相对应的位都为1时,该结果中的这一位才为1,否则为0。
【实例3.24】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>逐位与运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 9 & 12; 07 document.write(""9 & 12"的结果为:" + x + "<br>"); 08 var y = 1 & 15; 09 document.write(""1 & 15"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行使用了&运算符。在进行逐位与操作时,逐位与运算符会先将十进制的操作数转换为二进制,再对二进制中的每一位数值逐位进行AND操作,得出结果后,再将结果转换为十进制。其操作方式如下:
十进制 二进制 9 0000 0000 0000 0000 0000 0000 0000 1001 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 逐位与操作 8 0000 0000 0000 0000 0000 0000 0000 1000
十进制 二进制 1 0000 0000 0000 0000 0000 0000 0000 0001 15 0000 0000 0000 0000 0000 0000 0000 1111 --------------------------------------------------- 逐位与操作 1 0000 0000 0000 0000 0000 0000 0000 0001
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample24.htm”里的内容,其运行结果如图3.12所示。
图3.12 sample24.htm的运行结果
逐位或运算符(|)和逐位与运算符类似,可以对左右两个操作数逐位执行OR操作。两个操作数中相对应的位只要有一个为1时,该结果中的这一位就为1,其他情况都为0。
【实例3.25】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>逐位或运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 9 | 12; 07 document.write(""9 | 12"的结果为:" + x + "<br>"); 08 var y = 1 | 15; 09 document.write(""1 | 15"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行使用了“|”运算符。在进行逐位或操作时,逐位或运算符会先将十进制的操作数转换为二进制,对二进制中的每一位数值逐位进行OR操作,得出结果后,再将结果转换为十进制。其操作方式如下:
十进制 二进制 9 0000 0000 0000 0000 0000 0000 0000 1001 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 逐位或操作 13 0000 0000 0000 0000 0000 0000 0000 1101
十进制 二进制 1 0000 0000 0000 0000 0000 0000 0000 0001 15 0000 0000 0000 0000 0000 0000 0000 1111 --------------------------------------------------- 逐位或操作 15 0000 0000 0000 0000 0000 0000 0000 1111
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample25.htm”里的内容,其运行结果如图3.13所示。
图3.13 sample25.htm的运行结果
逐位异或运算符(^)和逐位与运算符类似,可以对左右两个操作数逐位执行异或操作。所谓异或操作是指,第1个操作数与第2个操作数相对应的位上两个数值相同时结果为0,否则为1。
【实例3.26】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>逐位异或运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 9 ^ 12; 07 document.write(""9 ^ 12"的结果为:" + x + "<br>"); 08 var y = 1 ^ 15; 09 document.write(""1 ^ 15"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行使用了^运算符。在进行逐位异或操作时,逐位异或运算符会先将十进制的操作数转换为二进制,对二进制中的每一位数值逐位进行异或操作,得出结果后,再将结果转换为十进制。其操作方式如下:
十进制 二进制 9 0000 0000 0000 0000 0000 0000 0000 1001 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 逐位异或操作 5 0000 0000 0000 0000 0000 0000 0000 0101
十进制 二进制 1 0000 0000 0000 0000 0000 0000 0000 0001 15 0000 0000 0000 0000 0000 0000 0000 1111 --------------------------------------------------- 逐位异或操作 14 0000 0000 0000 0000 0000 0000 0000 1110
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample26.htm”里的内容,其运行结果如图3.14所示。
图3.14 sample26.htm的运行结果
逐位非运算符(~)是一个一元操作符,作用于操作数之前,可以对操作数中所有位的数值取反。在JavaScript中,对一个带符号的整数进行逐位非运算,相当于将该整数改变符号后再减1。
【实例3.27】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>逐位非运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = ~12; 07 document.write(""~12"的结果为:" + x + "<br>"); 08 var y = ~-15; 09 document.write(""~-15"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行使用了“~”运算符。在进行逐位非操作时,逐位非运算符会先将十进制的操作数转换为二进制,对二进制中的每一位数值逐位取反,得出结果后再转换为十进制。其操作方式如下:
十进制 二进制 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 逐位非操作 1111 1111 1111 1111 1111 1111 1111 0011 (补码,最高位为1,所以是负数) 1111 1111 1111 1111 1111 1111 1111 0010 (反码) 0000 0000 0000 0000 0000 0000 0000 1101 (绝对值的原码,即13)
十进制 二进制 -15 0000 0000 0000 0000 0000 0000 0000 1111 (绝对值的原码) 1111 1111 1111 1111 1111 1111 1111 0000 (反码) 1111 1111 1111 1111 1111 1111 1111 0001 (补码) -------------------------------------------------- 逐位非操作 14 0000 0000 0000 0000 0000 0000 0000 1110 (补码,最高位为0,所以是正数)
要理解以上的转换过程,必须要掌握二进制的原码、反码和补码这几个概念。
■原码:原码可以分为两个部分,第一部分为二进制的最高位,用于区分正数和负数。如果一个二进制数的最高位为0,则代表正数,如果为1则代表负数。第二部分为数值部分,用二进制的绝对值表示。例如以下代码中,第1行是+0,第2行是-0,第3行是12,第4行是-12。
0000 0000 1000 0000 0000 1100 1000 1100
■反码:对于正数而言,反码等于原码;对于负数而言,反码等于其绝对值的原码并逐位取反。例如以下代码中,第1行是12,第2行是-12。
0000 1100 1111 0011
■补码:对于正数而言,补码等于原码;对于负数而言,补码等于反码加1。例如以下代码中,第1行是12,第2行是-12。
0000 1100 1111 0100
在计算机中,所有二进制都是以补码的形式存放的。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample27.htm”里的内容,其运行结果如图3.15所示。
图3.15 sample27.htm的运行结果
左移运算符(<<)是一个二元操作符,可以将第1个操作数中的所有数值(一共32位)向左移动,移动的位数由第2个操作数决定,因此第2个操作数应该是0~31的整数。
【实例3.28】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>左移运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 12 << 1; 07 document.write(""12 << 1"的结果为:" + x + "<br>"); 08 var y = 15 << 13; 09 document.write(""15 << 13"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行执行了“<<”运算,在进行左移操作时,左移运算符会先将第1个操作数转换为二进制,再根据第2个操作数来决定左移的位数。如果第2个操作数为1,则第1个操作数所有位数都向左移1位,即第1位变成第2位,第2位变成第3位,以此类推,而第32位则用0来补充。其操作方式如下:
十进制 二进制 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 左移操作 24 0000 0000 0000 0000 0000 0000 0001 1000
十进制 二进制 15 0000 0000 0000 0000 0000 0000 0000 1111 --------------------------------------------------- 左移操作 122880 0000 0000 0000 0001 1110 0000 0000 0000
将一个值左移1位,相当于将该数值乘以2;左移2位,相当于将该数值乘以4,以此类推。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample28.htm”里的内容,其运行结果如图3.16所示。
图3.16 sample28.htm的运行结果
带符号的右移运算符(>>)是一个二元操作符,可以将第1个操作数中的所有数值(一共32位)向右移动,移动的位数由第2个操作数决定,因此第2个操作数应该是范围在0~31的整数。
【实例3.29】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>带符号的右移运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 12 >> 1; 07 document.write(""12 >> 1"的结果为:" + x + "<br>"); 08 var y = -12 >> 1; 09 document.write(""-12 >> 1"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行执行了“>>”运算,在进行带符号的右移操作时,带符号的右移运算符会先将第1个操作数转换为二进制,再根据第2个操作数来决定右移的位数。如果第1个操作数为1,则第1个操作数所有位数都向右移1位,即第32位变成第31位,第31位变成第30位,以此类推。而第1位的数值补充要由原操作数的符号来决定,如果原操作数是正数,则用0来补充;如果原操作数是负数,则用1来补充。其操作方式如下:
十进制 二进制 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 带符号的右移操作 6 0000 0000 0000 0000 0000 0000 0000 0110
十进制 二进制 -12 1111 1111 1111 1111 1111 1111 1111 0100(补码) --------------------------------------------------- 带符号的右移操作 -6 1111 1111 1111 1111 1111 1111 1111 1010(补码)
将一个值带符号右移1位,相当于将该数值除以2(舍丢余数);右移2位,相当于将该数值除以4(舍丢余数),以此类推。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample29.htm”里的内容,其运行结果如图3.17所示。
图3.17 sample29.htm的运行结果
用0补足的右移运算符(>>>)与带符号的左移运算符类似,只是在右移时,最左侧的数值都是用0来补充的。
【实例3.30】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>用0补足的右移运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 12 >>> 1; 07 document.write(""12 >>> 1"的结果为:" + x + "<br>"); 08 var y = -12 >>> 1; 09 document.write(""-12 >>> 1"的结果为:" + y + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 </body> 15 </html>
【代码说明】 代码第6行和第8行执行了“>>>”运算,在进行用0补足的右移操作时,用0补足的右移运算符会先将第1个操作数转换为二进制,再根据第2个操作数来决定右移的位数。如果第2个操作数为1,则第1个操作数所有位数都向右移1位,即第32位变成第31位,第31位变成第30位,以此类推。而第1位的数值补充永远是0,无论原操作数是正数还是负数。其操作方式如下:
十进制 二进制 12 0000 0000 0000 0000 0000 0000 0000 1100 --------------------------------------------------- 用0补足的右移操作 6 0000 0000 0000 0000 0000 0000 0000 0110
十进制 二进制 -12 1111 1111 1111 1111 1111 1111 1111 0100(补码) ------------------------------------------------------- 用0补足的右移操作 2147483642 0111 1111 1111 1111 1111 1111 1111 1010
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample30.htm”里的内容,其运行结果如图3.18所示。
图3.18 sample30.htm的运行结果
除了前面章节里所介绍的运算符之外,JavaScript还支持许多其他运算符,请看以下介绍。
条件运算符(?:)是JavaScript中唯一的三元运算符。三元运算符必须有3个操作数:第1个操作数位于“?”之前;第2个操作数位于“?”与“:”之间;第3个操作数位于“:”之后。其语法代码如下:
X ? Y : Z
在条件运算符中,第1个操作数(X)必须是布尔值(如“a>b”),而第2个操作数(Y)和第3个操作数(Z),可以是任何类型的值。条件运算符返回的值是由第1个操作数的值所决定的,如果第1个操作数的值为true,那么返回第2个操作数的值;如果第1个操作数的值为false,那么返回第3个操作数的值。
【实例3.31】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>条件运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 12; 07 var a = "x大于10<br>"; 08 var b = "x不大于15<br>"; 09 document.write(x>10?a:b); 10 document.write(x>15?a:b); 11 --> 12 </script> 13 </head> 14 <body> 15 </body> 16 </html>
【代码说明】 在本例中,x的值为12,因此x>10的值为true,所以返回变量a的值,即“x大于10”。而x>15的值为false,所以返回变量b的值,即“x不大于15”。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample31.htm”里的内容,其运行结果如图3.19所示。
图3.19 sample31.htm的运行结果
在JavaScript中有很多内置对象,如日期对象、字符串对象、布尔对象和数值对象等,使用new运算符可以定义一个新的内置对象实例,JavaScript会调用构造函数初始化这个对象实例。new运算符的语法如下:
对象实例名称 = new 对象类型 (参数) 对象实例名称 = new 对象类型
当函数调用时,如果没有用到参数,可以省去括号,但这种省略方式只限于new运算符。
【实例3.32】 有关new运算符的使用请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>new运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var mydate = new Date(); 07 document.write(mydate.getFullYear() + "<br>"); 08 09 var arr = new Array; 10 arr = ["1",true]; 11 document.write(arr[1] + "<br>"); 12 --> 13 </script> 14 </head> 15 <body> 16 </body> 17 </html>
【代码说明】 本例中的知识点说明如下。
■代码第6行使用“var mydate = new Date();”定义了一个名为mydate的新的日期型对象。
■在定义了日期型对象实例之后,JavaScript会自动调用构造函数初始化mydate,因此,可以通过mydate.getYear()来获取该日期型对象中的年份。
■代码第9行使用“var arr = new Array;”定义了一个名为arr数组。在定义数组对象实例时,没有使用参数,所以可以省略Array后面的括号。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample32.htm”里的内容,其运行结果如图3.20所示。
图3.20 sample32.htm的运行结果
void运算符是一个特殊的一元运算符,可以作用在任何类型的操作数之前。void运算符可以让操作数进行运算,但是却舍弃运算之后的结果。通常void运算符出现在HTML代码的<a>标签中,其语法代码如下:
void 操作数 void(操作数)
【实例3.33】 有关void运算符的使用方法请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>void运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var a = 1; 07 var b = 2; 08 document.write("a+b = " + (a+b) + "<br>"); 09 document.write("void(a+b) = " + void(a+b) + "<br>"); 10 --> 11 </script> 12 </head> 13 <body> 14 <a href="javascript:void window.open()">打开一个新窗口</a><br> 15 <a href="javascript:window.open()">打开一个新窗口</a> 16 </body> 17 </html>
【代码说明】 在本例中可以看到,变量a加上变量b的结果为3,而void(a+b)的结果是undefined。单从这一步来看,好像并没有执行a+b操作,而事实上JavaScript是执行了a+b操作,只是弃舍了结果。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample33.htm”里的内容,其运行结果如图3.21所示。
图3.21 sample33.htm的运行结果
在本例中的第1个超链接里,使用了“javascript:void window. open()”语句来打开一个新窗口,如果单击该超链接,将会打开一个新窗口,如图3.22所示。
图3.22 单击第1个超链接后的结果
在本例中的第2个超链接里,使用了“javascript:window.open()”语句来打开一个新窗口,如果单击该超链接,也会打开一个新窗口,如图3.23所示。
图3.23 单击第2个超链接后的结果
比较图3.22与图3.23,可以发现,单击两个超链接之后,都会打开一个新窗口,但单击第1个超链接之后,原浏览器窗口中的内容并没有改变,而单击第2个超链接之后,原浏览器窗口中的内容已经改变。这是因为在第1个超链接中,使用了void运算符舍弃了操作数,而在第2个超链接中没有舍弃操作数。
typeof运算符是一个一元运算符,作用于操作数之前,该操作数可以是一个任何类型。typeof运算符可以返回一个字符串,该字符串说明操作数是什么类型。typeof运算符的语法代码如下:
typeof 操作数 typeof(操作数)
【实例3.34】 有关typeof运算符的使用方法请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>typeof运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var x = 12; //数字型 07 var a = "x大于10"; //字符串型 08 var b = true; //布尔型 09 var c = null; //空 10 var now = new Date(); //日期型 11 var arr = ["1",true]; //数组 12 function myalert() //函数 13 { 14 alert("警告"); 15 } 16 17 document.write(typeof x + "<br>"); 18 document.write(typeof a + "<br>"); 19 document.write(typeof(b) + "<br>"); 20 document.write(typeof(c) + "<br>"); 21 document.write(typeof(d) + "<br>"); 22 document.write(typeof(now) + "<br>"); 23 document.write(typeof(arr) + "<br>"); 24 document.write(typeof(myalert) + "<br>"); 25 --> 26 </script> 27 </head> 28 <body> 29 </body> 30 </html>
【代码说明】 在本例中可以看出,typeof运算符返回值的几种情况如下。
■当操作数为数字型时,返回“number”。
■当操作数为字符串型时,返回“string”。
■当操作数为布尔型时,返回“boolean”。
■当操作数为空时,返回“object”。
■当操作数不存在时,返回“undefined”。
■当操作数为日期型时,返回“object”。
■当操作数为数组时,返回“object”。
■当操作数为函数时,返回“function”。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample34.htm”里的内容,其运行结果如图3.24所示。
图3.24 sample34.htm的运行结果
对象属性存取运算符(.)是一个二元运算符,该运算符要求第1个操作数必须是对象或对象实例名,而第2个操作数必须是对象的属性名。对象属性存取运算符的语法代码如下:
对象名.属性名
【实例3.35】 有关对象属性存取运算符的使用方法如下所示,注意加粗的文字。
01 <html> 02 <head> 03 <title>对象属性存取运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个对象实例 07 myObject = new Object(); 08 //设置对象实例的属性 09 myObject = {a: "myObject对象a属性的值", b:"myObject对象b属性的值 10 "}; 11 12 //输出对象属性 13 document.write(myObject.a + "<br>"); 14 document.write(myObject.b + "<br>"); 15 16 //输出一个不存在的对象属性 17 document.write(myObject.d); 18 --> 19 </script> 20 </head> 21 <body> 22 </body> </html>
【代码说明】 在使用对象属性存取运算符时,有以下两点需要注意。
■虽然对象属性存取运算符要求第2个操作数是对象的属性名,但是如果第2个操作数所指定的属性不存在,JavaScript也不会报错,只会返回undefined。
■使用对象属性存取运算符,不但可以存取对象的属性,还可以调用对象的方法。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample35.htm”里的内容,其运行结果如图3.25所示。
图3.25 sample35.htm的运行结果
数组元素存取运算符([])用于存取数组中某个元素的值。在该运算符中,“[]”之前为第1个操作,该操作数必须是数组的名称。在“[”与“]”之间为第2个操作数,该操作数为数组的下标,并且必须是整数型,其取值范围为从0到数组元素个数减1。数组元素存取运算符的语法代码如下:
数组名[下标]
【实例3.36】 有关数组元素存取运算符的使用方法如下所示,注意加粗的文字。
01 <html> 02 <head> 03 <title>数组元素存取运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个数组 07 var arr = ["数组元素一","数组元素二"]; 08 09 //输出数组元素的值 10 document.write(arr[0] + "<br>"); 11 document.write(arr[1] + "<br>"); 12 13 //输出一个不存在的数据元素的值 14 document.write(arr[2]); 15 --> 16 </script> 17 </head> 18 <body> 19 </body> 20 </html>
【代码说明】 代码第7行定义了一个数组,包括两个值。代码第10~14行分别读取数组的值,其中第14行的索引已经超出了数组的边界。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample36.htm”里的内容,其运行结果如图3.26所示。
图3.26 sample36.htm的运行结果
如果数组的下标大于或等于数组元素的个数,JavaScript也不会报错,只会返回undefined。
数组元素存取运算符不但可以用来存取数组元素的值,还可以用来存取对象属性的值,此时要求第1个操作数为对象名称、第2个操作数为对象的属性名称。
【实例3.37】 请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>数组元素存取运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个对象 07 myObject = new Object(); 08 //设置对象的属性 09 myObject = {a:"myObject对象a属性的值" , b:"myObject对象b属性的值 10 "}; 11 12 //输出对象的属性值 13 document.write(myObject["a"] + "<br>"); 14 document.write(myObject["b"] + "<br>"); 15 --> 16 </script> 17 </head> 18 <body> 19 </body> 20 </html>
【代码说明】 代码第9~10行定义了一个数组,这里和以前有区别,在{ }内用“:”来间隔操作对象和对象的属性。代码第13~14行演示了这种读取方式。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample37.htm”里的内容,其运行结果如图3.27所示。
图3.27 sample37.htm的运行结果
delete运算符用于删除变量、对象的属性或数组中的元素。delete运算符返回的是布尔值数据。如果删除操作成功,则返回true,否则返回false。delete运算符的使用语法如下:
delete 对象名 delete 对象名称.属性 delete 数组[索引] delete 变量名
在使用delete运算符时,必须注意以下几点。
■并不是所有属性和变量都可以删除,某些对象的内部核心属性和客户端属性是不能删除的。
■使用var定义的变量、对象、数组是不能删除的。
■删除对象中不存在的属性会返回true。
■删除未定义的变量会返回true。
【实例3.38】 有关delete运算符的使用方法请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>delete运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //定义一个对象 07 myObject = new Object(); 08 //设置对象的属性 09 myObject = {a:"myObject对象a属性的值" , b:"myObject对象b属性的值 10 "}; 11 //定义变量 12 var a = "使用var定义的变量"; 13 b = "没有使用var定义的变量"; 14 //定义一个数组 15 var arr = ["数组元素一","数组元素二"]; 16 17 //输出对象属性 18 document.write(myObject.a + "<br>"); 19 document.write(myObject.b + "<br>"); 20 //删除对象属性 21 delete myObject.b; 22 //输出删除过的对象属性,此时myObject.b属性不存在,输出undefined 23 document.write(myObject.b + "<br>"); 24 //删除对象不存在的对象属性,也会返回true 25 document.write(delete myObject.c + "<br><br>"); 26 27 //删除对象 28 delete myObject; 29 //输出已删除的对象类型,此时myObject对象不存在,输出undefined 30 document.write(typeof(myObject) + "<br><br>"); 31 32 //输出变量a的值 33 document.write(a + "<br>"); 34 //删除变量a,由于变量a是使用var定义的,所以不能删除,返回false 35 document.write(delete a + "<br><br>"); 36 37 //输出变量b的值 38 document.write(b + "<br>"); 39 //删除变量b,由于变量b是没有使用var定义的,所以可以删除,返回true 40 document.write(delete b + "<br>"); 41 //输出已删除的变量b的类型,此时变量b不存在,输出undefined 42 document.write(typeof(b) + "<br><br>"); 43 44 //输出数组元素的值 45 document.write(arr[0] + "<br>"); 46 document.write(arr[1] + "<br>"); 47 //删除数组元素 48 delete arr[0]; 49 //输出数组元素的值,arr[0]被删除了,所以输出undefined 50 document.write(arr[0] + "<br>"); 51 document.write(arr[1] + "<br><br>"); 52 53 //不能删除未定义的变量,因此返回true 54 document.write(delete d); 55 --> 56 </script> 57 </head> 58 <body> 59 </body> 60 </html>
【代码说明】 在本例中的知识点如下。
■代码第7行定义了一个myObject对象,并为myObject对象创建a和b两个属性。使用delete运算符删除myObject.b属性,然后输出myObject.b属性。此时由于myObject.b属性已经删除,所以显示undefined。如图3.28所示中的第3行文字所示。
■使用delete运算符删除myObject对象中并不存在的c属性,但此时仍然返回true。如图3.28所示中第4行文字所示。
■使用delete运算符删除myObject对象,再使用typeof运算符返回myObject对象的类型。由于myObject对象已经删除,所以返回的是undefined。如图3.28所示中第5行文字所示。
■代码第12行使用var定义一个变量a,然后使用delete运算符删除变量a,此时返回false,因为delete运算符不能删除使用var定义的变量。如图3.28所示中的第7行文字。
■代码第13行定义一个变量b,该变量b没有使用var定义,然后使用delete运算符删除变量b,此时返回true。如图3.28所示中的第9行文字所示。
■再用typeof运算符返回变量b的类型,由于变量b已经删除,所以返回undefined。图3.28所示中的第10行文字所示。
■代码第15行定义一个名为arr的数组,该数组中有两个元素。使用delete运算符删除数组中的第1个元素。再输出arr数组中的第1个元素,由于该元素已经删除,所以返回undefined。图3.28所示中的第13行文字所示。
■使用delete运算符删除一个未定义的变量d,返回的还是true。图3.28所示中最后一行文字所示。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample38.htm”里的内容,其运行结果如图3.28所示。
图3.28 sample38.htm的运行结果
逗号运算符是一个二元运算符,其作用只是分隔两个操作数,JavaScript会先计算第1个操作数的值,再计算第2个操作数的值。通常逗号运算符都与for语句联合使用。
【实例3.39】 有关逗号运算符的使用请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>逗号运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 var a = 1; 07 var b = 2; 08 c = a+1, d = a+b; 09 document.write(c + "<br>"); 10 document.write(d + "<br>"); 11 for (i=0,j=1;i<3;i++,j=j+3) 12 { 13 document.write("i = " + i + ";j = " + j + "<br>"); 14 } 15 --> 16 </script> 17 </head> 18 <body> 19 </body> 20 </html>
【代码说明】 代码第8行使用了逗号运算符,其实这完成了两个运算。代码第11行中的for循环中也使用了逗号运算符,这里起到间隔的作用。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample39.htm”里的内容,其运行结果如图3.29所示。
图3.29 sample39.htm的运行结果
有关for语句的使用方法会在后续章节详细介绍。
函数调用运算符(())是一个特殊的运算符,其作用是调用函数。之所以说它特殊,是因为该运算符没有确定数量的操作数,操作数的多少由函数的参数多少来决定。函数调用运算符的语法代码如下:
函数名() 函数名(参数) 函数名(参数1,参数2,…) 对象名.方法名() 对象名.方法名(参数) 对象名.方法名(参数1,参数2,…)
【实例3.40】 有关函数调用运算符的使用方法请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>函数调用运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 //调用document对象的write()方法 07 document.write("输出文字<br>"); 08 09 //定义一个函数 10 function myFun() 11 { 12 alert("弹出警告框"); 13 } 14 //调用函数 15 myFun(); 16 --> 17 </script> 18 </head> 19 <body> 20 </body> 21 </html>
【代码说明】 代码第10~13行创建了一个函数myFun,代码第15行调用这个函数直接用名称+( )的形式即可。
【运行效果】 以上代码为本书配套代码文件目录“代码\第03章\sample40.htm”里的内容,其运行结果如图3.30所示。
图3.30 sample40.htm的运行结果
虽然在很多时候,都称this为运算符,但this更像是一个关键字,因为它不需要操作数。this所代表的是当前对象,其语法代码如下所示:
this[.属性]
【实例3.41】 有关this运算符的使用方法请看以下代码,注意加粗的文字。
01 <html> 02 <head> 03 <title>this运算符</title> 04 <script type="text/javascript"> 05 <!-- 06 function outtext1(obj) 07 { 08 alert(obj.value); 09 } 10 function outtext2(str) 11 { 12 alert(str); 13 } 14 --> 15 </script> 16 </head> 17 <body> 18 <input type="text" value="第一个文本框" onclick="outtext1(this)"> 19 <input type="text" value="第二个文本框" onclick="outtext2(this.value)"> 20 </body> 21 </html>
【代码说明】 在本例中,第18~19行创建了两个文本框,第6~13行表示在单击文本框时,会弹出一个警告窗口。
【运行效果】 以上代码为本书配套代码文件目录“代码\第三章\sample41.htm”里的内容,如图3.31为单击第1个文本框之后的结果。
图3.31 sample41.htm的运行结果
在本例中第1个文本框里使用了“onclick="outtext1(this)"”来调用outtext1函数,该函数中的参数为对象型参数,此时this代表的是第1个文本框对象。在本例中第2个文本框里使用了“onclick= "outtext2(this.value)"”来调用outtext2函数,该函数中的参数为字符串型参数,此时this代表的是第2个文本框对象,而this.value代表的是第2个文本框中的内容。
在一个表达式中,有可能同时出现多个运算符,如以下表达式:
var a = b + c * d /f
在这种表达式中,就涉及运算符的优先级问题。学过数学的人都知道,乘法除法要比加法减法的优先级高,在JavaScript中也一样,优先级高的运算符将被优先执行,优先级低的运算符后被执行,而优先级相同的运算符将从左至右执行。下面将运算符按优先级从高到低列为表3.4,越在前面出现的运算符优先级越高。
表3.4 运算符的优先级
本章主要介绍了JavaScript中的表达式、操作数与运算符。JavaScript中的运算符比较多,可以分为算术运算符、关系运算符、字符串运算符、赋值运算符、逻辑运算符、逐位运算符和其他运算符七大类。在使用JavaScript中的运算符时,要注意不同运算符的优先次序。下一章将会介绍JavaScript中的语句。
1. JavaScript中的字符与字符相连接使用__________运算符。
2. 逗号运算符的作用是什么?
3. +=的意思是__________?
A. 字符串追加连接符
B. 赋值运算符
C. 加法运算符
D. 移位运算符
4. typeof运算符返回的数据类型是__________。
A. 数值型
B. 字符型