javascript對象的數(shù)據(jù)屬性與訪問器屬性是什么?針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)公司是一家集成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、網(wǎng)站頁面設(shè)計、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)的建站公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗,以探求精品塑造與理念升華,設(shè)計最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅持講誠信,負責任的原則,為您進行細心、貼心、認真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
創(chuàng)建對象的方式有兩種:第一種,通過new操作符后面跟Object構(gòu)造函數(shù),第二種,對象字面量方式。如下
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)建出來的對象是一樣的,有相同的屬性和方法。這些屬性內(nèi)部都有描述其行為的屬性描述符。
Object.defineProperty()
通過Object.defineProperty() 可以直接在對象上創(chuàng)建一個屬性,也可以修改已有的屬性。
Object.defineProperty(obj, prop, descriptor) 接收三個參數(shù):
obj:屬性所在的對象
prop:要訪問的屬性名
descriptor:描述符對象
描述符對象包含六個屬性:configurable、enumerable、writable、value、get、set ,要修改屬性的特性,必須使用Object.defineProperty()方法。
通過以上兩種方式添加的對象屬性,其布爾值特性默認值是true,通過Object.defineProperty來修改屬性特性時,只設(shè)置需要修改的特性即可;而通過Object.defineProperty創(chuàng)建的屬性,其布爾值特性默認值是false。
ECMAScript中屬性分為兩種:數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性
數(shù)據(jù)屬性包含四個屬性描述符:
[[Configurable]] : 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為訪問器屬性。通過以上方式添加的對象屬性,默認為true。
[[Enumerable]] : 表示能否通過for-in 循環(huán)訪問屬性。通過以上方式添加的對象屬性,默認為true。
[[Writable]] : 表示能否修改屬性的值。通過以上方式添加的對象屬性,默認為true。
[[Value]] : 包含這個屬性的數(shù)據(jù)值,可讀取寫入。通過以上方式添加的對象屬性,默認為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默認為false,value值不可修改,此時修改name為Lee,在非嚴格模式下不會報錯,但操作被忽略,在嚴格模式下會報錯。
Configurable
var person = {
name: 'Nicy',
age: 21,
sayName: function() {
console.log(this.name);
}
}
Object.defineProperty(person, "name", {
configurable: false
})
delete person.name; // 操作被忽略,無法通過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可進行true -> false的單向修改
writable: false
})
Object.defineProperty(person, "name", { // throw error
value: 'Lee'
})
Object.defineProperty(person, "name", { // throw error,此時writable不可以false -> true
writable: true
})
總結(jié)一下configurable:當configurable設(shè)為false時,
1、不可以通過delete去刪除該屬性從而重新定義屬性;
2、不可以轉(zhuǎn)化為訪問器屬性;
3、configurable和enumerable不可被修改;
4、writable可單向修改為false,但不可以由false改為true;
5、value是否可修改根據(jù)writable而定。
當configurable為false時,用delete刪除該屬性,在非嚴格模式下,不會報錯,但操作被忽略,在嚴格模式下會報錯;其他不可被修改的特性修改時會報錯。
Enumerable
enumerable表示對象屬性是否可以在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)建對象的屬性,則這個屬性的enumerable默認為true for (var i in person) { console.log(i); } // 'a' 和 'd' Object.keys(person); // ["a", "d"]
訪問器屬性
訪問器屬性包含四個屬性描述符:
[[Configurable]] : 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為數(shù)據(jù)屬性。直接在對象上定義的屬性,默認為true。
[[Enumerable]] : 表示能否通過for-in 循環(huán)訪問屬性。直接在對象上定義的屬性,默認為true。
[[Get]] : 讀取屬性時調(diào)用的函數(shù),默認為undefined。
[[Set]] : 寫入屬性時調(diào)用的函數(shù),默認為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()定義的訪問器屬性,其configurable和enumerable默認為false。
數(shù)據(jù)屬性與訪問器屬性的相互轉(zhuǎn)換
Object.getOwnPropertyDescriptor 讀取屬性的特性
使用Object.getOwnPropertyDescriptor可以獲取到屬性的描述符:
Object.getOwnPropertyDescriptor(obj, prop)
obj:屬性所在的對象;
prop:要訪問的屬性名。
數(shù)據(jù)屬性 -> 訪問器屬性
屬性的特性只能是訪問器描述符和數(shù)據(jù)描述符中的一種,給已有的數(shù)據(jù)屬性加get或set轉(zhuǎn)換為訪問器屬性時,其屬性的value、writable就會被廢棄。
如下代碼,將對象原有的數(shù)據(jù)屬性year轉(zhuǎn)換為訪問器屬性:
*注:在訪問器屬性的get和set中,不可以使用this訪問屬性本身,否則會無限遞歸而導(dǎo)致內(nèi)存泄漏。
// 設(shè)置get和set其中任意一個即可轉(zhuǎ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)換為訪問器屬性。
訪問器屬性 -> 數(shù)據(jù)屬性
將訪問器屬性轉(zhuǎn)換為數(shù)據(jù)屬性,只需要給現(xiàn)有訪問器屬性設(shè)置value或writable這兩個屬性描述符中的任意一個即可,其原有的get和set就會被廢棄,從而轉(zhuǎn)換為數(shù)據(jù)屬性。
上面為person定義的訪問器屬性age,通過Object.defineProperty()只設(shè)置了get和set,所以configurable默認為false,不可以將其轉(zhuǎn)換為數(shù)據(jù)屬性??梢栽谠L問器屬性和數(shù)據(jù)屬性間相互轉(zhuǎn)化的屬性其configurable特性值必須為true。
如下代碼,我們?yōu)閜erson新定義一個訪問器屬性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其中任意一個即可轉(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 和訪問器描述符get、set不能同時設(shè)置,否則會報錯。
Object.defineProperties()
通過Object.defineProperties()可以一次性為對象定義多個屬性。
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對象的數(shù)據(jù)屬性與訪問器屬性是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。