物件屬性描述器 Property Descriptor(二)


Posted by nosleepengineer on 2023-07-26

存取器描述器( accessor descriptors )

前文提到存取器描述器包含 get 和 set,可以分別理解為取值和設值的方法。新增一個存取器描述器類型的屬性,有以下三種方式:

// 字面量聲明
let obj1 = {
    firstName: 'John',
    lastName: 'Rawls',
    get fullName() {
        return `${this.firstName} ${this.lastName}`
    },
    set fullName(value) {
        [ this.firstName, this.lastName ] = value.split(' ')
    }
}

// Object.defineProperty
let obj2 = {
    firstName: 'John',
    lastName: 'Rawls'
}
Object.defineProperty(obj2, 'fullName', {
    get: function() {
        return `${this.firstName} ${this.lastName}`
    },
    set: function(value) {
        [ this.firstName, this.lastName ] = value.split(' ')
    }
})

// class
class Name {
    constructor(fullName){
        [ this.firstName, this.lastName ] = fullName.split(' ')
    }
    set fullName(value){
        [ this.firstName, this.lastName ] = value.split(' ')
    }
    get fullName(){
        return `${this.firstName} ${this.lastName}`;
    }
}

let obj3 = new Name('John Rawls')


在上圖中,firstName 和 lastName 都是資料描述器,fullName 是存取器描述器,包括 configurableenumerablegetset 四個屬性,存取器描述器和資料描述器相同的地方在於兩者都有 configurableenumerable 這兩個屬性,它們的特性和資料描述器中相同,使用字面量聲明時預設為 true,使用靜態方法定義時預設為 false。obj3 的部份涉及 Class,不在本文處理。

取值器 Getter

Getter 在屬性描述器中以 get 表示,後面接著的是屬性名稱,不可傳入參數,必須 return 一個值,通常用來計算物件內部的屬性並返回結果,以 obj1 為例,當我們讀取 obj1.fullName 時,getter 會計算出結果並返回。因此,我們可以看到在 console 中輸出的 obj1 中,fullName 屬性並沒有直接顯示它的值,而是以 (...) 代替,只有在我們將它展開時才會計算出應該顯示的內容。

賦值器 Setter

Setter 在屬性描述器中以 set 表示,後面接著的也是屬性名稱,會傳入一個參數,參數就是賦予屬性的新值。setter 在屬性值修改時被呼叫,除了可以用來改變物件內的其他屬性外,也可用作賦值前的驗證、資料和 DOM 元素的雙向綁定等等。

let obj1 = {
    firstName: 'John',
    lastName: 'Rawls',
    get fullName() {
        return `${this.firstName} ${this.lastName}`
    },
    set fullName(value) {
        [ this.firstName, this.lastName ] = value.split(' ')
    }
}

obj1.fullName = 'Isaiah Berlin' // 即為傳入 setter 中的參數

console.log(obj1)

結論

屬性描述器可分為資料描述器和存取器描述器,两者互不相容。資料描述器包括 configurableenumerablevaluewritable ,四個屬性。存取器描述器包括 configurableenumerablegetset。value 和 get、set 只能擇一,同時設定會發生錯誤。取值器及設值器在程式設計上提供了許多可能性,Vue2 的雙向綁定就是以它們作為基礎。


#javascript #object







Related Posts

Playing with CSS Variables and JS

Playing with CSS Variables and JS

CH 11 類別(class)

CH 11 類別(class)

[22] 強制轉型 - ToBoolean、Falsy、Truthy

[22] 強制轉型 - ToBoolean、Falsy、Truthy


Comments