最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中的數(shù)據(jù)劫持和數(shù)據(jù)代理使用

 更新時(shí)間:2025年02月21日 17:13:09   作者:遇見很ok  
文章主要介紹了數(shù)據(jù)劫持(Object.defineProperty)和數(shù)據(jù)代理(Proxy)兩種方式在JavaScript中的應(yīng)用,并通過生活中的例子來詳細(xì)解釋它們的工作原理和使用場(chǎng)景,文章還對(duì)比了兩種方式的優(yōu)缺點(diǎn),并指出了它們?cè)赩ue.js中的應(yīng)用

一、數(shù)據(jù)劫持(Data Hijacking)

1. 生活中的例子

假設(shè)你開了一家餐廳,你雇了一個(gè) “賬房先生”(收銀員),他的工作是:

  • 任何客人 查詢賬單 時(shí),他都會(huì)記錄查詢行為,并告訴客人正確的金額。
  • 任何客人 修改賬單 時(shí),他都會(huì)檢查金額是否合理,并記錄修改情況。

現(xiàn)實(shí)中的“賬房先生”就是 Object.defineProperty(),它攔截每個(gè)數(shù)據(jù)的讀取和修改。

2. 代碼示例

我們用 Object.defineProperty() 來模擬這個(gè) “賬房先生”:

let bill = {};  // 創(chuàng)建賬單對(duì)象

Object.defineProperty(bill, 'amount', {
  get() {
    console.log('客人查詢了賬單金額');
    return 100; // 假設(shè)賬單金額是100
  },
  set(value) {
    console.log(`客人修改了賬單金額為 ${value}`);
  }
});

console.log(bill.amount);  // 觸發(fā) get 方法,查詢金額
bill.amount = 200;         // 觸發(fā) set 方法,修改金額

運(yùn)行結(jié)果:

客人查詢了賬單金額
100
客人修改了賬單金額為 200

問題:

  • 這個(gè)方法 只能劫持已sh()、pop() 這樣的操作不會(huì)觸發(fā) set。
  • 必須對(duì)每個(gè)屬性單獨(dú)定義 get/set,如
  • 有的屬性,如果 bill 里沒有 amountdefineProperty 無法監(jiān)聽到新增的 amount 屬性。
  • 無法監(jiān)聽數(shù)組變化,比如 pu
  • 果對(duì)象有很多屬性,就要定義很多次,性能較低。

二、數(shù)據(jù)代理(Data Proxy)

1. 生活中的例子

假設(shè)你家有一個(gè) 智能管家(類似于小愛同學(xué)、Siri),你可以問他:

  • "今天天氣怎么樣?" 他會(huì)去查天氣然后告訴你(相當(dāng)于攔截 讀取 操作)。
  • "幫我把燈光調(diào)亮一些" 他會(huì)控制家里的燈光調(diào)亮(相當(dāng)于攔截 修改 操作)。

智能管家就是 Proxy,它可以代理整個(gè)房子里所有的設(shè)備,而不需要逐個(gè)綁定(不像 Object.defineProperty() 必須單獨(dú)劫持每個(gè)設(shè)備的控制)。

2. 代碼示例

Proxy 實(shí)現(xiàn)智能管家的功能:

let house = { temperature: 22, light: 'off' }; // 房子里的設(shè)備

let smartHouse = new Proxy(house, {
  get(target, key) {
    console.log(`查詢 ${key} 的狀態(tài):${target[key]}`);
    return target[key];
  },
  set(target, key, value) {
    console.log(`修改 ${key} 的狀態(tài)為 ${value}`);
    target[key] = value;
    return true;
  }
});

console.log(smartHouse.temperature);  // 觸發(fā) get,查詢溫度
smartHouse.light = 'on';              // 觸發(fā) set,修改燈光狀態(tài)

運(yùn)行結(jié)果:

查詢 temperature 的狀態(tài):22
修改 light 的狀態(tài)為 on

Proxy 的優(yōu)勢(shì):

  • 可以代理整個(gè)對(duì)象,不用為每個(gè)屬性單獨(dú)定義 get/set。
  • 支持監(jiān)聽新增屬性,比如 house.newDevice = 'TV' 也能被攔截!
  • 支持?jǐn)?shù)組,例如監(jiān)聽 push()pop() 這些操作。

三、對(duì)比總結(jié)

對(duì)比項(xiàng)數(shù)據(jù)劫持(Object.defineProperty)數(shù)據(jù)代理(Proxy)
Vue 版本Vue 2.xVue 3.x
監(jiān)聽對(duì)象只能監(jiān)聽已有的屬性可以監(jiān)聽整個(gè)對(duì)象
監(jiān)聽新增/刪除屬性不能監(jiān)聽(需 Vue.set)可直接監(jiān)聽
監(jiān)聽數(shù)組需要重寫數(shù)組方法原生支持
深層嵌套需要遞歸遍歷訪問時(shí)自動(dòng)代理
兼容性ES5 及以上僅支持 ES6 及以上

四、再舉一個(gè)更貼近開發(fā)的例子

使用 Object.defineProperty() 監(jiān)聽對(duì)象

let person = { name: 'Alice', age: 25 };

function makeReactive(obj) {
  for (let key in obj) {
    let value = obj[key];
    Object.defineProperty(obj, key, {
      get() {
        console.log(`讀取 ${key}: ${value}`);
        return value;
      },
      set(newVal) {
        console.log(`修改 ${key} 為 ${newVal}`);
        value = newVal;
      }
    });
  }
}

makeReactive(person);

console.log(person.name);  // 讀取 name
person.age = 30;           // 修改 age

問題:

  • 不能監(jiān)聽 person.newProp = 'test' 這樣的新增屬性。
  • 不能監(jiān)聽 delete person.age 這樣的刪除操作。

使用 Proxy 監(jiān)聽整個(gè)對(duì)象

let person = { name: 'Alice', age: 25 };

let reactivePerson = new Proxy(person, {
  get(target, key) {
    console.log(`讀取 ${key}: ${target[key]}`);
    return target[key];
  },
  set(target, key, value) {
    console.log(`修改 ${key} 為 ${value}`);
    target[key] = value;
    return true;
  },
  deleteProperty(target, key) {
    console.log(`刪除屬性 ${key}`);
    return delete target[key];
  }
});

console.log(reactivePerson.name);  // 讀取 name
reactivePerson.age = 30;           // 修改 age
reactivePerson.newProp = 'test';   // 監(jiān)聽新增屬性
delete reactivePerson.age;         // 監(jiān)聽刪除屬性

優(yōu)勢(shì):

  • Proxy 可以監(jiān)聽對(duì)象的新增/刪除屬性,而 Object.defineProperty() 不行!
  • Proxy 可以監(jiān)聽數(shù)組的變化,而 Object.defineProperty() 不能監(jiān)聽 push()、splice()。
  • Proxy 可以代理整個(gè)對(duì)象,而 Object.defineProperty() 需要遍歷所有屬性,性能較差。

五、總結(jié)

概念方式適用場(chǎng)景優(yōu)勢(shì)
數(shù)據(jù)劫持Object.defineProperty()Vue 2.x兼容性好,支持老瀏覽器,但不能監(jiān)聽新增/刪除屬性
數(shù)據(jù)代理ProxyVue 3.x功能更強(qiáng),可監(jiān)聽新增/刪除,支持?jǐn)?shù)組操作

結(jié)論:

  • 如果是 Vue 2,只能用 Object.defineProperty() 來實(shí)現(xiàn)數(shù)據(jù)劫持。
  • 如果是 Vue 3,推薦用 Proxy,因?yàn)樗鼜?qiáng)大,能處理所有數(shù)據(jù)變化。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 5分鐘快速搭建vue3+ts+vite+pinia項(xiàng)目

    5分鐘快速搭建vue3+ts+vite+pinia項(xiàng)目

    本文主要介紹了5分鐘快速搭建vue3+ts+vite+pinia項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • JS獲取鼠標(biāo)選中的文字

    JS獲取鼠標(biāo)選中的文字

    下面是小編給大家分享的js獲取鼠標(biāo)選中的文字和js獲取鼠標(biāo)選中的值關(guān)鍵代碼,大家如果有需要可以參考下
    2016-08-08
  • 判斷iframe是否加載完成的完美方法

    判斷iframe是否加載完成的完美方法

    一般來說,我們判斷 iframe 是否加載完成其實(shí)與 判斷JavaScript 文件是否加載完成 采用的方法很類似
    2010-01-01
  • Popup對(duì)象實(shí)現(xiàn)右鍵菜單

    Popup對(duì)象實(shí)現(xiàn)右鍵菜單

    Popup對(duì)象實(shí)現(xiàn)右鍵菜單...
    2006-09-09
  • JavaScript異步編程中async函數(shù)詳解

    JavaScript異步編程中async函數(shù)詳解

    async函數(shù)是使用async關(guān)鍵字聲明的函數(shù)。 async函數(shù)是AsyncFunction構(gòu)造函數(shù)的實(shí)例, 并且其中允許使用await關(guān)鍵字。async和await關(guān)鍵字讓我們可以用一種更簡潔的方式寫出基于Promise的異步行為,而無需刻意地鏈?zhǔn)秸{(diào)用promise
    2022-11-11
  • JavaScript?中require?和?import區(qū)別及用法示例對(duì)比

    JavaScript?中require?和?import區(qū)別及用法示例對(duì)比

    在JavaScript中,require和import都是用來導(dǎo)入模塊的語法,但它們屬于不同的模塊系統(tǒng):CommonJS和ECMAScript Modules(ESM),這篇文章主要介紹了JavaScript中require和import區(qū)別及用法示例對(duì)比,需要的朋友可以參考下
    2025-09-09
  • 前端不使用i18n該如何優(yōu)雅的實(shí)現(xiàn)多語言

    前端不使用i18n該如何優(yōu)雅的實(shí)現(xiàn)多語言

    多語言的重要性相信不需要多言,下面這篇文章主要給大家介紹了關(guān)于前端不使用i18n該如何優(yōu)雅的實(shí)現(xiàn)多語言,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • JavaScript仿支付寶密碼輸入框

    JavaScript仿支付寶密碼輸入框

    那么今天我就用JavaScript代碼來實(shí)現(xiàn)這個(gè)效果吧,那么首先介紹一下整個(gè)的思路,首先我們先將確定輸入密碼的位數(shù),我的需求是5位,那么就用一個(gè)div標(biāo)簽包住5個(gè)input標(biāo)簽
    2015-12-12
  • JS如何讓你的移動(dòng)端交互體驗(yàn)更加優(yōu)秀

    JS如何讓你的移動(dòng)端交互體驗(yàn)更加優(yōu)秀

    現(xiàn)在在手機(jī)等移動(dòng)端設(shè)備訪問的人越來越多,我們前端開發(fā)者一直致力于將設(shè)計(jì)稿還原成頁面,供用戶訪問。但除高度還原設(shè)計(jì)稿外,交互上的良好體驗(yàn)也是我們應(yīng)該做到的。
    2021-05-05

最新評(píng)論

天等县| 泉州市| 茌平县| 汝阳县| 闽侯县| 宿松县| 新巴尔虎左旗| 巫山县| 淮南市| 萨嘎县| 祁东县| 黄陵县| 修水县| 边坝县| 绍兴市| 潜江市| 华池县| 阿拉善右旗| 娄底市| 三台县| 潮安县| 镇平县| 潼南县| 石棉县| 湘潭市| 鞍山市| 高阳县| 贺兰县| 松桃| 正安县| 广昌县| 沛县| 宁波市| 汽车| 惠东县| 南漳县| 松江区| 习水县| 桦甸市| 凤凰县| 怀柔区|