表达式是Javascript中的一个短语,javascript解释器会将其计算出一个结果。程序中常用量是最简单的一类表达式就是变量。变量名也是一种简单的表达式,它的值就是赋值给变量的值。复杂的表达式是由简单的表达式组成的。比如数组访问表达式是由一个表示数组的表达式,方括号、一个整数表达式构成。它们所组成新的表达式运算结果是该数组特定位置的元素值。同样的函
数调用表达式由一个表示函数对象的表达式和0个多个参数表达式构成。将简单表达式组成复杂表达式最常用的方法就是运算符。
本章(本文)将讲解所有javascript运算符。同时也讲解不涉及运算符的表达式(比如访问数组元素和函数调用),其语法和编程风格和c语言都很相似。
1.元素表达式
最简单的表达式是“原始表达式”,原始表达式是表达式的最小的单位--它们不包含其他表达式。javascript中的原始表达式包含常量或直接量。关键字和变量。直接量是直接在程序中出现的常数值。它们看起来像:
1.23 //数字直接量 "hello" //字符串直接量 /pattern/ //正则表达式直接量
javascript中的一些保留字构成了原始表达式
true //布尔值:真 false //假 null //返回一个值:空 this //返回"当前"对象
通过第三章的学习,和其它关键字不同,this并不是一个常量,他在程序的不同地方返回的值也不相同。this关键字经常在面向对象编程中出现。this返回方格方法的对象。最后,第三种原始表达式是变量
i //返回变量i的值 sum //返回sum的值 undefined //是全局变量,和null不同,它不是一个关键字
2.对象和数组的初始化表达式。
对象和数组初始化实际上是新创建的对象和数组,这些初始化的表达式有时候叫做“对象直接量”和“数组直接量”。然而和布尔直接量不同,他们不是原始表达式,因为他们所包含的成员或者元素都子表达式。
数组的初始化表达式语法非常简单,我们以下开始
数组的初始化表达式是通过一对方括号和其内由逗号隔开的列表构成的,初始化结果是一个新创建的数组。数组的元素是逗号分隔表达式的值。
[] //一个空数组;[]内留空即表示该数组没有任何元素[1+2,3+4] //有两个元素的数组,第一个3,第二个是7
数组初始化表达式中的元素初始化表达式可以是数组初始化表达式。也就是说表达式是可以嵌套的
var mat = [[1,2,3],[4,5,6],[7,8,9]];
数组直接量中列表之间的元素可以省略,空位就会填充undefined.例如下面:
var a=[1,,,,5]
其中4个元素是undefined.数组直接量的结尾处留下逗号,这时不会创建一个新的值为undefined的元素。
对象初始化表达式和数组初始化表达式非常相似,只是方括号被花括号代替。并每个字表达式包含一个属性名和非冒号作为前缀。
var p = {x: 2.1,y: -3} //一个拥有两个属性成员的对象 var q = {}; //空对象 q.x=2.1;q.y=-3; //q的属性成员和p的一样
对象直接量也可以嵌套,比如
var anh = {left:{x:2,y:3}, right:{x:4,y:5}}
javascript在计算对象初始化表达式的值时候,对象表达式都会各自计算一次,并且他们不必包含常数值:它们可以是任意javascript表达式。同样,对象直接量中属性的名称可以是字符串而不是标识符。(在在那行只能使用保留字或一些非法标识符作为属性名的时候非常有用)
var side = 1; var square = {"left":{x:p.x,y:p.y}, 'right':{x:p.x+side,y:p.y+side}}
第6 7章还会再次讨论对象和数组的初始化表达式。
3.函数表达式
函数定义表达式定义一个javascript函数。表达式的值是这个新定义的函数。从某种意义上将,函数定义表达式可以成为函数直接量,函数表达式可称为“函数直接量”,毕竟对象初始化表达式也称为“对象直接量”。一个典型的函数定义表达式包含关键字function,其后是一对圆括号,括号以内是逗号分隔的列表,列表包含0或多个标识符(参数名)。然后跟随花括号包裹的javascript代码段(函数体).
var square = function(x){ return x*x};
函数定义表达式同样可以包含函数的名字。函数也可以通过函数语句来定义,而不是函数表达式。更多内容会在第八章描述。
4.属性访问表达式
属性访问表达式运算得到一个对象或者一个数组元素的值。javascript为属性访问定义了两种方法。
exPRession . indentifier expression [expression]
第一种写法是一个表达式后跟随一个句点和标识符。表达式指定对象,标识符则指定要访问的属性明川。第二章写法是使用方括号,方括号内是一个表达式(这种方法适用于对象和数组)。第二个表达式指定要访问的属性的明川或者代表要访问数组元素的索引。这里有一些具体的例子
o.x //=>1表达式o的x属性 o.y.z //=>3 表达式o.y的z属性 o.["x"] //=>1的对象o的x属性 a[1] //=>4 表达式a索引为1的元素 a[2]["1"]//=>6 表达式a[2]中索引为1的元素 a[0].x //=>1: 表达式a[0]的x属性
不管使用哪种形式的属性访问表达式,在"."和"["之前的表达式总会首先计算。如果计算结果为null或者undefined,表达式会抛出类型错误异常,因为这两个值都不能包含任意属性。如果运算结果不是对象或数组,javascript会将其转换为对象(3章6节内容)
虽然.identifier的写法更加简单,但需要注意的是,这种方式只适用于要访问的属性名称是合法的标识符。并且需要知道要访问的属性名字。如果属性名称是一个保留字或者包含空格和标点符号,是一个数字(对于数组来说),则必须使用方括号的写法。当属性名是通过运算符得出的值而不是固定值的时候,这时候必须使用方括号的写法。(6章2节1小节)
5.调运表达式
javascript中的调用表达式(invocation expression)是一种调用(或者执行)函数或方法的语法表示。它以一个函数表达式开始,这个函数表达式指代了要调用的函数。函数表达式后跟随一对圆括号,括号内是一个以逗号隔开的参数列表。参数可以有0个也可以有多个。
f(0) //f是一个函数表达式:0是一个参数表达式。 Math.max(x,y,z) //Math.max是一个函数;x,y和z是参数 a.sort() //a.sort()是一个函数,它没有参数。
当调用表达式进行求值的时候,首先计算函数表达式,然后计算参数表达式,得到一组参数值。如果函数表达式的值不是一个可调用的对象,则抛出一个类型错误异常.然后参数的值依次被赋值给形参,这些形参是定义函数时定义的。接下来执行函数体。如果函数使用return语句给出一个返回值,那么这个返回值就是整个调用表达式的值。否则,调用表达式的值就是undefined.函数调用--包括形参表达式的个数和函数定义中实参的个数不匹配的时候运行的情况--的细节将会在第八章详细说明。
任何一个调用表达式都包含一对圆括号和左圆括号之前的表达式,如果这个表达式是一个属性访问表达式,那么这个调用叫做“方法调用”(method invication)。在方法调用中执行函数体的时候,作为属性访问主体的对象和数组便是其调用方法内this的指向。这种特性使得在面向对象编程的范例中,函数(其OO名称为“方法”)可调用其宿主对象(第9章会有更多相关内容)。
6.对象创建表达式
对象创建表达式(object creation expression)创建一个对象并调用一个函数(构造函数)来初始化对象的属性。对象创建表达式和函数调用表达式非常类似,只是对象创建表达式之前多了一个关键字new:
new Object() new Point(2,3)
如果对象创建表达式不需要传入任何参数给构造函数的话,那么这对圆括号是可以省略掉的,更多构造函数的细节将在9章说明
new Object new Point
7.运算符概述
javascript中的运算符用于算表表达式, 比较表达式, 逻辑表达式 ,赋值表达式等需要注意的是大多运算符都是标点符号来表示的,比如delete和instanceof.无论是关键字运算符还是符号运算符,所表示的运算符一样都是正规运算符,他们的语法都非常言简意赅。下标运算符的优先级来排序的,前边的运算符优先级高于后边的运算符优先级。被水平华丰隔开的运算符具有不同的优先级。A表示运算符的结合性。L从左至右或者R(从右至左)标题N的列表表示操作数的个数。类型表示期望的操作数的类型,以及运算符的结果类型(在"→"符号之后)
运算符 | 操作 | A | N | 类型 |
++ | 前/后增量 | R | 1 | lval→num |
-- | 前后减量 | R | 1 | lval→num |
- | 求反 | R | 1 | num→num |
+ | 转换为数字 | R | 1 | num→num |
~ | 按位求反 | R | 1 | int→int |
! | 逻辑非 | R | 1 | bool→bool |
delete | 删除属性 | R | 1 | lval→bool |
typeof | 检测操作类型 | R | 1 | any→Str |
void | 返回undefined值 | R | 1 | any→undef |
* 、/、% | 乘 除 求余 | L | 2 | num,num→num |
+、- | 加,减 | L | 2 | num,num→num |
+ | 字符串连接 | L | 2 | str,str→str |
<< | 左移位 | L | 2 | int,int→int |
>> | 右移位 | L | 2 | int,int→int |
>>> | 无符号右移 | L | 2 | int,int→int |
<,<=,>,>= | 比较数字顺序 | L | 2 | num,num→bool |
<,<=,>,>= | 比较在字母中的顺序 | L | 2 | str,str→bool |
instanceof | 测试对象类 | L | 2 | obj,func→bool |
in | 测试属性是否存在 | L | 2 | str,obj→bool |
== | 判断相等 | L | 2 | any,any→bool |