JavaScript中的new Proxy()和Object.defineProperty使用詳細,Vue2和vue3中雙向數據綁定的原理

簡介:

  • Object.defineProperty() 是 JavaScript 中一個強大且常用的方法,用于定義對象屬性,允許我們精確地控制屬性的行為,包括讀取、寫入和刪除等操作,是vue2中雙向數據綁定的原理;

  • new Proxy() 是ES6中一種用于創建代理對象的特殊對象,它允許我們攔截并自定義目標對象的操作,例如屬性訪問、賦值、函數調用等。Proxy提供了一種機制,可以在目標對象上設置攔截器,從而攔截對目標對象的操作,是vue3中雙向數據綁定的原理。

一、Object.defineProperty()

1、詳細介紹

?Object.defineProperty()方法?是一個用于定義或修改對象屬性的方法,可以精確地控制屬性的行為,例如可寫性、可枚舉性和可配置性;在Object.defineProperty 方法中,有三個必需的參數和一個可選的第四參數。

  • obj (必需):要定義屬性的對象。可以是任何 JavaScript 對象。
  • prop (必需):要定義或修改的屬性的名稱。可以是一個字符串,表示屬性的名稱。
  • descriptor (必需):一個對象,用于定義或修改屬性的特性。

還可以包含以下可選的屬性:

  • - configurable (可選):布爾值,表示該屬性是否可以被刪除或修改特性。默認為 false。
  • - enumerable (可選):布爾值,表示該屬性是否可以在 for...in 循環中被枚舉。默認為 false。
  • - value (可選):任意類型的值,表示屬性的初始值。默認為 undefined。
  • - writable (可選):布爾值,表示該屬性的值是否可以被修改。默認為 false。
  • - get (可選):函數,表示獲取屬性值時要調用的函數。
  • - set (可選):函數,表示設置屬性值時要調用的函數。

2、使用實例

  const obj = {    name: "小明", age: 18    }//或者const obj = {    }//這里不能使用const,const定義的是常量,無法修改;let demoBute= obj.name;//使用 Object.defineProperty 定義屬性名為 name 的屬性Object.defineProperty(obj, "name", {//可枚舉屬性,可以在 for...in 循環中被枚舉enumerable: true,//可配置屬性,可以使用 delete 運算符刪除屬性configurable: true,//獲取屬性值的函數get: function () {console.log("獲取,收集依賴");return demoBute},//設置屬性值的函數set: function (value) {console.log("更新,通知用戶");demoBute = value;}})//修改,觸發set函數obj.name = "小紅"//控制臺輸出:更新,通知用戶//調用,出發get函數console.log(obj.name);//控制臺輸出:獲取,收集依賴//小明//多次調用,看下運行順序,按照調用順序依次執行(set > get > log)//只要調用obj都會觸發依賴函數obj.name = "小紅";             //set >console.log(obj.name);         //get > log//控制臺輸出: //更新,通知用戶//獲取,收集依賴//小紅

3、注意事項

  • ?get 函數的作用是在訪問屬性值時被調用,它不接受任何參數,但需要返回屬性的值。在示例中,我們通過return demoBute返回了name的屬性值 ;

  • set 函數的作用是在設置屬性值時被調用,它接受一個參數 value,該參數表示要設置的屬性值。在示例中,我們直接把修改后的值value 賦值給demoBute,實現更新;

  • get 和set 函數,不會同時被觸發,它們根據屬性的讀取或設置操作來決定調用哪個函數;

  • 該方法按照調用順序,從上到下依次執行,就是有更新就只運行set函數,沒更新,就只運行get函數;

二、new?Proxy()

1、詳細介紹

?new Proxy() 方法是一個允許您攔截并自定義對象的底層操作。通過使用Proxy,您可以攔截對象的各種操作,如屬性訪問、屬性賦值、函數調用等,并在這些操作發生時執行自定義行為;在Proxy中,常用的有兩個參數target和handler,target 是您要代理的目標對象, handler 是一個包含各種攔截操作的對象。 handler 對象中的每個屬性都是一個特殊的攔截器,用于攔截不同的操作。

2、基本語法

const target = {...... }const handler = {get(target, property, receiver){//攔截屬性的讀取操作},set(target, property, value, receiver){//攔截屬性}
}???????const proxy = new Proxy(target, handler);

3、使用實例

在Proxy中,get和set是handler對象中兩個常用的攔截器函數,用于攔截對象屬性的讀取和賦值操作。下面詳細介紹這兩個函數的用法和功能:

(1)、get(target , property , receiver)

  • - target :目標對象,即被代理的對象。
  • - property :要訪問的屬性名。
  • - receiver:最初被調用的對象,通常是代理對象或繼承代理對象的對象。 - 返回值:返回屬性的值。

get 函數在訪問目標對象的屬性時觸發,可以用來攔截屬性的讀取操作。您可以在 get 函數內部添加自定義的邏輯,例如記錄日志、驗證訪問權限等。下面是一個示例:

const target = {name: "Bob",age: 18
};
const handler = {get(target, property, receiver) {console.log(`正在讀取屬性:${property}`);return target[property];}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 輸出:正在讀取屬性:name,Bob
console.log(proxy.age); // 輸出:正在讀取屬性:age,18

這里我們創建了一個代理對象 proxy ,當訪問 proxy 的屬性時, get 函數會被觸發,并打印相應的日志信息。

(2)、set(target , property , value , receiver)?

  • - target :目標對象,即被代理的對象。
  • - property :要設置的屬性名。
  • - value :要設置的屬性值。
  • - receiver:最初被調用的對象,通常是代理對象或繼承代理對象的對象。 - 返回值:返回一個布爾值,表示屬性是否設置成功。???????

set 函數在給目標對象的屬性賦值時觸發,可以用來攔截屬性的賦值操作。您可以在 set 函數內部添加自定義的邏輯,例如驗證賦值的合法性、記錄日志等。下面是一個示例:

const target = {name: "Carl",age: 20
};
const handler = {set(target, property, value, receiver) {console.log(`正在設置屬性:${property},新值為:${value}`);target[property] = value;return true;}
};
const proxy = new Proxy(target, handler);
proxy.age = 30; // 輸出:正在設置屬性:age,新值為:30
console.log(proxy.age); // 輸出:30

在這里,我們給proxy的age屬性賦值時,set函數會被觸發,并打印相應的日志信息;通過get 和 set 攔截器函數,您可以在讀取和賦值屬性時執行自定義的行為,從而實現更靈活和可控的對象操作。

(3)、完整實例?????

const target = {name: "Alice",age: 25
};const handler = {get(target, property, receiver) {console.log(`正在讀取屬性:${property}`);return target[property];},set(target, property, value, receiver) {console.log(`正在設置屬性:${property},新值為:${value}`);target[property] = value;return true;}
};const proxy = new Proxy(target, handler);console.log(proxy.name);     // 輸出:正在讀取屬性:name,Alice
proxy.age = 30;             // 輸出:正在設置屬性:age,新值為:30
console.log(proxy.age);     // 輸出:正在讀取屬性:age,30

4、handler對象中的其它參數

  • ?get(target, property, receiver):攔截屬性的讀取操作。
  • ?set(target, property, value, receiver):攔截屬性的賦值操作。
  • ?apply(target, thisArg, argumentsList):攔截函數的調用操作。
  • ?has(target, property):攔截in操作符的操作。
  • ?deleteProperty(target, property):攔截屬性的刪除操作

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/710674.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/710674.shtml
英文地址,請注明出處:http://en.pswp.cn/news/710674.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Tomcat布署及優化

1.Tomcat簡介 Tomcat 是 Java 語言開發的,Tomcat 服務器是一個免費的開放源代碼的 Web 應用服務器,Tomcat 屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試 JSP 程序的首選。一般來說&…

在實訓云平臺上配置云主機

文章目錄 零、學習目標一、實訓云升級二、實訓云登錄(一)登錄實訓云(二)切換界面語言(三)規劃云主機實例 三、創建網絡三、創建路由器2024-2-29更新到此四、添加接口五、創建端口六、添加安全組規則七、創建…

反相輸入放大器與生俱來的坑

我們都知道反相放大器能將輸入的信號反相放大,這是很基本的知識,學過電路的一般都知道。反相放大器的公式為Vout -Vin*Rf/Rin(運算放大器應用匯總)。根據已知的公式,能很輕松的完成設計,但反相放大器與生俱…

每日一類:QString類深入講解

QString類是Qt框架中的一個核心組件,設計用于方便、高效地處理Unicode字符串。與標準C中的字符串處理方式相比,QString提供了更為豐富的API,支持國際化,并且內部使用UTF-16編碼,能夠處理世界上幾乎所有的語言文字。 設…

【PHP進階】Rabbitmq的實際使用

RabbitMQ是一個流行的消息隊列中間件,它提供了可靠的消息傳遞機制。在使用RabbitMQ時,有幾個重要的概念需要了解: 消息隊列(Message Queue):RabbitMQ中的核心概念之一。它是消息的緩沖區,用于存…

容器安全工具使用指南:保障容器環境安全的利器

隨著容器技術的廣泛應用,容器安全成為關注的焦點。本文將深入介紹幾個流行的容器安全工具,我們將深入了解容器安全領域的Top 10工具,包括Trivy、veinmind-tools、Clair、Docker Bench for Security、Sysdig Falco、neuVector等,詳細講解它們的功能、原理、安裝和使用方法,…

【精簡版】Ubuntu/Linux Anaconda 命令行終端安裝

網上重復內容很多,大都啰里啰嗦,特作此筆記。 【精簡版】Ubuntu/Linux Anaconda 命令行安裝 1 下載安裝包1.1 尋找適配版本安裝包1.2 下載 2 運行安裝程序3 設置安裝路徑4 添加環境變量并運行4.1 環境變量4.2 運行 5 驗證安裝成功感謝及參考博文 1 下載…

js ES6判斷字符串是否以某個字符串開頭或者結尾startsWith、endsWith

1.前言 startsWith:startsWith方法用于檢查字符串是否以指定的字符串開頭。 endsWith:endsWith方法用于檢查字符串是否以指定的字符串結尾。 2.用法示例 const str Hello, world!;console.log(str.startsWith(Hello)); // true console.log(str.starts…

音頻提取使用什么方法?視頻提取音頻

在數字技術與多媒體日益普及的今天,音頻提取已成為一個常見且重要的任務。無論是為了制作視頻、編輯音樂,還是進行語音識別和分析,我們都需要從原始材料中提取音頻。那么,音頻提取通常使用什么方法呢? 1. 使用專業的音…

【Git教程】(七)變基與揀取 —— 變基操作的概念、適用場景及其實現方式,揀取操作的實現 ~

Git教程 變基與揀取 1?? 工作原理:復制提交2?? 避免“鉆石鏈”3?? 什么情況下會遇到沖突4?? 移植分支5?? 執行變基后原提交的情況6?? 提交的原件與副本存在于同一版本庫中所帶來的問題7?? 撿取🌾 總結 通常, 一段提交歷史中往…

編寫科技項目驗收測試報告需要注意什么?第三方驗收測試多少錢?

科技項目驗收測試是一個非常重要的環節,它對于確保科技項目的質量和可用性起著至關重要的作用。在項目完成后,進行科技項目驗收測試可以評估項目的功能、性能和可靠性等方面,并生成科技項目驗收測試報告,以提供給項目的相關方參考…

第十六屆“中關村青聯杯”全國研究生數學建模競賽-E題:全球變暖氣候預測分析(續)

目錄 五、問題二:模型的建立與求解 5.1 問題分析 5.2 數據獲取及處理 5.2.1 數據獲取

git commit 的規范

今天在一個項目中提交git時報了下面的錯誤:subject may not be empty [subject-empty] type may not be empty [type-empty],上網查閱了一些資料,發現這種一種規范約束,用下面的命令我又重新提交了一次 git commit -m "feat…

SpringFramework實戰指南(七)

SpringFramework實戰指南(七) 4.5 三種配置方式總結4.5.1 XML方式配置總結4.5.2 XML+注解方式配置總結4.5.3 完全注解方式配置總結4.6 整合Spring5-Test5搭建測試環境4.5 三種配置方式總結 4.5.1 XML方式配置總結 所有內容寫到xml格式配置文件中聲明bean通過<bean標簽<…

Docker技術概論(2):Docker環境的搭建

Docker技術概論&#xff08;2&#xff09; Docker環境的搭建 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blo…

自動采集API壁紙系統源碼自適應手機端

HTML5響應式自動采集API壁紙系統源碼自適應手機端 瀑布流加載 源碼下載&#xff1a;https://www.qqmu.com/2303.html

InnoDB備份與恢復篇(1)-InnoDB的備份與還原策略

InnoDB數據庫的備份與還原策略 MySQL是一種廣泛使用的關系型數據庫管理系統&#xff0c;而InnoDB是MySQL的默認存儲引擎之一。在生產環境中&#xff0c;對于數據庫的備份和還原至關重要&#xff0c;以確保數據的安全性和可靠性。本文將介紹MySQL數據庫InnoDB引擎的備份與還原策…

七、有序的列表

描述 創建一個依次包含字符串P、y、t、h、o和n的列表my_list&#xff0c;先使用sorted函數對列表my_list進行臨時排序&#xff0c;第一行輸出排序后的完整列表&#xff0c;第二行輸出原始的列表。再使用sort函數對列表my_list進行降序排序&#xff0c;第三行輸出排序后完整的列…

yolov8漲點技巧,添加SwinTransformer注意力機制,提升目標檢測效果

目錄 摘要 SwinTransformer原理 代碼實現 YOLOv8詳細添加步驟 ymal文件內容 one_swinTrans three_swinTrans 啟動命令 完整代碼分享 摘要 Swin Transformer通過引入創新的分層注意力機制展現了其架構的獨特性&#xff0c;該機制通過將注意力區域劃分為塊并在這些塊內執…

小白的matlab簡單應用

基本概念 1、數組array 數組是一個更通用的數據結構&#xff0c;可以是一維、二維或多維的。 一維數組通常被稱為向量。 二維數組可以被視為矩陣。 多維數組可以用來表示更高維度的數據&#xff0c;例如三維數組可以表示一系列的矩陣。 用過的函數 20240229 1、讀取excel文件…