国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

談?wù)勔騐ue.js引發(fā)關(guān)于getter和setter的思考

2019-11-19 18:43:18
字體:
供稿:網(wǎng)友

起因

當(dāng)我打印出Vue實(shí)例下的data對象里的屬性時,發(fā)現(xiàn)了一個有趣的事情:

它的每個屬性都有兩個相對應(yīng)的getset方法,我覺的這是多此一舉的,于是去網(wǎng)上查了查Vue雙向綁定的實(shí)現(xiàn)原理,才發(fā)現(xiàn)它和Angular.js雙向綁定的實(shí)現(xiàn)原理完全不同,Angular是用的數(shù)據(jù)臟檢測,當(dāng)Model發(fā)生變化,會檢測所有視圖是否綁定了相關(guān)數(shù)據(jù),再更改視圖。而Vue使用的發(fā)布訂閱模式,是點(diǎn)對點(diǎn)的綁定數(shù)據(jù)。

Vue的數(shù)據(jù)綁定只有兩個步驟,compile=>link

我一直在想,vue是通過什么去監(jiān)聽用戶對Model的修改,直到我發(fā)現(xiàn)Vue的data里,每個屬性都有setget屬性,我才明白過來。

在平時,我們創(chuàng)建一個對象,并修改它的屬性,是這樣的:

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

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

相關(guān)思考

這就要用到gettersetter了。

假設(shè)我現(xiàn)在要給一個碼農(nóng)對象添加一個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)

輸出:

你會發(fā)現(xiàn)這個對象和最上面的Vue中的data對象,打印出來的效果是一樣的,都擁有getset屬性。

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

我們先創(chuàng)建一個對象字面量:

var Coder = function() {...}

再把this緩存一下:

var that = this;

接下來是最重要的,我們return了一個對象回去:

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

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

你可以把getset理解為function,當(dāng)然,只是可以這么理解,這是完全不一樣的兩個東西。

接下來創(chuàng)建一個碼農(nóng)的實(shí)例,isMe;此時,isMe是沒有name屬性的,當(dāng)我們調(diào)用isMe.name時,我們會進(jìn)入到get name(){...}中,先判斷isMe是否有name屬性,答案是否定的,那麼就添加一個name屬性,并給它賦值:"你還沒有取名";如果有name屬性,那就返回name屬性。

看到這里你一定知道get怎么使用了,對,你可以把get看成一個取值的函數(shù),函數(shù)的返回值就是它拿到的值。

我感覺比較重要的是set屬性,當(dāng)我給實(shí)例賦值:

isMe.name="周神"

此時,會進(jìn)入set name(val){...};形參val就是我賦給name屬性的值,在這個函數(shù)里,我就可以做很多事了,比如雙向綁定!因?yàn)檫@個值的每次改變都必須經(jīng)過set,其他方式是改變不了它的,相當(dāng)于一個萬能的監(jiān)聽器。

還有另一種方法可以實(shí)現(xiàn)這個功能。

ES5的對象原型有兩個新的屬性__defineGetter____defineSetter__ ,專門用來給對象綁定get和set。

可以這樣書寫:

 var Coder = function() { } Coder.prototype.__defineGetter__('name', function() {  if (this.name) {   return this.name  }else{   return '你還沒有取名'  } }) Coder.prototype.__defineSetter__('name', function(val) {  this.name = val }) var isMe = new Coder() console.log(isMe.name) isMe.name = '周神' console.log(isMe.name) console.log(isMe)

效果是一樣的,建議使用下面這種方式,因?yàn)槭窃谠蜕蠒鴮懀钥梢岳^承和重用。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 江川县| 兴隆县| 东宁县| 罗源县| 综艺| 永定县| 图木舒克市| 石首市| 成武县| 翁牛特旗| 保靖县| 莲花县| 尼勒克县| 杭锦后旗| 海宁市| 红桥区| 耿马| 天气| 林西县| 岳普湖县| 同心县| 寿宁县| 宁阳县| 巴塘县| 深水埗区| 大田县| 库伦旗| 巴马| 临夏市| 布尔津县| 富民县| 湖北省| 青岛市| 冷水江市| 咸丰县| 黄龙县| 天镇县| 万全县| 新乐市| 伊通| 苏尼特右旗|