JavaScript中的Object的引用型別

zhangfaliang發表於2019-03-20

本章內容

  • 使用物件

引用型別的值(物件)是引用型別的一個例項。在ECMAScript中,引用資料型別是一種資料結構,從技術上講是一門物件導向的語言,但是它不具備傳統的面嚮物件語言所支援的類和介面等基本結構(es6以下的版本)。引用型別有時候也被稱為物件定義,因為它們描述的是一類物件所具備的屬性和方法。雖然引用型別和類看起來很相似,但它們並不是相同的概念。

物件是某個特定引用型別的例項。新物件是使用new 操作符後跟一個建構函式建立的。建構函式本身就是一個函式,只不過該函式是出於建立新物件的目的而定義的。請看下面這行程式碼:

var person = new Object();
複製程式碼

這行程式碼建立了Object引用型別的一個新的例項,然後把該例項儲存在了變數person中。使用的建構函式是Object,它只為新物件定義了預設屬性和方法。ECMAScript提供了很多原生引用型別,以便開發人員用以實現常見的計算任務。

Object 型別
我們看到的大多數引用型別值都是Object型別的例項;而且,Object也是ECMAScript中使用最多的一個型別。雖然Object的例項不具備多少功能,但是對於在應用程式中的儲存和傳輸資料而言,它們確實是非常理想的選擇。
建立Object例項的方式由兩種。第一種是使用new 操作符後面跟Object建構函式,如下:

var person = new Object();
person.name = 'Nicholas';
person.age = 29;
複製程式碼

另一種方式是使用物件字面量表示法。物件字面量是物件定義的一種簡寫形式,目的在於簡化建立包含大量屬性的物件的過程。下面這個例子就使用了物件字面量語法定義了與前面那個例子中相同的person物件:

var person = {
    name:'Nicholas',
    age:29
}
複製程式碼

在這個例子中,左邊的花括號({)表示物件字面量的開始,因為它出現在了表示式上下文中。ECMAScript中的表示式上線文指的是該上線文期待一個值(表示式)。賦值操作符表示後面是一個值,所以左花括號在這裡表示一個表示式的開始。同樣的花括號,如果出現在一個語句上下文(statement context)中,例如跟在if語句條件的後面,這表示一個語句塊的開始。
然後,我們定義了name屬性,之後是一個冒號,再後面是這個屬性的值。在物件字面量中,使用逗號來區分不同的屬性,因此‘Nicholas’後面是一個逗號。但是,在age屬性的值29的後面不能新增逗號,因為age這個物件的後面沒有其他屬性,如果新增了會在IE7及更早版本和opera中導致錯誤。在通過物件字面量定義物件時,實際上不會呼叫Object建構函式(Firfox 2及更早的版本會呼叫Object)
雖然可以使用前面簡介的任何一種方法來定義物件,但開發人員更青睞物件字面量語法,因為這種語法要求的程式碼量少,而且能夠給人封裝資料的感覺。實際上,物件字面量也是向函式傳遞大量可選參賽的首選方式,例如:

function dispalyInfo(args){
    var output = '';
    if(typeof args.name=='string')
    {
        outPut+='Name: '+args.name +'\n';
    }
    if(typeof args.age =='number'){
         outPut+='Age: '+args.age +'\n';
    }
    alert(outPut)
}
dispalyInfo({name:'Nicholas',age: 29});
dispalyInfo({
    name:'greg'
})
複製程式碼

在上面的例子中,函式dispalyInfo()接受一個名為args的引數。這個產數可能帶有一個名為name或age的屬性,也可能這兩個屬性都有或者多沒有。在這個函式的內部,我們通過typeof操作符來檢查每個屬性是否存在,然後在基於相應的屬性來構建一條要顯示的資訊。然後,我們呼叫了兩次這個函式,每次使用一個物件字面量來指定不同的資料。這兩次呼叫傳遞的引數雖然不同,但函式都能正常執行。這種傳遞引數的模式最適合需要向函式傳入大量可選引數的情形,一般來講,命名引數雖然容易處理,但在有多個可選引數的情況下就會顯示的不夠靈活。最好的做法是對那些必須值使用命名引數,而使用物件字面量來封裝是多個可選引數。
一般來說,訪問物件屬性時使用的都是點表示法,這也是很多物件導向語言中的通用的語法。不過,在JavaScript也可以使用方括號表示法來訪問物件的屬性。在使用方括號語法時,應該要訪問的屬性以字串的形式放在方括號裡面,如下的例子所示。

alert(person['name']);//'Nicholas'
alert(person.name);//'Nicholas'
複製程式碼

從功能上看,這兩種訪問物件屬性的方法沒有任何的區別,但方括號語法的主要優點是可以通過變數來訪問屬性,例如:

var propertyName = 'name';
alert(person[propertyName]);//'Nicholad'
複製程式碼

有一些物件的key是數字的情況下也建議使用方括號取,因為使用點取的話會出異常,例如:

var obj = {
    1:'1'
    2:'2'
}
// error 
console.log(obj.1)//Uncaught SyntaxError: Unexpected number
// right
console.log(obj[1])// 1
複製程式碼

如果屬性名中包含會導致語法錯誤的字元,或者屬性名使用的是關鍵字或者保留字,也可以使用方括號表示法。例如:

person['first name']= 'Nicholas';
複製程式碼

由於'first name'中包含一個空格,所以不能使用點表示法來訪問它。然而,屬性名中是可以包含非字母非數字的,這時候就可以使用方括號來訪問它們,通常,除了非必須使用變數來訪問屬性,否則我們建議使用點表示法
每個字面量或者使用new例項出來的物件,都會繼承Object基類的方法。Object的每個例項都會有一下屬性和方法。

  • constructor:儲存著建立當前物件的函式。對於var o = new Object而言,建構函式就是(corstructor)object()。
  • hasOwnProperty(propertyName):用於檢測給定的屬性在當前例項中(而不是在例項的原型中)是否存在。其中,作為引數的屬性名(propertyName)必須以字串形式指定(例如:o.hasOwnperproty('name')).
  • isPropertypeOf(object);用於檢測傳入的物件是否是當前物件的原型;
  • propertyIsEnumerable(propertyName);用於檢測給定屬性時候能過使用for-in語法來列舉。與hasOwnProperty()方法一樣,作為引數的屬性必須以字串形式指定;
  • toLocaleString();返回物件字串表示,該字串與執行環境的地區對應。
  • toString():返回物件字串表示,作為隱身轉換的一個方法;
  • 返回物件的字串、數值或布林值表示。通常與 toString()方法的返回值 相同。

相關文章