摘要:數據屬性數據屬性有個描述其行為的特性表示能否通過刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。在讀取訪問器屬性時,會調用函數,在寫入訪問器屬性時,又會調用函數并傳入新值。
JavaScript 數據屬性和訪問器屬性
一個例子原文鏈接
先看代碼:
var obj = {name:"percy"}; console.log(obj.name); // percy obj.name = "zyj"; console.log(obj.name); // zyj // 這里借 Math 對象來舉例 // 首先說明一下, Math 對象和上面定義的 obj 對象都只是 Object 對象的一個實例 console.log(Math.PI); // 3.1415926... Math.PI = 1234; console.log(Math.PI); // 3.1415926...
看到了嗎?同樣是 Object 的實例,obj 對象的屬性卻可以被改寫,而 Math 對象的屬性去不能被改寫。好,讓我們來碼一行,從而讓 obj 對象的屬性也不能被改寫:
var obj = {name:"percy"}; console.log(obj.name); // percy Object.defineProperty(obj,"name",{writable:false}); obj.name = "zyj"; console.log(obj.name); // percy
看到了嗎,這其中另有玄機,接下來就引入了我們的主角:對象的數據屬性和訪問器屬性。
數據屬性(Data Properties)為了表示特性是內部值,規范(ECMA-262)就把它們放到了兩對兒方括號里了,例如 [[Enumerable]]。
數據屬性有4個描述其行為的特性:
[[Configurable]] : 表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。
[[Enumerable]] : 表示能否通過 for-in 循環返回屬性。
[[Writable]] : 表示能否修改屬性的值。
[[Value]] : 包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值時,把新值保存在這個位置。默認值是 undefined。
像這樣(var obj = new Object(); obj.name = "percy";)或者像通過對象字面量(var obj = {name: "percy"};)直接在對象上定義的屬性,它們的 [[Configurable]]、[[Enumerable]] 和 [[Writable]] 特性默認都被設置為 true,而 [[Value]] 特性被設置為指定的值。
這里注意一下這個(可以先跳過,完了再看):
var person = {}; // 新建一個空對象 Object.defineProperty(person,"name",{ value: "percy" }); console.log(Object.getOwnPropertyDescriptor(person,"name")); // 打印:Object {value: "percy", writable: false, enumerable: false, configurable: false}
沒有按上面的2種方法為對象添加屬性,而直接通過 Object.defineProperty() 為對象添加屬性以及值,這種情況下,這個對象的這個屬性的另外3個特性的默認值都是 false。
要修改屬性默認的特性,必須使用 ECMAScript 的 Object.defineProperty() 方法。
Object.defineProperty( obj, prop, descriptor)
obj:需要定義屬性的對象。
prop:需定義或修改的屬性的名字。
descriptor:一個包含設置特性的對象
var person = {name: "percy"}; Object.defineProperty(person,"name",{ writable: false }); console.log(person.name); // percy person.name = "zyj"; console.log(person.name); // percy for(let prop in person){ console.log(prop + " : " + person[prop]); } // name : percy Object.defineProperty(person,"name",{ enumerable: false }); for(let prop in person){ console.log(prop + " : " + person[prop]); } // 什么也沒打印 Object.defineProperty(person,"name",{ configurable: false }); Object.defineProperty(person,"name",{ configurable: true }); // 報錯:TypeError: Cannot redefine property: name(…) // 一旦把屬性定義為不可配置的,那么就再也不能把屬性定義回可配置的了。訪問器屬性(Accessor Properties)
訪問器屬性不包含數據值,它們包含一對兒 getter 和 setter 函數(不過,這兩個函數都不是必需的)。在讀取訪問器屬性時,會調用 getter 函數,在寫入訪問器屬性時,又會調用 setter 函數并傳入新值。
訪問器屬性有如下4個特性:
[[Configurable]]:表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。
[[Enumerable]]:表示能否通過 for-in 循環返回屬性。
[[Get]]:在讀取屬性時調用的函數。默認值為 undefined。
[[Set]]:在寫入屬性時調用的函數。默認值為 undefined。
訪問器屬性不能直接定義,必須使用 Object.defineProperty() 來定義。
var book = { _year : 2004, edition : 1 }; Object.defineProperty(book,"year",{ get : function () { alert(this._year); }, set : function (newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year; // 彈出窗口,顯示 2004 book.year = 2005; console.log(book.edition); // 2
定義多個屬性要是上面的代碼有不懂得地方,參看這里,JavaScript理解對象:屬性類型(推薦)
Object.defineProperties(obj, props)
var obj = {}; Object.defineProperties(obj, { "property1": { value: true, writable: true }, "property2": { value: "Hello", writable: false } // 等等. }); console.log(obj); // Object {property1: true, property2: "Hello"}讀取屬性的特性
Object.getOwnPropertyDescriptor(obj, prop) 返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)
var girl = {name: "zyj"}; console.log(Object.getOwnPropertyDescriptor(girl,"name")); // Object {value: "zyj", writable: true, enumerable: true, configurable: true} Object.defineProperties(girl,{ name:{ writable: false }, age:{ writable: true, value: 22 } }); console.log(Object.getOwnPropertyDescriptor(girl,"name")); // Object {value: "zyj", writable: false, enumerable: true, configurable: true} console.log(Object.getOwnPropertyDescriptor(girl,"age")); // Object {value: 22, writable: true, enumerable: false, configurable: false} var descriptor = Object.getOwnPropertyDescriptor(girl,"age"); console.log(descriptor.value); // 22 console.log(descriptor.configurable); // false console.log(descriptor.writable); // true console.log(descriptor.get); // undefined console.log(descriptor.set); // undefined摘抄自文末的鏈接
A property is a name (string identifier) associated with a property descriptor.
As of ECMAScript 5, three property types are available:
Internal Properties
Data properties
Accessor properties
參考資料【書】《JavaScript 高級程序設計(第三版)》
【文章】Object: Data Property and Accessor Property(推薦)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80297.html
摘要:深入理解中的屬性和特性中屬性和特性是完全不同的兩個概念,這里我將根據自己所學,來深入理解中的屬性和特性。其中第三個參數描述符對象是對象字面量的方法創建的,里面的屬性和屬性值實際上保存的是要修改的特性和特性值。 深入理解JavaScript中的屬性和特性 JavaScript中屬性和特性是完全不同的兩個概念,這里我將根據自己所學,來深入理解JavaScript中的屬性和特性。 主...
摘要:上一篇面向對象版塊之理解對象下一篇面向對象版塊之定義多個對象屬性以及讀取屬性特性 這是 javascript 面向對象版塊的第二篇文章,主要講解的是對象的屬性,首先創建一個對象: var person = { name: Nicholas, age: 29, job: Software Engineer, sayName: function () { conso...
摘要:數據屬性有個描述其行為的特性表示能否通過刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。總結一波關于這些內容主要講的就是在的對象屬性可以分為兩類,一類就是數據屬性,一類就是訪問器屬性。 前言 面向對象的語言都有一個類的概念,通過類可以創建任意多個具有相同屬性和方法的對象。 JavaScript中把對象定義為無序屬性的集合,屬性可以包含基本值,對象或者函數...
摘要:面向對象的程序設計理解對象前言最近在細讀高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。總結如果英語水平足夠好的話,建議看英文原版書籍或者國外大師的博客。 JS面向對象的程序設計_理解對象 前言:最近在細讀Javascript高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。 如有紕漏或錯誤,會非...
摘要:但好在還給我們提供了一個方法,每一個對象都有這樣一個方法,專門用來判斷某個屬性是否是該對象的私有屬性。如果你想要用對象字面形式,你只能在創建對象時定義訪問器屬性。在中,我們使用凍結一個對象,并且使用來判斷一個對象是否被凍結。 說完了對象那些不常用的冷知識,是時候來看看JavaScript中對象屬性有哪些有意思的東西了。 不出你所料,對象屬性自然也有其相應的特征屬性,但是這個話題有點復雜...
閱讀 4078·2021-10-08 10:04
閱讀 3061·2021-08-11 11:20
閱讀 2731·2021-07-25 21:37
閱讀 2681·2019-08-30 12:44
閱讀 2306·2019-08-30 11:12
閱讀 1314·2019-08-26 13:45
閱讀 2338·2019-08-26 11:53
閱讀 3057·2019-08-26 11:32