深入理解 Getter和Setter 对对象的属性监听
阅读目录
- 一:理解普通对象在声明时添加 get、set
- 二:Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__
- 三:Object.defineProperty
- 四:Object.defineProperties
- 五:Proxy
一:理解普通对象在声明时添加 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 对对象的属性监听的更多相关文章
- vue2.x版本中Object.defineProperty对象属性监听和关联
前言 在vue2.x版本官方文档中 深入响应式原理 https://cn.vuejs.org/v2/guide/reactivity.html一文的解释当中,Object.defineProperty ...
- vue对象属性监听
对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...
- vue watch关于对象内的属性监听
vue可以通过watch监听data内数据的变化.通常写法是: data: { a: 100 }, watch: { a(newval, oldVal) { // 做点什么... console.lo ...
- Android 向Application对象添加Activity监听
可以建立对象把Application.ActivityLifecycleCallbacks接口中的函数实现,并利用public void registerActivityLifecycleCallba ...
- 使用MutationObserver对象封装一个监听DOM生成的函数
(function(win){ 'use strict'; var listeners = []; var doc = win.document; var MutationObserver = win ...
- Vue2实践computed监听Vuex中state对象中的对象属性时发生的一些有趣经历
今天想实现一个功能,在全局中随时改变用户的部分信息.这时候就想到了用Vuex状态控制器来存储用户信息,在页面中使用computed来监听用户这个对象.看似一个很简单的逻辑,就体现了我基本功的不扎实呀. ...
- vue2之对象属性的监听
对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...
- Event 对象的属性和方法
事件触发时,会将一个 Event 对象传递给事件处理程序,比如: document.getElementById("testText").addEventListener(&quo ...
- 理解defineProperty以及getter、setter
我们常听说vue是用getter与setter实现数据监控的,那么getter与setter到底是什么东西,它与defineProperty是什么关系,平时有哪些用处呢?本文将为大家一一道来. 对象的 ...
随机推荐
- Python绘图工具Plotly的简单使用
1.Plotly被称为史上最好的绘图工具之一,为了更好的展示金融数据的复杂性. Plotly的官方网站为:https://plot.ly/ python量化的关键是金融数据可视化,无论是传统的K线图, ...
- 对display主要属性的探究,以及vertical-aligin
display 首先要简单说明一下display的主要3个主要属性,分别为block,inline-block,inline,这里只提及主要,关于其他的inherit,none等可以自行了解 inli ...
- PHP断言(ASSERT)的用法
简述 编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式.程序员断言在程序中的某个特定点该的表达式值为真.如果该表达式为假,就中断操作. 可以 ...
- 【redis专题(7)】命令语法介绍之Pub/Sub
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似.p ...
- MySQL 如何查看表的存储引擎
MySQL 如何查看表的存储引擎 在MySQL中如何查看单个表的存储引擎? 如何查看整个数据库有那些表是某个特殊存储引擎,例如MyISAM存储引擎呢?下面简单的整理一下这方面的知识点. 如果要查看 ...
- 爬取mzi.com妹子图片网站(requests库)
看了崔大佬的文章,写了这个爬虫,学习了!原文地址 现在该网站加了反爬机制,不过在headers里加上refere参数就行了. 以下代码仅做学习记录之用: from bs4 import Beautif ...
- memcache缓存雪崩、缓存无底洞、缓存穿透、永久数据被踢现象
一.缓存雪崩现象 缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降, 缓存中缺失的数据去数据库查询,短时间内造成数据库服务器崩溃, 重启DB短期又被压跨,但新数据的缓存也更新一些,DB反 ...
- June 12. 2018 Week 24th. Tuesday
Just be yourself because you are unique and you will shine. 每个人都是独一无二的,做好你自己,你也能够光芒四射. From What a G ...
- 谱聚类算法(Spectral Clustering)
谱聚类(Spectral Clustering, SC)是一种基于图论的聚类方法--将带权无向图划分为两个或两个以上的最优子图,使子图内部尽量相似,而子图间距离尽量距离较远,以达到常见的聚类的 ...
- S/4 HANA中的MATDOC和MATDOC_EXTRACT
最近做了销售和物料管理方面的一些需求,因此对S/4中的MM的数据模型有了一定的了解.目前网络已经有一些介绍物料凭证表MATDOC的文章,内容好像不是很详细,另外也没发现介绍库存变更数据表MATDOC_ ...