iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
1
Modern Web

JavaScript Note系列 第 22

Object 物件

  • 分享至 

  • xImage
  •  

JavaScript型別可分為兩大類:

  • 基本型別(Primitive Type)
  • 物件型別(Object Type)

這次我們來討論物件型別(Object Type)。

  • 物件是由複合值所組成,一個非空物件,裡面至少包含一組(屬性名稱:值)的組合。
  • 屬性名稱可以是識別字(identifier)或是string,屬性值可以是基本型別(Primitive Type)、物件型別(Object Type)。
  • 任何不是基本型別(Primitive Type)的值,都是物件。
  • 物件是由屬性所構成的無序集合,每個屬性都有自己的名稱與值。

建立物件最簡單且直覺的方式,是使用物件字面值的方式建立:

let car = {
    make: 'toyota',
    model: 'camry',
    year: 2018,
    color: 'red'
}

首先宣告變數,代表這個物件的名稱,在指定運算式的右邊,使用大括號{ }建立物件的本體,加入每個屬性名稱與值(屬性名稱:值),每對屬性/值之間,使用逗號分隔。
以上就完成最簡單的物件建立。

剛剛建立了car物件,有4個屬性,分別是make、model、year、color,以及這些描述這些屬性的值。
要取得屬性值,可以使用.(dot)或中括號[ ]運算子。

console.log(car.make); //toyota
console.log(car['model']); //camry

我們也可以設定方法,讓此物件具有邏輯處理的能力。

let car = {
    make: 'toyota',
    model: 'camry',
    year: 2018,
    color: 'red',
    run: function () {
        console.log(`${this.model} is running`);
    }
}
car.run(); //camry is running

this關鍵字,指的是car這個物件。

物件的結構看似複雜,其實只要掌握一個原則:物件裡面只有屬性跟方法。
物件.屬性
物件.方法

可變(mutable)與不可變(immutable)

基本型別(Primitive Type)與物件型別(Object Type)有個很大的差異就是基型值是不可變(immutable)的,而物件是可變的,這究竟是什麼意思?

所謂的不可變(immutable)意指,當我們在操作基型值所回傳的結果,看似已經修改後結果,但實際上是回傳一個新的值,舉例來說:

let str = 'hello';
console.log(str.toUpperCase());
console.log(str);

結果
https://ithelp.ithome.com.tw/upload/images/20181106/20112573Rf1hAki5WK.png
toUpperCase( )的結果回傳大寫,但實際上並未改變str原本的內容。

物件的可變(mutable)

let obj1 = {
    prop: 'obj1'
}
let obj2 = obj1;
obj2.prop = 'obj2';
console.log(obj1.prop); //obj2
console.log(obj2.prop); //obj2

物件的操作是透過參考(by reference),而非值(by value),obj2與obj1參考到的其實是同一個物件,當改變obj2所參考到的物件屬性值,相對的,也會改變obj1的物件屬性值。

物件之間可以合併,也很常使用到,我們可以使用assign方法來實現:

let car1 = {
    make: 'toyota',
    model: 'camry',
    year: 2018,
    color: 'red'
}

let car2 = {
    make: 'toyota',
    model: 'rav4',
    year: 2018,
    color: 'white',
    type: 'suv',
    run: function () {
        console.log(`${this.model} is running`);
    }
}

Object.assign(car1, car2);
console.log(car1);

結果
https://ithelp.ithome.com.tw/upload/images/20181106/20112573RzrBjin5Cu.png
car2會合併到car1,有幾點要注意:

  • 若car2有car1沒有的屬性,car1會加入該屬性。
  • 有相同的屬性前者會被後者覆寫。
  • 這個方法會改變car1的物件內容。

若不想覆蓋原本的物件,可以在參數中設空物件,並傳給新的物件:

let car3 = Object.assign({}, car1, car2);
console.log(car3);
console.log(car1);

結果
https://ithelp.ithome.com.tw/upload/images/20181106/20112573ZN6Ng0Jyy8.png

內建物件

我們除了可以自己建立物件,來達到客製的需求之外,在開發Web的過程當中,往往需要更多關於瀏覽器或JavaScript的資訊,內建物件能提供一般程式開發常會使用到的功能,無需我們另外撰寫,當Web應用程式開始執行的時候,這些內建物件會一同被載入使用。

內建物件可分為三大類:

  • 瀏覽器物件
    也就是window物件,它代表目前的瀏覽器視窗或頁籤,window物件的屬性與函式非常多。
    https://ithelp.ithome.com.tw/upload/images/20181106/20112573mQAssRoPZM.png

  • DOM
    文件物件模型(Document Object Model),它代表當前網頁的頁面。
    當瀏覽器解析網頁時,會將HTML轉成DOM,放入記憶體中,JavaScript藉由控制DOM,來操縱網頁的行為。
    https://ithelp.ithome.com.tw/upload/images/20181106/201125730f6WfnxUHr.png

  • JavaScript全域物件
    基本功能物件,包括Array、Date、String、Number、Error等,讓我們在程式設計的過程當中可針對特定型別的物件做處理,它的功能相當多,我會在其他篇幅一一介紹。

包裹(Wrapper)物件

我們建立一個物件,並設定屬性值:

let obj = {
    prop: 'Hello'
}
console.log(obj.prop); //Hello

當我們需要取得屬性值,可以使用obj.prop,一切看起來很合理。

String也可以使用類似的方式取得長度:

let str = 'Hello world';
console.log(str.length); //11

可是明明String不是Object,沒有屬性,為何它可以用這種方式取得資料?

因為當我們需要參考到Primitive的資訊時,JavaScript會自動把Primitive轉型成Object,這時它就可以當成物件來處理,一旦執行完畢,這臨時新建的物件,生命週期也隨之結束。

這種物件也就稱為包裹(Wrapper)物件,就好像在Primitive Type身上包了物件的外衣一樣,讓Primitive Type短暫地擁有物件的行為。

這種物件跟一般物件的差異在於,它們的屬性都是唯讀的,我們不能改變也無法定義新屬性,這非常容易理解,因為我們只是要知道Primitive Type的資訊,如果藉由包裹(Wrapper)物件的方式去改變原本的屬性值,是很不合理的。

參考來源:
JavaScript大全
Speaking JavaScript|簡明完整的 JS 精要指南


上一篇
Exception handling 例外處理
下一篇
call by value 傳值 & call by reference 傳址
系列文
JavaScript Note31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言