首頁 web前端 js教程 詳解javascript物件的資料屬性與存取器屬性

詳解javascript物件的資料屬性與存取器屬性

Jul 09, 2020 pm 03:00 PM
javascript 物件

詳解javascript物件的資料屬性與存取器屬性

建立物件的方式有兩種:第一種,透過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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

如何將 MySQL 查詢結果陣列轉換為物件? 如何將 MySQL 查詢結果陣列轉換為物件? Apr 29, 2024 pm 01:09 PM

將MySQL查詢結果陣列轉換為物件的方法如下:建立一個空物件陣列。循環結果數組並為每一行建立一個新的物件。使用foreach迴圈將每一行的鍵值對賦給新物件的對應屬性。將新物件加入到物件數組中。關閉資料庫連線。

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

PHP 函數如何傳回物件? PHP 函數如何傳回物件? Apr 10, 2024 pm 03:18 PM

PHP函數可以透過使用return語句後接物件實例來傳回對象,從而將資料封裝到自訂結構中。語法:functionget_object():object{}。這允許創建具有自訂屬性和方法的對象,並以對象的形式處理資料。

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

C++ 函式回傳物件時有什麼需要注意的? C++ 函式回傳物件時有什麼需要注意的? Apr 19, 2024 pm 12:15 PM

在C++中,函數傳回物件需要注意三點:物件的生命週期由呼叫者負責管理,以防止記憶體洩漏。避免懸垂指針,透過動態分配記憶體或返回物件本身來確保物件在函數返回後仍然有效。編譯器可能會最佳化傳回物件的副本生成,以提高效能,但如果物件是值語義傳遞的,則無需副本生成。

數組和物件在 PHP 中的差異是什麼? 數組和物件在 PHP 中的差異是什麼? Apr 29, 2024 pm 02:39 PM

PHP中,數組是有序序列,以索引存取元素;物件是具有屬性和方法的實體,透過new關鍵字建立。數組存取透過索引,物件存取通過屬性/方法。數組值傳遞,物件參考傳遞。

See all articles