回顧 object.defineProperty() 方法
區別
defineProperty == 給物件定義屬性用的
需要傳遞三個基本引數
- 需要定義屬性的物件名
- 你要定義的屬性叫什麼名字(比如給person這個實體新增一個age屬性)
- 設定項(物件型別的引數,裡面存放鍵值對)
<script>
// 建立一個物件,該物件有兩個基本屬性
var person = {
name:"張三",
sex:"男"
}
// 為person物件新增屬性
// 1、給那個物件新增?
// 2、新增的屬性名是什麼?
// 3、這個屬性的基礎設定項(物件型別,鍵值對形式)
Object.defineProperty(person,"age",{
value:18, // 該屬性的值是
})
</script>
需求1
- 給 物件person,新增一個屬性age,有幾種方式?
- 三種
- 直接在 person物件當中新增屬性;該屬性值可以修改
- 通過 .屬性;對其設定;該屬性值可以修改
- 通過 Object.finedProperty()進行新增;該屬性值不可列舉(不可修改) 預設情況下
不可列舉性
通過 defineProperty新增的屬性
如果不設定設定項,那麼該屬性是不可列舉的;在控制檯中可以看到,顏色變淺了
該屬性不參與遍歷,我們可以測試下
基本設定項
value
最開始設定的
enumerable
Object.defineProperty(person,"age",{
value:18, // 該屬性的值是
enumerable:true, // 該設定項控制新增的屬性是否參與列舉
})
writable
設定屬性是否可以被修改
configurable
控制屬性是否可以被刪除
沒有通過函數新增age屬性的person物件
通過函數新增age屬性的person物件刪除屬性
設定設定項刪除掉age屬性
需求2
- 準備一個變數 number,值為18
- person當中有一個age屬性,這個屬性的value 是 number(不是手寫的18)
問題所在
- 這個變數的值可能會發生改變,如果呢?
- 修改number,person物件當中的age值並沒有發生改變
- 同理,修改age,number也不會發生改變
這倆好像有點關係,但好像又沒有關係,就js程式碼載入的時候這倆自頂而下有了這一層關係,但也僅僅只有這一層
那怎麼完成這個需求呢?
請看下方的高階設定項
高階設定項
get(getter)設定項
解析
- 它的資料型別是一個物件
- 當 有人讀取 person當中的age屬性的時候,get就會被呼叫
- 且get的返回值就是age 的 value值
- 自定義get(getter函數)的時候,不能再使用基礎設定了
那 返回一個 waves 字串吧
三個點兒
- invoke:對映
- property:屬性
- getter:get設定項 == 函數
- get是屬性名
- 他的型別是一個函數型別
- 加在一起就是getter
- age 屬性 是有的
- 但是 value 是多少,目前不知道(...)
- 想知道怎麼辦?點進去嘛
get函數
寫個程式碼測試一下,列印一句話
看樣子是的,我前面的措辭有問題
number與age進行關聯
對number值進行修改
那麼對age修改呢?
問題所在
- 一定是 先存取age
- 再呼叫getter
- 當number的value發生改變的時候
- 再次存取age,那麼就重新呼叫了getter函數
- 重新呼叫getter,會返回number,而這個number是修改過的,所以這邊資料是同步了
修改age;失敗
修改number,再存取age;成功
set(setter)設定項
同理,既然有get,那麼與之相輔相成的就是set
當你對age屬性進行修改的時候,set(setter)函數就被呼叫
且,呼叫的時候,會收到具體修改的 值
/**
* 需要傳遞一個引數value
* 被呼叫的時候,會收到具體修改的值
*/
set(value){
// 當你對age屬性進行修改的時候,set(setter)函數就被呼叫
// 被呼叫的時候,會收到具體修改的值
console.log("pseron.age屬性發生修改,修改的值是",value);
}
測試
實現雙向繫結
- get函數
- 實現了 number 與 age 的繫結,number發生修改的時候,age會發生變化
- 當 age的值發生變化的時候,number值不變,所以無論怎麼修改,age的值 === number
- set函數
- 實現了 age 與 number 的繫結,age的值發生變化的時候,number的值也會跟著變化
- set函數會接到 age所修改的value,將value 賦值 給 number,完成雙向繫結
測試
總結
通過案例
- number 與 person,是兩個東西
- 但是藉助 Object.defineProperty,使二者進行了關聯
- person,確實是一個物件,age確實是person當中的屬性
- 但是值呢?你現用,我現去給你取