谈谈因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灾难css灾难之 js私有函数和css选择器作为容器
Dec 11 Javascript
js arguments,jcallee caller用法总结
Nov 30 Javascript
jQuery.prop() 使用详解
Jul 19 Javascript
Node.js环境下JavaScript实现单链表与双链表结构
Jun 12 Javascript
angularjs 表单密码验证自定义指令实现代码
Oct 27 Javascript
JS敏感词过滤代码
Dec 23 Javascript
Webpack性能优化 DLL 用法详解
Aug 10 Javascript
使用JavaScript实现点击循环切换图片效果
Sep 03 Javascript
微信小程序使用wxParse解析html的实现示例
Aug 30 Javascript
vue项目打包部署_nginx代理访问方法详解
Sep 20 Javascript
用原生 JS 实现 innerHTML 功能实例详解
Apr 03 Javascript
ES6 Set结构的应用实例分析
Jun 26 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学习资源和链接.
2006/12/05 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
php+xml实现在线英文词典之添加词条的方法
2015/01/23 PHP
php按字符无乱码截取中文的方法
2015/03/27 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
php cookie工作原理与实例详解
2016/07/18 PHP
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
2013/12/02 Javascript
jQuery实现下拉框左右选择的简单实例
2014/02/22 Javascript
javascript(js)的小数点乘法除法问题详解
2014/03/07 Javascript
基于jQuery的Web上传插件Uploadify使用示例
2016/05/19 Javascript
Jquery ajax请求导出Excel表格的实现代码
2016/06/08 Javascript
jQuery选择器总结之常用元素查找方法
2016/08/04 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
2016/08/15 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
2016/12/07 Javascript
简单实现IONIC购物车功能
2017/01/10 Javascript
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
2017/06/02 jQuery
vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解
2018/05/28 Javascript
Vue中mintui的field实现blur和focus事件的方法
2018/08/25 Javascript
基于vue框架手写一个notify插件实现通知功能的方法
2019/03/31 Javascript
微信小程序webview 脚手架使用详解
2019/07/22 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
2020/04/10 Javascript
vue 限制input只能输入正数的操作
2020/08/05 Javascript
[01:02]2014 DOTA2国际邀请赛中国区预选赛 现场抢先看
2014/05/22 DOTA
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
Python中的并发处理之asyncio包使用的详解
2018/04/03 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
python爬虫中多线程的使用详解
2019/09/23 Python
html5设计原理(推荐收藏)
2014/05/17 HTML / CSS
日本食品网上商店:JaponShop.com
2017/11/28 全球购物
Paper Cape官网:美国婴儿和儿童服装品牌
2019/11/02 全球购物
高中历史教学反思
2014/02/08 职场文书
人事部经理岗位职责
2014/03/07 职场文书
土地转让协议书范本
2014/04/15 职场文书
优秀班主任主要事迹材料
2014/12/16 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书