JavaScript -- 對象屬性

ECMAScript 中有兩種數(shù)據(jù)屬性,分別是數(shù)據(jù)屬性和訪問器屬性,下面來依次介紹。


1. 數(shù)據(jù)屬性

數(shù)據(jù)屬性有四個(gè)特性:

  • configurable : 表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性改為訪問器屬性。

  • enumerable : 表示能否 for-in 循環(huán)返回屬性。

  • writable : 表示能否修改屬性的值。

  • value : 包含這個(gè)屬性的值。

需要注意的是,當(dāng)我們使用不同的方式定義屬性的時(shí)候,上述四個(gè)特性的默認(rèn)值使不同的。比如對于下面這段代碼

var person = {
    "age": "18"
};

var descriptor = Object.getOwnPropertyDescriptor(person, "age");
console.log(descriptor);

瀏覽器打印出如下信息 :

Object
    configurable:true
    enumerable:true
    value:"18"
    writable:true

這就說明,以上面這種方式定義屬性的時(shí)候,configurable, enumerable, writable 的默認(rèn)值將會是 true。

而定義屬性的方式還有另一種方法,那就是 defineProperty() 方法,這個(gè)方法定義的屬性 configurable, enumerable, writable 的默認(rèn)值將會使 false 。

var person = {};

Object.defineProperty(person, "age", {
    value: "22"
});

var descriptor = Object.getOwnPropertyDescriptor(person, "age");
console.log(descriptor);

瀏覽器打印的消息如下 :

Object
    configurable:false
    enumerable:false
    value:"22"
    writable:false

當(dāng)然,如果我們不滿足默認(rèn)值,在定義的屬性的時(shí)候可以自己設(shè)置,比如我們將 enumerable 設(shè)置為 true。

Object.defineProperty(person, "age", {
    enumerable: true,
    value: "22"
});

2. 訪問器屬性

訪問器特性與數(shù)據(jù)屬性的不同之處是,它并沒有 value 特性, 而是多了一對 settergetter 函數(shù)。下面來介紹訪問器的四個(gè)特性。

  • configurable : 表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性改為訪問器屬性。

  • enumerable : 表示能否 for-in 循環(huán)返回屬性。

  • get : 讀取屬性時(shí)調(diào)用的函數(shù)。

  • set : 寫入屬性時(shí)調(diào)用的函數(shù)。

訪問器的屬性不可以直接定義,需要借助于 defineProperty(),比如我們?yōu)?person 設(shè)置一個(gè) name 訪問器屬性。

var person = {
    _name: "hwaphon"
};

Object.defineProperty(person, "name", {
    get: function() {
        return this._name;
    },
    set: function(value) {
        if (typeof value === "string") {
            this._name = value;
        }
    }
});

注意,_name 屬性中的 _ 其實(shí)是一種標(biāo)記,用于表示這個(gè)屬性只能通過對象方法獲得。其實(shí)只要你調(diào)用 person._name 仍然能獲取它的值,所以我感覺使用 _ 像是一種約定。

為什么要使用 setget 呢?是為了對數(shù)據(jù)進(jìn)行驗(yàn)證,比如我們在設(shè)置年齡的時(shí)候,可以檢測輸入值是否為數(shù)字以及是否在合理范圍內(nèi)。

var person = {
    _age: 12
};

Object.defineProperty(person, "age", {
    get: function() {
        return this._name;
    },
    set: function(newAge) {
        if (typeof newAge === "number" && newAge > 0 && newAge <= 150) {
            this._age = newAge;
        } else {
            console.log("not match!");
        }
    }
});

當(dāng)一個(gè)訪問器屬性只設(shè)置了 set 函數(shù)時(shí),由于沒有 get 函數(shù),所以這個(gè)屬性是不可讀的。

當(dāng)一個(gè)訪問器屬性只設(shè)置了 get 函數(shù)時(shí),由于沒有 set 函數(shù),所以這個(gè)屬性使不可寫入的。

還有一點(diǎn)值得注意,由于 Objcet.defineProperty()ECMAScript 5 中才出現(xiàn)的,那么在不支持這個(gè)方法的瀏覽器中,該怎么定義 getset 呢?可以借助于兩個(gè)非標(biāo)準(zhǔn)的方法, __defineGetter__()__defineSetter__()。

var person = {
    _age: 12
};

person.__defineGetter__("age", function() {
    return this._age;
});

person.__defineSetter__("age", function(newAge) {
    if (typeof newAge == "number") {
        this._age = newAge;
    }
});

提示: 方法中使用的是雙下劃線!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容