代理(Proxy)是 JavaScript 提供的一种元编程的能力,它可以拦截对象的一些基本操作,比如读写属性、调用方法等。在 ES11 中,代理的功能得到了进一步增强,本文将详细介绍如何更好地使用 JavaScript 的代理。
基本用法
在 ES6 中,我们已经可以使用代理来拦截对象的基本操作了,例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - ----------- ----- - -------------------- ---------- ------ ------------- -- ----------- ----- ------ - -------------------- ------- -- ----------- ------------ - ------ - --- ----------- -- -- ------- ---- -- -- ------- --------- - --- -- -- ------- --- -- -- ----------------------- -- -- ------- --- -- -- --
上面的代码中,我们使用 new Proxy()
创建了一个代理对象 proxy
,它可以拦截对象 obj
的读写操作。其中,拦截读操作的方法是 get()
,拦截写操作的方法是 set()
。当我们使用 proxy.name
读取属性值时,会触发 get()
方法,并输出 Getting name
;当我们使用 proxy.age = 20
修改属性值时,会触发 set()
方法,并输出 Setting age to 20
。
新增的拦截方法
在 ES11 中,代理新增了一些拦截方法,让我们可以更加精细地控制对象的行为。
has()
has()
方法用于拦截 in
操作符,即判断对象是否包含某个属性。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - ----------- ----- - --------------------- ------- ------------ ------ ---- -- ------- - --- ----- -- ------ -- -- -------- --- --------- -- -- ---- -------- -- ------ -- -- -------- ------ --------- -- -- -----
上面的代码中,我们使用 has()
方法拦截了 in
操作符,当我们使用 'age' in proxy
判断属性存在时,会触发 has()
方法,并输出 Checking age existence
。
apply()
apply()
方法用于拦截函数的调用。例如:
-------- ------ -- - ------ - - -- - ----- ----- - --- ---------- - ------------- -------- ----- - -------------------- -------------- ---- ---------- ------ --------------------- ------ - --- -------- --- -- -- ------- --- ---- --- -- -- -
上面的代码中,我们使用 apply()
方法拦截了函数的调用,当我们使用 proxy(1, 2)
调用函数时,会触发 apply()
方法,并输出 Calling add with 1,2
。
construct()
construct()
方法用于拦截 new
操作符,即创建对象实例时的行为。例如:
----- ------ - ----------------- ---- - --------- - ----- -------- - ---- - - ----- ----- - --- ------------- - ----------------- ----- - --------------------- -------------- -------- ---- ---------- ------ --- ---------------- - --- ----- - - --- -------------- ---- -- -- -------- ------ -------- ---- -------- --------------- -- -- ------ - ----- -------- ---- -- -
上面的代码中,我们使用 construct()
方法拦截了 new
操作符,当我们使用 new proxy('Alice', 18)
创建对象实例时,会触发 construct()
方法,并输出 Creating Person instance with Alice,18
。
deleteProperty()
deleteProperty()
方法用于拦截 delete
操作符,即删除对象属性的行为。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - ---------------------- ----- - --------------------- ---------- ------ ------ ------------- - --- ------ ---------- -- -- -------- --- ------------------- -- -- - ----- ------- -
上面的代码中,我们使用 deleteProperty()
方法拦截了 delete
操作符,当我们使用 delete proxy.age
删除属性时,会触发 deleteProperty()
方法,并输出 Deleting age
。
getOwnPropertyDescriptor()
getOwnPropertyDescriptor()
方法用于拦截 Object.getOwnPropertyDescriptor()
方法,即获取对象属性描述符的行为。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - -------------------------------- ----- - -------------------- ---------- -- ---------- ------ --------------------------------------- ------ - --- -------------------------------------- ------- -- -- ------- ---------- -- --- -- -- - ------ --- --------- ----- ----------- ----- ------------- ---- -
上面的代码中,我们使用 getOwnPropertyDescriptor()
方法拦截了 Object.getOwnPropertyDescriptor()
方法,当我们使用 Object.getOwnPropertyDescriptor(proxy, 'age')
获取属性描述符时,会触发 getOwnPropertyDescriptor()
方法,并输出 Getting descriptor of age
。
getPrototypeOf()
getPrototypeOf()
方法用于拦截 Object.getPrototypeOf()
方法,即获取对象原型的行为。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - - ------- -------- -- ----- ----- - --- ---------- - ---------------------- - -------------------- --------- -- ------------ ------ ------ - --- ----------------------------- -- -- ------- --------- -- ------- ------- -- -- - ------- -------- -
上面的代码中,我们使用 getPrototypeOf()
方法拦截了 Object.getPrototypeOf()
方法,当我们使用 Object.getPrototypeOf(proxy)
获取对象原型时,会触发 getPrototypeOf()
方法,并输出 Getting prototype of [object Object]
。
isExtensible()
isExtensible()
方法用于拦截 Object.isExtensible()
方法,即判断对象是否可扩展的行为。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - -------------------- - --------------------- --------- ---------------- ------ ---------------------------- - --- --------------------------- -- -- -------- ------- ------- ------------- -- -- ----
上面的代码中,我们使用 isExtensible()
方法拦截了 Object.isExtensible()
方法,当我们使用 Object.isExtensible(proxy)
判断对象是否可扩展时,会触发 isExtensible()
方法,并输出 Checking [object Object] extensibility
。
ownKeys()
ownKeys()
方法用于拦截 Object.getOwnPropertyNames()
、Object.getOwnPropertySymbols()
和 Object.keys()
方法,即获取对象自身属性名的行为。例如:
----- --- - - ----- -------- ---- -- -- ----- ----- - --- ---------- - --------------- - -------------------- --- ---- -- ------------ ------ ------------------------ - --- ---------------------------------- -- -- ------- --- ---- -- ------- ------- -- -- - ------- ----- - ------------------------------------ -- -- ------- --- ---- -- ------- ------- -- -- -- ------------------- -- -- ------- --- ---- -- ------- ------- -- -- - ------- ----- -
上面的代码中,我们使用 ownKeys()
方法拦截了 Object.getOwnPropertyNames()
、Object.getOwnPropertySymbols()
和 Object.keys()
方法,当我们使用这些方法获取对象自身属性名时,会触发 ownKeys()
方法,并输出 Getting own keys of [object Object]
。
总结
在 ES11 中,代理的功能得到了进一步增强,我们可以使用新增的拦截方法更加精细地控制对象的行为。本文介绍了这些拦截方法的用法,并给出了示例代码。希望本文对你学习和使用 JavaScript 的代理有帮助。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/65bdf1d4add4f0e0ff78bf74