vue2響應(yīng)式原理之Object.defineProperty()方法的使用
前言
最近一直在研究vue2響應(yīng)式原理,去官網(wǎng)看一遍文檔,好像懂了但又好像不懂,然后去查看別人寫的響應(yīng)式原理和視頻,好的理解了百分六七十頭皮發(fā)麻,vue2的響應(yīng)式原理實現(xiàn)的核心就是Object.defineProperty()方法,所以自己也跟著手敲一下響應(yīng)式源碼記錄對Object.defineProperty的理解
一、Object.defineProperty()
1.概念
Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性,并返回此對象.
這句話到底什么意思呢?
我們簡單實現(xiàn)這個方法
var obj = {}
Object.defineProperty(obj, 'name', {
value:'科比'
})
console.log(obj.name) //科比
可以看出Object.defineProperty()能為我們定義一個屬性,又有人會想為什么我們不直接定義obj.name='科比',而使用這個方法不更加麻煩嗎?
2.Object.definProperty()方法
可以設(shè)置額外隱藏的屬性使用這些屬性能夠使對象更加自由的被定義
var obj = {}
Object.defineProperty(obj, 'name', {
value:'科比',
//是否可寫
writable: false
})
Object.defineProperty(obj, 'number', {
value:24,
//是否可枚舉
enumerable: false
})
//修改屬性報錯
obj.name = "庫里" //Cannot assign to read only property 'name' of object '#<Object>'
console.log(obj.name) 通過obj對象定義writable: false 使你屬性不能修改,如果修改obj.name就會報錯;enumerable是否可以枚舉,所以使用這些屬性能夠使對象更加自由的被定義
二、Object.definProperty()方法的get()和set()
代碼如下(示例):
通過這個示例可知訪問obj.name屬性就會觸發(fā)get()方法,修改obj.name屬性觸發(fā)set()方法
但是我們發(fā)現(xiàn)修改obj.name屬性為"喬丹",打印為undefined這是為什么呢?


看一下get和set方法的介紹:
get
- 屬性的 getter 函數(shù),如果沒有 getter,則為 undefined。當(dāng)訪問該屬性時,會調(diào)用此函數(shù)。
- 執(zhí)行時不傳入任何參數(shù),但是會傳入 this 對象(由于繼承關(guān)系,這里的this并不一定是定義該屬性的對象)。
- 該函數(shù)的返回值會被用作屬性的值。
- 默認為 undefined。
set
- 屬性的 setter 函數(shù),如果沒有 setter,則為 undefined。
- 當(dāng)屬性值被修改時,會調(diào)用此函數(shù)。
- 該方法接受一個參數(shù)(也就是被賦予的新值),會傳入賦值時的 this 對象。
- 默認為 undefined。
因為get的函數(shù)返回值會被當(dāng)作屬性的值,而我們示例中g(shù)et和set沒有return 任何值,就默認為undefined,修改后:
const obj = {}
Object.defineProperty(obj , 'name' , {
get(){
console.log('訪問obj.name屬性觸發(fā)')
return "喬丹"
},
set(newValue) {
console.log('修改obj.name屬性觸發(fā)' , newValue)
}
})
obj.name //訪問屬性
console.log(obj.name) //喬丹
obj.name = "科比" //修改屬性
console.log(obj.name) //喬丹 
能夠訪問到設(shè)置的obj屬性了,但是修改了obj.name = "科比"
最后打印還是"喬丹" ,但是set方法觸發(fā)的newValue是科比這又是為什么呢?
因為getter并不能返回你修改的值,只要你訪問obj.name他就是返回return "喬丹"
就如同你設(shè)置的set新屬性從未改變一樣非常固執(zhí),那么我們應(yīng)該怎么解決這個問題呢?
我們可以通過一個變量com進行周轉(zhuǎn),修改如下:
var obj = {}
var com; //設(shè)置變量周轉(zhuǎn)
Object.defineProperty(obj , 'name' , {
get(){
console.log('訪問obj.name屬性觸發(fā)')
return com
},
set(newValue) {
console.log('修改obj.name屬性觸發(fā)' , newValue)
com = newValue
}
})
obj.name //訪問屬性
console.log(obj.name) //喬丹
obj.name = "科比" //修改屬性科比
console.log(obj.name) //最后控制臺打印 科比總結(jié)
vue2的響應(yīng)式原理核心就是基于Object.defineProperty()方法實現(xiàn)的喲,不過完整的響應(yīng)式源碼可不止這樣簡單,所以下一篇博客就是手敲完整vue2響應(yīng)式源碼實現(xiàn),加深理解.
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
實例詳解Vue項目使用eslint + prettier規(guī)范代碼風(fēng)格
這篇文章主要介紹了Vue項目使用eslint + prettier規(guī)范代碼風(fēng)格,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2018-08-08
Vue.js綁定HTML class數(shù)組語法錯誤的原因分析
Vue.js綁定HTML class數(shù)組語法錯誤有哪些原因?qū)е碌哪?,該如何解決呢?下面小編給大家分享Vue.js綁定HTML class數(shù)組語法錯誤的原因分析,感興趣的朋友一起看看吧2016-10-10
vue?cli3配置image-webpack-loader方式
這篇文章主要介紹了vue?cli3配置image-webpack-loader方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
vue+iview+less+echarts實戰(zhàn)項目總結(jié)
本篇文章是作者通過學(xué)習(xí)vue+iview+less+echarts制作一個小系統(tǒng)后,做的心得以及遇到的坑的總結(jié),值得大家學(xué)習(xí)參考。2018-02-02

