Object-Advanced笔记
JavaScript对象进阶
数据劫持
1. 概念
一旦访问或者修改对象的属性时 拦截这个行为(访问/修改) 并对其添加除这个行为外的操作 最后返回结果
2. 实现
2.1 getter和setter
在对象中通过在对象中设置 getter 和 setter 方法拦截属性的 访问 / 修改
get方法无参数 但是有返回值
set方法有参数 但是无返回值
const obj = {
// 在属性前面加上 _ 代表该属性私有 能被外部访问 但是不应该被外部直接访问
_name:"bob",
// 这里的方法名不能和_name相同 否则会无限递归
get name(){
console.log(this._name + '被人访问了')
return this._name;
},
set name(value){
console.log(this._name + '被修改为' + value)
this._name = value;
}
}
//这里应该使用getter 和 setter 设置的属性名操作
//而不是对象中的私有属性
// 在访问有get语法的属性时,调用绑定的函数
obj.name // bob被人访问了
// 在改变有set语法的属性时,调用绑定的函数
obj.name = 'tom' // bob被修改为tom
缺点
每有一个需要劫持的对象属性就要设置一对getter和setter
对象属性和get set后面设置的属性名不能相同 否则会造成无限递归
2.2 Object.defineProperty
Object.defineProperty(obj, prop, descriptor)
obj: 要定义属性的对象
prop: 要定义或修改的属性的名称或 Symbol
descriptor: 要定义或修改的属性描述符
返回值: obj(传递给函数的对象)
descriptor描述符
- configurable
表示对象的属性是否可以被删除 以及除 value 和 writable 特性外的其他特性是否可以被修改
const object = {}
Object.defineProperty(object, 'name', {
get() {
return name;
},
set(value) {
name = value;
},
// 属性可以被删除 默认不可删除 configurable : false
configurable : true
});
object.name = 'tom';
console.log(object.name)// tom
delete object.name
console.log(object.name)// undefined
- enumerable
定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举
const object = {}
Object.defineProperty(object, 'name', {
value : 'tom',
enumerable : true
});
Object.defineProperty(object, 'age', {
// 默认无法被枚举 enumerable = false
value : 18
});
for (i in object) {
console.log(i)
}
- value
该属性对应的值 可以是任何有效的 JavaScript 值(数值 对象 函数等) 默认为 undefined
const object = {};
Object.defineProperty(object, 'name', {
// name默认值为tom
value : 'tom'
});
console.log(object.name);//tom
- writable
当且仅当该属性的 writable 键值为 true 时,属性的值 也就是上面的 value,才能被赋值运算符改变 默认为 false
const object = {};
Object.defineProperty(object, 'name', {
get(){
console.log(name + '被访问了');
return name;
},
// object中的name不可被修改
writable : false;
});
console.log(object.name);//tom
- get
当访问该属性时 会调用此函数 执行时不传入任何参数 但是会传入 this 对象(由于继承关系 这里的this并不一定是定义该属性的对象) 该函数的返回值为属性的值 默认为 undefined
const object = {};
Object.defineProperty(object, 'name', {
// 访问劫持
get(){
console.log(name + '被访问了');
return name;
}
});
console.log(object.name); //空
- set
当属性值被修改时 会调用此函数 该方法接受一个参数(也就是被赋予的新值)会传入赋值时的 this 对象 默认为 undefined
const object = {};
Object.defineProperty(object, 'name', {
// 访问劫持
get(){
console.log(name + '被访问了');
return name;
},
// 修改劫持
set(value){
name = value
}
});
object.name = 'tom';
console.log(object.name);//tom
注意:
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
描述符可拥有的键值
| configurable | enumerable | value | writable | get | set | |
|---|---|---|---|---|---|---|
| 数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
2.3 Object.defineProperties
Object.defineProperty(obj, prop1:{
...descriptor
},prop2:{
...descriptor
},...
)
obj: 要定义属性的对象
prop: 要定义或修改的属性的名称或 Symbol
descriptor: 要定义或修改的属性描述符
返回值: obj(传递给函数的对象)
用法和Object.defineProperty大致相同
var obj = {};
Object.defineProperties(obj, {
// obj第一个属性
'property1': {
value: true,
writable: true
},
// obj第二个属性
'property2': {
value: 'Hello',
writable: false
}
});
和 Object.defineProperty 区别
- Object.defineProperty每个属性都要写一遍
- Object.defineProperties多个属性可以写在一起
2.4 数据代理Proxy
ES6新增本地对象 new Proxy(target, handler)
- target: 要代理的目标对象
- handler: 描述符( 以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理的行为 )
- 返回值: 代理后的对象
const obj = { name: 'Jack', age: 18 }
// 开始代理
const result = new Proxy(obj, {
// 配置 get 进行代理设置
get (target, property) {
// target:要代理的目标对象
// property:该对象内的每一个属性,自动遍历
return target[property];
},
// 配置 set 进行修改
set (target, property, val) {
// target:要代理的目标对象
// property:该对象内要修改的属性
// val:要修改的属性的值
target[property] = val
// 注意:简单代理需要返回:true
return true;
}
})
Proxy方法和handler方法参考MDN:[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy]
Object-Advanced笔记的更多相关文章
- ECMAScript5之Object学习笔记(一)
随着IE的逐步追赶,目前到IE11已经能够很好的支持ECMAScript5标准了,其他的现代浏览器像firefox,chrome,opera就更不用说了. 再加上nodejs使得javascript在 ...
- Object学习笔记
<script type="text/javascript"> function forEach(o){ var html =""; for(var ...
- [javascript|基本概念|Object]学习笔记
对象:数据和功能的集合 创建对象:new 对象类型名称 e.g.: var o = new Object(); 或 var o = new Object(省略(),不推荐) 或 var o = {}( ...
- javascript,object,IDispatchEx笔记
//js: var testObj=new Object; //com内部: testObj=Object::InvokeEx(wFlags==DISPATCH_CONSTRUCT); //注: // ...
- ECMAScript5之Object学习笔记(三)
第三部分继续... Object.getOwnPropertyDescriptor(obj, prop) 获取一个对象的属性描述符 根据"Own"这个词我们可以猜到,prop只能是 ...
- ECMAScript5之Object学习笔记(二)
继续第二部分 Object.freeze(obj) 看字面意思就是“把一个对象冻结”. 下面我们来看个简单的例子以作说明: // a person instance var person = { na ...
- JavaScript Object学习笔记二
Object.create(proto, [propertiesObject])//创建对象,使用参数一来作为新创建对象的__proto__属性,返回值为在指定原型对象上添加自身属性后的对象 //参数 ...
- JavaScript Object学习笔记一
Object.assign(target, source1, source2, ...)//用于对象的复制合并(同名属性后覆盖前)或拷贝(拷贝自身可枚举属性,不拷贝继承属性或不可枚举属性),将sour ...
- DetNet: A Backbone network for Object Detection 笔记
1 前言 主要贡献: (1)第一个分析微调传统ImageNet预训练模型应用于目标检测器的固有缺点 (2)提出一个名为DetNet的新的骨干结构,它通过保持空间分辨率和扩大感受野的方式来专门设计用于目 ...
- Java 常用集合笔记
自增数组 ArrayList<Integer>G[]=new ArrayList[N] 详细笔记 相关题目 栈 Stack<Integer> stack=new Stack&l ...
随机推荐
- 查看app包名
操作步骤: 1.cmd中输入命令:adb shell am monitor 2.启动需要获取包名的应用
- 【组会】2023_1_6 4d mmwave
A NEW AUTOMOTIVE RADAR 4D POINT CLOUDS DETECTOR BY USING DEEP LEARNING ICASSP 2021 - 2021 IEEE Inter ...
- How to enable CIFS in kernel 4.9
kernel config 要打开这几项
- 九九乘法表打印记一次al面试
for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(i + "x&quo ...
- 使用阿里云镜像安装tensorflow
pip --default-timeout=1000 install --index-url https://mirrors.aliyun.com/pypi/simple tensorflow pip ...
- pod进阶
一.Lifecycle 官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/ 通过前面的分享,关于pod是什么相信看 ...
- k8s探针
探针是由kubelet对容器执行的定期诊断.要执行诊断,kubelet调用由容器实现的Handler.有三类处理程序: ExecAction:在容器内执行指定命令.如果命令退出时返回码为0认为诊断成功 ...
- 记一个快捷在线接口YAPI
在线地址:http://192.168.252.152:3000 1.idea中file下setting中plugins搜索并加载插件YAPI 2.idea中的.idea中.misc.xml文件配置. ...
- linux环境下部署mysql环境
一.部署步骤 1.将安装包上传到Linux服务器上(目录随意),然后解压缩 2.进入到解压后的目录下,分别执行以下命令安装四个包(严格按照顺序执行) rpm -ivh mysql-community- ...
- 如何基于Security框架兼容多套用户密码加密方式
一.说明 当已上线的系统存在使用其他的加密方式加密的密码数据,并且密码 不可逆 时,而新的数据采用了其他的加密方式,则需要同时兼容多种加密方式的密码校验. 例如下列几种情况: 旧系统用户的密码采用了 ...