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 相关文章推荐
基于jQuery的前端数据通用验证库
Aug 08 Javascript
JavaScript实现从数组中选出和等于固定值的n个数
Sep 03 Javascript
Bootstrap中的fileinput 多图片上传及编辑功能
Sep 05 Javascript
微信公众号  提示:Unauthorized API function 问题解决方法
Dec 05 Javascript
JavaScript & jQuery完美判断图片是否加载完毕
Jan 08 Javascript
js实现加载页面就自动触发超链接的示例
Aug 31 Javascript
node.js学习之事件模块Events的使用示例
Sep 28 Javascript
微信小程序实现带缩略图轮播效果
Nov 04 Javascript
解决vue admin element noCache设置无效的问题
Nov 12 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
Apr 11 Javascript
npm全局环境变量配置详解
Dec 15 Javascript
js前端图片加载异常兜底方案
Jun 21 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
php array_map()数组函数使用说明
2011/07/12 PHP
phpMyAdmin自动登录和取消自动登录的配置方法
2014/05/12 PHP
ThinkPHP静态缓存简单配置和使用方法详解
2016/03/23 PHP
PHP微信开发之查询微信精选文章
2016/06/23 PHP
PHP转换文本框内容为HTML格式的方法
2016/07/20 PHP
PHP命名空间namespace的定义方法详解
2017/03/29 PHP
深入理解 PHP7 中全新的 zval 容器和引用计数机制
2018/10/15 PHP
jquery1.4 教程二 ajax方法的改进
2010/02/25 Javascript
caller和callee的区别介绍及演示结果
2013/03/10 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
js实现简单的二级联动效果
2017/03/09 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
微信小程序登录数据解密及状态维持实例详解
2019/05/06 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
js实现简单分页导航栏效果
2019/06/28 Javascript
javascript实现鼠标点击生成文字特效
2019/12/24 Javascript
jQuery加PHP实现图片上传并提交的示例代码
2020/07/16 jQuery
[03:01]2014DOTA2国际邀请赛 小组赛7月13日TOPPLAY
2014/07/14 DOTA
Python中使用PyQt把网页转换成PDF操作代码实例
2015/04/23 Python
Python模块文件结构代码详解
2018/02/03 Python
Python实现的读取/更改/写入xml文件操作示例
2018/08/30 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
django 自定义过滤器的实现
2019/02/26 Python
windows10下安装TensorFlow Object Detection API的步骤
2019/06/13 Python
python对文件的操作方法汇总
2020/02/28 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
python中常见错误及解决方法
2020/06/21 Python
使用npy转image图像并保存的实例
2020/07/01 Python
Python爬虫爬取有道实现翻译功能
2020/11/27 Python
印度购买眼镜和太阳镜网站:Coolwinks
2018/09/26 全球购物
奥地利领先的在线药房:SHOP APOTHEKE
2019/10/07 全球购物
汽车销售顾问求职自荐信
2014/01/01 职场文书
暑期实践思想汇报
2014/01/06 职场文书
车辆转让协议书
2014/09/24 职场文书