谈谈因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 相关文章推荐
js中有关IE版本检测
Jan 04 Javascript
jQuery遍历json中多个map的方法
Feb 12 Javascript
jQuery实现判断滚动条到底部
Jun 23 Javascript
JS版元素周期表实现方法
Aug 05 Javascript
jQuery on()方法绑定动态元素的点击事件实例代码浅析
Jun 16 Javascript
AngularJS  自定义指令详解及实例代码
Sep 14 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
Mar 07 Javascript
基于iScroll实现下拉刷新和上滑加载效果
Jul 18 Javascript
React如何避免重渲染
Apr 10 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
Aug 16 Javascript
vue实现滑动超出指定距离回顶部功能
Jul 31 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
Aug 07 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
ThinkPHP提交表单时默认自动转义的解决方法
2014/11/25 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
javascript 异步页面查询实现代码(asp.net)
2010/05/26 Javascript
JavaScript 原型继承之构造函数继承
2011/08/26 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
2011/10/16 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
javascript类型转换示例
2014/04/29 Javascript
jQuery中多个元素的Hover事件解决方案
2014/06/12 Javascript
jquery实现多条件筛选特效代码分享
2015/08/28 Javascript
AngularJs动态加载模块和依赖注入详解
2016/01/11 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
JS获取中文拼音首字母并通过拼音首字母快速查找页面内对应中文内容的方法【附demo源码】
2016/08/19 Javascript
AngularJS  $on、$emit和$broadcast的使用
2016/09/05 Javascript
使用react实现手机号的数据同步显示功能的示例代码
2018/04/03 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
Vue数字输入框组件的使用方法
2019/10/19 Javascript
Vue Elenent实现表格相同数据列合并
2020/11/30 Vue.js
[05:07]DOTA2英雄梦之声_第14期_暗影恶魔
2014/06/20 DOTA
[02:30]辉夜杯主赛事第二日胜者组半决赛 CDEC.Y赛后采访
2015/12/26 DOTA
anaconda中更改python版本的方法步骤
2019/07/14 Python
Python K最近邻从原理到实现的方法
2019/08/15 Python
详解python opencv、scikit-image和PIL图像处理库比较
2019/12/26 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
Omio葡萄牙:全欧洲低价大巴、火车和航班搜索和比价
2019/02/09 全球购物
Ever New美国:澳大利亚领先的女装时尚品牌
2019/11/28 全球购物
台湾专柜女包:KINAZ
2019/12/26 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
注塑工厂厂长岗位职责
2013/12/02 职场文书
体育教育专业自荐信范文
2013/12/20 职场文书
先进事迹材料范文
2014/12/29 职场文书
业务员辞职信范文
2015/03/02 职场文书
Go获取两个时区的时间差
2022/04/20 Golang
Python FuzzyWuzzy实现模糊匹配
2022/04/28 Python
前端canvas中物体边框和控制点的实现示例
2022/08/05 Javascript