javascript(五)表达式

表达式 (expression) JavaScript中的一个短语, JavaScript解释器会将其计算(evaluate) 出一 个结果。程序中的常量是最简单的一类表达式。变量名也是一种简单的表达式,它的值就是赋值给变量的值。复杂表达式是由简单表达式组成的。如数组访问表达式是由一个表示数组的表达式,左方括号,一个整数表达式和右方括号构成。它们锁组成的新的表达式的运算结果是该数组的特定位置的元素值。同样的,函数调用哪个表达式由一个个表示函数对象的表达式和0个或多个参数表达式构成。

将简单表达式组合成复杂表达式最常用的方法就是使用运算符 (operator) 。运算符按照特定的运算规则对操作数(通常是两个)进行运算, 并计算出新值。乘法运算符 "*" 是比较简单的例子。表达式x*y是对两个变址表达式x和y进行运算并得出结果。有时我们更愿意说运算符返回了一个值而不是 计算 出了一个值。 

原始表达式
最简单的表达式是 原始表达式" (primary expression) 。原始表达式是表达式的最小单位一一它们不再包含其他表达式。JavaScript中的原始表达式包含常址或直接量、 关键字和变量。
直接最是直接在程序中出现的常数值。它们看起来像:

1.23           // 数字
"hello"       // 字符串
/pattern/  // 正则表达式

JavaScript中的一些保留字构成了原始表达式:

true       // 返回一个布尔值
false      // 返回一个布尔值
null       // 返回一个null
this       // 返回当前对象

this关键字它在程序的不同地方返回的值也不相同。 this关键字经常在面向对象编程中出现。 在一个方法体内,this返回调用这个方法的对象。 
第三种原始表达式是变量:

i                 // 返回变量i的值
sum           // 返回sum的值
undefined   // undefined是全局变量,和null不同,它不是一个关键字

当JavaScript代码中出现了标识符,JavaScript会将其当做变量而去查找它的值。 如果变址名不存在,表达式运算结果为undefined。然而,在ECMAScript 5的严格模式中,对不存在的变量进行求值会抛出一个引用错误异常。

对象和数组的初始化表达式
对象和数组初始化表达式实际上是一个新创建的对象和数组。 这些初始化表达式有时称做对象直接量和数组直接量。然而和布尔直接量不同,它们不是原始表达式。以为它们所包含的成员或者元素都是子表达式。数组城市化表达式语法非常简单,我们以此开始。数组初始化表达式是通过一对方括号和其内由逗号隔开的列表构成的。 初始化的结果是 一个新创建的数组。 数组的元素是逗号分隔的表达式的值:

[]                  // 空数组
[1+2,3+4]     // 拥有两个元素的数组,第一个是3第二个是7

数组初始化表达式中的元素初始化表达式也可以是数组初始化表达式。 也就是说,这些 表达式是可以嵌套的:

var matrix= [[1,2,3], [4,5,6], [7,8,9]]; 

JavaScript对数组初始化表达式进行求值的时候, 数组初始化表达式中的元素表达式也都会各自计算一次。 也就是说,数组初始化表达式每次计算的值有可能是不同的。
数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充值undefined。例如, 下面这个数组包含5个元素, 其中三个元素是undefined:

var sparseArray = [1,,,,s]; 

数组直接扯的元素列表结尾处可以留下单个逗号,这时并不会创建一个新的值为undefined的元素。
对象初始化表达式和数组初始化表达式非常类似, 只是方括号被花括号代替, 并且每个 子表达式都包含一个属性名和一个冒号作为前缀:

var p = { x:2.3, y:-1.2 }; // 一个拥有两个恶属性成员的对象

var q = {};                  // 一个空对象
q.x = 2.3; q.y = -1.2;  // q的属性成员和p的一样

对象直接量也可以嵌套:

var rectangle= { upperLeft: { x: 2, y: 2 }, 1 owerR1ght: { x: 4, y: 5} };

JavaScript求对象初始化表达式的值的时候, 对象表达式也都会各自计算一次, 并且它们不必包含常数值:它们可以是任意JavaScript表达式。 同样, 对象直接址中的属性名称可以是字符串而不是标识符(这在那些只能使用保留字或一些非法标识符作为属性名的地方非常有用):

var side ; 1; 
var square ; { "upperLeft": { x: p.x, y: p.y }, 'lowerRight': { x: p.x + side, y: p.y + side}}; 

函数定义表达式
函数定义表达式定义一个JavaScript函数。 表达式的值是这个新定义的函数。 从某种意义上讲, 函数定义表达式可称为 "函数直接量” ,毕竞对象初始化表达式也称为 “对象直接址” 。 一个典型的函数定义表达式包含关键字function, 跟随其后的是一对圆括号,括号内是一个以逗号分割的列表,列表含有0个或多个标识符(参数名), 然后再跟随一个由花括号包裹的JavaScript代码段(函数体),例如:

//这个函数返回传入参数值的平方

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

函数定义表达式同样可以包含函数的名字。函数也可以通过函数语句来定义, 而不是函 数表达式。


属性访问表达式
属性访问表达式运算得到一个对象属性或一个数组元素的值。JavaScript为属性访问定义了两种语法:

expression . identifier 
expression [expression] 

第一种写法是一个表达式后跟随一个句点和标识符。表达式指定对象,标识符则指定需要访间的属性的名称。第二种写法是使用方括号, 方括号内是另外一个表达式(这种方 法适用于对象和数组)。第二个表达式指定要访间的属性的名称或者代表要访问数组元素的索引。这里有一些具体的例子:

var o = {x:1,y:{z:3}};     // 一个示例对象
var a= [o,4,[S,6]];        // 一个包含这个对象的示例数组
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[o] .x                    // => 1: 表达式a[o]的x属性

不管使用哪种形式的属性访问表达式, 在 "." 和 "["之前的表达式总是会首先计算。 如果计算结果是null或者undefined, 表达式会抛出一个类型错误异常, 因为这两个值都不能包含任意属性。如果运算结果不是对象(或者数组),JavaScript会将其转换为对象 。如果对象表达式后跟随句点和标识符, 则会查找由这个标识符所指定的 属性的值,井将其作为整个表达式的值返回。如果对象表达式后跟随一对方括号, 则会计算方括号内的表达式的值并将它转换为字符串。不论哪种情况, 如果命名的属性不存在, 那么整个属性访问表达式的值就是undefined。
显然.identifier的写法更加简单,但需要注意的是,这种方式只适用于要访问的属性名称是合法的标识符,并且需要知道要访间的属性的名字。如果属性名称是一个保留字或者包含空格和标点符号,或是一个数字(对于数组来说),则必须使用方括号的写法。当属性名是通过运算得出的值而不是固定的值的时候,这时必须使用方括号写法。

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

f(0)                     // f是一个函数表达式I Q是一个参数表达式
Math.max(x,y,z)          // Math.max是一个函数; x, y和z是参数 
a.sort()                 // a.sort是一个函数, 它没有参数

当对调用表达式进行求值的时候, 首先计算函数表达式, 然后计算参数表达式,得到一 组参数值。 如果函数表达式的值不是一个可调用的对象,则抛出一个类型错误异常(所有的函数都是可调用的,即使宿主对象不是函数它也有可能被调用)。 然后, 实参的值被依次赋值给形参, 这些形参是定义函数时指定的,接下来开始执行函数体。 如果函数使用return语句给出一个返回值,那么这个返回值就是整个调用表达式的值。 否则,调用表达式的值就是undefined。函数调用一包括当形参表达式的个数和函数定义中实参的个数不匹配的时候的运行情况。
任何一个调用表达式都包含一对圆括号和左圆括号之前的表达式。 如果这个表达式是一 个属性访问表达式,那么这个调用称做 “方法调用" (method invocation) 。在方法调用中,执行函数体的时候,作为属性访问主题的对象和数组便是其调用方法内this的指向。 这种特性使得在面向对象编程范例中,函数(其00名称为 “方法")可以调用其宿主对象。 
并不是方法调用的调用表达式通常使用全局对象作为this关键字的值。 然而在ECMAScript 5中,那些通过严格模式定义的函数在调用时将使用undefined作为this的 值,this不会指向全局对象。 


对象创建表达式
对象创建表达式 (object creation expression) 创建一个对象并调用一个函数(这个函数称做构造函数)初始化新对象的属性。对象创建表达式和函数调用表达式非常类似,只是对象创建表达式之前多了一个关键字new:

new Object() 
new Point(2,3) 

如果一个对象创建表达式不需要传入任何参数给构造函数的话,那么这对空圆括号是可以省略掉的:

new Object
new Date 

当计算一个对象创建表达式的值时, 和对象初始化表达式通过{}创建对象的做法一样, JavaScript首先创建一个新的空对象, 然后,JavaScript通过传入指定的参数并将这个新
对象当做this的值来调用一个指定的函数。 这个函数可以使用this来初始化这个新创建对象的属性。 那些被当成构造函数的函数不会返回一个值, 并且这个新创建并被初始化 后的对象就是整个对象创建表达式的值。 如果一个构造函数确实返回了一个对象值, 那 么这个对象就作为整个对象创建表达式的值, 而新创建的对象就废弃了。

 

原文地址:https://www.cnblogs.com/caesar-id/p/10807150.html