谈谈因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 相关文章推荐
jquery下操作HTML控件的实现代码
Jan 12 Javascript
jQuery筛选器children()案例详解(图文)
Feb 17 Javascript
jQuery实现单行文字间歇向上滚动源代码
Jun 02 Javascript
JS实现局部选择打印和局部不选择打印
Apr 03 Javascript
一个JavaScript操作元素定位元素的实例
Oct 29 Javascript
JavaScript中的事件委托及好处
Jul 12 Javascript
js实现类bootstrap模态框动画
Feb 07 Javascript
bootstrap的常用组件和栅格式布局详解
May 02 Javascript
Vue精简版风格概述
Jan 30 Javascript
JS中DOM元素的attribute与property属性示例详解
Sep 04 Javascript
微信小程序配置服务器提示验证token失败的解决方法
Apr 03 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
Apr 15 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
PDO实现学生管理系统
2020/03/21 PHP
入门基础学习 ExtJS笔记(一)
2010/11/11 Javascript
Js base64 加密解密介绍
2013/10/11 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
2014/08/27 Javascript
js和jquery如何获取图片真实的宽度和高度
2014/09/28 Javascript
jquery实现红色竖向多级向右展开的导航菜单效果
2015/08/31 Javascript
jquery实现鼠标悬浮停止轮播特效
2020/08/20 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
Angular多选、全选、批量选择操作实例代码
2017/03/10 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
react.js 获取真实的DOM节点实例(必看)
2017/04/17 Javascript
详解node HTTP请求客户端 - Request
2017/05/05 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
2017/05/11 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
2017/05/24 Javascript
ES6学习笔记之map、set与数组、对象的对比
2018/03/01 Javascript
vue 表单输入格式化中文输入法异常问题
2018/05/30 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
重置Redux的状态数据的方法实现
2019/11/18 Javascript
python实现文件路径和url相互转换的方法
2015/07/06 Python
高质量Python代码编写的5个优化技巧
2017/11/16 Python
浅谈numpy数组的几种排序方式
2017/12/15 Python
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
学习python可以干什么
2019/02/26 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
tensorflow 初始化未初始化的变量实例
2020/02/06 Python
Python常用编译器原理及特点解析
2020/03/23 Python
如何通过python实现IOU计算代码实例
2020/11/02 Python
移动端HTML5开发神器之vconsole详解
2020/12/15 HTML / CSS
应届生船舶驾驶求职信
2013/10/19 职场文书
我的大学生活职业生涯规划
2014/01/02 职场文书
新学期校长寄语
2014/01/18 职场文书
中秋节礼品促销方案
2014/02/02 职场文书
个人典型事迹材料
2014/12/30 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书