建立物件的方式有兩種:第一種,透過new運算子後面跟著Object建構函數,第二種,物件字面量方式。如下
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); } }
這兩種方式建立出來的物件是一樣的,有相同的屬性和方法。這些屬性內部都有描述其行為的屬性描述符。
Object.defineProperty()
#透過Object.defineProperty() 可以直接在物件上建立一個屬性,也可以修改現有的屬性。
Object.defineProperty(obj, prop, descriptor) 接收三個參數:
obj:屬性所在的物件
prop:要存取的屬性名稱
descriptor:描述子物件
描述子物件包含六個屬性:configurable、enumerable、writable、value、get、set ,要修改屬性的特性,必須使用Object.defineProperty()方法。
透過上述兩種方式新增的物件屬性,其布林值特性預設值是true,透過Object.defineProperty來修改屬性特性時,只設定需要修改的特性即可;而透過Object .defineProperty所建立的屬性,其布林值特性預設值是false。
ECMAScript中屬性分為兩種:資料屬性和存取器屬性。
資料屬性
資料屬性包含四個屬性描述符:
#[[Configurable]] : 表示能否透過delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為存取器屬性。透過以上方式新增的物件屬性,預設為true。
[[Enumerable]] : 表示能否透過for-in 迴圈存取屬性。透過以上方式新增的物件屬性,預設為true。
[[Writable]] : 表示能否修改屬性的值。透過以上方式新增的物件屬性,預設為true。
[[Value]] : 包含這個屬性的資料值,可讀取寫入。透過以上方式新增的物件屬性,預設為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直接建立的屬性writable預設為false,value值不可修改,此時修改name為Lee,在非嚴格模式下不會報錯,但操作被忽略,嚴格模式會報錯。
Configurable
<span style="font-size: 13px;"><span style="color: #0000ff;"></span>var person = {<br> name: 'Nicy',<br> age: 21,<br> sayName: function() {<br> console.log(this.name);<br> }<br>}<br><br>Object.defineProperty(person, "name", {<br> configurable: false<br>})<br><br>delete person.name; // 操作被忽略,无法通过delete删除属性<br>Object.defineProperty(person, "name", { // throw error<br> configurable:true <br>}) <br>Object.defineProperty(person, "name", { // throw error<br> enumerable: false<br>}) <br>Object.defineProperty(person, "name", { // 由于writable为true,所以可以修改value<br> value: 'Lucy'<br>})console.log(person.name) // Lucy<br>Object.defineProperty(person, "name", { // writable可进行true -> false的单向修改<br> writable: false<br>})<br>Object.defineProperty(person, "name", { // throw error<br> value: 'Lee'<br>})<br>Object.defineProperty(person, "name", { // throw error,此时writable不可以false -> true<br> writable: true<br>})<span style="color: #000000;"></span></span>
總結configurable:當configurable設為false時,
1、不可以透過delete去刪除該屬性從而重新定義屬性;
2、不可以轉換為存取器屬性;
3、configurable和enumerable無法修改;
4、writable可單向修改為false,但不可以由false改為true;
5、value是否可修改根據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; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable默认为true for (var i in person) { console.log(i); } // 'a' 和 'd' Object.keys(person); // ["a", "d"]
存取器屬性
存取器屬性包含四個屬性描述符:
[[Configurable]] :表示能否透過delete刪除屬性從而重新定義屬性,能否修改屬性特性,能否把屬性修改為資料屬性。直接在物件上定義的屬性,預設為true。
[[Enumerable]] : 表示能否透過for-in 迴圈存取屬性。直接在物件上定義的屬性,預設為true。
[[Get]] : 讀取屬性時呼叫的函數,預設為undefined。
[[Set]] : 寫入屬性時呼叫的函數,預設為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。
資料屬性與存取器屬性的相互轉換
#Object.getOwnPropertyDescriptor 讀取屬性的特性
使用Object.getOwnPropertyDescriptor可以取得到屬性的描述子:
Object.getOwnPropertyDescriptor(obj, prop)
obj:屬性所在的物件;
obj:屬性所在的物件; prop:要存取的屬性名稱。
資料屬性-> 存取器屬性屬性的特性只能是存取器描述符和資料描述符中的一種,給已有的數據當屬性加get或set轉換為存取器屬性時,其屬性的value、writable就會被廢棄。 如下程式碼,將物件原有的資料屬性year轉換為存取器屬性:
*註:在存取器屬性的get和set中,不可以使用this訪問屬性本身,否則會無限遞歸而導致記憶體洩漏。// 设置get和set其中任意一个即可转换为访问器属性
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}
在原有的資料屬性year中,使用Object.defineProperty()為屬性設定get 或 set,都可以轉換為存取器屬性。
将访问器属性转换为数据属性,只需要给现有访问器属性设置value或writable这两个属性描述符中的任意一个即可,其原有的get和set就会被废弃,从而转换为数据属性。
上面为person定义的访问器属性age,通过Object.defineProperty()只设置了get和set,所以configurable默认为false,不可以将其转换为数据属性。可以在访问器属性和数据属性间相互转化的属性其configurable特性值必须为true。
如下代码,我们为person新定义一个访问器属性job,将其configurable设置为true ,并将其转换为数据属性:
Object.defineProperty(person, "job", { configurable: true, enumerable: true, get: function() { return this._job; }, set: function(value) { this._job = value; } }) // 设置value和writable其中任意一个即可转换为数据属性 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}
数据描述符value、writable 和访问器描述符get、set不能同时设置,否则会报错。
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; } } });
相关教程推荐:JavaScript视频教程
以上是詳解javascript物件的資料屬性與存取器屬性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

在JavaScript中如何獲取原型鏈上函數的參數在JavaScript編程中,理解和操作原型鏈上的函數參數是常見且重要的任�...

在微信小程序web-view中使用Vue.js動態style位移失效的原因分析在使用Vue.js...

在Tampermonkey中如何對多個鏈接進行並發GET請求並依次判斷返回結果?在Tampermonkey腳本中,我們經常需要對多個鏈...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1
強大的PHP整合開發環境