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


Posted in Javascript onDecember 02, 2016

起因

当我打印出Vue实例下的data对象里的属性时,发现了一个有趣的事情:

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

它的每个属性都有两个相对应的getset方法,我觉的这是多此一举的,于是去网上查了查Vue双向绑定的实现原理,才发现它和Angular.js双向绑定的实现原理完全不同,Angular是用的数据脏检测,当Model发生变化,会检测所有视图是否绑定了相关数据,再更改视图。而Vue使用的发布订阅模式,是点对点的绑定数据。

Vue的数据绑定只有两个步骤,compile=>link

我一直在想,vue是通过什么去监听用户对Model的修改,直到我发现Vue的data里,每个属性都有setget属性,我才明白过来。

在平时,我们创建一个对象,并修改它的属性,是这样的:

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

没有任何问题,但是如果要你去监测,当我修改了这个对象的属性时,要去做一些事,你会怎么做?

相关思考

这就要用到gettersetter了。

假设我现在要给一个码农对象添加一个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.js引发关于getter和setter的思考

你会发现这个对象和最上面的Vue中的data对象,打印出来的效果是一样的,都拥有getset属性。

我们来一步步分析下上面的代码,很有趣。

我们先创建一个对象字面量:

var Coder = function() {...}

再把this缓存一下:

var that = this;

接下来是最重要的,我们return了一个对象回去:

{

get name(){...},


set name(val){...}

}

顾名思义,get为取值,set为赋值,正常情况下,我们取值和赋值是用obj.prop的方式,但是这样做有一个问题,我如何知道对象的值改变了?所以就轮到set登场了。

你可以把getset理解为function,当然,只是可以这么理解,这是完全不一样的两个东西。

接下来创建一个码农的实例,isMe;此时,isMe是没有name属性的,当我们调用isMe.name时,我们会进入到get name(){...}中,先判断isMe是否有name属性,答案是否定的,那麽就添加一个name属性,并给它赋值:"你还没有取名";如果有name属性,那就返回name属性。

看到这里你一定知道get怎么使用了,对,你可以把get看成一个取值的函数,函数的返回值就是它拿到的值。

我感觉比较重要的是set属性,当我给实例赋值:

isMe.name="周神"

此时,会进入set name(val){...};形参val就是我赋给name属性的值,在这个函数里,我就可以做很多事了,比如双向绑定!因为这个值的每次改变都必须经过set,其他方式是改变不了它的,相当于一个万能的监听器。

还有另一种方法可以实现这个功能。

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)

效果是一样的,建议使用下面这种方式,因为是在原型上书写,所以可以继承和重用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
学习ExtJS Window常用方法
Oct 07 Javascript
js prototype截取字符串函数
Apr 01 Javascript
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
Jun 28 Javascript
浅析JavaScript基本类型与引用类型
May 28 Javascript
javascript实现Table排序的方法
May 15 Javascript
javascript实现随机显示星星特效
Jan 28 Javascript
详解JavaScript按概率随机生成事件
Aug 02 Javascript
ES6 javascript中class静态方法、属性与实例属性用法示例
Oct 30 Javascript
基于react后端渲染模板引擎noox发布使用
Jan 11 Javascript
JavaScript原型对象、构造函数和实例对象功能与用法详解
Aug 04 Javascript
vue项目中在外部js文件中直接调用vue实例的方法比如说this
Apr 28 Javascript
JS函数本身的作用域实例分析
Mar 16 Javascript
jquery获取input type=text中的值的各种方式(总结)
Dec 02 #Javascript
vue.js入门(3)——详解组件通信
Dec 02 #Javascript
javascript实现鼠标点击页面 移动DIV
Dec 02 #Javascript
jquery对所有input type=text的控件赋值实现方法
Dec 02 #Javascript
bootstrap使用validate实现简单校验功能
Dec 02 #Javascript
在网页中插入百度地图的步骤详解
Dec 02 #Javascript
PHP获取当前页面完整URL的方法
Dec 02 #Javascript
You might like
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
解析PHP实现下载文件的两种方法
2013/07/05 PHP
php+mysqli实现批量执行插入、更新及删除数据的方法
2015/01/29 PHP
thinkPHP通用控制器实现方法示例
2017/11/23 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
2019/07/03 PHP
jQuery 学习 几种常用方法
2009/06/11 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
JSON辅助格式化处理方法
2013/03/26 Javascript
JQuery触发事件例如click
2013/09/11 Javascript
node.js中的querystring.unescape方法使用说明
2014/12/10 Javascript
Java中Timer的用法详解
2015/10/21 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
nodeJs爬虫获取数据简单实现代码
2016/03/29 NodeJs
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
小程序云开发实战小结
2018/10/25 Javascript
Pyramid将models.py文件的内容分布到多个文件的方法
2013/11/27 Python
python中pycurl库的用法实例
2014/09/30 Python
Python检测一个对象是否为字符串类的方法
2015/05/21 Python
Python实现生成密码字典的方法示例
2019/09/02 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
2020/03/06 Python
python爬虫中PhantomJS加载页面的实例方法
2020/11/12 Python
canvas像素画板的实现代码
2018/11/21 HTML / CSS
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
澳大利亚的奢侈品牌:Oroton
2016/08/26 全球购物
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
介绍一下Python中webbrowser的用法
2013/05/07 面试题
高分子材料个人求职信范文
2013/09/25 职场文书
测绘专业大学生职业生涯规划书
2014/02/10 职场文书
《观舞记》教学反思
2014/04/16 职场文书
工作自我评价范文
2015/03/05 职场文书
上下班时间调整通知
2015/04/23 职场文书
证婚人婚礼致辞
2015/07/28 职场文书
【DOTA2】半决赛强强对话~ PSG LGD vs EHOME - DPC 2022 CN REGIONAL FINALS WINTER
2022/04/02 DOTA