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 无符号右移赋值操作
Apr 17 Javascript
jquery 双色表格实现代码
Dec 08 Javascript
js时间日期和毫秒的相互转换
Feb 22 Javascript
JS(JQuery)操作Array的相关方法介绍
Feb 11 Javascript
页面按钮禁用与解除禁用的方法
Feb 19 Javascript
关于微信中a链接无法跳转问题
Aug 02 Javascript
你知道setTimeout是如何运行的吗?
Aug 16 Javascript
浅谈js的ajax的异步和同步请求的问题
Oct 07 Javascript
javascript简单进制转换实现方法
Nov 24 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
angular5 httpclient的示例实战
Mar 12 Javascript
Angular 4.x+Ionic3踩坑之Ionic 3.x界面传值详解
Mar 13 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
ubuntu 编译安装php 5.3.3+memcache的方法
2010/08/05 PHP
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
PHP文件上传操作实例详解
2016/09/27 PHP
PHP实现RTX发送消息提醒的实例代码
2017/01/03 PHP
全面解析PHP面向对象的三大特征
2017/06/10 PHP
PHP+MySql实现一个简单的留言板
2020/07/19 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
利用jquery操作select下拉列表框的代码
2010/06/04 Javascript
myeclipse安装jQuery插件的方法
2011/03/29 Javascript
JavaScript中数据结构与算法(二):队列
2015/06/19 Javascript
JavaScript数组去重的3种方法和代码实例
2015/07/01 Javascript
Javascript中判断一个值是否为undefined的方法详解
2016/09/28 Javascript
Jqprint实现页面打印
2017/01/06 Javascript
原生JS仿QQ阅读点击展开、收起效果
2017/03/08 Javascript
JS获取填报扩展单元格控件的值的解决办法
2017/07/14 Javascript
Node.js服务器开启Gzip压缩教程
2017/08/11 Javascript
vue综合组件间的通信详解
2017/11/06 Javascript
浅谈js中的bind
2019/03/18 Javascript
Element Steps步骤条的使用方法
2020/07/26 Javascript
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
2020/12/24 Javascript
[04:16]完美世界DOTA2联赛PWL S2 集锦第一期
2020/11/23 DOTA
python遍历 truple list dictionary的几种方法总结
2016/09/11 Python
Python遍历目录并批量更换文件名和目录名的方法
2016/09/19 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
Python 带有参数的装饰器实例代码详解
2018/12/06 Python
详解Anconda环境下载python包的教程(图形界面+命令行+pycharm安装)
2019/11/11 Python
pytorch方法测试——激活函数(ReLU)详解
2020/01/15 Python
使用Python爬取弹出窗口信息的实例
2020/03/14 Python
Python venv虚拟环境配置过程解析
2020/07/08 Python
会计系个人求职信范文分享
2013/12/20 职场文书
求职信的要素有哪些呢
2013/12/26 职场文书
董事长秘书岗位职责
2015/02/13 职场文书
党员个人承诺书
2015/04/27 职场文书
Idea连接MySQL数据库出现中文乱码的问题
2021/04/14 MySQL
国产动画《万圣街》日语配音版制作决定!
2022/03/20 国漫
纯CSS打字动画的实现示例
2022/08/05 HTML / CSS