擱置了幾天我還是決定再次重寫鳍怨!
下邊我們來具體聊聊先從defineProperty開始說起
defineproperty
//defineproperty 有個定義object屬性的功能,應(yīng)該沒幾個人用顷级,因為相對于obj.a = 1這種方式簡直不能再難用。
//通常我們定義obj屬性
let obj = {
a:1
}
obj.b = 2
obj['c'] = 3
console.log(obj)//{a: 1, b: 2,c: 3}
Object.defineProperty(obj,'d',{
value: 4
})
console.log(obj)//{a: 1, b: 2,c: 3,d:4} //defineProperty可以定義對象屬性
//也可以修改
Object.defineProperty(obj,'b',{
value: 5
})
console.log(obj)//{a: 1, b: 5, c: 3, d: 4}
//對你沒看錯defineProperty有這個功能俺抽,不知可以定義新的屬性還可以修改呛讲,這么逆天難用的功能為什么還要造出來?說這個有什么用莫湘?別急往下看
descriptor詳解
defineProperty 接收三個參數(shù)
object (必須有 操作的對象本身 這個很容易理解不傳它操作誰?)
propertyname (必須有 屬性名 添加修改屬性得有屬性名)
-
descriptor (必須有 官方說的我理解不了郑气,我理解的是 屬性描述
1幅垮、簡單點就是 設(shè)置屬性的值value,
2竣贪、是否可操作屬性值 writable军洼,
3、是否可修改配置configurable如果值為false descriptor內(nèi)的屬性都不可操作)
4演怎、是否可枚舉enumerable*descriptor內(nèi)配置可有可無匕争,value默認(rèn)undefind,其余默認(rèn)為false
先做了介紹我們下邊來證明下
writable
//栗子還是這個栗子
let obj = {
a: 1
}
Object.defineProperty(obj, 'b', {
value: 2,
writable: false//不可修改
})
obj.b = 3
console.log(obj) //{a: 1, b: 2} 還真是不可以
//難道是姿勢不對爷耀?
Object.defineProperty(obj, 'b', {
value: 3
})
console.log(obj)//{a: 1, b: 2} 一樣的效果 和姿勢無關(guān)甘桑。
configurable
//configurable 這個比較厲害 控制descriptor內(nèi)屬性都不可改變不知道是不是真的
//還是這個栗子
let obj = {
a: 1
}
Object.defineProperty(obj, 'b', {
value: 2,
//writable: false//不可修改
configurable: false
})
obj.b = 5
console.log(obj)//[1,2]
enumerable
對否可枚舉
let obj = {
a: 1
}
Object.defineProperty(obj, 'b', {
value: 2,
//writable: false//不可修改
//configurable: false
enumerable: false
})
//obj.b = 5
console.log(Object.keys(obj))//["a"]
接了下來說到重點: set和get這也是vue3.0前observe的實現(xiàn)原理
let obj = {
a: 1
}
let newValue = 45
Object.defineProperty(obj, 'b', {
get(value) {
console.log('獲取')
return value
},
set(newValue) {
console.log('設(shè)置')
value = newValue
}
})
obj.b = 6 //設(shè)置
obj.b //獲取
知道用法了我們來實踐一下
//html
<div></div>
<input type="text">
//js
//類似 vue的data
let obj = {}
/*
*obj 要劫持的對象
*name 要劫持對象的屬性
*callback 劫持以后的操作
*/
function watch(obj, name, callback) {
let value = obj.name
Object.defineProperty(obj, name, {
set(msg) {
// 觸發(fā)setter給obj賦值
value = msg
//執(zhí)行劫持后的操作
callback(value)
},
get() {
//返回獲取屬性值
return value
}
})
}
//
function doSomething(value) {
document.querySelector('div').innerHTML = value
document.querySelector('input').value = value
}
//監(jiān)聽input變化
//可以參考全兼容版:https://segmentfault.com/a/1190000017524278
document.querySelector('input').addEventListener('input', (e) => {
obj['msg'] = e.target.value
})
watch(obj, 'msg', doSomething)
效果:
1、input輸入改變div內(nèi)容
2、改變obj name屬性
3跑杭、獲取改變后的obj屬性name
簡單的用defineProperty實現(xiàn)了雙向綁定
歡迎吐槽铆帽!您的點贊是我繼續(xù)的動力!謝謝