日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS高级——Proxy、Reflect

發(fā)布時間:2024/7/5 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS高级——Proxy、Reflect 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、監(jiān)聽對象的操作

我們先來看一個需求:有一個對象,我們希望監(jiān)聽這個對象中的屬性被設置或獲取的過程

  • 通過我們前面所學的知識,能不能做到這一點呢?
  • 其實是可以的,我們可以通過之前的屬性描述符中的存儲屬性描述符來做到;

下面這段代碼就利用了前面講過的 Object.defineProperty 的存儲屬性描述符來對屬性的操作進行監(jiān)聽:

但是這樣做有什么缺點呢?

  • 首先,Object.defineProperty設計的初衷,不是為了去監(jiān)聽截止一個對象中所有的屬性的。我們在定義某些屬性的時候,初衷其實是定義普通的屬性,但是后面我們強行將它變成了數據屬性描述符。
  • 其次,如果我們想監(jiān)聽更加豐富的操作,比如新增屬性、刪除屬性,那么Object.defineProperty是無能為力的。
  • 所以我們要知道,存儲數據描述符設計的初衷并不是為了去監(jiān)聽一個完整的對象。

二、Proxy基本使用

在ES6中,新增了一個Proxy類,這個類從名字就可以看出來,是用于幫助我們創(chuàng)建一個代理的:

  • 也就是說,如果我們希望監(jiān)聽一個對象的相關操作,那么我們可以先創(chuàng)建一個代理對象(Proxy對象);
  • 之后對該對象的所有操作,都通過代理對象來完成,代理對象可以監(jiān)聽我們想要對原對象進行哪些操作;

我們可以將上面的案例用Proxy來實現一次:

  • 首先,我們需要new Proxy對象,并且傳入需要偵聽的對象以及一個處理對象,可以稱之為handler;
const p = new Proxy(target, handler)
  • 其次,我們之后的操作都是直接對Proxy的操作,而不是原有的對象,因為我們需要在handler里面進行偵聽;

三、Proxy的set和get捕獲器

如果我們想要偵聽某些具體的操作,那么就可以在handler中添加對應的捕捉器(Trap):

const obj = {name: 'zep',age: 22 }const proxyObj = new Proxy(obj, {// 獲取值時的捕獲器get: function (target, key, receiver) {console.log(`監(jiān)聽到對象的${key}屬性被訪問了`, target)return target[key]},// 設置值時的捕獲器set: function (target, key,newValue, receiver) {console.log(`監(jiān)聽到對象的${key}屬性被設置值`, target)target[key] = newValue},// 監(jiān)聽in的捕獲器has: function (target, key) {console.log(`監(jiān)聽到對象的${key}屬性的in操作`, target)return key in target},// 監(jiān)聽delete的捕獲器deleteProperty: function (target, key) {console.log(`監(jiān)聽到對象的${key}屬性的delete操作`, target)delete target[key]} })// proxyObj.name = 'lala' // 監(jiān)聽到對象的name屬性被設置值 { name: 'zep', age: 22 } // console.log(proxyObj.name) // 監(jiān)聽到對象的name屬性被訪問了 { name: 'lala', age: 22 } // lala// console.log(obj.name) // lala// in操作符 // console.log('name' in proxyObj) // 監(jiān)聽到對象的name屬性的in操作 { name: 'zep', age: 22 } // true// delete操作 delete proxyObj.age // 監(jiān)聽到對象的age屬性的delete操作 { name: 'zep', age: 22 }

四、Proxy所有捕獲器

五、Proxy的construct和apply

當然,我們還會看到捕捉器中還有construct和apply,它們是應用于函數對象的:

六、Reflect的作用

Reflect也是ES6新增的一個API,它是一個對象,字面的意思是反射。
那么這個Reflect有什么用呢?

  • 它主要提供了很多操作JavaScript對象的方法,有點像Object中操作對象的方法;
  • 比如Reflect.getPrototypeOf(target)類似于 Object.getPrototypeOf();
  • 比如Reflect.defineProperty(target, propertyKey, attributes)類似于Object.defineProperty() ;


那么Object和Reflect對象之間的API關系,可以參考MDN文檔:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods

七、Reflect的常見方法

八、Reflect的使用

那么我們可以將之前Proxy案例中對原對象的操作,都修改為Reflect來操作:

九、Receiver的作用

我們發(fā)現在使用getter、setter的時候有一個receiver的參數,它的作用是什么呢?

  • 如果我們的源對象(obj)有setter、getter的訪問器屬性,那么可以通過receiver來改變里面的this;

我們來看這樣的一個對象:

Reflect的construct:

總結

以上是生活随笔為你收集整理的JS高级——Proxy、Reflect的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。