vue源码学习之Object.defineProperty对象属性监听


Posted in Javascript onMay 30, 2018

本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下:

参考版本 vue源码版本:0.11

相关

vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。

在MDN上查看有关Object.defineProperty 的解释。

我们先从最简单的开始:

let a = {'b': 1};
Object.defineProperty(a, 'b', {
  enumerable: false,
  configurable: false,
  get: function(){
    console.log('b' + '被访问');
  },
  set: function(newVal){
    console.log('b' + '被修改,新' + 'b' + '=' + newVal);
  }
});

a.b = 2;  // b被修改,新b=2
a.b;    // b被访问

这样,我们就能监听对象了!但问题并不仅仅这么简单。。。

我们可能会有对象中属性的值还是对象这种嵌套情况,可以通过递归解决!

在vue源代码文件 srcobserveobserver.js 中

// 观察者构造函数
function Observer(data){
  this.data = data;
  this.walk(data);
}

let p = Observer.prototype;
p.walk = function(obj){
  let val;
  for(let key in obj){
    // 通过 hasOwnProperty 过滤掉一个对象本身拥有的属性 
    if(obj.hasOwnProperty(key)){
      val = obj[key];
      // 递归调用 循环所有对象出来
      if(typeof val === 'object'){
        new Observer(val);
      }
      this.convert(key, val);
    }
  }
};

p.convert = function(key, val){
  Object.defineProperty(this.data, key, {
    enumerable: false,
    configurable: false,
    get: function(){
      console.log(key + '被访问');
    },
    set: function(newVal){
      console.log(key + '被修改,新' + key + '=' + newVal);
      if(newVal === val) return ;
      val = newVal;
    }
  })
};

let data = {
  user: {
    name: 'zhangsan',
    age: 14
  },
  address: {
    city: 'beijing'
  }
}

let app = new Observer(data);
data.user.name;  // user被访问

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript Firefox与IE 替换节点的方法
Feb 24 Javascript
JavaScript里四舍五入函数round用法实例
Apr 06 Javascript
简易的投票系统以及js刷票思路和方法
Apr 07 Javascript
详解JavaScript中getFullYear()方法的使用
Jun 10 Javascript
使用javascript提交form表单方法汇总
Jun 25 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
May 18 Javascript
jquery实现刷新随机变化样式特效(tag标签样式)
Feb 03 Javascript
js实现短信发送倒计时功能(正则验证)
Feb 10 Javascript
vue项目中axios使用详解
Feb 07 Javascript
vue计算属性computed、事件、监听器watch的使用讲解
Jan 21 Javascript
layui表格内容溢出的解决方法
Sep 06 Javascript
Angular8 实现table表格表头固定效果
Jan 03 Javascript
Angular搜索场景中使用rxjs的操作符处理思路
May 30 #Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
May 30 #Javascript
vue通过点击事件读取音频文件的方法
May 30 #Javascript
vue 表单输入格式化中文输入法异常问题
May 30 #Javascript
详解如何使用babel进行es6文件的编译
May 29 #Javascript
基于打包工具Webpack进行项目开发实例
May 29 #Javascript
JavaScript反射与依赖注入实例详解
May 29 #Javascript
You might like
一个捕获函数输出的函数
2007/02/14 PHP
for循环连续求和、九九乘法表代码
2012/02/20 PHP
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
2014/08/15 PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
2014/08/19 PHP
php-app开发接口加密详解
2018/04/18 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
javascript call和apply方法
2008/11/24 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
2013/03/28 Javascript
jquery ui resize 中border-box的bug修正
2015/04/26 Javascript
详解JavaScript语言的基本语法要求
2015/11/20 Javascript
JS实现队列与堆栈的方法
2016/04/21 Javascript
Javascript 使用ajax与C#获取文件大小实例详解
2017/01/13 Javascript
微信小程序  http请求封装详解及实例代码
2017/02/15 Javascript
深入理解vue-loader如何使用
2017/06/06 Javascript
ES6新增数据结构WeakSet的用法详解
2017/08/07 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
element-ui 实现响应式导航栏的示例代码
2020/05/08 Javascript
vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作
2020/11/09 Javascript
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
横向对比分析Python解析XML的四种方式
2016/03/30 Python
python实现跨excel的工作表sheet之间的复制方法
2018/05/03 Python
django将图片上传数据库后在前端显式的方法
2018/05/25 Python
Python实现插入排序和选择排序的方法
2019/05/12 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
2019/08/26 Python
关于numpy数组轴的使用详解
2019/12/05 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
2020/02/07 Python
python如何求100以内的素数
2020/05/27 Python
英国领先的票务代理商之一:The Ticket Factory
2019/02/09 全球购物
材料加工硕士生求职信
2013/10/10 职场文书
行政助理工作职责范本
2014/03/04 职场文书
空气环保标语
2014/06/12 职场文书
委托书格式要求
2015/01/28 职场文书
离婚起诉书范本
2015/05/18 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS
Oracle 触发器trigger使用案例
2022/02/24 Oracle