js對象object屬性詳解_js對象object屬性全面介紹

JavaScript對象屬性分為數據屬性和訪問器屬性。1. 數據屬性包含實際值,并有configurable、enumerable、writable和value特性;2. 訪問器屬性通過getter和setter函數控制讀寫,具有configurable、enumerable、get和set特性。Object.getownpropertydescriptor()可用于獲取屬性特性。定義屬性可用直接賦值或object.defineproperty(),后者可精細控制屬性行為。getter和setter可用于實現計算屬性。for…in循環遍歷自身及原型鏈上的可枚舉屬性,而object.keys()僅返回自身的可枚舉屬性。為防止屬性被修改,可用object.preventextensions()阻止擴展、object.seal()密封對象、或object.freeze()凍結對象,三者保護級別遞增且均不作用于嵌套對象。

js對象object屬性詳解_js對象object屬性全面介紹

JavaScript對象(Object)的屬性是構成對象的核心部分,它們定義了對象的狀態和行為。理解對象屬性對于編寫高效、可維護的JavaScript代碼至關重要。

js對象object屬性詳解_js對象object屬性全面介紹

JavaScript對象屬性的全面介紹:

js對象object屬性詳解_js對象object屬性全面介紹

屬性的類型和特性

屬性從類型上可以分為兩種:數據屬性和訪問器屬性。數據屬性包含一個保存數據值的位置,而訪問器屬性不直接保存數據值,而是通過getter和setter函數來讀寫數據。

每個屬性還具有一些特性,這些特性描述了屬性的行為。這些特性包括:

js對象object屬性詳解_js對象object屬性全面介紹

  • [[Configurable]]: 表示屬性是否可以通過delete刪除并重新定義,是否可以修改它的特性,以及是否可以修改為訪問器屬性。默認為true。
  • [[Enumerable]]: 表示屬性是否可以通過for-in循環返回。默認為true。
  • [[Writable]]: 表示屬性的值是否可以修改。默認為true。
  • [[Value]]: 包含屬性實際的值。這是數據屬性特有的。
  • [[Get]]: 在讀取屬性時調用的函數。這是訪問器屬性特有的。
  • [[Set]]: 在寫入屬性時調用的函數。這是訪問器屬性特有的。

可以通過Object.getOwnPropertyDescriptor()方法來獲取屬性的特性。

let person = {   name: "Alice" };  let descriptor = Object.getOwnPropertyDescriptor(person, "name"); console.log(descriptor); // 輸出: // { //   value: 'Alice', //   writable: true, //   enumerable: true, //   configurable: true // }

如何定義屬性?直接賦值,還是用Object.defineProperty?

直接賦值是最簡單的方式,但Object.defineProperty提供了更精細的控制。直接賦值創建的屬性,其configurable、enumerable和writable特性都默認為true。而使用Object.defineProperty,可以顯式地設置這些特性。

let person = {};  // 直接賦值 person.age = 30;  // 使用Object.defineProperty Object.defineProperty(person, "gender", {   value: "female",   writable: false,   enumerable: true,   configurable: false });  console.log(person.age); // 30 console.log(person.gender); // female  person.gender = "male"; // 嘗試修改,嚴格模式下會報錯,非嚴格模式下靜默失敗 console.log(person.gender); // female (值未改變)  delete person.gender; // 嘗試刪除,無效 console.log(person.gender); // female (屬性仍然存在)

副標題1

如何利用getter和setter實現計算屬性?

Getter和setter允許你定義屬性的讀取和寫入行為。這在需要根據其他屬性計算屬性值,或者需要在設置屬性值時執行一些額外的邏輯時非常有用。

let rectangle = {   width: 10,   height: 5,   get area() {     return this.width * this.height;   },   set area(newArea) {     // 這里可以添加一些驗證邏輯     let newWidth = Math.sqrt(newArea * 2); // 假設保持長寬比不變     this.width = newWidth;     this.height = newArea / newWidth;   } };  console.log(rectangle.area); // 50  rectangle.area = 100; console.log(rectangle.width); // 14.142135623730951 console.log(rectangle.height); // 7.0710678118654755

副標題2

for…in循環和Object.keys()有什么區別?何時使用哪個?

for…in循環會遍歷對象自身及其原型鏈上所有可枚舉的屬性。而Object.keys()只會返回對象自身的可枚舉屬性的數組。

  • 使用for…in循環來遍歷對象的所有可枚舉屬性,包括繼承的屬性。
  • 使用Object.keys()來獲取對象自身的可枚舉屬性的數組,然后可以使用for…of循環或foreach()方法來迭代這些屬性。
let animal = {   name: "Generic Animal" };  let dog = Object.create(animal); dog.breed = "Labrador";  console.log("for...in loop:"); for (let key in dog) {   console.log(key); // 輸出: breed, name }  console.log("Object.keys():"); console.log(Object.keys(dog)); // 輸出: [ 'breed' ]

副標題3

如何防止對象屬性被意外修改?Object.freeze()、Object.seal() 和 Object.preventExtensions() 的區別是什么?

JavaScript提供了幾種方法來防止對象屬性被意外修改:

  • Object.freeze(): 凍結對象。不能添加、刪除或修改對象的屬性。configurable和writable特性都會變為false。這是一個最高級別的保護。
  • Object.seal(): 密封對象。不能添加或刪除對象的屬性,但可以修改現有屬性的值。configurable特性會變為false。
  • Object.preventExtensions(): 阻止對象擴展。不能向對象添加新屬性,但可以刪除和修改現有屬性。
let obj = {   prop1: "value1",   prop2: "value2" };  // Object.preventExtensions() Object.preventExtensions(obj); obj.prop3 = "value3"; // 嘗試添加新屬性,嚴格模式下會報錯,非嚴格模式下靜默失敗 console.log(obj.prop3); // undefined  // Object.seal() Object.seal(obj); delete obj.prop1; // 嘗試刪除屬性,嚴格模式下會報錯,非嚴格模式下靜默失敗 obj.prop2 = "new value2"; // 可以修改現有屬性 console.log(obj); // 輸出: { prop1: 'value1', prop2: 'new value2' }  // Object.freeze() Object.freeze(obj); obj.prop2 = "another value"; // 嘗試修改屬性,嚴格模式下會報錯,非嚴格模式下靜默失敗 console.log(obj); // 輸出: { prop1: 'value1', prop2: 'new value2' }

理解這些方法及其區別,可以根據不同的安全需求選擇合適的保護級別。需要注意的是,這些方法都是淺層的,只對對象自身的屬性有效,對于屬性值為對象的屬性,仍然可以修改其內部屬性。

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享