ES6 Reflect

在这里插入图片描述

前言

  此文总结了Reflect对象的部分语法,对比了与Object方法的差异性,希望对你有用。

语法

  ReflectMath类似,都是JavaScript内置对象,提供了工具方法。

typeof Reflect // object

get

  Reflect.get(target, property, receiver) 用于读取对象属性,其中target为目标对象,property为属性名称。

var object = { x: 1 }

Reflect.get(object, 'x') // 1

  读取目标对象的访问器属性时,访问器getterthis上下文就是参数receiver。未指定参数receiver,默认为目标对象。

var object = {
  y: 1,
  get x() {
    return this
  },
}
var receiver = {}

Reflect.get(object, 'x') === object // true
Reflect.get(object, 'x', receiver) === receiver // true

set

  Reflect.set(target, property, value, receiver) 用于设置对象属性,其中target为目标对象,property为属性名称,value为属性值。

var object = { x: 1 }

Reflect.set(object, 'x', 2)

object // {x: 2}

  类似的,访问器setterthis上下文就是参数receiver,默认为目标对象。

var object = {
  y: 1,
  set x(v) {
    this.y = v
  },
}
var receiver = {}

Reflect.set(object, 'x', 2)
object // {y: 2}

Reflect.set(object, 'x', 3, receiver)
receiver // {y: 3}

has

  Reflect.has(object, property) 判断对象是否有此属性,本质上与in操作符功能相同。

var object = { x: undefined }

Reflect.has(object, 'x') // true

deleteProperty

  Reflect.deleteProperty(target, property) 用于删除对象属性,本质上与delete操作符功能相同。

var object = { x: 1 }

Reflect.deleteProperty(object, 'x')

object // {}

ownKeys

  Reflect.ownKeys(target) 返回对象自身所有属性,等价于Object.getOwnPropertyNames(target)Object.getOwnPropertySymbols(target)之和。

var object = { x: 1, [Symbol('y')]: 2 }

Object.defineProperty(object, 'z', {
  value: 3,
  enumerable: false,
})

Reflect.ownKeys(object) // ['x', 'z', Symbol(y)]

getOwnPropertyDescriptor

  Reflect.getOwnPropertyDescriptor(target, property) 用于获取对象属性描述符。

var object = { x: 1 }

Reflect.getOwnPropertyDescriptor(object, 'x')
// {
//   configurable: true,
//   enumerable: true,
//   value: 1,
//   writable: true,
// }

  与Object.getOwnPropertyDescriptor不同之处在于,target为非对象时,Object版本静默失败并返回undefined。而Reflect版本则抛出错误,提示开发者注意参数类型。

Object.getOwnPropertyDescriptor(1, 'x')
// undefined

Reflect.getOwnPropertyDescriptor(1, 'x')
// Uncaught TypeError: Reflect.getOwnPropertyDescriptor called on non-object

defineProperty

  Reflect.defineProperty(target, property, descriptor) 用于定义对象属性,其中target为目标对象,value为属性名称,descriptor为属性描述符。

var object = {}

Reflect.defineProperty(object, 'x', { value: 1 })

Reflect.getOwnPropertyDescriptor(object, 'x')
// {
//   configurable: false,
//   enumerable: false,
//   value: 1,
//   writable: false,
// }

  若属性定义失败,Object版本将抛出错误,而Reflect版本将返回false

var object = Object.freeze({})

Reflect.defineProperty(object, 'x', { value: 1 })
// false

Object.defineProperty(object, 'x', { value: 1 })
// Uncaught TypeError: Cannot define property x, object is not extensible

preventExtensions

  Reflect.preventExtensions(target) 阻止对象拓展。

var object = {}

Reflect.preventExtensions(object)

Reflect.isExtensible(object) // false

  类似的,target为非对象时,Object版本静默失败,而Reflect版本将抛出错误。

Object.preventExtensions(1)
// 1

Reflect.preventExtensions(1)
// Uncaught TypeError: Reflect.preventExtensions called on non-object

isExtensible

  Reflect.isExtensible(target) 判断对象是否可拓展。

var object = {}

Reflect.preventExtensions(object)

Reflect.isExtensible(object) // false

  若参数为非对象,Reflect版本将抛出错误,而Object版本则静默失败并返回false。不合理之处在于参数为非对象,讨论是否可拓展并没有任何意义。

Reflect.isExtensible(1)
// Uncaught TypeError: Reflect.isExtensible called on non-object

Object.isExtensible(1)
// false

getPrototypeOf

  Reflect.getPrototypeOf(target) 获取对象原型。

Reflect.getPrototypeOf({}) === Object.prototype // true

  参数target为非对象时,Object版本存在类型转换,而Reflect版本将抛出错误。

Object.getPrototypeOf(1) === Number.prototype
// true

Reflect.getPrototypeOf(1)
// Uncaught TypeError: Reflect.getPrototypeOf called on non-object

setPrototypeOf

  Reflect.setPrototypeOf(target, prototype) 用于设置原型,返回值为布尔值。

var object = {}

Reflect.setPrototypeOf(object, null)

Reflect.getPrototypeOf(object) // null

  类似的,参数target为非对象时,Object版本静默失败并返回target,而Reflect版本将抛出错误。

Object.setPrototypeOf(1, null)
// 1

Reflect.setPrototypeOf(1, null)
// Uncaught TypeError: Reflect.setPrototypeOf called on non-object

apply

  Reflect.apply(target, thisArg, args) 用于调用函数,其中target为目标函数,thisArg为函数被调用时的上下文对象thisargs为函数参数。

function fn(x, y) {
  return this.v + x + y
}

Reflect.apply(fn, { v: 1 }, [2, 3]) // 6

  若函数apply属性被占用,运行apply方法绑定this将抛出错误。

function fn(x, y) { return x + y }

fn.apply = 1

fn.apply(null, [3, 4])
// Uncaught TypeError: fn.apply is not a function

  替换为原型apply方法可规避,但语义不明显。

Function.prototype.apply.call(fn, null, [3, 4]) // 7

  而Reflect.apply执行方式则更简洁清晰。

Reflect.apply(fn, null, [3, 4]) // 7

construct

  Reflect.construct(target, args, newTarget)new操作符行为类似,其中target为构造函数,args为函数参数。

function F(x, y) {
  this.x = x
  this.y = y
}

Reflect.construct(F, [1, 2]) // F {x: 1, y: 2}

  参数newTarget有两个用处,第一个是指定新对象的原型为newTarget的原型对象。

function F() {}
function NT() {}

var object = Reflect.construct(F, [], NT)

Reflect.getPrototypeOf(object) === NT.prototype // true

  除此之外,原构造函数内部new.target会被指向newTarget函数。

function F() {
  console.log(new.target === NT) // true
}
function NT() {}

Reflect.construct(F, [], NT)

小结

  Reflect对象的设计目的主要包括。

  • 语言内部的元编程行为,统一移动至Reflect,未来新的元编程行为将只添加到Reflect
  • Object部分函数的行为不合理,在Reflect版本进行修正
  • 符合函数式编程,语义更清晰
  • ProxyReflect结合在代理同时还能保持默认行为

🎉 写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!

手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~

GitHub / GiteeGitHub Pages掘金CSDN 同步更新,欢迎关注😉~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 设置代理 在ES6中,可以使用Proxy对象来设置代理。 Proxy对象是一个代理对象,它可以拦截并重定义基本操作,比如属性访问、赋值、函数调用等。通过Proxy对象可以实现对一个对象的代理访问,从而实现对该对象的控制。 使用Proxy对象时,需要传入两个参数:要代理的对象和一个处理程序对象。处理程序对象是一个包含各种捕捉器的对象,用于拦截基本操作。 下面是一个简单的例子,展示如何使用Proxy对象设置代理: ```javascript let target = {}; // 要代理的对象 let handler = { // 处理程序对象 get: function(target, prop) { // get捕捉器,拦截属性访问操作 console.log(`访问了属性 ${prop}`); return target[prop]; }, set: function(target, prop, value) { // set捕捉器,拦截属性赋值操作 console.log(`设置了属性 ${prop},新值为 ${value}`); target[prop] = value; return true; } }; let proxy = new Proxy(target, handler); // 创建代理对象 proxy.name = "Tom"; // 设置代理对象的属性 console.log(proxy.name); // 访问代理对象的属性 ``` 上面的代码中,我们使用了Proxy对象设置了一个代理对象。代理对象可以通过handler对象中的get和set捕捉器来拦截属性访问和赋值操作,并进行相应的处理。 2. 获取代理 在ES6中,可以使用Reflect对象的get方法来获取代理对象的属性值。 Reflect对象是一个内置对象,它提供了一组静态方法,用于操作对象。其中,Reflect.get方法可以用于获取对象的属性值。 下面是一个简单的例子,展示如何使用Reflect.get方法获取代理对象的属性值: ```javascript let target = { name: "Tom" }; // 要代理的对象 let handler = { // 处理程序对象 get: function(target, prop) { // get捕捉器,拦截属性访问操作 console.log(`访问了属性 ${prop}`); return target[prop]; } }; let proxy = new Proxy(target, handler); // 创建代理对象 console.log(Reflect.get(proxy, "name")); // 获取代理对象的属性值 ``` 上面的代码中,我们使用了Reflect.get方法获取了代理对象的属性值。这个方法接收两个参数:要获取属性值的对象和属性名。在这个例子中,我们传入了代理对象和属性名,从而获取了代理对象的属性值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DonV

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值