文章目錄
- Object 對象具有下列屬性:
- Object 對象還具有幾個方法:
- 參閱
- toFixed() 方法
- toExponential() 方法
- toPrecision() 方法
- 參閱
- length 屬性
- charAt() 和 charCodeAt() 方法
- concat() 方法
- indexOf() 和 lastIndexOf() 方法
- localeCompare() 方法
- slice() 和 substring()
- toLowerCase()、toLocaleLowerCase()、toUpperCase() 和 toLocaleUpperCase()
參考型別通常叫做類(class)。
本教程會討論大量的 ECMAScript 預定義參考型別。
參考型別
參考型別通常叫做類(class),也就是說,遇到引用值,所處理的就是對象。
本教程會討論大量的 ECMAScript 預定義參考型別。
從現在起,將重點討論與已經討論過的原始類型緊密相關的參考型別。
注意:從傳統意義上來說,ECMAScript 並不真正具有類。事實上,除了說明不存在類,在 ECMA-262 中根本沒有出現“類”這個詞。ECMAScript 定義了“對象定義”,邏輯上等價於其他程式設計語言中的類。
提示:本教程將使用術語“對象”。
對象是由 new 運算子加上要執行個體化的對象的名字建立的。例如,下面的代碼建立 Object 對象的執行個體:
var o = new Object();
這種文法與 Java 語言的相似,不過當有不止一個參數時,ECMAScript 要求使用括弧。如果沒有參數,如以下代碼所示,括弧可以省略:
var o = new Object;
注意:儘管括弧不是必需的,但是為了避免混亂,最好使用括弧。
提示:我們會在對象基礎這一章中更深入地探討對象及其行為。
這一節的重點是具有等價的原始類型的參考型別。
Object 對象
Object 對象自身用處不大,不過在瞭解其他類之前,還是應該瞭解它。因為 ECMAScript 中的 Object 對象與 Java
中的 java.lang.object 相似,ECMAScript 中的所有對象都由這個對象繼承而來,Object
對象中的所有屬性和方法都會出現在其他對象中,所以理解了 Object 對象,就可以更好地理解其他對象。
Object 對象具有下列屬性:
-
constructor
-
對建立對象的函數的引用(指標)。對於 Object 對象,該指標指向原始的 Object() 函數。
-
Prototype
-
對該對象的對象原型的引用。對於所有的對象,它預設返回 Object 對象的一個執行個體。
Object 對象還具有幾個方法:
-
hasOwnProperty(property)
-
判斷對象是否有某個特定的屬性。必須用字串指定該屬性。(例如,o.hasOwnProperty("name"))
-
IsPrototypeOf(object)
-
判斷該對象是否為另一個對象的原型。
-
PropertyIsEnumerable
-
判斷給定的屬性是否可以用 for...in 語句進行枚舉。
-
ToString()
-
返回對象的原始字串表示。對於 Object 對象,ECMA-262 沒有定義這個值,所以不同的 ECMAScript 實現具有不同的值。
-
ValueOf()
-
返回最適合該對象的原始值。對於許多個物件,該方法返回的值都與 ToString() 的傳回值相同。
注釋:上面列出的每種屬性和方法都會被其他對象覆蓋。
Boolean 對象
Boolean 對象是 Boolean 原始類型的參考型別。
要建立 Boolean 對象,只需要傳遞 Boolean 值作為參數:
var oBooleanObject = new Boolean(true);
Boolean 對象將覆蓋 Object 對象的 ValueOf() 方法,返回原始值,即 true 和 false。ToString() 方法也會被覆蓋,返回字串 "true" 或 "false"。
遺憾的是,在 ECMAScript 中很少使用 Boolean 對象,即使使用,也不易理解。
問題通常出現在 Boolean 運算式中使用 Boolean 對象時。例如:
var oFalseObject = new Boolean(false);
var bResult = oFalseObject && true;//輸出 true
在這段代碼中,用 false 值建立 Boolean 對象。然後用這個值與原始值 true 進行 AND 操作。在 Boolean
運算中,false 和 true 進行 AND 操作的結果是 false。不過,在這行代碼中,計算的是 oFalseObject,而不是它的值
false。
正如前面討論過的,在 Boolean 運算式中,所有對象都會被自動轉換為 true,所以 oFalseObject 的值是 true。然後 true 再與 true 進行 AND 操作,結果為 true。
注意:雖然你應該瞭解 Boolean 對象的可用性,不過最好還是使用 Boolean 原始值,避免發生這一節提到的問題。
參閱
如需更多有關 Boolean 對象的資訊,請訪問 JavaScript Boolean 對象參考手冊。
Number 對象
正如你可能想到的,Number 對象是 Number 原始類型的參考型別。要建立 Number 對象,採用下列代碼:
var oNumberObject = new Number(68);
您應該已認出本章前面小節中討論特殊值(如 Number.MAX_VALUE)時提到的 Number 對象。所有特殊值都是 Number 對象的靜態屬性。
要得到數字對象的 Number 原始值,只需要使用 valueOf() 方法:
var iNumber = oNumberObject.valueOf();
當然,Number 類也有 toString() 方法,在討論類型轉換的小節中已經詳細討論過該方法。
除了從 Object 對象繼承的標準方法外,Number 對象還有幾個處理數值的專用方法。
toFixed() 方法
toFixed() 方法返回的是具有指定位元小數的數位字串表示。例如:
var oNumberObject = new Number(68);
alert(oNumberObject.toFixed(2)); //輸出 "68.00"
在這裡,toFixed() 方法的參數是 2,說明應該顯示兩位小數。該方法返回 "68.00",空的字串位由 0 來補充。對於處理貨幣的應用程式,該方法非常有用。toFixed() 方法能表示具有 0 到 20 位小數的數字,超過這個範圍的值會引發錯誤。
toExponential() 方法
與格式化數字相關的另一個方法是 toExponential(),它返回的是用科學計數法表示的數位字串形式。
與 toFixed() 方法相似,toExponential() 方法也有一個參數,指定要輸出的小數的位元。例如:
var oNumberObject = new Number(68);
alert(oNumberObject.toExponential(1)); //輸出 "6.8e+1"
這段代碼的結果是 "6.8e+1",前面解釋過,它表示 6.8x101。問題是,如果不知道要用哪種形式(預定形式或指數形式)表示數字怎麼辦?可以用 toPrecision() 方法。
toPrecision() 方法
toPrecision() 方法根據最有意義的形式來返回數位預定形式或指數形式。它有一個參數,即用於表示數的數字總數(不包括指數)。例如,
var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(1)); //輸出 "7e+1"
這段代碼的任務是用一位元字表示數字 68,結果為 "7e+1",以另外的形式表示即 70。的確,toPrecision() 方法會對數進行舍入。不過,如果用 2 位元字表示 68,就容易多了:
var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(2)); //輸出 "68"
當然,輸出的是 "68",因為這正是該數的準確表示。不過,如果指定的位元多於需要的位元又如何呢?
var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(3)); //輸出 "68.0"
在這種情況下,toPrecision(3) 等價於 toFixed(1),輸出的是 "68.0"。
toFixed()、toExponential() 和 toPrecision() 方法都會進行舍入操作,以便用正確的小數位元正確地表示一個數。
提示:與 Boolean 對象相似,Number 對象也很重要,不過應該少用這種對象,以避免潛在的問題。只要可能,都使用數位原始標記法。
參閱
如需更多有關 Number 對象的資訊,請訪問 JavaScript Number 對象參考手冊。
String 對象
String 對象是 String 原始類型的對象標記法,它是以下方式建立的:
var oStringObject = new String("hello world");
String 對象的 valueOf() 方法和 toString() 方法都會返回 String 類型的原始值:
alert(oStringObject.valueOf() == oStringObject.toString());//輸出 "true"
如果運行這段代碼,輸出是 "true",說明這些值真的相等。
注釋:String 對象是 ECMAScript 中比較複雜的參考型別之一。同樣,本節的重點只是 String 類的準系統。更多的進階功能請閱讀本教程相關的章節,或參閱 JavaScript String 對象參考手冊。
length 屬性
String 對象具有屬性 length,它是字串中的字元個數:
var oStringObject = new String("hello world");
alert(oStringObject.length);//輸出 "11"
這個例子輸出的是 "11",即 "hello world" 中的字元個數。注意,即使字串包含雙位元組的字元(與 ASCII 字元相對,ASCII 字元只佔用一個位元組),每個字元也只算一個字元。
charAt() 和 charCodeAt() 方法
String 對象還擁有大量的方法。
首先,兩個方法 charAt() 和 charCodeAt() 訪問的是字串中的單個字元。這兩個方法都有一個參數,即要操作的字元的位置。
charAt() 方法返回的是包含指定位置處的字元的字串:
var oStringObject = new String("hello world");
alert(oStringObject.charAt(1));//輸出 "e"
在字串 "hello world" 中,位置 1 處的字元是 "e"。在“ECMAScript 原始類型”這一節中我們講過,第一個字元的位置是 0,第二個字元的位置是 1,依此類推。因此,調用 charAt(1) 返回的是 "e"。
如果想得到的不是字元,而是字元代碼,那麼可以調用 charCodeAt() 方法:
var oStringObject = new String("hello world");
alert(oStringObject.charCodeAt(1));//輸出 "101"
這個例子輸出 "101",即小寫字母 "e" 的字元代碼。
concat() 方法
接下來是 concat() 方法,用於把一個或多個字串串連到 String 對象的原始值上。該方法返回的是 String 原始值,保持原始的 String 對象不變:
var oStringObject = new String("hello ");
var sResult = oStringObject.concat("world");
alert(sResult);//輸出 "hello world"
alert(oStringObject);//輸出 "hello "
在上面這段代碼中,調用 concat() 方法返回的是 "hello world",而 String 對象存放的仍然是 "hello "。出於這種原因,較常見的是用加號(+)連接字串,因為這種形式從邏輯上表明了真正的行為:
var oStringObject = new String("hello ");
var sResult = oStringObject + "world";
alert(sResult);//輸出 "hello world"
alert(oStringObject);//輸出 "hello "
indexOf() 和 lastIndexOf() 方法
迄今為止,已討論過連接字串的方法,訪問字串中的單個字元的方法。不過如果無法確定在某個字串中是否確實存在一個字元,應該調用什麼方法呢?這時,可調用 indexOf() 和 lastIndexOf() 方法。
indexOf() 和 lastIndexOf() 方法返回的都是指定的子串在另一個字串中的位置,如果沒有找不到子串,則返回 -1。
這兩個方法的不同之處在於,indexOf() 方法是從字串的開頭(位置 0)開始檢索字串,而 lastIndexOf() 方法則是從字串的結尾開始檢索子串。例如:
var oStringObject = new String("hello world!");
alert(oStringObject.indexOf("o"));輸出 "4"
alert(oStringObject.lastIndexOf("o"));輸出 "7"
在這裡,第一個 "o" 字串出現在位置 4,即 "hello" 中的 "o";最後一個 "o" 出現在位置 7,即 "world"
中的 "o"。如果該字串中只有一個 "o" 字串,那麼 indexOf() 和 lastIndexOf() 方法返回的位置相同。
localeCompare() 方法
下一個方法是 localeCompare(),對字串進行排序。該方法有一個參數 - 要進行比較的字串,返回的是下列三個值之一:
- 如果 String 對象按照字母順序排在參數中的字串之前,返回負數。
- 如果 String 對象等於參數中的字串,返回 0
- 如果 String 對象按照字母順序排在參數中的字串之後,返回正數。
注釋:如果返回負數,那麼最常見的是 -1,不過真正返回的是由實現決定的。如果返回正數,那麼同樣的,最常見的是 1,不過真正返回的是由實現決定的。
樣本如下:
var oStringObject = new String("yellow");
alert(oStringObject.localeCompare("brick"));//輸出 "1"
alert(oStringObject.localeCompare("yellow"));//輸出 "0"
alert(oStringObject.localeCompare("zoo"));//輸出 "-1"
在這段代碼中,字串 "yellow" 與 3 個值進行了對比,即 "brick"、"yellow" 和
"zoo"。由於按照字母順序排列,"yellow" 位於 "brick" 之後,所以 localeCompare() 返回
1;"yellow" 等於 "yellow",所以 localeCompare() 返回 0;"zoo" 位於 "yellow"
之後,localeCompare() 返回 -1。再強調一次,由於返回的值是由實現決定的,所以最好以下面的方式調用
localeCompare() 方法:
var oStringObject1 = new String("yellow");
var oStringObject2 = new String("brick");
var iResult = sTestString.localeCompare("brick");
if(iResult < 0) {
alert(oStringObject1 + " comes before " + oStringObject2);
} else if (iResult > 0) {
alert(oStringObject1 + " comes after " + oStringObject2);
} else {
alert("The two strings are equal");
}
採用這種結構,可以確保這段代碼在所有實現中都能正確運行。
localeCompare()
方法的獨特之處在於,實現所處的地區(locale,兼指省/地區和語言)確切說明了這種方法啟動並執行方式。在美國,英語是 ECMAScript
實現的標準語言,localeCompare() 是區分大小寫,大寫字母在字母順序上排在小寫字母之後。不過,在其他地區,情況可能並非如此。
slice() 和 substring()
ECMAScript 提供了兩種方法從子串建立字串值,即 slice() 和
substring()。這兩種方法返回的都是要處理的字串的子串,都接受一個或兩個參數。第一個參數是要擷取的子串的起始位置,第二個參數(如果使用
的話)是要擷取子串終止前的位置(也就是說,擷取終止位置處的字元不包括在返回的值內)。如果省略第二個參數,終止位就預設為字串的長度。
與 concat() 方法一樣,slice() 和 substring() 方法都不改變 String 對象自身的值。它們只返回原始的 String 值,保持 String 對象不變。
var oStringObject = new String("hello world");
alert(oStringObject.slice("3"));//輸出 "lo world"
alert(oStringObject.substring("3"));//輸出 "lo world"
alert(oStringObject.slice("3, 7"));//輸出 "lo w"
alert(oStringObject.substring("3, 7"));//輸出 "lo w"
在這個例子中,slice() 和 substring() 的用法相同,傳回值也一樣。當只有參數 3 時,兩個方法返回的都是 "lo
world",因為 "hello" 中的第二個 "l" 位於位置 3 上。當有兩個參數 "3" 和 "7" 時,兩個方法返回的值都是 "lo
w"("world" 中的字母 "o" 位於位置 7 上,所以它不包括在結果中)。
為什麼有兩個功能完全相同的方法呢?事實上,這兩個方法並不完全相同,不過只在參數為負數時,它們處理參數的方式才稍有不同。
對於負數參數,slice() 方法會用字串的長度加上參數,substring() 方法則將其作為 0 處理(也就是說將忽略它)。例如:
var oStringObject = new String("hello world");
alert(oStringObject.slice("-3"));//輸出 "rld"
alert(oStringObject.substring("-3"));//輸出 "hello world"
alert(oStringObject.slice("3, -4"));//輸出 "lo w"
alert(oStringObject.substring("3, -4"));//輸出 "hel"
這樣即可看出 slice() 和 substring() 方法的主要不同。
當只有參數 -3 時,slice() 返回 "rld",substring() 則返回 "hello world"。這是因為對於字串
"hello world",slice("-3") 將被轉換成 slice("8"),而 substring("-3") 將被轉換成
substring("0")。
同樣,使用參數 3 和 -4 時,差別也很明顯。slice() 將被轉換成 slice(3, 7),與前面的例子相同,返回 "lo
w"。而 substring() 方法則將兩個參數解釋為 substring(3, 0),實際上即 substring(0, 3),因為
substring() 總把較小的數字作為起始位,較大的數字作為終止位。因此,substring("3, -4") 返回的是
"hel"。這裡的最後一行代碼用來說明如何使用這些方法。
toLowerCase()、toLocaleLowerCase()、toUpperCase() 和 toLocaleUpperCase()
最後一套要討論的方法涉及大小寫轉換。有 4 種方法用於執行大小寫轉換,即
- toLowerCase()
- toLocaleLowerCase()
- toUpperCase()
- toLocaleUpperCase()
從名字上可以看出它們的用途,前兩種方法用於把字串轉換成全小寫,後兩種方法用於把字串轉換成全大寫的。
toLowerCase() 和 toUpperCase() 方法是原始的,是以 java.lang.String 中相同方法為原型實現的。
toLocaleLowerCase() 和 toLocaleUpperCase() 方法是基於特定的地區實現的(與
localeCompare() 方法相同)。在許多地區中,地區特定的方法都與通用的方法完全相同。不過,有幾種語言對 Unicode
大小寫轉換應用了特定的規則(例如土耳其語),因此必須使用地區特定的方法才能進行正確的轉換。
var oStringObject = new String("Hello World");
alert(oStringObject.toLocaleUpperCase());//輸出 "HELLO WORLD"
alert(oStringObject.toUpperCase());//輸出 "HELLO WORLD"
alert(oStringObject.toLocaleLowerCase());//輸出 "hello world"
alert(oStringObject.toLowerCase());//輸出 "hello world"
這段代碼中,toUpperCase() 和 toLocaleUpperCase() 輸出的都是 "HELLO
WORLD",toLowerCase() 和 toLocaleLowerCase() 輸出的都是 "hello
world"。一般來說,如果不知道在以哪種編碼運行一種語言,則使用地區特定的方法比較安全。
提示:記住,String 對象的所有屬性和方法都可應用於 String 原始值上,因為它們是偽對象。
instanceof 運算子
在使用 typeof 運算子時採用參考型別儲存值會出現一個問題,無論引用的是什麼類型的對象,它都返回 "object"。ECMAScript 引入了另一個 Java 運算子 instanceof 來解決這個問題。
instanceof 運算子與 typeof 運算子相似,用於識別正在處理的對象的類型。與 typeof 方法不同的是,instanceof 方法要求開發人員明確地確認對象為某特定類型。例如:
var oStringObject = new String("hello world");
alert(oStringObject instanceof String);//輸出 "true"
這段代碼問的是“變數 oStringObject 是否為 String 對象的執行個體?”oStringObject 的確是 String
對象的執行個體,因此結果是 "true"。儘管不像 typeof 方法那樣靈活,但是在 typeof 方法返回 "object"
的情況下,instanceof 方法還是很有用的。