getter與setter被JS對象添加5種方法

一、定義 getter 與 setter

1.通過對象初始化器在創(chuàng)建對象的時候指明也可以稱為通過字面值創(chuàng)建對象時聲明)

在 chrome 中調(diào)試視圖如下:

可以看到對象下多了?get?屬性以及?set?屬性

當然?get?語句與?set?語句可以聲明多次用來對應(yīng)多個?getter?和?setter

使用這種方法的好處是可以在聲明屬性的時候同時聲明對應(yīng)的?getter?和?setter

這里就有人問了,能不能將o 對象的?get?及?set?方法的方法名都改成 “a”,這樣就可以直接通過“.”來訪問方法直接操作

打開 chrome 查看創(chuàng)建后的視圖如下:?

可以看到這個時候的get與set方法已經(jīng)和上面不同,但是是否真的能起作用呢,答案是否定的,當我們通過o.a調(diào)用的是get語句 聲明的 a方法,進入到該方法后遇到this.a方法繼續(xù)調(diào)用該方法形成死循環(huán)最終導致死循環(huán)報內(nèi)存溢出錯誤。

新語法(ES6):暫時只有 firefox 支持,其他瀏覽器會報錯

打開 firefox 查看調(diào)試:?

輸出結(jié)果如下:

2.使用?Object.create?方法

引用 MDN:

概述 Object.create() 方法創(chuàng)建一個擁有指定原型和若干個指定屬性的對象。 語法 Object.create(proto, [ propertiesObject ])

我們都知道使用?Object.create?方法傳遞一個參數(shù)的時候可以創(chuàng)建一個以該參數(shù)為原型的對象。

第二個參數(shù)是可選項,是一個匿名的參數(shù)對象,該參數(shù)對象是一組屬性與值,該對象的屬性名稱將是新創(chuàng)建的對象的屬性名稱,值是屬性描述符(包擴數(shù)據(jù)描述符或存取描述符,具體解釋看后面的內(nèi)容 什么是屬性描述符)。

通過屬性描述符我們可以實現(xiàn)為新創(chuàng)建的對象添加?get?方法以及?set?方法

在 chrome 中調(diào)試試圖如下:?

可以看到新創(chuàng)建對象通用多了?get?以及?set?屬性。

輸出結(jié)果如下:?

上面這個例子并沒有用來針對的?get?方法以及?set?方法使用的屬性

亦或者是:

輸出結(jié)果如下:

使用這種方式的好處是可配置性高,但初學者容易迷糊。

3.使用??Object.defineProperty??方法

引用 MDN:

概要 Object.defineProperty() 方法直接在一個對象上定義一個新屬性,或者修改一個已經(jīng)存在的屬性, 并返回這個對象。 語法 Object.defineProperty(obj, prop, descriptor) 參數(shù) obj 需要定義屬性的對象。 prop 需被定義或修改的屬性名。 descriptor 需被定義或修改的屬性的描述符。

這個方法與前面兩種的區(qū)別是:使用前面兩種只能在聲明定義的時候指定getter與setter,使用該方法可以隨時的添加或修改。

如果說需要一次性批量添加 getter 與 setter 也是沒問題的,使用如下方法:

4.使用??Object.defineProperties?方法

MDN:

概述 Object.defineProperties() 方法在一個對象上添加或修改一個或者多個自有屬性,并返回該對象。 語法 Object.defineProperties(obj, props) 參數(shù) obj 將要被添加屬性或修改屬性的對象 props 該對象的一個或多個鍵值對定義了將要為對象添加或修改的屬性的具體配置

不難看出用法與Object.defineProperty方法類似

輸出結(jié)果如下:

5.使用?Object.prototype.__defineGetter__?以及?Object.prototype.__defineSetter__??方法

輸出結(jié)果為1和2 查看 MDN 有如下說明:?

二、什么是屬性描述符?

MDN:

對象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符。

數(shù)據(jù)描述符是一個擁有可寫或不可寫值的屬性。

存取描述符是由一對 getter-setter 函數(shù)功能來描述的屬性。

描述符必須是兩種形式之一;不能同時是兩者。

數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:

value 與屬性相關(guān)的值??梢允侨魏斡行У?JavaScript 值(數(shù)值,對象,函數(shù)等)。默認為 undefined。 writable true 當且僅當可能用 賦值運算符 改變與屬性相關(guān)的值。默認為 false。

存取描述符同時具有以下可選鍵值:get

一個給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。方法將返回用作屬性的值。默認為 undefined。 set 一個給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。該方法將收到作為唯一參數(shù)的新值分配給屬性。默認為 undefined。

以上是摘自MDN的解釋,看起來是很晦澀的,具體什么意思呢: 首先我們從以上解釋知道該匿名參數(shù)對象有個很好聽的名字叫屬性描述符,屬性描述符又分成兩大塊:數(shù)據(jù)描述符以及存取描述符(其實只是一個外號,給指定的屬性集合起個外號)。

數(shù)據(jù)描述符包括兩個屬性 :value屬性以及writable屬性,第一個屬性用來聲明當前欲修飾的屬性的值,第二個屬性用來聲明當前對象是否可寫即是否可以修改

存取描述符就包括get與set屬性用來聲明欲修飾的象屬性的getter及setter

屬性描述符內(nèi)部,數(shù)據(jù)描述符與存取描述符只能存在其中之一,但是不論使用哪個描述符都可以同時設(shè)置configurable屬性以及enumerable屬性。

configurable屬性用來聲明欲修飾的屬性是否能夠配置,僅有當其值為true時,被修飾的屬性才有可能能夠被刪除,或者重新配置。

enumerable屬性用來聲明欲修飾屬性是否可以被枚舉。

知道了什么是屬性描述符,我們就可以開始著手創(chuàng)建一些對象并開始配置其屬性

三、創(chuàng)建屬性不可配置不可枚舉的對象

輸出結(jié)果如下:

五、Configurable 特性

六、提高及擴展

1.屬性描述符中容易被誤導的地方之writable與configurable

2.通過上面的學習,我們都知道傳遞屬性描述符參數(shù)時,是定義一個匿名的對象,里面包含屬性描述符內(nèi)容,若每定義一次便要創(chuàng)建一個匿名對象傳入,將會造成內(nèi)存浪費。故優(yōu)化如下:

如果有其他疑問或是看法可以在評論里或投稿跟小編進行討論,也可以關(guān)注微信公眾號【筑夢前端】進行投稿,與小編一起探討更多的編程知識。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容