Javascript表达式和运算符

JavaScript 2015年04月03日

javascript

4 表达式和运算符

表达式(Expression)是JavaScript中的一个短语,JavaScript解释器将其计算(Evaluate)出一个结果。简单的表达式可以组成复杂表达式。

4.1 原始表达式

最简单的表达式是原始表达式(Primary Expression)。原始表达式是表达式的最小单位。JavaScript中的原始表达式包含常量或者直接量、关键字、变量。如:

1.23            // literal
true            // reserved word
i               // variable
undefined       // variable

4.2 对象和数组的初始化表达式

对象和数组的初始化表达式实际上是一个新创建的对象和数组。有时称为对象直接量或者数组直接量。但它们不是原始表达式,它们所含的成员或者元素都是子表达式。

数组初始化表达式是通过一对方括号和其内由逗号隔开的列表构成,其内的元素也可以是数组。如:

[]              // empty array
[1, 2]          // 2-elements array
[[1, 2], [2, 3]]

JavaScript对数组初始化表达式进行求值时,其元素的初始化表达式会先进行求值。数组直接量中的列表逗号之间的元素可以省略,省略的空值会填充为undefined。元素结尾的单个逗号不会再数组最后添加undefined值。如:

var a = [1,,2,];        // [1, undefined, 2] length is 3
var b = [1,2,,];        // [1, 2, undefined] length is 3

对象初始化表达式和数组初始化表达式非常类似,只是方括号被花括号代替,且每个子表达式都包含一个属性名和一个冒号作为前缀。如:

var p = ( x: 2.3, y:-1.2};
var q = { };
q.x = 2.3; q.y = -1.2;      // q has the same properties as p

4.3 函数定义表达式

函数定义表达式定义一个JavaScript函数。表达式的值是这个新定义的函数。也称为函数直接量。函数的典型定义方式包含关键字function,跟随其后的是一对圆括号,括号内是一个以逗号分割的列表,列表含有0个或者多个标识符(参数名),然后再跟随一个由花括号包裹的JavaScript代码段(函数体),如:

var square = function(x) { return x * x; }

4.4 属性访问表达式

属性访问表达式运算得到一个对象属性或者一个数组元素的值。在JavaScript中有两种方法来访问属性:

    expression.identifier
    expression[expression]

第一种写法表达式指定对象,标识符则指定需要访问的属性的名称。第二种写法方括号内的表达式指定要访问的属性的名称或者代表要访问数组元素的索引。如:

var o = {x: 1, y: {z: 3}};
var a = [o, 4, [5, 6]];
o.x                         // 1
o.y.z                       // 3
o['x']                      // 1
a[1]                        // 4
a[2]["1"]                   // 6
a[o].x                      // 1

在.和[之前的表达式总是会首先计算。如果结果是null或者undefined,表达式将抛出一个类型错误异常,因为这两个属性不能包含任意属性。如果结果不是对象,则JavaScript会将其转换为对象。如果对象表达式之后跟随句点和标识符,则会查找由这个标识符所指定的属性的值,并将其作为整个表达式的值返回。如果对象表达式后跟随一对方括号,则会计算方括号的表达式的值并将它转换为字符串。如果命名的属性不存在,那么整个属性访问表达式的值就是undefined。

4.5 调用表达式

JavaScript中调用表达式(Invocation expression)是一种调用(或者执行)函数或者方法的语法表示。它以一个函数表达式开始,这个函数表达式指定了要调用的函数。函数表达式后跟随一对圆括号,括号内是一个以逗号隔开的参数列表,参数可以有0个也可以有多个。如:

f(0);
Math.max(x, y, z);
a.sort()

当对调用表达式进行求值时,首先计算函数表达式,然后计算参数表达式。如果函数表达式的值不是一个可调用的对象,则抛出一个类型错误异常。然后,实参的值被依次赋值给形参,这些形参是定义函数时指定的,接下来开始执行函数体,如果函数使用return语句给出一个返回值,那么这个值就是整个调用表达式的值。否则,调用表达式的值就是undefined。

任何一个调用表达式都包含一对圆括号和左圆括号之前的表达式。如果这个表达式是一个属性访问表达式,那么这个调用称作方法调用(Method Invocation)。方法调用中使用this指向当前对象(该方法所属对象)。如果不是方法调用,this的值为undefined。

4.6 对象创建表达式

对象创建表达式(Object Creation Expression)创建一个对象并调用一个函数(构造函数)初始化新对象的属性。语法如下:

new Object();
new Object;
new Object(1, 2);

如果一个对象创建表达式不需要传入任何参数给构造函数,则括号可以省略。当计算一个对象创建表达式的值时,和对象初始化表达式通过{}创建对象的做法一样,JavaScript首先创建一个新的空对象,然后,JavaScript通过传入指定的参数并将这个新对象当做this的值来调用指定的函数。

4.7 运算符概述

JavaScript中的运算符用于算术表达式、比较表达式、逻辑表达式、赋值表达式等。如下按照运算符的优先级列出JavaScript中的运算符。

运算符 操作 A N 类型
++
--
-
+
~
!
delete
typeof
void
前/后增量
前/后减量
求反
转换为数字
按位求反
逻辑非
删除属性
检测操作数类型
返回undefined值
R
R
R
R
R
R
R
R
R
1
1
1
1
1
1
1
1
1
lval->num
lval->num
num->num
num->num
int->int
bool->bool
lval->lval
any->str
any->undef
* / % 乘 除 求余 L 2 num,num->num
+ -
+
加 减
字符串连接
L
L
2
2
num,num->num
str,str->str
<<
>>
>>>
左移位
有符号右移位
无符号右移位
L
L
L
2
2
2
int,int-int
int,int->int
int,int->int
< <= > >=
< <= > >=
instanceof
in
比较数字顺序
比较在字母表中的顺序
测试对象类
测试属性是否存在
L
L
L
L
2
2
2
2
num,num->bool
str,str->bool
obj,func->bool
str,obj->bool
==
!=
===
!==
判断相等
判断不等
判断恒等
判断非恒等
L
L
L
L
2
2
2
2
any,any->bool
any,any->bool
any,any->bool
any,any->bool
& 按位与 L 2 int,int->int
^ 按位异或 L 2 int,int->int
| 按位或 L 2 int,int->int
&& 逻辑与 L 2 any,any-any
|| 逻辑或 L 2 any,any-any
?: 条件运算符 R 3 bool,any,any->any
=
*= /= %= += -= &= ^= |= <<= >>= >>>=
赋值
运算并赋值
R
R
2
2
lval,any->any
lval,any->any
, 逗号 L 2 any,any->any

表中:

  • 越靠前优先级越高
  • A列表示结合性,L表示从左向右,R表示从右向左
  • N列表示操作数的个数
  • 类型列,->前表示操作数的类型,->后表示操作结果类型
  • lval(left value)表示左值

4.7.1 操作数的个数

运算符根据需要的操作数的数量可分为三类:

  • 一元操作符(Unary Operator)
  • 二元操作符(Binary Operator)
  • 三元操作符(Ternary Operator)

4.7.2 操作数类型和结果类型

一些运算符可以作用任何数据类型,介仍然希望它们的操作数是指定类型的数据,并且大多数运算符返回(或计算出)一个特定类型的值。JavaScript运算符通常会根据需要对操作数进行类型转换。

4.7.3 左值

左值(lvalue)指表达式只能出现在赋值运算符的左侧。在JavaScript中,变量、对象属性、数组元素都是左值。ECMAScript规范允许内置函数返回一个左值,但自定义函数则不能返回左值。

4.7.4 运算符的副作用

运算符的副作用是指执行完表达式后会对操作数进行修改。如++和--运算符会改变操作数的值。delete删除一个属性像给这个属性赋值undefined。

4.7.5 运算符的优先级

运算符的优先级控制着运算符的执行顺序。优先级高的运算符先执行,优先级低的运算符后执行。如:

var w = 1 + 2 * 3;      // 7

由于*的优先级高于+,所以先计算乘法,再计算加法。如果不确定运算符的优先级,可以使用圆括号重写,始终会先计算括号里面的表达式。

4.7.6 运算符的结合性

运算符的结合性指定了在多个具有相同优先级的运算符表达式中运算顺序。如:

var w = 6 - 2 + 1;      // 5

由于-和+具有相同的优先级,二者还都是左结合,所以从左向右计算。

4.7.7 运算顺序

运算符的优先级和结合性规定了它们在复杂表达式中的运算顺序,但并没有规定子表达式的计算过程中的顺序。JavaScript总是严格按照从左到右的顺序来计算表达式的值。

只有在任何一个表达式具有副作用而影响到其他表达式的时候,其求值顺序才会和看上去有所不同。如:

var a = 1;
var b = a++ + a;        // b = 3;

虽然不提倡写出上述的代码,但是还是在明白表达式的求值的顺序。

4.8 算术表达式

4.8.1 "+"运算符

二元运算符"+"可以对两个数字做加法,也可以做字符串连接操作:

1 + 2               // 3
"hello" + " world"  // "hello world"
"1" + "2"           // "12"

当两个操作数都是数字或者字符串时,计算结果是显而易见的。对于其他情况需要进行类型转换,加号首先考虑字符串连接,如果其中一个操作数是字符串或者转换为字符串的对象,另一个操作数也会转换为字符串,加号将进行字符串的连接。如果两个操作数都不是字符串的,那么将进行算术加法运算。具体如下:

  • 如果其中一个操作数是对象,则对象会遵循对象到原始值的转换规则转换为原始值:日期对象通过toString()方法执行转换,其他对象通过valueOf()方法执行转换。由于多数对象都不具备可用的valueOf()方法。因此它们会通过toString()方法执行转换。
  • 在进行了对象到原始值的转换后,如果其中一个操作数是字符串的话,另一个操作数也会转换为字符串,然后进行字符串连接。
  • 否则,两个操作数都将转换为数字,或者NaN,然后进行加法操作。
1 + 2           // 3
"1" + "2"       // "12"
"1" + 2         // "12"
1 + {}          // "1[object Object]"
true + true     // 2
1 + null        // 1
1 + undefined   // NaN

1 + 2 + " furzoom"  // "3 furzoom"
1 + (2 + " furzoom")// "12 furzoom"

注意结合性的影响。

4.8.2 一元算术运算符

一元运算符用于一个单独的操作数,并产生一个新值。在JavaScript中,一元运算符具有很高的优先级,而且都是右结合(Right-associative)。

4.8.2.1 一元加法(+)

一元加法运算符把操作数转换为数字(或者NaN),并返回这个转换后的数字,如果操作数本身就是数字,则直接返回这个数字。

4.8.2.2 一元减法(-)

一元减法运算符把操作数转换为数字(或者NaN),然后改变运算结果的符号。

4.8.2.3 递增(++)

递增++运算符对其操作数进行增量操作,操作数必须是左值(变量、数组元素或者对象属性)。如果递增运算符的操作数不是数字,则尝试将其转换为数字,然后给数字加1,并将结果赋值给操作数。递增运算符根据它与操作数的位置关系分为前增量和后增量,具体区别如下:

var i = 1; j = ++i;     // j = 2; i = 2;
var i = 1; j = i++;     // j = 1; i = 2;

var i = "1";
i++;                    // i = 2

4.8.2.4 递减(--)

递减--运算符对其操作数进行减1运算。其余与递增运算符类似。

4.8.3 位运算符

位运算符可以对由数字表示的二进制数据进行更低层级的按位运算。这些运算符在JavaScript编程中并不常用。位运算符要求它的操作数是整数,且为32位整型。位运算符会将NaN、Infinity和-Infinity都转换为0。

4.8.3.1 按位与(&)

位运算符&对它的整型操作数逐位执行布尔与(AND)操作。如:

var a = 0x1234 & 0x00FF;    // 0x0034

4.8.3.2 按位或(|)

位运算符|对它的整型操作数逐位执行布尔或(OR)操作。如:

var a = 0x1234 | 0x00FF;    // 0x12FF

4.8.3.3 按位异或(^)

位运算符^对它的整型操作数逐位执行布尔异或(XOR)操作。如:

var a = 0x1234 ^ 0x00FF;    // 0x12CB

4.8.3.4 按位非(~)

位运算符~对它的整型操作数逐位执行布尔非(NOT)操作。如:

var a = ~0x00FF;            // 0xFFFFFF00

4.8.3.5 左移(<<)

位运算符<<对它的第一个整型操作数的每一位进制左移操作,左侧溢出的位丢弃,用0填补在右边的位。左移一位相当于乘2,如:

 var a = 7 << 2;             // 28 

4.8.3.6 带符号右移(>>)

位运算符>>对它的第一个整型操作数的每一位进制右移操作,右侧溢出的位丢弃,填补在左边的位由原操作数的符号位决定。左移一位相当于除以2,如:

var a = 7 >> 2;             // 1
var a = -7 >> 2;            // -2

4.8.3.7 无符号右移(>>>)

位运算符>>>对它的第一个整型操作数的每一位进制右移操作,右侧溢出的位丢弃,用0填补在左边的位。左移一位相当于除以2,如:

var a = 7 >>> 2;            // 1
var a = -7 >>> 2;           // 1073741822 3ffffffe

4.9 关系表达式

在JavaScript中关系运算符用于测试两个值之间的关系。得到结果为true或false。常用在条件语句和循环语句中。

4.9.1 相等和不相等运算符

==和===运算符用于比较两个值是否相等。两者允许任意类型的操作数,如果操作数相等则返回true,否则返回false。==允许操作数作类型转换,===不允许操作数作类型转换。

!=和!==运算符的检测规则与==和===运算符的求反。

前面介绍过对于对象的比较是引用的比较,而不是值的比较。对象只和其本身是相等的。

严格相等运算符===首先计算操作数的值,然后比较两个值,比较过程中没有任何类型转换:

  • 如果两个值类型不相同,则它们不相等。
  • 如果两个值都是null或者都是undefined,则它们不相等。
  • 如果两个值都是布尔值true或者都是布尔值false,则它们相等。
  • 如果其中一个值是NaN,或者两个都都是NaN,则它们不相等。NaN和其他任何值都不相等。当x为NaN时,x!==x结果为true。
  • 如果两个值为数字且数值相等,则它们相等。如果一个值为0,另一个值为-0,则它们同样相等。
  • 如果两个值为字符中,且所含的对应位上的16位数完全相等,则它们相等。如果它们的长度或者内容不同,则它们不相等。两个字符串可能含义完全一样且所显示出的字符也一样,但具有不同的编码的16位值,通过===和==测试结果都为false。
  • 如果两个引用值指向同一个对象、数组或者函数,则它们是相等的。否则不相等。

相等运算符==,如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较:

  • 如果两个操作数的类型相同,则和上文的严格相等的比较规则一样。如果不严格相等,那么比较结果为相等。如果它们不严格相等,则比较结果为不相等。
  • 如果两个操作数类型不同,==相等操作符也可能会认为它们相等,检测相等将会遵守如下规则和类型转换:
    • 如果一个值为null,另一个是undefined,则它们相等。
    • 如果一个值是数字,另一个是字符串,先将字符串转换为数字,然后使用转换后的值进行比较。
    • 如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,将其转换为0再进行比较。
    • 如果一个值是对象,另一个值是数字或字符串,则使用3.8.3提到的转换规则将对象转换为原始值,然后再进行比较。对象通过toString()方法或者valueOf()方法转换为原始值。
    • 其他不同类型之间的比较均不相等。
'1' == true;        // true

4.9.2 比较运算符

比较运算符用来检测两个操作数的大小关系(数值大小或者字母表的顺序):

  • 小于(<)
    • 如果第一个操作数小于第二个操作数,则<运算符的计算结果为true,否则为false。
  • 大于(>)
    • 如果第一个操作数大于第二个操作数,则>运算符的计算结果为true,否则为false。
  • 小于等于(<=)
    • 如果第一个操作数小于等于第二个操作数,则<=运算符的计算结果为true,否则为false。
  • 大于(>=)
    • 如果第一个操作数大于等于第二个操作数,则>=运算符的计算结果为true,否则为false。

比较操作符的操作数可能是做生意类型。然而,只有数字和字符串才能真正执行比较操作,因此其他类型的操作数都要进行类型转换,类型转换规则如下:

  • 如果操作数为对象,那么这个对象将依照3.8.3描述的转换规则转换为原始值:如果valueOf()返回一个原始值,那么直接使用这上原始值,否则,使用toString()的转换结果进行比较操作。
  • 在对象转换为原始值之后,如果两个操作数都是字符串,那么将依照字母表的顺序对两个字符串进行比较,这里提到的字母表顺序是指组成这个字符串的16位Unicode字符的索引顺序。
  • 在对象转换为原始值之后,如果至少有一个操作数不是字符串,那么两个操作数将转换为数字进行数值比较。0和-0是相等的。Infinity比其他任何数字都大(除了Infinity本身),-Infinity比其他任何数字都小(除了它自身)。如果其中一个操作数是NaN,那么比较操作符问题返回false。

4.9.3 in运算符

in运算符希望它的左操作数是一个字符串或者可以转换为字符串的类型,希望它的右操作数是一个对象。如果右操作数的对象拥有一个名为左操作数值的属性名,那么表达式返回true,如:

var point = {x:1, y:1};
"x" in point;           // true
"z" in point;           // false
"toString" in point;    // true

var data = [7, 8, 9];
"0" in data;            // true
"1" in data;            // true
"3" in data;            // false

4.9.4 instanceof操作符

instanceof运算符希望左操作数是一个对象,右操作数是标识对象的类。如果左侧的对象是右侧类的实例,则表达式返回true。否则返回false。JavaScript中对象是通过初始化它们的构造函数来定义的。instanceof的右操作数应当是一个函数。如:

var d = new Date();
d instanceof Date;
d instanceof Object;
d instanceof Number;

var a = [1, 2, 3];
a instanceof Array;
a instanceof Object;
a instanceof RegExp;

所有对象都是Object的实例。如果左操作数不是对象的话,instanceof返回false,如果右操作数是不是函数,则抛出一个类型错误异常。

4.10 逻辑表达式

逻辑运算符&&、||、!是对操作数进行布尔算术运算,经常和关系运算符一直配合使用,逻辑运算符将多个关系表达式组合起来组成一个更复杂的表达式。

4.10.1 逻辑与(&&)

&&运算符可以从三个不同的层次进行理解。第一个层次就是,当操作数都是布尔值时,&&对两个值执行布尔与(AND)操作,只有在第一操作数和第二个操作数都是true的时候,它才返回true。否则返回false。

&&的操作数并不一定是布尔值,假值有false、null、undefined、0、-0、NaN、"",其他值都是真值。第二层次的理解是,&&可以对真值和假值进行布尔与操作。如果两个操作数都是真值,那返回一个真值,否则返回一个假值。

真值和假值到底是什么值,就是第三个层次的理解。运算符首先计算左操作数的值,如果结果为假值,那么整个表达式的结果为假值,因此&&返回左操作数的值,并不会对右操作数进行计算。如果左操作数的计算结果是真值,则计算右操作数的值,并返回右操作数的值。

&&的这种行为被称作短路(Short Circuiting)。有时会乃至这种技巧。如下两行代码是等价的:

if (a == b) stop();
(a == b) && stop();

4.10.2 逻辑或(||)

||运算符对两个操作数做布尔或(OR)运算。如果其中一个或者两个操作数是真值,它返回一个真值,否则,返回假值。

||与&&的行为类似。一般情况下只是做简单的布尔或(OR)运算。也会首先计算第一个操作数的值,如果为真值,那么返回这个值。否则,再计算第二个操作数的值,并返回其值。

4.10.3 逻辑非(!)

!运算符是一元运算符,它将操作数的布尔值求反。它只返回false或者true。它会将操作数转换为布尔值,再将其求反。

4.11 赋值表达式

JavaScript使用=运算符来给变量或者属性赋值。如:

i = 0;
o.x = 1;

=运算符希望它的左操作数是一个左值:一个变量或者对象属性。它的右操作数可以是任意类型的任意值。赋值表达式的值就是右操作数的值。赋值表达式的副作用是,右操作数的赋值给左侧的变量或者对象属性。

带操作的赋值运算

除了常规的赋值运算=之外,JavaScript还支持许多其他的赋值运算符,这些运算符将赋值运算符连接起来,提供一种更为快捷的运算方式。如:

total += sales_tax;
total = total + sales_tax;

上述两行代码是等价的。这一类的运算符有如下:

运算符 示例 等价于
+= a += b a = a + b
-= a -= b a = a - b
*= a *= b a = a * b
/= a /= b a = a / b
%= a %= b a = a % b
<<= a <<= b a = a << b
>>= a >>= b a = a >> b
>>>= a >>>= b a = a >>> b
&= a &= b a = a & b
|= a |= b a = a | b
^= a ^= b a = a ^ b

4.12 表达式计算

JavaScript可以解释运行由JavaScript源代码组成的字符串,并产生一个值。JavaScript通过全局函数eval()来完成这个工作:

eval("2 + 3");      // 5

动态执行源代码中的字符串是一种强大的语言特性,几乎没有必要在实际中应用。

4.12.1 eval()

eval()只有一个参数。如果传入的参数不是字符串,它直接返回这个参数。如果参数是字符串,它会把字符串当成JavaScript代码进行编译(parse),如果编译失败则抛出一个语法错误异常。如果编译成功,则执行这段代码,并返回字符串中最后一个表达式或语句的值。如果最后一个表达式或语句没有返回值,则返回undefined。

关于eval()最重要的是,它使用了调用它的变量作用域环境。使用eval()时需要注意作用域的影响。

4.12.2 全局eval()

eval()具有改变局部变量的能力。如果脚本定义了eval()的一个别名,且用另一个名称调用它,eval()会将其字符串当成顶层的全局代码来执行。如:

var geval = eval;
var x = "global", y = "global";
function f() {
    var x = "local";
    eval("x += 'changed';");
    return x;
}
function g() {
    var y = "local";
    geval("y += 'changed';");
    return y;
}
console.log(f(), x);    // localchanged global
console.log(g(), y);    // local globalchanged

4.12.3 严格eval()

ECMAScript 5严格模式对eval()函数的行为有更多的限制,在严格模式下,eval()是私有上下文环境中的局部eval。也就是说,在严格模式下,eval执行的代码段可以查询或更改局部变更,但不能在局部作用域中定义新的变量和函数。

严格模式将eval列为保留字,不能用别名覆盖eval()函数。

4.13 其他运算符

4.13.1 条件运算符(?:)

条件运算符是JavaScript中唯一的一个三元运算符。条件运算符的操作数可以是任意类型的。第一个操作数当成布尔值,如果它是真值,那么将计算第二个操作数,并返回其计算结果。否则,如果第一个操作数是假值,那么将计算第三个操作数,并返回其计算结果。if语句可以带来同样的效果,如下两段代码是等价的:

greeting = "hello " + (username ? username : "there");
greeting = "hello ";
if (username)
    greeting += username;
else
    greeting += "there";

4.13.2 typeof运算符

typeof是一元运算符,放在其单个操作数的前面,操作数可以是任意类型。返回值为表示操作数类型的一个字符串。如下表:

x typeof x
undefined "undefined"
null "object"
true "boolean"
false "boolean"
任意数字或NaN "number"
任意字符串 "string"
任意函数 "function"
任意内置对象 "object"
任意宿主对象 由编译器各自实现的字符串

typeof最常用的用法是写在表达式中,如:

(typeof value == "string") ? "'" + value + "'" : value

typeof运算符可以带上圆括号,如:

typeof(f)

当操作数是null的时候,typeof将返回"object"。对于宿主对象来说,typeof有可能并不返回"object",而返回其他字符串。但一般情况下,客户端宿主都返回"object"。

由于对象和数组的typeof运算符结果是"object"而不是"function",因此它对于区分对象和其他原始值来说是十分有帮助的。如果想区分对象的类,则需要使用其他的手段,如instanceof运算符等。

4.13.3 delete运算符

delete是一元运算符,它用来删除对象属性或者数组元素。如:

var o = { x: 1, y: 2};
delete o.x;
"x" in o;               // false

var a = [5, 6, 7];
2 in a;                 // true
delete a[2];
2 in a;                 // false
a.length;               // 3 [5, 6, undefined]

删除属性或者删除数组元素不仅仅是设置了一个undefined的值,当删除一个属性时,这个属性将一再存在。读取一个不存在的属性将返回undefined,但可以通过in运算符来检测这个属性是否在对象中存在。

delete希望它的操作数是一个左值,如果它不是左值,那么delete将不进行任何操作,同时返回true。否则,delete将试图删除这个指定的左值。如果删除成功,delete将返回true。然而并不是所有属性都可以删除,一些内置核心的客户端属性是不能删除的,用户通过var语句声明的变量不能删除。同样,通过function语句定义的函数和函数参数也不能删除。如:

var o = {x: 1, y: 2};
delete o.x;
typeof o.x;             // "undefined"
delete o.x;             // true
delete o;               // false

delete 1;               // true
this.x = 1;
delete x;               // true

x;                      // x is not defined

4.13.4 void运算符

void是一元运算符,它出现在操作数之前,操作数可以是做任意类型。操作数会照常计算,但忽略计算结果并返回undefined。在操作数具有副作用时使用void来让程序更具有语义。

4.13.5 逗号运算符(,)

逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数,最后返回右操作数的值,如:

a = 1, b = 2;       // 表达式结果为2

Author website: furzoom

如无特别说明,本站文章皆为原创,若要转载,务必请注明以下原文信息:
日志标题:《Javascript表达式和运算符》
日志链接:http://furzoom.com/4_expressions_and_operators/
博客名称:枫竹梦

1 篇回应 (访客:1 篇, 博主:0 篇)

  1. Lovie 2016-24-10

    ada bukti nyata ke pdo? Penah lihat sendiri dengan mata kepala pdo? Kenyataan dengan mendengar tak sama dengan melihat senr.dii.. jgn sampai jatuh fitnah …neraka jahanam yg akan menunggu nanti… di dunia kita berkuasa tapi di akhirat … hanya DIA yg berkuasa

    #-49楼

插入图片

NOTICE1:请申请gravatar头像,没有头像的评论可能不会被回复!

回到顶部