阅读目录

一:理解普通对象在声明时添加 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. 洛谷P3209 [HNOI2010]PLANAR(2-SAT)

    题目描述 若能将无向图G=(V,E)画在平面上使得任意两条无重合顶点的边不相交,则称G是平面图.判定一个图是否为平面图的问题是图论中的一个重要问题.现在假设你要判定的是一类特殊的图,图中存在一个包含所 ...

  2. Mysql sql 功能分类

    分类 DDL:数据定义语言,用于定义数据库对象,比如创建表,列,库等 DML:数据操作语言,用于添加.删除.修改数据 DQL:数据查询语言,用于查询(结果集是虚拟表,放在内存中) DCL:数据控制语言 ...

  3. leetcode-67.二进制求和

    leetcode-67.二进制求和 Points 数组 数学 题意 给定两个二进制字符串,返回他们的和(用二进制表示). 输入为非空字符串且只包含数字 1 和 0. 示例 1: 输入: a = &qu ...

  4. Spring Data Redis 让 NoSQL 快如闪电 (1)

    [编者按]本文作者为 Xinyu Liu,详细介绍了 Redis 的特性,并辅之以丰富的用例.在本文的第一部分,将重点概述 Redis 的方方面面.文章系国内 ITOM 管理平台 OneAPM 编译呈 ...

  5. NAT穿越(一) NAT类型

    NAT分为四种类型: (1)完全透明NAT(Full Cone NAT): 从内部主机  (IN IP ipa) +端口(IN PORT porta) 发送的数据映射为  IP(OUT IP IPA) ...

  6. Redis常用命令【列表】

    一.简介 基于Linked List实现,元素是字符串类型,列表头尾增删快,中间增删慢,增删元素是常态. 元素可以重复出现,最多包含2^32-1个元素. 二.命令 1.说明 1.1 B block 块 ...

  7. 使用fiddler对手机上的程序进行抓包

    用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用.   前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 备注:如果电脑用的是台式机,可以安装一个 ...

  8. ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0

    ASP.NET 5.0 将改名为 ASP.NET Core 1.0 ASP.NET MVC 6  将改名为 ASP.NET MVC Core 1.0 Entity Framework 7.0    将 ...

  9. 洗礼灵魂,修炼python(79)--全栈项目实战篇(7)—— 多级目录菜单之地址管理系统升级版

    要求: 1.在上一篇的地址管理系统的基础上做升级改动 2.添加增删改的功能 3.尽量的贴近生活常识中的地址管理 分析: 需求不用多说了,干就完了 相关文件源码地址:github 这次由于要有增删改的操 ...

  10. Not Found woff 字体库

    原因是,默认在IIS上是没有添加对*.woff,*.svg文件的Mime类型,因此在客户端请求此类文件时得到的都是404. 所以我们只需要在我们对应网站下的Mime类型中添加文件对应的类型就行了 .w ...