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.getPrototypeOfObject.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会报错

  • 如果第一个参数是undefinednullObject.setPrototypeOfReflect.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.getOwnPropertyNamesObject.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 映射相关推荐

  1. 深入浅出JS—15 ES6中Proxy及Reflect的使用

    在一些前端框架中,常常需要监听数据变化,页面进行响应.为了监听对象的变化,需要对对象的操作进行捕获.本文着重介绍ES6中Proxy代理对象的使用,以及涉及到的映射对象Reflect使用 1. Prox ...

  2. golang实现webgis后端开发

    目录 前言 二.实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转 ...

  3. tf.pad详解(能懂版)

    tf.pad:填充函数 tf.pad( tensor,paddings, mode='CONSTANT',name=None) tensor是要填充的张量 padings ,代表每一维填充多少行/列, ...

  4. Python ORM之SQLAlchemy 数据库连接引擎实现Mysql、PostgreSQL、Oracle连接以及高级查询的相关实例

    1 环境 SQLAlchemy 2.0.7 PyMySQL 1.0.2 Python 3.8.16 2 背景 SQLAlchemy 工具 实现多种数据库连接支持 MetaData.automap_ba ...

  5. delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据

    delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据 一.工程 program TreeView; usesSystem.StartUpCopy,FMX. ...

  6. Angular应用中tsconfig.json文件配置说明及配置全局路径映射

    tsconfig.json文件配置说明 1. tsconfig.json文件中的选项配置 2. 配置全局路径映射 1. tsconfig.json文件中的选项配置 TypeScript编译器配置文件的 ...

  7. 【转】MFC消息映射详解(整理转载)

    消息:主要指由用户操作而向应用程序发出的信息,也包括操作系统内部产生的消息.例如,单击鼠标左按钮,windows将产WM_LBUTTONDOWN消息,而释放鼠标左按钮将产生WM_LBUTTONUP消息 ...

  8. Java注解初体验(简单ORM映射框架)

    2019独角兽企业重金招聘Python工程师标准>>> Java学了很久了,始终没有深入学习过注解反射这些高级特性,晚上花时间研究了一下,其实还挺有意思的,貌似也搞清楚了像Hiber ...

  9. NeHe OpenGL教程 第二十三课:球面映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

最新文章

  1. MySQL 字段类型知识
  2. mysql 查询某个日期时间段,每天同一时间段的数据
  3. 无刷电机真威武,一通操作猛如虎
  4. SVN库迁移整理方法总结
  5. 【转载】尝试使用GraphicsMagick的缩略图功能
  6. JAVA多线程互斥同步例子
  7. 直播预告丨云时代的数据库客户端——CloudQuery最佳实践
  8. 关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案
  9. java中设置http响应头控制浏览器禁止缓存当前文档内容
  10. TFTP服务器的使用
  11. 黑龙江工程学院锐捷校园网连接路由器免认证
  12. python基础学习之python操作PDF文件、发送邮件添加附件10
  13. 【附源码】计算机毕业设计SSM汽车租赁系统
  14. 小米手机便签怎么批量导出到另一个手机
  15. matlab绘制符号函数的ezplot函数
  16. 用Multisim对高频丙类谐振功率放大器进行仿真
  17. 豆瓣fm android,豆瓣 FM
  18. 【python办公自动化(17)】利用python向PPT文档中写入内容(证书生成器)
  19. 【Python零基础快速入门系列 | 03】AI数据容器底层核心之Python列表
  20. 运算放大器的稳定性分析(一)

热门文章

  1. 跑腿兔(TaskRabbit)是一个跑腿网站
  2. 提交MapReduce任务出错:unknown queue: default
  3. 三谈大数据之足球盘口赔率水位分析思路及其实现利器
  4. 程序员:我的if else代码一个字也不能简化,网友好评如潮
  5. Spring声明式事务原理
  6. 台式计算机材质,台式电脑显示器购买的时候主要看哪些参数?
  7. js中数组删除对象的几种方式总结
  8. 关于android输入法
  9. Python 从业十年是种什么体验?
  10. mysql左连接表要取最新的一条数据_MySQL的左连接查询,只取出最大的一条数据...