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 对象、函数和继承
Jul 07 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
Oct 12 Javascript
纯JS实现动态时间显示代码
Feb 08 Javascript
学JavaScript七大注意事项【必看】
May 04 Javascript
jQuery操作cookie
Aug 08 Javascript
JavaScript制作颜色反转小游戏
Sep 25 Javascript
String字符串截取的四种方式总结
Nov 28 Javascript
利用JQuery阻止事件冒泡
Dec 01 Javascript
Javascript中 带名 匿名 箭头函数的重要区别(推荐)
Jan 29 Javascript
Vue学习笔记进阶篇之多元素及多组件过渡
Jul 19 Javascript
小程序组件之自定义顶部导航实例
Jun 12 Javascript
js基于canvas实现时钟组件
Feb 07 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
MySQL 日期时间函数常用总结
2012/06/12 PHP
最常用的8款PHP调试工具
2014/07/06 PHP
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
php返回当前日期或者指定日期是周几
2015/05/21 PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
2017/06/11 PHP
PDO::setAttribute讲解
2019/01/29 PHP
PHP7内核CGI与FastCGI详解
2019/04/14 PHP
js+数组实现网页上显示时间/星期几的实用方法
2013/01/18 Javascript
JS创建类和对象的两种不同方式
2014/08/08 Javascript
js图片实时加载提供网页打开速度
2014/09/11 Javascript
jQuery实现鼠标单击网页文字后在文本框显示的方法
2015/05/06 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
jQuery选择器基础入门教程
2016/05/10 Javascript
从零学习node.js之详解异步控制工具async(八)
2017/02/27 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
详解angular ui-grid之过滤器设置
2017/06/07 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
2019/09/02 Javascript
Vue实现商品详情页的评价列表功能
2019/09/04 Javascript
vue实现数字滚动效果
2020/06/29 Javascript
[02:31]2014DOTA2国际邀请赛2009专访:干爹表现出乎意料 看好DK杀回决赛
2014/07/20 DOTA
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
python使用pyhook监控键盘并实现切换歌曲的功能
2014/07/18 Python
python:socket传输大文件示例
2017/01/18 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
Python列表如何更新值
2020/05/27 Python
Django 构建模板form表单的两种方法
2020/06/14 Python
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
HTML5 canvas基本绘图之绘制线条
2016/06/27 HTML / CSS
Skyscanner台湾:全球知名的旅行比价引擎
2018/07/01 全球购物
.NET是怎么支持多种语言的
2015/02/24 面试题
财务会计专业求职信范文
2013/12/31 职场文书
2014五一国际劳动节活动总结范文
2014/04/14 职场文书
志愿者活动总结
2014/04/28 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android