阅读目录html
一:理解普通对象在声明时添加 get、setvue
在作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);
打印会以下所示:函数
当咱们继续打印以下信息:this
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这样的方法。spa
二:Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__prototype
上面只是在声明obj对象的时候,编写get和set 对应的属性。可是若是已经存在的对象的时候,再想继续添加 get/set呢?那只有使用code
Object.prototype.__defineGetter__ 和 Object.prototype.__defineSetter__ 了,以下代码演示:htm
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方法的对象。
那么具体项了解该方法的使用及详解,请看我这篇文章(http://www.javashuo.com/article/p-qpgkyhbt-hh.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是啥,是干啥使用的,请看我这篇文章(http://www.javashuo.com/article/p-gfvzjduv-be.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