大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说Object.defineProperty and Proxy,希望您对编程的造诣更进一步.
Object.defineProperty
**Object.defineProperty()** 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法:Object.defineProperty(obj, prop, descriptor)
参数:
obj:要定义属性的对象。
prop:要定义或修改的属性的名称或 Symbol 。
descriptor:要定义或修改的属性描述符。
返回值:被传递给函数的对象。
描述
该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for...in 或 Object.keys 方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):
-
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。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的this对象。 默认为undefined。
描述符默认值汇总
- 拥有布尔值的键
configurable、enumerable和writable的默认值都是false。 - 属性值和函数的键
value、get和set字段的默认值为undefined。
描述符可拥有的键值
configurable``enumerable``value``writable``get``set数据描述符可以可以可以可以不可以不可以存取描述符可以可以不可以不可以可以可以
如果一个描述符不具有 value、writable、get 和 set 中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常。
Proxy
Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
语法
const p = new Proxy(target, handler)
参数
-
target要使用
Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。 -
handler一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理
p的行为。
方法
-
创建一个可撤销的
Proxy对象。
handler 对象的方法
handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。
所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。
-
handler.getPrototypeOf():是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。语法
const p = new Proxy(obj, { getPrototypeOf(target) { ... } });参数
当
getPrototypeOf方法被调用时,this指向的是它所属的处理器对象。-
target被代理的目标对象。
返回值
getPrototypeOf方法的返回值必须是一个对象或者null。Object.getPrototypeOf方法的捕捉器。返回指定对象的原型语法
Object.getPrototypeOf(object)参数:
obj要返回其原型的对象。返回值:给定对象的原型。如果没有继承属性,则返回
null。 -
-
handler.setPrototypeOf():方法主要用来拦截Object.setPrototypeOf().语法
var p = new Proxy(target, { setPrototypeOf: function(target, prototype) { } });参数
以下参数传递给
setPrototypeOf方法.-
target被拦截目标对象.
-
prototype对象新原型或为
null.
返回值
如果成功修改了
[[Prototype]],setPrototypeOf方法返回true,否则返回false.Object.setPrototypeOf方法的捕捉器。设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或null。语法
Object.setPrototypeOf(obj, prototype)参数
-
obj
要设置其原型的对象。.
-
prototype
该对象的新原型(一个对象 或
null).
描述
如果对象的[[Prototype]]被修改成不可扩展(通过
Object.isExtensible()查看),就会抛出TypeError异常。如果prototype参数不是一个对象或者null(例如,数字,字符串,boolean,或者undefined),则什么都不做。否则,该方法将obj的[[Prototype]]修改为新的值。Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于Object.prototype.__proto__,它被认为是修改对象原型更合适的方法 -
-
handler.isExtensible():用于拦截对对象的Object.isExtensible()。语法
var p = new Proxy(target, { isExtensible: function(target) { } });参数
下列参数将会被传递给
isExtensible方法。 this 绑定在 handler 对象上。-
target目标对象。
返回值
isExtensible方法必须返回一个 Boolean值或可转换成Boolean的值。Object.isExtensible方法的捕捉器。 -
-
handler.preventExtensions():用于设置对Object.preventExtensions()的拦截语法
var p = new Proxy(target, { preventExtensions: function(target) { } });参数
以下参数传递给
preventExtensions方法. 它会绑定到这个handler.-
target所要拦截的目标对象.
返回值
preventExtensions方法返回一个布尔值.Object.preventExtensions方法的捕捉器。 -
-
handler.getOwnPropertyDescriptor():是Object.getOwnPropertyDescriptor()的钩子。语法
var p = new Proxy(target, { getOwnPropertyDescriptor: function(target, prop) { } });参数
下列参数会被传入 getOwnPropertyDescriptor方法中。这是绑定到handler上。-
target目标对象。
-
prop返回属性名称的描述。
返回值
getOwnPropertyDescriptor方法必须返回一个 object 或undefined。Object.getOwnPropertyDescriptor方法的捕捉器。 -
-
handler.defineProperty():拦截对对象的Object.defineProperty()操作。语法
var p = new Proxy(target, { defineProperty: function(target, property, descriptor) { } });参数
下列参数将会被传递给
defineProperty方法。this绑定在 handler 对象上。-
target目标对象。
-
property待检索其描述的属性名。
-
descriptor待定义或修改的属性的描述符。
返回值
defineProperty方法必须以一个Boolean返回,表示定义该属性的操作成功与否。Object.defineProperty方法的捕捉器。 -
-
handler.has():是针对in操作符的代理方法。语法
var p = new Proxy(target, { has: function(target, prop) { } });参数
下面是传递给 has方法的参数.thisis bound to the handler.-
target目标对象.
-
prop需要检查是否存在的属性.
返回值
has方法返回一个 boolean 属性的值.拦截
这个钩子可以拦截下面这些操作:
- 属性查询:
foo in proxy - 继承属性查询:
foo in Object.create(proxy) with检查: with(proxy) { (foo); }Reflect.has()
-
-
handler.get():用于拦截对象的读取属性操作。语法
var p = new Proxy(target, { get: function(target, property, receiver) { } });参数
以下是传递给get方法的参数,
this上下文绑定在handler对象上.-
target目标对象。
-
property被获取的属性名。
-
receiverProxy或者继承Proxy的对象
返回值
get方法可以返回任何值。
拦截
该方法会拦截目标对象的以下操作:
- 访问属性:
proxy[foo]和proxy.bar - 访问原型链上的属性:
Object.create(proxy)[foo] Reflect.get()
-
-
handler.set():是设置属性值操作的捕获器。语法
const p = new Proxy(target, { set: function(target, property, value, receiver) { } });参数
以下是传递给
set()方法的参数。this绑定在 handler 对象上。-
target目标对象。
-
property将被设置的属性名或
Symbol。 -
value新属性值。
-
receiver最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。**比如:**假设有一段代码执行
obj.name = "jen",obj不是一个 proxy,且自身不含name属性,但是它的原型链上有一个 proxy,那么,那个 proxy 的set()处理器会被调用,而此时,obj会作为 receiver 参数传进来。
返回值
set()方法应当返回一个布尔值。- 返回
true代表属性设置成功。 - 在严格模式下,如果
set()方法返回false,那么会抛出一个TypeError异常。
-
-
handler.deleteProperty():用于拦截对对象属性的delete操作。语法
var p = new Proxy(target, { deleteProperty: function(target, property) { } });参数
deleteProperty方法将会接受以下参数。this被绑定在 handler上。-
target目标对象。
-
property待删除的属性名。
返回值
deleteProperty必须返回一个Boolean类型的值,表示了该属性是否被成功删除。 -
-
handler.ownKeys():用于拦截Reflect.ownKeys().语法
var p = new Proxy(target, { ownKeys: function(target) { } });参数
下面的参数被传递给
ownKeys。this被绑定在handler上。-
target目标对象.
返回值
ownKeys方法必须返回一个可枚举对象. -
-
handler.apply():用于拦截函数的调用。语法
var p = new Proxy(target, { apply: function(target, thisArg, argumentsList) { } });参数
以下是传递给apply方法的参数,
this上下文绑定在handler对象上.-
target目标对象(函数)。
-
thisArg被调用时的上下文对象。
-
argumentsList被调用时的参数数组。
返回值
apply方法可以返回任何值。
函数调用操作的捕捉器。
-
-
handler.construct():用于拦截new操作符. 为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]内部方法(即new target必须是有效的)。语法
var p = new Proxy(target, { construct: function(target, argumentsList, newTarget) { } });参数
下面的参数将会传递给
construct方法,this绑定在handler上。-
target目标对象。
-
argumentsListconstructor的参数列表。
-
newTarget最初被调用的构造函数,就上面的例子而言是p。
返回值
construct方法必须返回一个对象。 -
一些不标准的捕捉器已经被废弃并且移除了。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13647.html