阅读目录

一:理解普通对象在声明时添加 get、set

在做vue的时候,我们经常会看到 data里面的属性 都有 get 和 set方法,如下所示:

如上vue中data里面它有两个属性,一个xxx 数组 和 一个 testA对象,但是都有get和set方法。也就是说在vue中data里面的每个属性都有两个相对应的get和set方法。为什么会有这样的呢?下面我们先来看一个普通的对象,如下代码所示:

const obj = {
name: 'kongzhi',
_age: 30,
get age() {
return this._age;
},
set age(x) {
this._age = x;
}
}; console.log(obj);

打印会如下所示:

当我们继续打印如下信息:

console.log(obj._age); // 输出:30
console.log(obj.age); // 输出:30 // 设置值
obj.age = 31; console.log(obj.age); // 输出:31 console.log(obj.age()); // Uncaught TypeError: obj.age is not a function

如上代码演示所示,我们在对象里面使用 get 或 set定义的 age, 它只是obj中的一个属性,它并不是方法,因此如上我们使用获取属性的值或设置属性的值操作是正常的,当我们使用 obj.age() 把它当做一个方法调用的时候,它会报错。因此在vue中所有的属性有get、set这样的,当我们自动给某个属性赋值的时候,它会自动调用 set对应的方法,当我们获取某个属性的时候,它会自动调用get方法。但是我们不能手动调用 set/get xxx() 中的xxx这样的方法。

二:Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__

上面只是在声明obj对象的时候,编写get和set 对应的属性。但是如果已经存在的对象的时候,再想继续添加 get/set呢?那只有使用

Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__ 了,如下代码演示:

const obj = {
name: 'kongzhi',
_age: 30
}; obj.__defineGetter__('age', function(){
console.log('监听到正在获取属性age的值');
return this._age;
}); obj.__defineSetter__('age', function(value) {
console.log('监听到正在设置属性age的值为:' + value);
this._age = value;
}); /*
* 打印:监听到正在获取属性age的值
* 输出:30
*/
console.log(obj.age); // 打印:监听到正在设置属性age的值为:31
obj.age = 31; /*
* 打印:监听到正在获取属性age的值
* 输出: 31
*/
console.log(obj.age);

但是呢?Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__ 这个方法已经不推荐使用了,并且随着以后浏览器的发展,可能会不再支持该方法,那怎么办呢?当然会有新的替代方案的,我们继续往下讲。

三:Object.defineProperty

该方法它是由两部分组成,分别是:数据描述符和访问器描述符,数据描述符的含义是:它是一个包含属性的值,并说明这个属性值是可读或不可读的对象。访问器描述符的含义是:包含该属性的一对 getter/setter方法的对象。

那么具体项了解该方法的使用及详解,请看我这篇文章(https://www.cnblogs.com/tugenhua0707/p/10261170.html),下面看使用 Object.defineProperty 来监听对象属性值的变化,如下代码:

const obj = {
name: 'kongzhi',
_age: 30
};
Object.defineProperty(obj, 'age', {
get() {
console.log('监听到正在获取属性age的值');
return this._age;
},
set(value) {
console.log('监听到正在设置属性age的值为:' + value);
this._age = value;
return this._age;
}
}); /*
* 打印:监听到正在获取属性age的值
* 输出:30
*/
console.log(obj.age); // 打印:监听到正在设置属性age的值为:31
obj.age = 31; /*
* 打印:监听到正在获取属性age的值
* 输出: 31
*/
console.log(obj.age);

四:Object.defineProperties

Object.defineProperties 是对 Object.defineProperty的扩展的,它可以一次性添加多个/修改多个对象属性描述符。
如下代码演示:

const obj = {
_name: 'kongzhi',
_age: 30
};
Object.defineProperties(obj, {
age: {
get() {
console.log('监听到正在获取属性age的值');
return this._age;
},
set(value) {
console.log('监听到正在设置属性age的值为:' + value);
this._age = value;
return this._age;
}
},
name: {
get() {
console.log('监听到正在获取属性name的值');
return this._name;
},
set(value) {
console.log('监听到正在设置属性name的值为:' + value);
this._name = value;
return this._name;
}
}
});
/*
* 打印:监听到正在获取属性age的值
* 输出:30
*/
console.log(obj.age); // 打印:监听到正在设置属性age的值为:31
obj.age = 31; /*
* 打印:监听到正在获取属性age的值
* 输出: 31
*/
console.log(obj.age); console.log('-------下面是对象name属性的监听-------');
/*
* 打印:监听到正在获取属性name的值
* 输出:kongzhi
*/
console.log(obj.name); // 打印:监听到正在设置属性name的值为:longen
obj.name = 'longen'; /*
* 打印:监听到正在获取属性name的值
* 输出: longen
*/
console.log(obj.name);

五:Proxy

那么具体了解Proxy是啥,是干啥使用的,请看我这篇文章(https://www.cnblogs.com/tugenhua0707/p/10306793.html);

那么它也可以监听对象属性值的变化,如下代码演示:

const target = {
name: 'kongzhi'
}; const handler = {
get: function(target, key) {
console.log(`${key} 被读取`);
return target[key];
},
set: function(target, key, value) {
console.log(`${key} 被设置为 ${value}`);
target[key] = value;
}
}; const testObj = new Proxy(target, handler); /*
获取testObj中name属性值
会自动执行 get函数后 打印信息:name 被读取 及输出名字 kongzhi
*/
console.log(testObj.name); /*
改变target中的name属性值
打印信息如下: name 被设置为 111
*/
testObj.name = 111; console.log(target.name); // 输出 111

深入理解 Getter和Setter 对对象的属性监听的更多相关文章

  1. vue2.x版本中Object.defineProperty对象属性监听和关联

    前言 在vue2.x版本官方文档中 深入响应式原理 https://cn.vuejs.org/v2/guide/reactivity.html一文的解释当中,Object.defineProperty ...

  2. vue对象属性监听

    对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...

  3. vue watch关于对象内的属性监听

    vue可以通过watch监听data内数据的变化.通常写法是: data: { a: 100 }, watch: { a(newval, oldVal) { // 做点什么... console.lo ...

  4. Android 向Application对象添加Activity监听

    可以建立对象把Application.ActivityLifecycleCallbacks接口中的函数实现,并利用public void registerActivityLifecycleCallba ...

  5. 使用MutationObserver对象封装一个监听DOM生成的函数

    (function(win){ 'use strict'; var listeners = []; var doc = win.document; var MutationObserver = win ...

  6. Vue2实践computed监听Vuex中state对象中的对象属性时发生的一些有趣经历

    今天想实现一个功能,在全局中随时改变用户的部分信息.这时候就想到了用Vuex状态控制器来存储用户信息,在页面中使用computed来监听用户这个对象.看似一个很简单的逻辑,就体现了我基本功的不扎实呀. ...

  7. vue2之对象属性的监听

    对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...

  8. Event 对象的属性和方法

    事件触发时,会将一个 Event 对象传递给事件处理程序,比如: document.getElementById("testText").addEventListener(&quo ...

  9. 理解defineProperty以及getter、setter

    我们常听说vue是用getter与setter实现数据监控的,那么getter与setter到底是什么东西,它与defineProperty是什么关系,平时有哪些用处呢?本文将为大家一一道来. 对象的 ...

随机推荐

  1. 洛谷P4591 [TJOI2018]碱基序列(hash dp)

    题意 题目链接 Sol \(f[i][j]\)表示匹配到第\(i\)个串,当前在主串的第\(j\)个位置 转移的时候判断一下是否可行就行了.随便一个能搞字符串匹配的算法都能过 复杂度\(O(|S| K ...

  2. Centos 7下VMware三台虚拟机Hadoop集群初体验

    一.下载并安装Centos 7 传送门:https://www.centos.org/download/    注:下载DVD ISO镜像 这里详解一下VMware安装中的两个过程 网卡配置 是Add ...

  3. listview 异步加载图片并防止错位

    1.图片错位原理: 如果我们只是简单显示list中数据,而没用convertview的复用机制和异步操作,就不会产生图片错位:重用convertview但没用异步,也不会有错位现象.但我们的项目中li ...

  4. Kotlin入门(24)如何自定义视图

    Android提供了丰富多彩的视图与控件,已经能够满足大部分的业务需求,然而计划赶不上变化,总是有意料之外的情况需要特殊处理.比如PagerTabStrip无法在布局文件中指定文本大小和文本颜色,只能 ...

  5. 转载:使用redis+flask维护动态代理池

    githu源码地址:https://github.com/Germey/ProxyPool更好的代理池维护:https://github.com/Python3WebSpider/ProxyPool ...

  6. 如何在Ruby中编写微服务?

    [编者按]本文作者为 Pierpaolo Frasa,文章通过详细的案例,介绍了在Ruby中编写微服务时所需注意的方方面面.系国内 ITOM 管理平台 OneAPM 编译呈现. 最近,大家都认为应当采 ...

  7. 企业建立成功 DevOps 模式所需应对的5个挑战

    [编者按]本文作者为 Kevin Goldberg,主要介绍要想成功部署 DevOps 模式,企业所需应对的5大挑战与问题.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 要给 DevOps ...

  8. mssql sqlserver 批量删除所有存储过程的方法分享

    转自:http://www.maomao365.com/?p=6864 摘要: 下文讲述采用sql脚本批量删除所有存储过程的方法,如下所示: 实验环境:sqlserver 2008 R2 平常使用sq ...

  9. 代码管理工具:Git 和 Svn 的简单操作

    1. git 先注册git config --global user.name "name" git config --global user.email "email& ...

  10. 【2018.04.19 ROS机器人操作系统】机器人控制:运动规划、路径规划及轨迹规划简介之一

    参考资料及致谢 本文的绝大部分内容转载自以下几篇文章,首先向原作者致谢,希望自己能在这些前辈们的基础上能有所总结提升. 1. 运动规划/路径规划/轨迹规划的联系与区别 https://blog.csd ...