谈谈因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 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
Apr 10 Javascript
jQuery之ajax删除详解
Feb 27 Javascript
JS运动相关知识点小结(附弹性运动示例)
Jan 08 Javascript
详解javascript传统方法实现异步校验
Jan 22 Javascript
纯js仿淘宝京东商品放大镜功能
Mar 02 Javascript
setTimeout时间设置为0详细解析
Mar 13 Javascript
Vue.directive使用注意(小结)
Aug 31 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
Mar 29 Javascript
js计算最大公约数和最小公倍数代码实例
Sep 11 Javascript
layer.open组件获取弹出层页面变量、函数的实例
Sep 25 Javascript
微信小程序 冒泡事件原理解析
Sep 27 Javascript
微信小程序修改数组长度的问题的解决
Dec 17 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
PHP设计模式之模板方法模式定义与用法详解
2018/04/02 PHP
PHP使用PDO实现mysql防注入功能详解
2019/12/20 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
IE与FF下javascript获取网页及窗口大小的区别详解
2014/01/14 Javascript
jquery删除数据记录时的弹出提示效果
2014/05/06 Javascript
jQuery实现隔行背景色变色
2014/11/24 Javascript
javascript 中__proto__和prototype详解
2014/11/25 Javascript
JavaScript计算两个日期时间段内日期的方法
2015/03/16 Javascript
JQuery插件ajaxfileupload.js异步上传文件实例
2015/05/19 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
2015/08/23 Javascript
浅谈JavaScript中的分支结构
2016/07/01 Javascript
WebSocket+node.js创建即时通信的Web聊天服务器
2016/08/08 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
three.js实现围绕某物体旋转
2017/01/25 Javascript
深入浅析Nodejs的Http模块
2017/06/20 NodeJs
微信小程序商品到详情的实现
2017/06/27 Javascript
深入理解ES7的async/await的用法
2017/09/09 Javascript
JS 数组随机洗牌的实例代码
2018/09/12 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
一个手写的vue放大镜效果
2019/08/09 Javascript
原生js实现的移动端可拖动进度条插件功能详解
2019/08/15 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
2020/08/25 Javascript
python 测试实现方法
2008/12/24 Python
用Python进行基础的函数式编程的教程
2015/03/31 Python
python字符类型的一些方法小结
2016/05/16 Python
python验证码识别的示例代码
2017/09/21 Python
vscode 远程调试python的方法
2017/12/01 Python
django有哪些好处和优点
2020/09/01 Python
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
德国亚马逊官方网站:Amazon.de
2020/11/15 全球购物
团代会主持词
2014/04/02 职场文书
英语故事演讲稿
2014/04/29 职场文书
2016年大学生社区服务活动总结
2016/04/06 职场文书
读鲁迅先生的经典名言
2019/08/20 职场文书
创业计划书之酒厂
2019/10/14 职场文书
Java完整实现记事本代码
2022/06/16 Java/Android