iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Software Development

從零開始,在 coding 路上的 30 個為什麼?不對!是無數個為什麼!系列 第 10

Day 10 - 理解 JavaScript,為什麼要知道如何建立物件?

  • 分享至 

  • xImage
  •  

物件是 JavaScript 中的核心概念,上篇有提及 new,今天來點如何建立物件吧!

JavaScript 的基本型別

在之前的篇章中都未提及過的基本型別,在說明建立物件之前,來簡單說明一下:

  1. 數字(Number): 用於表示數值。可以是整數或浮點數。例如:423.14159
  2. 字串(String): 用於表示文本。字串必須包含在單引號(')或雙引號(")之間。
    例如:'Hello, World!'
  3. 布林(Boolean): 用於表示邏輯值,只有兩個可能的值:truefalse
  4. 未定義(Undefined): 表示變數已宣告但尚未賦值的狀態。宣告一個變數但未初始化時,
    其值為 undefined
  5. 空(Null): 表示變數的值為空或不存在。通常是在明確指示變數不包含任何有效值時使用。
  6. 符號(Symbol,ES6引入): 一種唯一且不可變的數據類型,通常用於定義對象的唯一屬性名稱。

除了以上這些基本型別以外的類型,都是物件~
接著,我們來看看要如何建立物件吧!

JavaScript 如何建立物件?

  • Object Literals(物件實字):
    最簡單的方式是使用花括號 {} 來建立物件,並在其中指定屬性和屬性值。

    const person = {
        name: 'Viii',
        age: 18
    };
    
  • Constructor(建構式):
    使用建構式來創建多個具有相似結構的物件。
    建構式通常以大寫字母開頭,並使用 new 關鍵字來創建物件。

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    
    const person1 = new Person('Viii', 18);
    const person2 = new Person('Bob', 25);
    

    如果忘記使用 new 關鍵字...:

    function Person(name) {
      this.name = name;
    }
    
    // 不使用 new 關鍵字
    const person3 = Person('Jay');
    console.log(person3); // undefined,因為函數內的 this 參考全域物件,未返回新的物件
    console.log(name); // 'Jay',name 屬性被設置為全域變數
    
  • Object.create() 方法:

    先創建一個名為 Person 的物件,
    該物件包含 firstNamelastName 屬性和一個 getFullName 方法。

    const Person = {
      firstName: 'Default',
      lastName: 'Default',
      getFullName: function () {
        return this.firstName + " " + this.lastName;
      }
    };
    

    接著使用 Object.create() 方法創建新的物件並基於 Person 物件來繼承他的屬性和方法:

    const viii = Object.create(Person);
    viii.firstName = 'Viii';
    viii.lastName = 'Chang';
    
    console.log(viii.getFullName()); // 輸出:'Viii Chang'
    

    使用 Object.create(Person) 基於 Person 物件創建了一個名為 viii 的新物件,然後設置了 firstNamelastName 屬性的值。最後,我們調用 viii.getFullName() 以獲取完整名字。由於 viii 物件繼承了 getFullName 方法,所以返回完整的名字。

    而關於繼承,在 JavaScript 中,物件之間的繼承是通過原型鏈(prototype chain)實現的,
    這部分將在下篇整理~

    關於屬性描述器

    當使用 Object.create() 創建了一個新物件,可以在建立新物件時,
    使用屬性描述器來設定屬性的各種特性,藉由在第二個參數中傳遞一個屬性描述器,
    便可以在建立新物件時直接給予預設值:

    const Person = {
      firstName: 'Default',
      lastName: 'Default',
      getFullName: function () {
        return this.firstName + " " + this.lastName;
      }
    };
    
    // 創建一個新物件,繼承自 Person,並設定屬性描述器
    const viii = Object.create(Person, {
      firstName: {
        value: 'Viii',
        writable: true, // 該屬性是否可寫入
        configurable: true // 該屬性是否可配置
      }
    });
    
    console.log(viii.firstName); // 輸出:'Viii'
    

    屬性描述器可分為六種:

    • value:屬性的值,這裡設定為 'Viii'
    • writable:指示屬性是否可寫入,這裡設定為 true,表示可以修改該屬性的值。
    • enumerable:指示屬性是否可透過 for...in 迴圈中迭代列舉。
    • configurable:指示屬性是否可配置,這裡設定為 true,表示該屬性的描述器可以被修改。
    • get: getter function。
    • set: setter function。

    除了上面的方式,我們也可以透過 Object.defineProperty() 方法!
    Object.defineProperty() 方法是 JavaScript 中用來定義或修改物件屬性的方法,
    並且可以設置屬性的特性,包括 getset 存取器函數。

    Object.defineProperty(obj, prop, descriptor);
    
    • obj:要定義或修改屬性的目標物件。
    • prop:要定義或修改的屬性名稱。
    • descriptor:一個屬性描述器對象,用來指定屬性的特性,包括 valuewritableenumerableconfigurablegetset

    現在讓我們看一個具體的例子:

    const person = {};
    
    // 使用 Object.defineProperty 定義一個名為 "fullName" 的計算屬性
    Object.defineProperty(person, 'fullName', {
      // 定義 getter
      get: function() {
        return this.firstName + ' ' + this.lastName;
      },
    
      // 定義 setter
      set: function(fullName) {
        const names = fullName.split(' ');
        this.firstName = names[0];
        this.lastName = names[1];
      },
    
      // 設置 enumerable 特性為 true,使屬性可列舉
      enumerable: true,
    
      // 設置 configurable 特性為 true,使屬性可配置
      configurable: true
    });
    
    person.firstName = 'Viii';
    person.lastName = 'Chang';
    
    console.log(person.fullName); // 輸出:'Viii Chang'
    
    // 使用 setter 設置 fullName
    person.fullName = 'Jay Lin';
    
    console.log(person.firstName); // 輸出:'Jay'
    console.log(person.lastName); // 輸出:'Lin'
    

    使用 Object.defineProperty() 定義了一個計算屬性 fullName,並為它指定了 getset 存取器函數。get 存取器返回 firstNamelastName 的結合,而 set 存取器接受一個完整名字,並將其拆分為 firstNamelastName


透過這些內容,了解到 Object Literals(物件實字)來快速建立物件,或者使用 Constructor(建構式)來建立具有相似結構的多個物件。此外,Object.create() 方法允許我們基於現有物件來創建新的物件,並繼承屬性和方法。還可以使用 Object.defineProperty() 方法來定義或修改物件的屬性,並為這些屬性指定各種特性,包括 getset 存取器函數。

關於原型與繼承,在 JavaScript 中,物件之間的繼承是通過 prototype chain(原型鏈)實現的!

是不是開始好奇原型、原型鏈與原型繼承了呢!為什麼要理解他們?

下篇待續!

文章同步於個人部落格:Viiisit!(歡迎參觀 ୧ʕ•̀ᴥ•́ʔ୨)


上一篇
Day 09 - 理解 JavaScript ,為什麼要知道 this?
下一篇
Day 11 - 理解 JavaScript,為什麼要知道原型、原型鏈與原型繼承?
系列文
從零開始,在 coding 路上的 30 個為什麼?不對!是無數個為什麼!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言