Reflect 映射
Reflect 映射
1. Reflect 映射
Reflect
对象与 Proxy
对象一样,也是 ES6
为了操作对象而提供的新 API
Reflect
是一个内置的对象,而不是一个函数对象,因此它是不可构造的
Reflect
作用:
- 优化
Object
的一些操作方法以及合理的返回Object
操作返回的结果 Proxy
在拦截访问目标对象,或者对代理对象操作都是通过Reflect
映射来完成
let obj = {name: 'jsx'
};
// 获取对象属性
console.log(Reflect.ownKeys(obj)); // ['name']// 结合Proxy使用
let proxy = new Proxy(obj, {get(target, prop, receiver) {return Reflect.get(target, prop, receiver);},set(target, prop, value, receiver) {return Reflect.set(target, prop, value, receiver)}
})
console.log(proxy.name); // jsx
console.log(proxy.title = 'Reflect映射'); // Reflect映射
2. Reflect 静态方法
对于每个可被 Proxy
捕获的内部方法,在 Reflect
中都有一个对应的方法,其名称和参数与 Proxy
捕捉器相同
Proxy
对象可以方便地调用对应的 Reflect
方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy
怎么修改默认行为,你总可以在Reflect
上获取默认行为
2-1 Reflect.get
Reflect.get(target, name, receiver)
Reflect.get
方法查找并返回target
对象的name
属性,如果没有该属性,则返回undefined
- 如果
name
属性部署了读取函数get()
,则读取函数的this
绑定receiver
- 如果第一个参数不是对象,
Reflect.get
方法会报错``
// Reflect.get(target, name, receiver) 返回target对象的name属性
let myobj = {name: 'jsx',age: 22,get info() {return this.name + ' ' + this.age}
}
console.log(Reflect.get(myobj, 'name')) // jsx
// 没有属性返回undefined
console.log(Reflect.get(myobj, 'names')); // undefined
// 设置 get()函数后 this 指向第三个参数 receiver
let receiver = {name: 'ljj',age: 23
}
console.log(Reflect.get(myobj, 'info', receiver)); // ljj 23// 第一个参数必须是对象,否则报错
// console.log(Reflect.get(true, 'name')) Uncaught TypeError
2-2 Reflect.set
Reflect.set(target, name, value, receiver)
Reflect.set
方法设置target
对象的name
属性等于value
如果
name
属性设置了赋值函数,则赋值函数的this
绑定receiver
如果第一个参数不是对象,
Reflect.set
会报错
// Reflect.set(target, name, value, receiver)
// 设置target对象的name属性等于value 返回布尔值
let myobj = {name: 'jsx',age: 22,set info(value) {return this.name}
}console.log(Reflect.set(myobj, 'info', 'javascript')); // true
console.log(myobj.name) // jsx
let receiver = {name: 'vue'
}
// 设置第四个参数后,set() 赋值函数this指向第四个参数receiver
console.log(Reflect.set(myobj, 'info', 'javascript', receiver))
console.log(receiver.name); // vue// 第一个参数必须为对象
// console.log(Reflect.set(true, 'info')) Uncaught TypeError
如果 Proxy
对象和 Reflect
对象联合使用,前者拦截赋值操作,后者完成赋值的默认行为,并且传入了receiver
,那么Reflect.set
会触发Proxy.defineProperty
拦截
// proxy和Reflect联合使用时 指定第四个参数后会触发proxy中的definedProperty拦截器
let title = {lesson: 'jsx'
}
let proxy = new Proxy(title, {set(target, key, value, receiver) {console.log('触发')return Reflect.set(target, key, value, receiver)},defineProperty(target, key, desc) {console.log('触发')return Reflect.defineProperty(target, key, desc)}
})
console.log(proxy.lesson = 'javascript')
2-3 Reflect.has
Reflect.has(obj, name)
Reflect.has
方法对应name in obj
里面的in
运算符- 如果
Reflect.has()
方法的第一个参数不是对象,会报错
// Reflect.has(obj, name)
// 对应name in obj里面的in运算符
let obj = {name: 'jsx'
}// 旧写法
console.log('name' in obj) // true// 新写法
console.log(Reflect.has(obj, 'name')); // true
2-4 Reflect.deleteProperty
Reflect.deleteProperty(obj, name)
Reflect.deleteProperty
方法等同于delete obj[name]
,用于删除对象的属性
- 该方法返回一个布尔值。如果删除成功,或者被删除的属性不存在,返回
true
;删除失败,被删除的属性依然存在,返回false
- 如果
Reflect.deleteProperty()
方法的第一个参数不是对象,会报错
// Reflect.deleteProperty(obj, name)
// 删除对象属性
let obj = {name: 'jsx',lesson: 'js'
}
// 旧写法
delete obj.name;
console.log(obj); // {lesson: 'js'}// 新写法
console.log(Reflect.deleteProperty(obj, 'lesson')); // true
console.log(obj); // {}// 第一个参数必须为对象,否则报错
// console.log(Reflect.defineProperty(true, 'lesson'))
2-5 Reflect.apply
Reflect.apply(func, thisArg, args)
Reflect.apply
方法等同于Function.prototype.apply.call(func, thisArg, args)
,调用一个方法并且显式地指定 this
变量和参数列表,参数列表可以是数组,或类似数组的对象
// Reflect.apply(func, thisarg, args)
// 指定函数,指定this指向,参数数组 类似于Function.prototype.apply.call(func, thisArg, args)
let obj = {name: 'jsx'
}function getName(name) {return name
}
// 旧写法
console.log(Function.prototype.apply.call(getName, obj, ['ljj'])); // ljj// 新写法
console.log(Reflect.apply(getName, obj, ['jsx'])); // jsx
2-6 Reflect.construct
Reflect.construct(target, args)
Reflect.construct
方法等同于new target(...args)
,这提供了一种不使用new
,来调用构造函数的方法
- 如果
Reflect.construct()
方法的第一个参数不是函数,会报错
// Reflect.construct(target, args)
// 类似于 new调用函数 相等于不使用new调用构造函数
function User(name) {this.name = name
}// new 写法
let user = new User('jsx');
console.log(user); // User {name: 'jsx'}// Reflect.construct
let user1 = Reflect.construct(User, ['ljj'])
console.log(user1); // User {name: 'ljj'}// 第一个参数不是函数会报错
// let user2 = Reflect.construct(true, ['ljj']); Uncaught TypeError
2-7 Reflect.getPrototypeOf
Reflect.getPrototypeOf(obj)
Reflect.getPrototypeOf
方法用于读取对象的__proto__
属性,对应Object.getPrototypeOf(obj)
Reflect.getPrototypeOf
和Object.getPrototypeOf
的区别:
- 如果参数不是对象,
Object.getPrototypeOf
会将这个参数转为对象,然后再运行 - 如果参数不是对象,
Reflect.getPrototypeOf
会报错
// Reflect.getPrototype(obj)
// 用于获取对象的原型,相等于__proto__
function User() {}
let user = new User()// 旧的写法
console.log(Object.getPrototypeOf(user));
console.log(Object.getPrototypeOf(1)); // 参数不是对象会转换成对象类型// 新的写法
console.log(Reflect.getPrototypeOf(user))
// console.log(Reflect.getPrototypeOf(1)); // 参数不是对象会报错
2-8 Reflect.setPrototypeOf
Reflect.setPrototypeOf(obj, newProto)
Reflect.setPrototypeOf
方法用于设置目标对象的原型,对应Object.setPrototypeOf(obj, newProto)
方法。它返回一个布尔值,表示是否设置成功
如果无法设置目标对象的原型目标对象禁止扩展,
Reflect.setPrototypeOf
方法返回false
如果第一个参数不是对象,
Object.setPrototypeOf
会返回第一个参数本身,而Reflect.setPrototypeOf
会报错如果第一个参数是
undefined
或null
,Object.setPrototypeOf
和Reflect.setPrototypeOf
都会报错
// Reflect.setPrototypeOf(obj, newProto)
// 类似于Objec.setPrototypeOf方法,用于设置对象的原型
let myobj = {name: 'jsx'
}
let proto = {proto: 'ljj'
};// 旧的写法
console.log(Object.setPrototypeOf(myobj, proto));
// 设置成功返回成功后的对象
console.log(myobj)
// 第一个参数不是对象,返回第一个参数
console.log(Object.setPrototypeOf(1, proto)); // 1
// 第一个参数为null或者undefined 会报错
// Object.setPrototypeOf(null, proto)// 新的写法
console.log(Reflect.setPrototypeOf(myobj, proto)); // 设置成功返回true
// 第一个参数不是对象,报错
// console.log(Reflect.setPrototypeOf(1, proto)); // Uncaught TypeError
// 第一个参数为null或者undefined 会报错
// Reflect.setPrototypeOf(null, proto)
2-9 Reflect.defineProperty
Reflect.defineProperty(target, propertyKey, attributes)
Reflect.defineProperty
方法基本等同于Object.defineProperty
,用来为对象定义属性
- 如果
Reflect.defineProperty
的第一个参数不是对象,就会抛出错误 - 可以与
Proxy.defineProperty
配合使用
// Reflect.defineProperty(target, key, description)
// 设置对象的描述特征 相当于Object.defineProperty
let obj = {name: 'jsx'
};
let proxy = new Proxy(obj, {defineProperty(target, key, desc) {console.log(desc);// {value: 'ljj', writable: true, enumerable: true, configurable: true}return Reflect.defineProperty(target, key, desc)}
})
console.log(Object.defineProperty(proxy, 'name', {value: 'ljj',writable: true,enumerable: true,configurable: true
})); // {name: 'ljj'}// 如果第一个参数不是对象,会报错
// Reflect.defineProperty(true, 'name', {value: 'js'}) Uncaught TypeError
2-10 Reflect.getOwnPropertyDescriptor
Reflect.getOwnPropertyDescriptor(target, propertyKey)
Reflect.getOwnPropertyDescriptor
基本等同于Object.getOwnPropertyDescriptor
,用于得到指定属性的描述对象
Reflect.getOwnPropertyDescriptor
如果第一个参数不是对象会抛出错误Object.getOwnPropertyDescriptor
如果第一个参数不是对象不报错,返回undefined
// Reflect.getOwnPropertyDescriptor(target, propertyKey)
// 等同于Object.getOwnPropertyDescriptor 获取对象属性描述
let obj = {};
Object.defineProperty(obj, 'name', {value: 'jsx',writable: true,enumerable: true,configurable: true
})// 旧的写法
console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
// {value: 'jsx', writable: true, enumerable: true, configurable: true}
// 参数不为对象返回undefined
console.log(Object.getOwnPropertyDescriptor(true, 'name')); // undefined// 新的写法
console.log(Reflect.getOwnPropertyDescriptor(obj, 'name'));
// {value: 'jsx', writable: true, enumerable: true, configurable: true}
// 参数不为对象报错
// console.log(Reflect.getOwnPropertyDescriptor(true, 'name')); // Uncaught TypeError
2-11 Reflect.isExtensible
Reflect.isExtensible (target)
Reflect.isExtensible
方法对应Object.isExtensible
,返回一个布尔值,表示当前对象是否可扩展
- 如果参数不是对象,
Object.isExtensible
会返回false
, - 如果参数不是对象,
Reflect.isExtensible
会报错
// Reflect.isExtensible(target)
// 等同于Object.isExtensible 对象是否可扩展 返回布尔在
let obj = {name: 'jsx'
};
// 旧的写法
console.log(Object.isExtensible(obj)) // true
// 参数不是对象返回false
console.log(Object.isExtensible(true)) // false// 新的写法
console.log(Reflect.isExtensible(obj)); // true
// 参数不是对象报错
// console.log(Reflect.isExtensible(true)) // 报错
2-12 Reflect.preventExtensions
Reflect.preventExtensions(target)
Reflect.preventExtensions
对应Object.preventExtensions
方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功
- 如果参数不是对象,
Object.preventExtensions
在 ES5 环境报错,在 ES6 环境返回传入的参数 - 如果参数不是对象,
Reflect.preventExtensions
会报错
// Reflect.preventExtensions(target)
// 等同于Object.preventExtensions 设置对象不可扩展
let obj = {name: 'jsx'
};// 旧的写法
Object.preventExtensions(obj);
console.log(Object.isExtensible(obj)); // false
// 参数不是对象返回传入的参数
console.log(Object.preventExtensions(1))// 新的写法
Reflect.preventExtensions(obj);
console.log(Reflect.isExtensible(obj)); // false
// 参数不是对象报错
// Reflect.preventExtensions(1) // 报错
2-13 Reflect.ownKeys
Reflect.ownKeys (target)
Reflect.ownKeys
方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames
与Object.getOwnPropertySymbols
之和
- 如果
Reflect.ownKeys()
方法的第一个参数不是对象,会报错
// Reflect.ownKeys(target)
// 获取对象的所有属性,字符串类型和Symbol类型
// Object.getOwnPropertySymbols + Object.getOwnPropertyNames
let obj = {name: 'jsx','title': 'Reflect',[Symbol('hello')]: 'hello'
}
console.log(Reflect.ownKeys(obj))
// ['name', 'title', Symbol(hello)]// 参数不是对象则会报错
// console.log(Reflect.ownKeys(true)); // 报错
Reflect 映射相关推荐
- 深入浅出JS—15 ES6中Proxy及Reflect的使用
在一些前端框架中,常常需要监听数据变化,页面进行响应.为了监听对象的变化,需要对对象的操作进行捕获.本文着重介绍ES6中Proxy代理对象的使用,以及涉及到的映射对象Reflect使用 1. Prox ...
- golang实现webgis后端开发
目录 前言 二.实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转 ...
- tf.pad详解(能懂版)
tf.pad:填充函数 tf.pad( tensor,paddings, mode='CONSTANT',name=None) tensor是要填充的张量 padings ,代表每一维填充多少行/列, ...
- Python ORM之SQLAlchemy 数据库连接引擎实现Mysql、PostgreSQL、Oracle连接以及高级查询的相关实例
1 环境 SQLAlchemy 2.0.7 PyMySQL 1.0.2 Python 3.8.16 2 背景 SQLAlchemy 工具 实现多种数据库连接支持 MetaData.automap_ba ...
- delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据
delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据 一.工程 program TreeView; usesSystem.StartUpCopy,FMX. ...
- Angular应用中tsconfig.json文件配置说明及配置全局路径映射
tsconfig.json文件配置说明 1. tsconfig.json文件中的选项配置 2. 配置全局路径映射 1. tsconfig.json文件中的选项配置 TypeScript编译器配置文件的 ...
- 【转】MFC消息映射详解(整理转载)
消息:主要指由用户操作而向应用程序发出的信息,也包括操作系统内部产生的消息.例如,单击鼠标左按钮,windows将产WM_LBUTTONDOWN消息,而释放鼠标左按钮将产生WM_LBUTTONUP消息 ...
- Java注解初体验(简单ORM映射框架)
2019独角兽企业重金招聘Python工程师标准>>> Java学了很久了,始终没有深入学习过注解反射这些高级特性,晚上花时间研究了一下,其实还挺有意思的,貌似也搞清楚了像Hiber ...
- NeHe OpenGL教程 第二十三课:球面映射
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
最新文章
- MySQL 字段类型知识
- mysql 查询某个日期时间段,每天同一时间段的数据
- 无刷电机真威武,一通操作猛如虎
- SVN库迁移整理方法总结
- 【转载】尝试使用GraphicsMagick的缩略图功能
- JAVA多线程互斥同步例子
- 直播预告丨云时代的数据库客户端——CloudQuery最佳实践
- 关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案
- java中设置http响应头控制浏览器禁止缓存当前文档内容
- TFTP服务器的使用
- 黑龙江工程学院锐捷校园网连接路由器免认证
- python基础学习之python操作PDF文件、发送邮件添加附件10
- 【附源码】计算机毕业设计SSM汽车租赁系统
- 小米手机便签怎么批量导出到另一个手机
- matlab绘制符号函数的ezplot函数
- 用Multisim对高频丙类谐振功率放大器进行仿真
- 豆瓣fm android,豆瓣 FM
- 【python办公自动化(17)】利用python向PPT文档中写入内容(证书生成器)
- 【Python零基础快速入门系列 | 03】AI数据容器底层核心之Python列表
- 运算放大器的稳定性分析(一)