1. 程式人生 > >javascript(五)表達式

javascript(五)表達式

得出 16px 我們 square 數組 lse 編程 upper 函數對象

表達式 (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來初始化這個新創建對象的屬性。 那些被當成構造函數的函數不會返回一個值, 並且這個新創建並被初始化 後的對象就是整個對象創建表達式的值。 如果一個構造函數確實返回了一個對象值, 那 麽這個對象就作為整個對象創建表達式的值, 而新創建的對象就廢棄了。

javascript(五)表達式