JavaScript之表达式和操作符
本文翻译自Mozilla的官方JavaScript教程系列之《Values, variables, and literals》。
原文地址:
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Expressions_and_Operators
这一章主要将讨论JavaScript的表达式和操作符,包括赋值、比较、算术、移位、逻辑、字符串和特殊的运算。
表达式
一个表达式是解决一个值的有效单元。
从概念上来说,表达式包括两种类型:一种是给一个变量赋值,另一种是仅仅表示一个值。比如说,表达式x=7就是一个给x赋值为7的表达式,这种表达式就是表达给自己赋值为7,像这样的表达式一般会用赋值运算符。另一种就是仅仅像这样 3+4 的一个表达式,这个并不表示为一种赋值操作。
JavaScript有以下几种类型的表达式:
- 算术:用一个数字赋值,比如3.14159。(一般使用算术运算)
- 字符串:用一个字符串,比如,"Fred" 或者 "234". (一般使用字符操作)
- 逻辑运算:使用true或者false赋值。(参考逻辑操作)
- 对象:用一个对象赋值。(详见用特殊操作符为对象赋值)
操作符
JavaScript有以下几种操作符。这里主要介绍这些操作符和包含在运算过程里的一些信息。
- 赋值运算
- 比较运算
- 算术运算
- 移位运算
- 逻辑运算
- 字符串运算
- 特殊运算
JavaScript除了有一元和二元运算符,还有一个特殊的三元运算符,也就是条件运算符。二元运算符需要两个操作数,一个在操作符的前面,一个在操作符的后面:
操作数1 操作符 操作数2
比如,3+4 或者 x*y
一个一元操作符需要一个操作数,放在运算符前或者后:
操作符 操作数
或者
操作数 操作符
比如,x++或者++x
赋值运算符
一个赋值运算符用于把运算符右边的值赋给运算符左边的数。
Shorthand operator | Meaning |
---|---|
x += y |
x = x + y |
x -= y |
x = x - y |
x *= y |
x = x * y |
x /= y |
x = x / y |
x %= y |
x = x % y |
x <<= y |
x = x << y |
x >>= y |
x = x >> y |
x >>>= y |
x = x >>> y |
x &= y |
x = x & y |
x ^= y |
x = x ^ y |
x |= y |
x = x | y |
比较运算符
比较运算符是通过比较操作数的结果,会返回一个逻辑结果。这些操作数可以是数字、字符串、逻辑值或者对象的值。字符串是通过标准字典顺序,使用Unicode编码来判定。大多数情况下,如果两个操作数不是同一种类型,JavaScript会尝试先转换类型,然后再比较。(但是有一个唯一的例外就是 ===和 !==,这两个操作符都是严格进行比对,而不做任何的转换)。上面的这些比较最终其实就是转换到数字的比较。下面的表表示了操作符,首先假设下面的代码:
var var1 = 3, var2 = 4;
操作符 | 描述 | 样例(返回true) |
---|---|---|
等于(== ) |
如果操作数相同,返回true | 3 == var1
3 == '3' |
不等于 (!= ) |
如果操作数不同,返回true | var1 != 4 |
绝对相等(=== ) |
如果操作数相同,并且类型也相同,返回true | 3 === var1 |
不绝对相等 (!== ) |
如果操作数不同,并且类型也不同,返回true | var1 !== "3" |
大于(> ) |
如果右边操作数大于左边操作数,返回true | var2 > var1 |
大于等于 (>= ) |
如果右边操作数大于或者等于左边操作数,返回true | var2 >= var1 |
小于 (< ) |
如果右边操作数小于左边操作数,返回true | var1 < var2 |
小于等于 (<= ) |
如果右边操作数小于或者等于左边操作数,返回true | var1 <= var2 |
算术操作符
算术运算符使用数字、文本、或者变量作为其操作符,然后返回一个单一的数值。标准的运算符有加(+)、减(-),乘(*)和除(/)。这些操作符的功能和他们在其他语言上所表现的一样(尤其注意在除法运算中,除数不能为0)。下面是一些例子:
console.log(1 / 2); /* prints 0.5 */ console.log(1 / 2 == 1.0 / 2.0); /* also this is true */
Operator | Description | Example |
---|---|---|
% (模) |
二元操作符。返回两个数相除的整数部分 | 12 % 5 返回2. |
++ (加1) |
一元操作符.如果是用的前置符号(++x ), 首先操作数加1,然后返回操作数; 如果是后置(x++ ), 首先返回这个操作数,然后操作数加1. |
如果x 是 3, 那么++x 将先让赋值x为4,然后返回4 , 相反x++ 返回3 然后再将x设为4. |
-- (减1) |
一元操作符.如果是用的前置符号(--x ), 首先操作数减1,然后返回操作数; 如果是后置(x-- ), 首先返回这个操作数,然后操作数减1. |
如果x 是 3, 那么--x 将先让赋值x为2,然后返回2 , 相反x-- 返回3 然后再将x设为2. |
- (逻辑非) |
一元操作符.返回这个数的相反数。 | 如果x 是3, 那么-x 将返回-3. |
位操作符
位操作符会把他们的操作数都看作32位的二进制数集合(0和1组成),而不是像十进制、十六进制或者八进制。比如十进制的9将会被1001的二进制表示。位操作符会以这些二进制来计算,但是计算后,将返回标准JavaScript的数值。
下面的表概述了位操作符.
操作符 | 用法 | 描述 |
---|---|---|
按位与 | a & b |
当两个数相同位都为1时返回1,否则返回0 |
按位或 | a | b |
当两个数只有有一个为1,就为1 |
按位异或 | a ^ b |
两个操作数对应位不相同时结果的相应位为1 |
按位非 | ~ a |
位非运算符“~”实现对操作数按位取反运算,属于单目运算符. |
左移 | a << b |
左移运算符“<<”实现整体向左移动底位补 0 的功能,属双目运算符 |
有符号右移运算 | a >> b |
右移运算符“>>”实现整体向左移动底位补 0 的功能,属双目运算符,但符号位不变 |
无符号右移运算 | a >>> b |
无符号右移运算符由三个大于号(>>>)表示,它将无符号 32 位数的所有数位整体右移。对于正数,无符号右移运算的结果与有符号右移运算一样。 |
逻辑位运算
从概念上来说,逻辑运算包含的逻辑运算如下:
- 操作数首先会被转化为32位的数被一系列的0或1代替。
- 第一个操作数和第二个操作数的每一位都一一对应,第一个比特和第一个比特对应,第二个和第二个对应。
- 操作数将会对每一对对应的比特进行运算,然后得到新的比特。
比如,9 的二进制表示为 1001, 而15的二进制是 1111. 所以,当位运算运用于这两个数的时候,结果会如下:
表达式 | 结果 | 二进制描述 |
---|---|---|
15 & 9 |
9 |
1111 & 1001 = 1001 |
15 | 9 |
15 |
1111 | 1001 = 1111 |
15 ^ 9 |
6 |
1111 ^ 1001 = 0110 |
~15 |
0 |
~1111 = 0000 |
~9 |
6 |
~1001 = 0110 |
位移操作符
位移操作数需要两个操作数: 第一个数作为被操作数,第二个数指定了第一个数将会被位移的位数. 位移的方向由操作符的方向决定.
位移操作符首先将把他们的操作数转换为32位比特数,然后返回一个和左边操作数一样类型的数.
逻辑运算符
逻辑运算符一般使用逻辑运算值布尔来表示;当使用他们时,他们将返回一个布尔值。但是,像&&和||运算符事实上是返回其中一个指定的操作数,因此说,如果这两个运算符被运用和一些非布尔的值进行运算,他们将会返回一个非布尔的值。下面的表描述了关于逻辑运算符。
操作符 | 用途 | 描述 |
---|---|---|
&& |
|
(逻辑与) 如果expr1能被转化为false,那么返回expr1,否则返回expr2。因此,如果用于布尔值的话,只有当两个操作数都为true的时候,返回ture. |
|| |
expr1 || expr2 |
(逻辑或) 如果expr1能被转化为ture,那么返回expr1,否则返回expr2。因此,如果用于布尔值的话,当操作数中至少有一个为true的时候,返回ture. |
! |
!expr |
(逻辑非) 如果expr能被转化为false,那么将返回true |
下面的例子中,如果表达式是null,0,空字符串或者是undefined,那么将返回false.
下面的例子列举了逻辑运算与:
var a1 = true && true; // t && t returns true var a2 = true && false; // t && f returns false var a3 = false && true; // f && t returns false var a4 = false && (3 == 4); // f && f returns false var a5 = "Cat" && "Dog"; // t && t returns Dog var a6 = false && "Cat"; // f && t returns false var a7 = "Cat" && false; // t && f returns false
下面的例子列举了逻辑运算或:
var o1 = true || true; // t || t returns true var o2 = false || true; // f || t returns true var o3 = true || false; // t || f returns true var o4 = false || (3 == 4); // f || f returns false var o5 = "Cat" || "Dog"; // t || t returns Cat var o6 = false || "Cat"; // f || t returns Cat var o7 = "Cat" || false; // t || f returns Cat
下面的例子列举了逻辑运算非:
var n1 = !true; // !t returns false var n2 = !false; // !f returns true var n3 = !"Cat"; // !t returns false
字符串操作符
和用于字符串比较运算符相比,连接操作符(+)用于把两个字符串连结起来,然后返回另一个由两个操作数字符串结合的字符串。比如,"my " + "string"
返回字符串"my string"。
一个快捷的操作符+=也可以用于连结字符串。
比如,如果一个变量mystring
的值为"alpha",那么表达式mystring += "bet"
将会把 "alphabet" 赋值给mystring。
特殊操作符
JavaScript 提供了一下特殊操作符:
条件运算符
条件运算符是JavaScript里唯一的一个采用三个操作数的运算符。这个操作符用于根据一个条件来得到两个值中的其中一个。语法如下:
condition ? val1 : val2
如果condition
为真,,将得到val1的值,否则取val2的值。
比如
var status = (age >= 18) ? "adult" : "minor";
This statement assigns the value "adult" to the variable status
if age
is eighteen or more. Otherwise, it assigns the value "minor" to status
.
这个表达式表示了如果年龄大于或者等于18,把status赋值为adult,否则minor。
逗号操作符
这种操作符主要在for循环中使用,在循环过程中,允许每次循环可以一次更新多个变量
比如,如果a是一个包含10元素的二维数组,下面的代码展示了如何用逗号操作符同时增加两变量值:
for (var i = 0, j = 9; i <= 9; i++, j--) document.writeln("a[" + i + "][" + j + "]= " + a[i][j]);
delete
delete 操作符用于删除一个对象,对象的属性或者在一个数组中指定了下标的元素。语法如下:
delete objectName; delete objectName.property; delete objectName[index]; delete property; // 只可用于一个with的表达式中
在这上面的例子中,objectName是一个元素的名字,
property是一个存在的属性,index是一个代表一个数组的下标。
第四行只用于在一个with的表达式中,用于去删除一个对象中的属性。
你可以使用 delete 操作符去删除那些隐式声明的变量,也就就是那些声明时没有使用var的变量(翻译补充:其实那些没有使用var声明的严格意义上来说并不是变量,而会成为全局对象globle的一个属性)。
如果 delete 操作符操作成功,那么它将把这个属性或者这个元素设置为 undefined.。除此外,如果delete 能操作,那么会返回true,反之,false。
x = 42; var y = 43; myobj = new Number(); myobj.h = 4; // 创建属性h delete x; // 返回true,(因为是隐式声明的) delete y; // 返回false,不能删除使用var申明的变量 delete Math.PI; // 返回false,不能删除预定义属性 delete myobj.h; // 返回true,可以删除自定义属性 delete myobj; // 返回true,可以删除隐式申明的对象
删除数组元素
当你删除了一个数组里的元素时,这个数组的长度是不会受影响的。比如,如果你删除了a[3],那么a[4]还仍然是a[4],而此时,a[3]是undefined。
当使用delete操作符移除一个数组元素时,这个元素将不存在与这个数组中。在下面的例子中,trees[3]是使用delete来移除的。然而,trees[3]仍然可访问并且返回undefied。
var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); delete trees[3]; if (3 in trees) { // 这里将不执行 }
如果你想要一个元素继续存在数组中,并且值是undefined,使用undefined关键字来代替delete是个更好的选择。在下面的例子中,trees[3]被赋值undefied,三十这个元素仍然存在:
var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); trees[3] = undefined; if (3 in trees) { // 这里可执行 }
in
The in
operator returns true if the specified property is in the specified object. The syntax is:
如果指定的属性存在于指定的对象中,in 操作飞将会返回true。语法如下:
propNameOrNumber in objectName
在这里,propNameOrNumber 是一个字符串或者是数字用于代表属性名或者数组下标,而objectName是这个对象的名字。
下面的例子展示了in操作符的一些用法:
// 数组 var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); 0 in trees; // returns true 3 in trees; // returns true 6 in trees; // returns false "bay" in trees; // returns false (你必须指定下标,而不是该下标代表的元素值) "length" in trees; // returns true (length 是数组的一个属性) // 预定义对象 "PI" in Math; // returns true var myString = new String("coral"); "length" in myString; // returns true // 自定义对象 var mycar = {make: "Honda", model: "Accord", year: 1998}; "make" in mycar; // returns true "model" in mycar; // returns true
instanceof
如果指定的对象是指定的对象类型,那么使用instanceof操作符会返回true。语法如下:
objectName instanceof objectType
where objectName
is the name of the object to compare to objectType
, and objectType
is an object type, such as Date
or Array
.
在这里objectName是要比较对象类型的对象名,而objectType则是表示对象类型,比如Date或者Array。
当你需要在运行时的时候确认一个元素的类型时,instanceof将会派上用场。比如,当捕获异常是,你可以根据抛出异常的类型来确认可能出现该异常的代码段。
在下面的代码中,就使用instanceof来判定theDay是不是一个date对象。因为theDay是一个date对象,所以能进入if执行语句。
var theDay = new Date(1995, 12, 17); if (theDay instanceof Date) { // statements to execute }
this
使用this关键字用于引用当前的对象。一般来说,在一个方法中,this用于引用正在调用该方法的对象。使用this可以像下面这样:
this["propertyName"]
this.propertyName
样例 1.
假设有一个方法叫 validate用于去验证一个对象的value属性,传入的参数是当前对象,最大值,和最小值:
1
2
3
4
|
function validate(obj, lowval, hival){ if ((obj.value < lowval) || (obj.value > hival)) alert( "Invalid Value!" ); } |
你可以在每个form元素的onChange事件中调用validade方法,传入的参数时,就可以使用this来引用到当前的这个form元素,如下:
1
2
3
|
< B >Enter a number between 18 and 99:</ B > < INPUT TYPE = "text" NAME = "age" SIZE = 3 onChange = "validate(this, 18, 99);" > |
样例 2.
结合form属性,this甚至可以引用到当前对象的上一级form对象。在下面的例子中,表单myForm包含了一个Text对象和一个按钮。当用户点击按钮时,这个Text对象的值被设置为这个表单的名字。按钮的onClick事件用于捕捉通过使用this.form去引用父元素form:
1
2
3
4
5
6
|
< FORM NAME = "myForm" > Form name:< INPUT TYPE = "text" NAME = "text1" VALUE = "Beluga" > < P > < INPUT NAME = "button1" TYPE = "button" VALUE = "Show Form Name" onClick = "this.form.text1.value = this.form.name;" > </ FORM > |
typeof
typeof操作符有以下两种使用方法:
-
1
typeof
operand
-
1
typeof
(operand)
typeof操作符会返回一个用于表明操作数类型的字符串。该操作数可以是字符串,变量,关键字,或者对象。这里的括号是可选的。
假设你已定义了以下变量:
1
2
3
4
|
var myFun = new Function( "5 + 2" ); var shape = "round" ; var size = 1; var today = new Date(); |
那么对于这些变量,typeof操作符将会返回以下结果:
1
2
3
4
5
|
typeof myFun; // returns "function" typeof shape; // returns "string" typeof size; // returns "number" typeof today; // returns "object" typeof dontExist; // returns "undefined" |
对于关键字true和null,typeof会返回下面的结果:
1
2
|
typeof true ; // returns "boolean" typeof null ; // returns "object" |
对于数字或者字符串,typeof会返回下面的结果:
1
2
|
typeof 62; // returns "number" typeof 'Hello world' ; // returns "string" |
对于那些属性值,typeof会返回这个属性包含值的类型:
1
2
3
|
typeof document.lastModified; // returns "string" typeof window.length; // returns "number" typeof Math.LN2; // returns "number" |
对于方法,typeof会返回下面的结果:
1
2
3
4
|
typeof blur; // returns "function" typeof eval; // returns "function" typeof parseInt; // returns "function" typeof shape.split; // returns "function" |
对于预定义对象,typeof会返回以下结果:
1
2
3
4
5
|
typeof Date; // returns "function" typeof Function; // returns "function" typeof Math; // returns "object" typeof Option; // returns "function" typeof String; // returns "function" |
void
void操作符有以下两种使用方式:
-
1
void (expression)
-
1
void expression
void操作符用于指定一段可执行的表达式将不会返回值。包含表达式的括号是可以选的,但是一个好的习惯就是加上他吧。
You can use the void
operator to specify an expression as a hypertext link. The expression is evaluated but is not loaded in place of the current document.
你可以使用void操作符去指定一个表达式作为其超链接。
下面的代码用于创建一个当用户点击时不会有任何反应的超链接。当用户点击连接时,void(0)被认为是undefined,而这个在javascript中是没有任何影响的:
1
|
< A HREF = "javascript:void(0)" >Click here to do nothing</ A > |
下面的代码用户当用户点击超链接时,提交当前form数据:
1
2
|
< A HREF = "javascript:void(document.form.submit())" > Click here to submit</ A > |
操作数优先级
操作符的优先级决定了当在执行一段表达式时各种操作符之间的有线关系。你可以通过使用括弧来改变其属性。
下面的表格从高到底,依次展示了他们的有线关系。
操作符类型 | 典型操作符 |
---|---|
成员 | . [] |
调用或创建实例 | () new |
逻辑非或递增减 | ! ~ - + ++ -- typeof void delete |
乘或除 | * / % |
加或减 | + - |
位移 | << >> >>> |
关系 | < <= > >= in instanceof |
等于 | == != === !== |
按位与 | & |
按位或 | ^ |
按位非 | | |
逻辑与 | && |
逻辑或 | || |
条件表达式 | ?: |
赋值 | = += -= *= /= %= <<= >>= >>>= &= ^= |= |
逗号 | , |
关于这个表格的各种操作符的更多信息可以在这里找到:JavaScript Reference.