摘要:數(shù)據(jù)屬性有個描述其行為的特性。表示能否通過刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。表示能否修改屬性的值。其中,描述符對象的屬性必須是和。返回值被傳遞給函數(shù)的對象。
屬性類型
ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性:
數(shù)據(jù)屬性包含一個數(shù)據(jù)值的位置。在這個位置可以讀取和寫入值。數(shù)據(jù)屬性有4個描述其行為的特性。
[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。在對象上直接定義的屬性,它們的這個特性默認值為true。 [[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。在對象上直接定義的屬性,它們的這個特性默認值為true。 [[Writable]]:表示能否修改屬性的值。在對象上直接定義的屬性,它們的這個特性默認為true. [[Value]]:包含這個屬性的數(shù)據(jù)值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為undefined。
要修改屬性默認的特性,必須使用ECMAScript5的Object.defineProperty()方法。這個方法接受三個參數(shù):屬性所在的對象、屬性的名字和一個描述符對象。其中,描述符對象的屬性必須是:configurable、enumerable、writable和value。設(shè)置其中的一個或多個值,可以修改對應(yīng)的特性值。例如:
var person = {}; Obejct.defineproperty(person,"name",{ writable:false, value:"Nics" }) console.log(person.name)//Nics person.name = "tom"; console.log(person.name)//Nics
這個例子創(chuàng)建了一個明為name的屬性,它的值是只讀的,如果為它指定新的值,在非嚴格模式下,賦值操作將被忽略;在嚴格模式下賦值操作將會拋出錯誤。
如果把configurable設(shè)置為false,表示不能從對象中刪除屬性,而且一旦把屬性定義為不可配置的,就不能再把它變?yōu)榭膳渲昧恕4藭r再調(diào)用Object.defineProperty()方法修改writable之外的特性都會拋出錯誤。
也就是說,可以多次調(diào)用Object.defineProperty()方法修改同一個屬性,但在把configurable特性設(shè)置為false之后就會有限制了。
再調(diào)用Object.defineProperty()方法創(chuàng)建一個新的屬性的時候,如果不指定configurable、enumerable、writable特性的默認值都是false。
Obejct.defineProperty(obj,prop,descriptor)方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性,并返回這個對象。
參數(shù):
obj:要在其上定義屬性的對象。 prop:要定義或修改的屬性的名稱。 descriptor:將被定義或修改的屬性描述符。
返回值:
被傳遞給函數(shù)的對象。
屬性描述符:
configurable:當且僅當改屬性的configurable為true時,該屬性描述符才能夠被改變,同時該屬性也能從對應(yīng)的對象上被刪除。默認為false。 enumerable:當且僅當改屬性的enumerable為true時,改屬性才能夠出現(xiàn)在對象的枚舉屬性中。默認為false。 數(shù)據(jù)描述符同時具有以下可選鍵值: value:該屬性對應(yīng)的值??梢允侨魏斡行У腏avaScript值(數(shù)值,對象,函數(shù)等)。默認為undefined。 writable:當且僅當該屬性的writable為true時,value才能被賦值運算符改變。默認為false。 存取描述符同時具有以下可選鍵值: get:一個給屬性提供getter的方法,如果沒有g(shù)etter則為undefined。當訪問改屬性時,該方法會被執(zhí)行,方法執(zhí)行時沒有參數(shù)傳入,但是會傳入this對象(由于繼承關(guān)系,這里的this并不一定是定義該屬性的對象)默認為undefined。 set:一個給屬性提供setter的方法,如果沒有setter則為undefined。當屬性值修改時,觸發(fā)執(zhí)行該方法。該方法將接受唯一參數(shù),即改屬性新的參數(shù)值。
var o = {} //在對象中添加一個屬性與數(shù)據(jù)描述符的示例。 Obejct.defineProperty(o,"a",{ value:37, writable:true, enumerable:true, configurable:true }) //對象o擁有了屬性a,值為37 //在對象中添加一個屬性與存取描述符的示例。 var bValue; Obejct.defineProperyty(o,"b",{ get:function(){ return bValue; }, set:function(newValue){ bValue = newValue; }, enumerable:true, configurable:true }) o.b = 38; //對象o擁有了屬性b,值為38. //數(shù)據(jù)描述符和存取描述符不能混合使用。
一般的Setters和Getters
下面的例子展示了如何實現(xiàn)一個自存檔對象。當設(shè)置temperature屬性時,archive數(shù)組會獲取日志條目。
function Archiver(){ var temperatrue = null; var aechive = []; Obejct.defineProperty(this,"temperatrue",{ get:function(){ console.log("get!"); return temperature; }, set:function(value){ temperature = value; archive.push({val:temperature}) } }); this.getArchive = function(){return archive} } var arc = new Archiver(); arc.temperature;//"get!"; arc.temperature = 11; arc.temperature = 13; arc.getArchive();//[{val:11},{val:13}]
或:
var pattern = { get:function(){ return "I alway return this string,whatever you have assigned" }, set:function(){ this.myname = "this is my name string" } } function TestDefineSetAndGet(){ Object.defineProperty(this,"myproperty",pattern); } var instance = new TestDefineSetAndGet(); instance.myproperty = "test"; console.log(instance.myproperty); console.log(instance.myname)
如果訪問者的屬性是被繼承的,他的get和set方法會在子對象的屬性被訪問或者修改時被調(diào)用。如果這些方法用一個變量存值,該值會被所有對象共享。
function myclass(){} var value; Obejct.defineProperty(myclass.prototype,"x",{ get(){ return value; }, set(x){ value = x; } }) var a = new myclass(); var b = new myclass(); a.x=1; console.log(b.x);//1
在get和set方法中,this指向某個被訪問和修改屬性的對象。
function myclass(){} Obejct.defineProperty(myclass.prototype,"x",{ get(){ return this.stored_x; }, set(x){ this.stored_x = x; } }); var a = new myclass(); var b = new myclass(); a.x=1; console.log(b.x)//undefined
不像訪問者屬性,值屬性始終在對象自身上設(shè)置,而不是一個原型。然而,如果一個不可寫的屬性被繼承,它仍然可以防止修改對象的屬性。
function myclass() { } myclass.prototype.x = 1; Object.defineProperty(myclass.prototype, "y", { writable: false, value: 1 }); var a = new myclass(); a.x = 2; console.log(a.x); // 2 console.log(myclass.prototype.x); // 1 a.y = 2; // Ignored, throws in strict mode console.log(a.y); // 1 console.log(myclass.prototype.y); // 1
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/102797.html
摘要:通過設(shè)置我們可以將一些屬性鎖定,來防止別人的修改,這是一種防御編程形式,就像語言的內(nèi)置對象一樣不過的內(nèi)置對象都可以被隨意更改??梢允褂脕砼袛嗄骋粋€屬性是否可以枚舉。 對象管理器(defineProperty) 在 JavaScript 里面聲明一個變量,通常我們有三種方式可以實現(xiàn): let person = {} // 對象字面量 let cat = new Objec...
摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅持健身三個月早睡早起游戲時間大大縮減,學(xué)會生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...
摘要:面向?qū)ο蟾攀雒嫦驅(qū)ο缶幊痰娜Q是簡稱為。面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建給予現(xiàn)實世界模型的一種編程模式。構(gòu)造函數(shù)構(gòu)造函數(shù)又被稱為構(gòu)造器或?qū)ο竽0澹莿?chuàng)建對象的一個方法。 面向?qū)ο?概述 面向?qū)ο缶幊痰娜Q是Object Oriented Programming,簡稱為OOP。面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建給予現(xiàn)實世界模型的一種編程模式。面向?qū)ο缶幊炭梢悦嫦驅(qū)ο缶幊痰娜齻€主要特征是:1.封裝 ...
摘要:函數(shù)式對象的一個子類型,中的函數(shù)是一等公民內(nèi)置對象中還有一些對象子類型,通常被稱為內(nèi)置對象。內(nèi)容對象的內(nèi)容是由一些存儲在特定命名位置的任意類型的值組成的,我們稱之為屬性。 語法 對象兩種定義形式 聲明(文字)形式 構(gòu)造形式 //聲明(文字)形式 var myObj = { key: value // ... } //構(gòu)造形式 var myObj = new Ob...
摘要:枚舉對象的屬性第二種情況設(shè)置為,可以被枚舉。內(nèi)置對象訪問器屬性方法介紹摘自方法返回指定對象上一個自有屬性對應(yīng)的屬性描述符。對象中存在的屬性描述符主要有數(shù)據(jù)描述符和訪問器描述符兩種返回傳遞給函數(shù)的對象參考中的 1. 什么是對象 對象是無序?qū)傩缘募?創(chuàng)建自定義對象最簡單的方式就是以字面量的形式創(chuàng)建對象(或創(chuàng)建一個Object實例),然后再為它添加屬性和方法,如下所示: var perso...
閱讀 3868·2021-09-02 09:53
閱讀 2870·2021-07-30 14:57
閱讀 3634·2019-08-30 13:09
閱讀 1280·2019-08-29 13:25
閱讀 890·2019-08-29 12:28
閱讀 1520·2019-08-29 12:26
閱讀 1211·2019-08-28 17:58
閱讀 3384·2019-08-26 13:28