溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

javascript對(duì)象的數(shù)據(jù)屬性與訪問(wèn)器屬性是什么

發(fā)布時(shí)間:2020-07-22 11:54:08 來(lái)源:億速云 閱讀:145 作者:Leah 欄目:web開(kāi)發(fā)

javascript對(duì)象的數(shù)據(jù)屬性與訪問(wèn)器屬性是什么?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)建對(duì)象的方式有兩種:第一種,通過(guò)new操作符后面跟Object構(gòu)造函數(shù),第二種,對(duì)象字面量方式。如下

var person = new Object();
person.name = 'Nicy';
person.age = 21;
person.sayName = function() {
    console.log(this.name);
};        
var person = {
    name: 'Nicy',
    age: 21,
    sayName: function() {
        console.log(this.name);
    }
}

這兩種方式創(chuàng)建出來(lái)的對(duì)象是一樣的,有相同的屬性和方法。這些屬性?xún)?nèi)部都有描述其行為的屬性描述符。

Object.defineProperty()

通過(guò)Object.defineProperty() 可以直接在對(duì)象上創(chuàng)建一個(gè)屬性,也可以修改已有的屬性。

Object.defineProperty(obj, prop, descriptor) 接收三個(gè)參數(shù):

  obj:屬性所在的對(duì)象  

  prop:要訪問(wèn)的屬性名

  descriptor:描述符對(duì)象

描述符對(duì)象包含六個(gè)屬性:configurable、enumerable、writable、value、get、set ,要修改屬性的特性,必須使用Object.defineProperty()方法。

通過(guò)以上兩種方式添加的對(duì)象屬性,其布爾值特性默認(rèn)值是true,通過(guò)Object.defineProperty來(lái)修改屬性特性時(shí),只設(shè)置需要修改的特性即可;而通過(guò)Object.defineProperty創(chuàng)建的屬性,其布爾值特性默認(rèn)值是false。

ECMAScript中屬性分為兩種:數(shù)據(jù)屬性和訪問(wèn)器屬性。

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

數(shù)據(jù)屬性包含四個(gè)屬性描述符:

[[Configurable]] : 表示能否通過(guò)delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為訪問(wèn)器屬性。通過(guò)以上方式添加的對(duì)象屬性,默認(rèn)為true。

[[Enumerable]] : 表示能否通過(guò)for-in 循環(huán)訪問(wèn)屬性。通過(guò)以上方式添加的對(duì)象屬性,默認(rèn)為true。

[[Writable]] : 表示能否修改屬性的值。通過(guò)以上方式添加的對(duì)象屬性,默認(rèn)為true。

[[Value]] : 包含這個(gè)屬性的數(shù)據(jù)值,可讀取寫(xiě)入。通過(guò)以上方式添加的對(duì)象屬性,默認(rèn)為undefined。

Writable

var person = {};

Object.defineProperty(person, "name", {
    value: 'Nicy'
})
person.name = 'Lee';  
console.log(person.name)    // 'Nicy'

Object.defineProperty(person, "name", {
    writable: true
})
person.name = 'Lee';
console.log(person.name)    // 'Lee'

Object.defineProperty直接創(chuàng)建的屬性writable默認(rèn)為false,value值不可修改,此時(shí)修改name為L(zhǎng)ee,在非嚴(yán)格模式下不會(huì)報(bào)錯(cuò),但操作被忽略,在嚴(yán)格模式下會(huì)報(bào)錯(cuò)。

Configurable

var person = {
   name: 'Nicy',
   age: 21,
   sayName: function() {
       console.log(this.name);
   }
}

Object.defineProperty(person, "name", {
   configurable: false
})

delete person.name;    // 操作被忽略,無(wú)法通過(guò)delete刪除屬性
Object.defineProperty(person, "name", {    // throw error
   configurable:true    
})    
Object.defineProperty(person, "name", {    // throw error
   enumerable: false
})  
Object.defineProperty(person, "name", {     // 由于writable為true,所以可以修改value
   value: 'Lucy'
})console.log(person.name)    // Lucy
Object.defineProperty(person, "name", {    // writable可進(jìn)行true -> false的單向修改
   writable: false
})
Object.defineProperty(person, "name", {     // throw error
   value: 'Lee'
})
Object.defineProperty(person, "name", {    // throw error,此時(shí)writable不可以false -> true
   writable: true
})

總結(jié)一下configurable:當(dāng)configurable設(shè)為false時(shí),

  1、不可以通過(guò)delete去刪除該屬性從而重新定義屬性;

  2、不可以轉(zhuǎn)化為訪問(wèn)器屬性;

  3、configurable和enumerable不可被修改;

  4、writable可單向修改為false,但不可以由false改為true;

  5、value是否可修改根據(jù)writable而定。

當(dāng)configurable為false時(shí),用delete刪除該屬性,在非嚴(yán)格模式下,不會(huì)報(bào)錯(cuò),但操作被忽略,在嚴(yán)格模式下會(huì)報(bào)錯(cuò);其他不可被修改的特性修改時(shí)會(huì)報(bào)錯(cuò)。

Enumerable

enumerable表示對(duì)象屬性是否可以在for...in和Object.keys()中被枚舉。

var person = {};
Object.defineProperty(person, "a", { value : 1, enumerable:true });
Object.defineProperty(person, "b", { value : 2, enumerable:false });
Object.defineProperty(person, "c", { value : 3 }); // enumerable defaults to false
person.d = 4; // 如果使用直接賦值的方式創(chuàng)建對(duì)象的屬性,則這個(gè)屬性的enumerable默認(rèn)為true

for (var i in person) {    
  console.log(i);  
}  //  'a' 和 'd' 

Object.keys(person); // ["a", "d"]

訪問(wèn)器屬性

訪問(wèn)器屬性包含四個(gè)屬性描述符:

[[Configurable]] : 表示能否通過(guò)delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為數(shù)據(jù)屬性。直接在對(duì)象上定義的屬性,默認(rèn)為true。

[[Enumerable]] : 表示能否通過(guò)for-in 循環(huán)訪問(wèn)屬性。直接在對(duì)象上定義的屬性,默認(rèn)為true。

[[Get]] : 讀取屬性時(shí)調(diào)用的函數(shù),默認(rèn)為undefined。

[[Set]] : 寫(xiě)入屬性時(shí)調(diào)用的函數(shù),默認(rèn)為undefined。

var person = {
    name: 'Nicy',
    _age: 21,
    year: 1997,
    _year: 1997,
    sayName: function() {
        console.log(this.name);
    }
}

Object.defineProperty(person, "age", {
    get: function() {
        return this._age;
    },
    set: function(value) {
        this._age = value;
                // ...
    }
})

用Object.defineProperty()定義的訪問(wèn)器屬性,其configurable和enumerable默認(rèn)為false。

數(shù)據(jù)屬性與訪問(wèn)器屬性的相互轉(zhuǎn)換

Object.getOwnPropertyDescriptor 讀取屬性的特性

使用Object.getOwnPropertyDescriptor可以獲取到屬性的描述符:

Object.getOwnPropertyDescriptor(obj, prop)

  obj:屬性所在的對(duì)象;

  prop:要訪問(wèn)的屬性名。

數(shù)據(jù)屬性 -> 訪問(wèn)器屬性

屬性的特性只能是訪問(wèn)器描述符和數(shù)據(jù)描述符中的一種,給已有的數(shù)據(jù)屬性加get或set轉(zhuǎn)換為訪問(wèn)器屬性時(shí),其屬性的value、writable就會(huì)被廢棄。

如下代碼,將對(duì)象原有的數(shù)據(jù)屬性year轉(zhuǎn)換為訪問(wèn)器屬性:

*注:在訪問(wèn)器屬性的get和set中,不可以使用this訪問(wèn)屬性本身,否則會(huì)無(wú)限遞歸而導(dǎo)致內(nèi)存泄漏。

// 設(shè)置get和set其中任意一個(gè)即可轉(zhuǎn)換為訪問(wèn)器屬性
Object.defineProperty(person, "year", {
    get: function() {
//        return this,year;    // error
        return this._year;    
    },
    set: function(value) {
//             this.year = value;  // error
        this._year= value;
    }
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'year');
console.log(descriptor);    // {get: ?, set: ?, enumerable: true, configurable: true}

在原有的數(shù)據(jù)屬性year中,使用Object.defineProperty()為屬性設(shè)置get 或 set,都可以將其轉(zhuǎn)換為訪問(wèn)器屬性。

訪問(wèn)器屬性 -> 數(shù)據(jù)屬性

將訪問(wèn)器屬性轉(zhuǎn)換為數(shù)據(jù)屬性,只需要給現(xiàn)有訪問(wèn)器屬性設(shè)置value或writable這兩個(gè)屬性描述符中的任意一個(gè)即可,其原有的get和set就會(huì)被廢棄,從而轉(zhuǎn)換為數(shù)據(jù)屬性。

上面為person定義的訪問(wèn)器屬性age,通過(guò)Object.defineProperty()只設(shè)置了get和set,所以configurable默認(rèn)為false,不可以將其轉(zhuǎn)換為數(shù)據(jù)屬性。可以在訪問(wèn)器屬性和數(shù)據(jù)屬性間相互轉(zhuǎn)化的屬性其configurable特性值必須為true。

如下代碼,我們?yōu)閜erson新定義一個(gè)訪問(wèn)器屬性job,將其configurable設(shè)置為true ,并將其轉(zhuǎn)換為數(shù)據(jù)屬性:

Object.defineProperty(person, "job", {
    configurable: true,
    enumerable: true,
    get: function() {
        return this._job;
    },
    set: function(value) {
        this._job = value;
    }
})

// 設(shè)置value和writable其中任意一個(gè)即可轉(zhuǎn)換為數(shù)據(jù)屬性        
Object.defineProperty(person, "job", {
    value: 'worker',
    writable: true
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'job');
console.log(descriptor);    // {value: "worker", writable: true, enumerable: true, configurable: true}

數(shù)據(jù)描述符value、writable 和訪問(wèn)器描述符get、set不能同時(shí)設(shè)置,否則會(huì)報(bào)錯(cuò)。

Object.defineProperties()

通過(guò)Object.defineProperties()可以一次性為對(duì)象定義多個(gè)屬性。

var person = {};
Object.defineProperties(person, {
  name: {
    value: 'Nicy',
    writable: true
  },
  _age: {
    value: 21,
    enumerable: true,
    writable: true,
    configurable: true
  },
   age: {
    get: function() {
    return this._age;
    },
    set: function(value) {
    this._age = value;
    }
  }
});

關(guān)于javascript對(duì)象的數(shù)據(jù)屬性與訪問(wèn)器屬性是什么問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI