首頁  >  文章  >  web前端  >  談談因Vue.js引發關於getter和setter的思考

談談因Vue.js引發關於getter和setter的思考

高洛峰
高洛峰原創
2017-01-03 17:01:031122瀏覽

起因

當我印出Vue實例下的data物件裡的屬性時,發現了一個有趣的事情:

它的每個屬性都有兩個相對應的get和set方法,我覺的這是多此一舉的,於是去網上查了查Vue雙向綁定的實現原理,才發現它和Angular.js雙向綁定的實現原理完全不同,Angular是用的數據臟檢測,當Model發生變化,會檢測所有視圖是否綁定了相關數據,再更改視圖。而Vue使用的發布訂閱模式,是點對點的綁定資料。

Vue的資料綁定只有兩個步驟,compile=>link。

我一直在想,vue是透過什麼去監聽使用者對Model的修改,直到我發現Vue的data裡,每個屬性都有set和get屬性,我才明白。

在平時,我們創建一個對象,並修改它的屬性,是這樣的:

var obj = {
 val:99
}
obj.val = 100;
console.log(obj.val)//100

   

沒有任何問題,但是如果要你去監測,當我修改了這個對象的屬性時,要去做一些事,你會怎麼做?

相關思考

這就要用到getter和setter了。

假設我現在要為一個碼農物件加上name屬性,而且每次更新name屬性時,我要去完成一些事,我們可以這樣做:

var Coder = function() {
 var that = this;
 return {
  get name(){
   if(that.name){
    return that.name
   }
   return '你还没有取名'
  },
  set name(val){
   console.log('你把名字修成了'+val)
   that.name = val
  }
 }
}
var isMe = new Coder()
console.log(isMe.name)
isMe.name = '周神'
console.log(isMe.name)
console.log(isMe)

   

輸出:

輸出:

輸出:

會發現這個物件和最上面的Vue中的data對象,印出來的效果是一樣的,都擁有get和set屬性。

我們來一步步分析下上面的程式碼,很有趣。

我們先建立一個物件字面量:

var Coder = function() {...}

   

再把this快取一下:

var that = this;

  

rr

顧名思義,get為取值,set為賦值,正常情況下,我們取值和賦值是用obj.prop的方式,但是這樣做有一個問題,我如何知道對象的值改變了?所以就輪到set登場了。

你可以把get和set理解為function,當然,只是可以這麼理解,這是完全不一樣的兩個東西。

接下來創建一個碼農的實例,isMe;此時,isMe是沒有name屬性的,當我們呼叫isMe.name時,我們會進入到get name(){...}中,先判斷isMe是否有name屬性,答案是否定的,那麽就加上一個name屬性,並給它賦值:「你還沒取名";如果有name屬性,那就回傳name屬性。

看到這裡你一定知道get怎麼使用了,對,你可以把get看成一個取值的函數,函數的回傳值就是它拿到的值。

我覺得比較重要的是set屬性,當我給實例賦值:

{
 
  get name(){...},
 
  set name(val){...}
 
}

   

此時,會進入set name(val){...};形參val就是我賦給name屬性的值,在這個函數裡,我就可以做很多事了,例如雙向綁定!因為這個值的每次改變都必須經過set,其他方式是改變不了它的,相當於萬能的監聽器。

還有另一種方法可以實現這個功能。

ES5的物件原型有兩個新的屬性__defineGetter__和__defineSetter__ ,專門用來給物件綁定get和set。

可以這樣寫:

isMe.name="周神"

   


效果是一樣的,建議使用下面這種方式,因為是在原型上書寫,所以可以繼承和重寫。

🎜總結🎜🎜以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。 🎜🎜更多談談因Vue.js引發關於getter和setter的思考相關文章請關注PHP中文網! 🎜🎜🎜🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn