es6 对象中是否有键值_ES6新增操作对象API ---- Reflect

概述

文章参考阮一峰大佬的ES6标准入门:http://es6.ruanyifeng.com/#docs/reflect

Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新 APIReflect 对象的设计目的有这样几个。

1, 将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty ),放到 Reflect 对象上。现阶段,某些方法同时在 Object Reflect对象上部署,未来的新方法将只部署在 Reflect 对象上。也就是说,从 Reflect 对象上可以拿到语言内部的方法。

2,修改某些 Object 方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc) 在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc) 则会返回 false。

0a49290e87cc09b39c5b6dc0efff94c0.png

3, 让 Object 操作都变成函数行为。某些 Object 操作是命令式,比如name in objdelete obj[name],而 Reflect.has(obj, name) Reflect.deleteProperty(obj, name) 让它们变成了函数行为。

b8c5ad41f4a36077facf4e1261139628.png

ps: in 运算符 如果指定的属性在指定的对象或其原型链中,则in 运算符 返回 true ,否者返回false。

4, Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。

4961bfcef9d334d2ba87a8da7eb56e0e.png

Reflect 对象上的方法

325f9dd9dd8be683e224e8a32c53ce88.png

Reflect 对象上的方法详细解释

Reflect.get(target, name, receiver)

Reflect.get 方法查找并返回 target 对象的 name 属性,如果没有该属性,则返回undefined

eg:

0b18d4a93a1bb7055f26c418766c55fd.png

另外,关于Reflect.get方法的第三个参数是可选的,当你没有传这个参数时,如果 target 对象的 name 属性部署了读取函数(getter),则读取函数的 this 绑定的还是 target。

bba8e4cc72d9865d10cfb218912712e0.png

如果你传入了第三个参数,且 target 对象的 name 属性部署了读取函数(getter),则读取函数的 this 绑定的是你传入的那个参数

eg:

7667428b748091b602cc3ac6fc6c6eb3.png

Reflect.set(target, name, value, receiver)

Reflect.set 方法设置 target 对象的 name属性等于 value (即将 value 赋值给 target 对象的name)。

7fe9c86eb17995d6c6fcedf95c72a71f.png

从图中可以看出,两个属性都赋值给了空对象 obj,这种操作是没有毛病滴。

关于Reflect.get方法的第四个参数(receiver)是可选的,同get方法一样,当你没有传这个参数时,如果 target 对象的 name 属性部署了赋值函数(setter),则读取函数的 this 绑定的还是 target。

d924ed854d4837c88b99e11d9eaf346e.png

如果你传入了第三个参数,且 target 对象的 name 属性部署了赋值函数(setter),则读取函数的 this 绑定的是你传入的那个参数

Reflect.has(obj, name)

Reflect.has 方法对应 name in obj 里面的 in 运算符。

7148ad610095ec93ecf46b3544dc1f37.png

如果第一个参数不是对象,Reflect.has in 运算符都会报错。

Reflect.deleteProperty(obj, name)

Reflect.deleteProperty 方法等同于delete obj[name],用于删除对象的属性。

e6aabf02a05e94fdac19e0badfaa3bd5.png

该方法返回一个布尔值。如果删除成功,或者被删除的属性不存在,返回 true;删除失败,被删除的属性依然存在,返回 false

fffb470addca3f453fa776bdf5e75548.png

Reflect.construct(target, args)

Reflect.construct 方法等同于 new target(...args),这提供了一种不使用 new,来调用构造函数的方法。

d9e484dd4569f2ae55c1c4c8eb695f08.png

第一个参数是一个构造函数,第二个参数是一个数组。

29d41092b7aec1febd19ffd017ca1f0a.png

Reflect.getPrototypeOf(obj)

Reflect.getPrototypeOf 方法用于读取对象的__proto__属性,对应Object.getPrototypeOf(obj)

7f8613a9e0e67b10a3e5eded833e4f8e.png

Reflect.defineProperty(target, propertyKey, attributes)

Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性。唯一不同是返回 Boolean 值。未来,后者会被逐渐废除,请从现在开始就使用Reflect.defineProperty代替它。

ps(Object.defineProperty() ):

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

语法:

Object.defineProperty(obj, prop, descriptor)

obj

要在其上定义属性的对象。

prop

要定义或修改的属性的名称。

descriptor(对象形式)

将被定义或修改的属性描述符。

81ff505c966aa166746659fe55086663.png

什么是属性描述符:

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

数据描述符和存取描述符均具有以下可选键值:

configurable

当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false

enumerable

当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false

数据描述符同时具有以下可选键值

value

该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined

writable

当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false

存取描述符同时具有以下可选键值

get

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined

set

一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

描述符可同时具有的键值:

d0e0f478a1a6cc0bcbafd887aa738eb0.png

如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

ps: 这个知识点蛮大的,举两个例子:

1,属性描述符中的 writable 属性(Object.defineProperty(obj, prop, descriptor)中的descriptor是一个对象形式):

当writable属性设置为false时,该属性被称为“不可写”。它不能被重新分配(控制对象是否可以被修改,默认为 false。但是我们的对象都是继承自原型的,原型上它为true,所以可以被修改)。

1cbf6dfbaed0246779fb03709531c972.png

2,enumerable定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。

2b330db76dabd42442a3fe81dd8d182e.png

从图中可以看出,in 运算符是可以的,但是使用for..in循环遍历的时候是找不到它的~

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Reflect.getOwnPropertyDescriptor 基本等同于 Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替代掉后者。

866c42c8d6083ad8b7655f05da59b148.png

Reflect.getOwnPropertyDescriptorObject.getOwnPropertyDescriptor的一个区别是,如果第一个参数不是对象,Object.getOwnPropertyDescriptor(1, 'foo')不报错,返回undefined,而Reflect.getOwnPropertyDescriptor(1, 'foo')会抛出错误,表示参数非法。

Reflect.isExtensible (target)

Reflect.isExtensible 方法对应 Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。

014e0690fbdb47d8e53e92b7ee8baf88.png

使用 Object.preventExtensions(obj) 阻止对象扩展!

59919cf3edbb14285a52789f5e81c62c.png

Reflect.preventExtensions(target)

Reflect.preventExtensions 对应 Object.preventExtensions 方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功。

132c1f11d895d1ee6547ad5654b271db.png

Reflect.ownKeys (target)

Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。

1188476e1cc64caa340bc7ea0891166d.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值