js 数据监听--对象的变化
Object.defineProperty第三个参数descriptor的说明。
数据描述符和存取描述符均具有以下可选键值:
定义了 value 或 writable , 一定不能有 get 或 set, 反之亦然, 否则报错.
configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
可以将属性函数化。
eg:
var student = {
age: 14,
sayHi: function (name){
console.log('hi~' + name);
}
}
Object.defineProperty(student,'age',{
configurable: true,
enumerable: true,
value(){
return 1;
},
})
student.age // ƒ value(){ return 1; }
student.age() // 1
writable
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
默认为 undefined。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
默认为 undefined。
class Observer {
constructor(data) {
this.data = data;
this.filterObj(data);
}
static isObject(obj) {
if (Object.prototype.toString.call(obj) === "[object Object]") {
return true;
}
return false;
}
filterObj(data) {
if (!Observer.isObject(data)) return;
for (const key in data) {
// 过滤原型链上的属性。
if (data.hasOwnProperty(key)) {
const value = data[key];
if (Observer.isObject(data[key])) {
new Observer(data[key]);
};
this.watch(key, value);
}
}
}
watch(k, v) {
Object.defineProperty(this.data, k, {
enumerable: true,
configurable: true,
get: function () {
console.log(`${k},被访问。`)
return v;
},
set: function (newV) {
console.log(`${k},属性值发生变化。`)
console.log(`新的值为:${JSON.stringify(newV)}。`)
if (Observer.isObject(newV)) {
new Observer(newV);
}
v = newV;
},
})
}
}
let data = {
time: '2048',
user: {
name: 'naruto',
equipment: {
arms: 'kuwu',
ArmGuard: 'long',
}
},
};
const app = new Observer(data);

/*
Array.prototype重写method
getOwnPropertyDescriptor方法可以查看原生js的push等方法是否可以重写。
MDN:
Object.getOwnPropertyDescriptor(obj, prop)通过方法可查看自有属性对应的属性描述符。
(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
Object.getOwnPropertyDescriptor(Array.prototype, "push");
{value: ƒ push(), writable: true, enumerable: false, configurable: true}
*/
Object.defineProperty(Array.prototype, "push", {
configurable: true,
enumerable: false,
writable: true,
value: function () {
const arg = [].slice.call(arguments);
// console.log('');
const len = this.length;
for (let i = 0; i < arg.length; i++) {
this[len + i] = arg[i]
}
return this.length;
}
});
// Array.prototype.push = function () {
// ...
// }
/*
MDN:
Array.isArray(Array.prototype); // true;
Array.prototype[0]; // undefined
鲜为人知的事实:Array.prototype 本身也是一个 Array。
Array拥有的静态方法:from isArray of。
Array.prototype.constructor
所有的数组实例都继承了这个属性,它的值就是 Array,表明了所有的数组都是由 Array 构造出来的。
Array.prototype.length
上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
look like this:
Array.prototype.first = function() {};
Array.prototype.mapping = function() {};
Array.prototype["mapping"];
*/
操作对象中的Getter
Object.defineProperty(Array.prototype,'fn',{
configurable:true,
enumerable:true,
get(){
const test = function(){};
test.f1 = ()=>{
console.log(this)
};
return test;
}
});
[1,2,3].fn.f1() //[1, 2, 3]
Array.prototype.__defineGetter__('fn',function(){
//const a = {};
//const a = function(){};
a.f1 = ()=>{
console.log(this);
};
return a;
});
[1,2,3].fn.f1() //[1, 2, 3]
var a = {};
a.__defineGetter__('name',function(){
return 'wfc';
});
a.name //'wfc
js 数据监听--对象的变化的更多相关文章
- Object.defineProperty 监听对象属性变化
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- vue 2.0 watch 监听对象的变化
- Proxy监听对象的数据变化,处理绑定数据很有用
Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作.一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处. }; //interceptor 拦截 var ...
- js动态监听dom变化
原生js 动态监听dom变化,根据不同的类型绑定不同的处理逻辑 // Firefox和Chrome早期版本中带有前缀 var MutationObserver = window.MutationO ...
- vue 监听对象里的特定数据
vue 监听对象里的特定数据变化 通常是这样写的,只能监听某一个特定数据 watch: { params: function(val) { console.log(val) this.$ajax.g ...
- js 实时监听input中值变化
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
- js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange
(1) 先说jquery, 使用 jQuery 库的话,只需要同时绑定 oninput 和 onpropertychange 两个事件就可以了,示例代码: $('#username').bin ...
- JS 获取和监听屏幕方向变化(portrait / landscape)
移动设备的屏幕有两个方向: landscape(横屏)和portrait(竖屏),在某些情况下需要获取设备的屏幕方向和监听屏幕方向的变化,因此可以使用Javascript提供的 MediaQueryL ...
- vue--》如何使用wacth监听对象的属性变化?
在开发过程中,我们经常需要监听watch监听一个对象的变化,但是如何来实现 监听对象中属性的变化呢? 先回顾一下如何监听整个对象的变化,使用watch就行了 export default { ...
随机推荐
- 图的最小生成树的理解和实现:Prim和Kruskal算法
最小生成树 一个连通图的生成树是一个极小的连通子图,它含有图中所有的顶点,但只有足以构成一棵树的n-1条边.我们将构造连通网的最小代价生成树称为最小生成树(Minimum Cost Spanning ...
- 创建第一个flask项目
安装flask模块 pip install flask或conda install flask 创建一个run.py文件,文件内容如下: from flask import Flask app = F ...
- TX2 刷机时遇到Parsing board information failed
因为之前调试I2C时,修改了EEPROM Layout,所以,在刷机时遇到此问题. 解决办法是按照此文档中的介绍来修改布局. 实际操作时,我拿了一块正常的TX2,按照指令: sudo i2cdump ...
- Vue 不睡觉教程3 - 来点实在的:自动计算剩余时间的任务列表
目标前两课教的是入门和文件结构.都没有什么实在的东西.这次我们要来点实在的.我们要做出一个待办列表.这个待办列表有以下特点: 可以自动从文本中抽取出这件事情的开始时间可以显示当前距离这件事情的开始时间 ...
- (Android+IOS)正在做一个新闻App,做的差不多了,听听大家的建议 (图)
(Android+IOS)正在做一个新闻App,做的差不多了,听听大家的建议! 新闻采集器做好了,前端展示APP界面感觉还不是很好,还需要改进改进,希望发布(Android和IOS版本)前听听大家的建 ...
- Tomcat开发Comet要点
Comet技术的悄然流行,Jetty在比较早地支持了Comet,提供了Comet 的Servlet,同样从Tomcat6开始,Comet已经在Tomcat的标准Servlet中开始支持了,这是个好事情 ...
- System.Web.Caching.Cache类 缓存 各种缓存依赖(转)
转自:http://www.cnblogs.com/kissdodog/archive/2013/05/07/3064895.html Cache类,是一个用于缓存常用信息的类.HttpRuntime ...
- [CPP] Big Three
前言 上一篇攻略中,我们已经充分理解了不带指针的类的设计原则,并且还从标准库设计大师的作品里收获了不少功力.而这一篇攻略,将继续完成基于对象的类的关卡,解决这一关的最后一个问题,那就是带指针的类.在这 ...
- 【WAN】PPPOE宽带上网功能详解
1.mac地址克隆 某些地方的运营商会把宽带账号和用户电脑的mac地址绑定起来,运营商的账号只能让当前的电脑去上网,限制路由器上网,这时候路由器可以复制用户电脑的mac伪装成这台电脑去上网,实现路由器 ...
- shell 10个好习惯
The Linux Cookbook 一书的作者 Michael Stutz 凭借自己多年使用 UNIX 的经验,总结了 10 个良好习惯,个人认为真的很受用,现摘要如下与大家分享. 1.建立层级目录 ...