javascript快速入門9--引用型別

水之原發表於2013-12-01

引用型別通常叫做類(class),也就是說,遇到引用值,所處理的就是物件。

注意:從傳統意義上來說,ECMAScript 並不真正具有類。事實上,除了說明不存在類,在 ECMA-262 中根本沒有出現“類”這個詞。ECMAScript 定義了“物件定義”,邏輯上等價於其他程式設計語言中的類

Object

物件是由 new 運算子加上要例項化的物件的名字建立的。例如,下面的程式碼建立 Object 物件的例項:

    var obj = new Object();

 

這種語法與 Java 語言的相似,不過當有不止一個引數時,ECMAScript 要求使用括號。如果沒有引數,如以下程式碼所示,括號可以省略:

    var o = new 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(property)
判斷給定的屬性是否可以用 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 原始值,避免發生這一節提到的問題。

Number

Number 物件是 Number 原始型別的引用型別。要建立 Number 物件,採用下列程式碼:

    var oNumberObject = new Number(68);

 

Number.MAX_VALUE,Number.MIN_VALUE等特殊值都是 Number 物件的靜態屬性。

要得到數字物件的 Number 原始值,只需要使用 valueOf() 方法:

    var iNumber = oNumberObject.valueOf();

 

當然,Number 類也有 toString() 方法.除了從 Object 物件繼承的標準方法外,Number 物件還有幾個處理數值的專用方法:

toFixed() 方法返回的是具有指定位數小數的數字的字串表示。例如:

    var oNumberObject = new Number(68);
    alert(oNumberObject.toFixed(2));  //輸出 "68.00"

 

在這裡,toFixed() 方法的引數是 2,說明應該顯示兩位小數。該方法返回 "68.00",空的字串位由 0 來補充。對於處理貨幣的應用程式,該方法非常有用。toFixed() 方法能表示具有 0 到 20 位小數的數字,超過這個範圍的值會引發錯誤。

與格式化數字相關的另一個方法是 toExponential(),它返回的是用科學計數法表示的數字的字串形式。與 toFixed() 方法相似,toExponential() 方法也有一個引數,指定要輸出的小數的位數。例如:

    var oNumberObject = new Number(68);
    alert(oNumberObject.toExponential(1));  //輸出 "6.8e+1"

 

這段程式碼的結果是 "6.8e+1",前面解釋過,它表示 6.8x101。問題是,如果不知道要用哪種形式(預定形式或指數形式)表示數字怎麼辦?可以用 toPrecision() 方法。

toPrecision() 方法根據最有意義的形式來返回數字的預定形式或指數形式。它有一個引數,即用於表示數的數字總數(不包括指數)。例如:

    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() 方法都會進行舍入操作,以便用正確的小數位數正確地表示一個數。

String

String 物件是 String 原始型別的物件表示法,它是以下方式建立的:

     var oStringObject = new String("hello world");

 

String 物件的 valueOf() 方法和 toString() 方法都會返回 String 型別的原始值:

    alert(oStringObject.valueOf() == oStringObject.toString());    //輸出 "true"

 

String 物件具有屬性 length,它是字串中的字元個數:

    var oStringObject = new String("hello world");
    alert(oStringObject.length);    //輸出 "11"

 

注意,即使字串包含雙位元組的字元(與 ASCII 字元相對,ASCII 字元只佔用一個位元組),每個字元也只算一個字元。

String 物件還擁有大量的方法。

localeCompare() 方法,對字串進行排序。該方法有一個引數 - 要進行比較的字串,返回的是下列三個值之一:

  • 如果 String 物件按照字母順序排在引數中的字串之前,返回負數。
  • 如果 String 物件等於引數中的字串,返回 0
  • 如果 String 物件按照字母順序排在引數中的字串之後,返回正數。

如果返回負數,那麼最常見的是 -1,不過真正返回的是由實現決定的。如果返回正數,那麼同樣的,最常見的是 1,不過真正返回的是由實現決定的。而且對於中文字元,雖然表面上看是按拼音排序的,但並不一定!事實上,它們按Unicode編碼排序,小的排在前面,大的排在後面

示例如下:

    var oStringObject = new String("yellow");
    alert(oStringObject.localeCompare("brick"));        //輸出 "1"
    alert(oStringObject.localeCompare("yellow"));        //輸出 "0"
    alert(oStringObject.localeCompare("zoo"));        //輸出 "-1"

 

再強調一次,由於返回的值是由實現決定的,所以最好以下面的方式呼叫 localeCompare() 方法:

    var oStringObject1 = new String("yellow");
    var oStringObject2 = new String("brick");
    var iResult = oStringObject1.localeCompare(oStringObject2);
    if(iResult < 0) {
      alert(oStringObject2 + " 排在字串 " + oStringObject1 +"後面");
    } else if (iResult > 0) {
      alert(oStringObject2 + " 排在字串 " + oStringObject1+"前面");
    } else {
      alert("兩個字串排序是一樣的!");
    }

 

localeCompare() 方法的獨特之處在於,實現所處的區域(locale,兼指國家/地區和語言)確切說明了這種方法執行的方式。在美國,英語是 ECMAScript 實現的標準語言,localeCompare() 是區分大小寫的,大寫字母在字母順序上排在小寫字母之後。不過,在其他區域,情況可能並非如此。

ECMAScript 提供了兩種方法從子串建立字串值,即 slice() 和 substring()。這兩種方法返回的都是要處理的字串的子串,都接受一個或兩個引數。第一個引數是要獲取的子串的起始位置,第二個引數(如果使用的話)是要獲取子串終止前的位置(也就是說,獲取終止位置處的字元不包括在返回的值內)。如果省略第二個引數,終止位就預設為字串的長度。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() 方法則將其作為 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"

 

最後一套要討論的方法涉及大小寫轉換。有 4 種方法用於執行大小寫轉換,即

  • toLowerCase()
  • toLocaleLowerCase()
  • toUpperCase()
  • toLocaleUpperCase()

從名字上可以看出它們的用途,前兩種方法用於把字串轉換成全小寫的,後兩種方法用於把字串轉換成全大寫的。toLowerCase() 和 toUpperCase() 方法是原始的,是以 java.lang.String 中相同方法為原型實現的。toLocaleLowerCase() 和 toLocaleUpperCase() 方法是基於特定的區域實現的(與 localeCompare() 方法相同)。在許多區域中,區域特定的方法都與通用的方法完全相同。不過,有幾種語言對 Unicode 大小寫轉換應用了特定的規則(例如土耳其語),因此必須使用區域特定的方法才能進行正確的轉換。

String 物件的所有屬性和方法都可應用於 String 原始值上,因為它們是偽物件。

String物件方法參考

方法描述
charAt() 返回在指定位置的字元。
charCodeAt() 返回在指定的位置的字元的 Unicode 編碼。
concat() 連線字串。
fromCharCode() 從字元編碼建立一個字串。
indexOf() 檢索字串。
lastIndexOf() 從後向前搜尋字串。
localeCompare() 用本地特定的順序來比較兩個字串。
match() 找到一個或多個正規表示式的匹配。
replace() 替換與正規表示式匹配的子串。
search() 檢索與正規表示式相匹配的值。
slice() 提取字串的片斷,並在新的字串中返回被提取的部分。
split() 把字串分割為字串陣列。
substr() 從起始索引號提取字串中指定數目的字元。
substring() 提取字串中兩個指定的索引號之間的字元。
toLocaleLowerCase() 把字串轉換為小寫。
toLocaleUpperCase() 把字串轉換為大寫。
toLowerCase() 把字串轉換為小寫。
toUpperCase() 把字串轉換為大寫。
toString() 返回字串。
valueOf() 返回某個字串物件的原始值。

Global

Global是一個最為特殊的物件,因為它實際上根本不存在!如果嘗試輸出Global物件將出錯:

    alert(Global);

 

但Global確實是一個物件,要理解這一點要先理解ECMAScript中一個概念,即在ECMAScript中不存在獨立的函式,所有的函式必須是某個物件的方法. 像之前所使用的isNaN(),parseInt()看上去像獨立的函式,其實它們都是Global物件的方法,Global物件的方法還不止這些,如用於編解碼URI的函式:encodeURI與decodeURI方法

    var url = "http://www.g.cn/trend page";
    alert(encodeURI(url));//該方法會將一些不能用在URI中的字元進行編碼
    //上面的空格將會被替換成%20,與之對應的decodeURI則是用來解碼的
    alert(decodeURI(encodeURI(url)));//原樣輸出

 

與encodeURI和decodeURI相似的encodeURIComponent和decodeURIComponent . 這兩個方法不但對空格之類的字元進行編碼,還對"/"和":"這些URL中的特殊字元進行編碼

    var url = "http://www.g.cn";
    alert(encodeURIComponent(url));
    //輸出http://%3A%2F%2Fwww.g.cn

 

一般情況下要把一些字串作為QueryString值新增到URL後面時,使用encodeURIComponent更安全些. encodeURI之類的方法代替了以前BOM提供的escape與unescape之類的方法,URI方法更可取,因為escape方法只能對ASCII字元進行編碼,而URI方法則可以對所有的Unicode字元進行編碼. 應該總是使用URI方法,避免使用escape方法!

Global物件不但有方法,還有一些屬性:如undefined,NaN,Infinity這些特殊值都是Global物件的屬性,還有所有的內建引用型別的建構函式(Array,Date等)都是的,只是不能通過Global.Array這樣方法輸出來,它們都被對映到了window物件上了.

相關文章