源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

谈谈因Vue.js引发关于getter和setter的思考

  • 时间:2022-05-29 14:47 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:谈谈因Vue.js引发关于getter和setter的思考
[b]起因[/b] 当我打印出Vue实例下的data对象里的属性时,发现了一个有趣的事情: [img]http://files.jb51.net/file_images/article/201612/201612190227295.png?20161129248[/img] 它的每个属性都有两个相对应的[code]get[/code]和[code]set[/code]方法,我觉的这是多此一举的,于是去网上查了查Vue双向绑定的实现原理,才发现它和Angular.js双向绑定的实现原理完全不同,Angular是用的数据脏检测,当Model发生变化,会检测所有视图是否绑定了相关数据,再更改视图。而Vue使用的发布订阅模式,是点对点的绑定数据。 Vue的数据绑定只有两个步骤,[code]compile=>link[/code]。 我一直在想,vue是通过什么去监听用户对Model的修改,直到我发现Vue的data里,每个属性都有[code]set[/code]和[code]get[/code]属性,我才明白过来。 在平时,我们创建一个对象,并修改它的属性,是这样的:
 var obj = {
  val:99
 }
 obj.val = 100;
 console.log(obj.val)//100
没有任何问题,但是如果要你去监测,当我修改了这个对象的属性时,要去做一些事,你会怎么做? [b]相关思考[/b] 这就要用到[code]getter[/code]和[code]setter[/code]了。 假设我现在要给一个码农对象添加一个[code]name[/code]属性,而且每次更新[code]name[/code]属性时,我要去完成一些事,我们可以这样做:
 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)
输出: [img]http://files.jb51.net/file_images/article/201612/201612290350951.png?20161129359[/img] 你会发现这个对象和最上面的Vue中的[code]data[/code]对象,打印出来的效果是一样的,都拥有[code]get[/code]和[code]set[/code]属性。 我们来一步步分析下上面的代码,很有趣。 我们先创建一个对象字面量:
var Coder = function() {...}
再把[code]this[/code]缓存一下:
var that = this;
接下来是最重要的,我们[code]return[/code]了一个对象回去:
{

  get name(){...},

  set name(val){...}

}
顾名思义,get为取值,set为赋值,正常情况下,我们取值和赋值是用[code]obj.prop[/code]的方式,但是这样做有一个问题,我如何知道对象的值改变了?所以就轮到set登场了。 你可以把[code]get[/code]和[code]set[/code]理解为[code]function[/code],当然,只是可以这么理解,这是完全不一样的两个东西。 接下来创建一个码农的实例,isMe;此时,isMe是没有[code]name[/code]属性的,当我们调用[code]isMe.name[/code]时,我们会进入到[code]get name(){...}[/code]中,先判断isMe是否有[code]name[/code]属性,答案是否定的,那麽就添加一个[code]name[/code]属性,并给它赋值:"你还没有取名";如果有[code]name[/code]属性,那就返回[code]name[/code]属性。 看到这里你一定知道[code]get[/code]怎么使用了,对,你可以把[code]get[/code]看成一个取值的函数,函数的返回值就是它拿到的值。 我感觉比较重要的是[code]set[/code]属性,当我给实例赋值:
isMe.name="周神"
此时,会进入[code]set name(val){...};[/code]形参val就是我赋给[code]name[/code]属性的值,在这个函数里,我就可以做很多事了,比如双向绑定!因为这个值的每次改变都必须经过set,其他方式是改变不了它的,相当于一个万能的监听器。 还有另一种方法可以实现这个功能。 ES5的对象原型有两个新的属性[code]__defineGetter__[/code]和[code]__defineSetter__[/code] ,专门用来给对象绑定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)
效果是一样的,建议使用下面这种方式,因为是在原型上书写,所以可以继承和重用。 [b]总结[/b] 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部