handler.defineProperty()
handler.defineProperty()
方法是对 [[DefineOwnProperty]]
对象内部方法 的陷阱,被 Object.defineProperty()
等操作使用。
¥The handler.defineProperty()
method is a trap for the [[DefineOwnProperty]]
object internal method, which is used by operations such as Object.defineProperty()
.
Try it
语法
参数
¥Parameters
以下参数传递给 defineProperty()
方法。this
绑定到处理程序。
¥The following parameters are passed to the defineProperty()
method. this
is bound to the handler.
target
-
目标对象。
property
-
表示属性名称的字符串或
Symbol
。 descriptor
-
正在定义或修改的属性的描述符。
返回值
¥Return value
defineProperty()
方法必须返回 Boolean
指示属性是否已成功定义。其他值为 强制转换为布尔值。
¥The defineProperty()
method must return a Boolean
indicating whether or not the property has been successfully defined. Other values are coerced to booleans.
如果 [[DefineOwnProperty]]
内部方法返回 false
,则许多操作(包括 Object.defineProperty()
和 Object.defineProperties()
)会抛出 TypeError
。
¥Many operations, including Object.defineProperty()
and Object.defineProperties()
, throw a TypeError
if the [[DefineOwnProperty]]
internal method returns false
.
描述
拦截
¥Interceptions
该陷阱可以拦截以下操作:
¥This trap can intercept these operations:
或调用 [[DefineOwnProperty]]
内部方法 的任何其他操作。
¥Or any other operation that invokes the [[DefineOwnProperty]]
internal method.
不变量
¥Invariants
如果处理程序定义违反以下不变量之一,则代理的 [[DefineOwnProperty]]
内部方法将抛出 TypeError
:
¥The proxy's [[DefineOwnProperty]]
internal method throws a TypeError
if the handler definition violates one of the following invariants:
- 如果目标对象不可扩展,则无法添加属性。也就是说,如果
Reflect.isExtensible()
对target
返回false
,并且Reflect.getOwnPropertyDescriptor()
对target
上的属性返回undefined
,则陷阱必须返回一个假值。 - 属性不能是不可配置的,除非存在目标对象的相应不可配置自有属性。也就是说,如果
Reflect.getOwnPropertyDescriptor()
对target
上的属性返回undefined
或configurable: true
,并且descriptor.configurable
是false
,则陷阱必须返回一个假值。 - 不可配置的属性不能是不可写的,除非存在目标对象的相应不可配置、不可写的自有属性。也就是说,如果
Reflect.getOwnPropertyDescriptor()
为target
上的属性返回configurable: false, writable: true
,而descriptor.writable
是false
,则陷阱必须返回一个假值。 - 如果某个属性在目标对象上具有相应的属性,则目标对象属性的描述符必须与
descriptor
兼容。也就是说,假装target
是一个普通对象,并且Object.defineProperty(target, property, descriptor)
会抛出错误,则陷阱必须返回一个假值。Object.defineProperty()
参考包含更多信息,但总结一下,当目标属性不可配置时,必须满足以下条件:configurable
、enumerable
、get
和set
不能更改- 属性不能在数据和访问器之间切换
writable
属性只能从true
更改为false
- 只有当
writable
为true
时,才能更改value
属性
示例
捕获 defineProperty
¥Trapping of defineProperty
以下代码捕获 Object.defineProperty()
。
¥The following code traps Object.defineProperty()
.
const p = new Proxy(
{},
{
defineProperty(target, prop, descriptor) {
console.log(`called: ${prop}`);
return true;
},
},
);
const desc = { configurable: true, enumerable: true, value: 10 };
Object.defineProperty(p, "a", desc); // "called: a"
当调用 Object.defineProperty()
或 Reflect.defineProperty()
时,传递给 defineProperty()
陷阱的 descriptor
有一个限制 - 只有以下属性可用(非标准属性将被忽略):
¥When calling Object.defineProperty()
or
Reflect.defineProperty()
, the descriptor
passed to
defineProperty()
trap has one restriction—only following properties are
usable (non-standard properties will be ignored):
enumerable
configurable
writable
value
get
set
const p = new Proxy(
{},
{
defineProperty(target, prop, descriptor) {
console.log(descriptor);
return Reflect.defineProperty(target, prop, descriptor);
},
},
);
Object.defineProperty(p, "name", {
value: "proxy",
type: "custom",
}); // { value: 'proxy' }
规范
Specification |
---|
ECMAScript Language Specification # sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc |
浏览器兼容性
BCD tables only load in the browser