中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中Proxy是什么

發布時間:2020-12-07 11:24:50 來源:億速云 閱讀:208 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關JavaScript中Proxy是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Proxy 讓我們可以對任何對象的絕大部分行為進行監聽和干涉,實現更多的自定義程序行為。

用法:new Proxy(target, handler)。

Proxy 通過設置行為監聽方法來捕獲程序對對應對象的行為。

    const obj = {};
    const proxy = new Proxy(obj, {
        // ...
    })

Proxy 的構造器接受兩個參數,第一個參數為需要進行包裝的目標對象,第二個參數則為用于監聽目標對象行為的監聽器,其中監聽器可以接受一些參數以監聽相對應的程序行為。
監聽屬性、參數及監聽內容

屬性值監聽器參數監聽內容
has(target, prop)監聽 in 語句的使用
get(target, prop, reciver)監聽目標對象的屬性讀取
set(target, prop, value, reciver)監聽目標對象的屬性賦值
deleteProperty(target, prop)監聽 delete 語句對目標對象的刪除屬性行為
ownKeys(target)監聽 Object.getOwnPropertyName() 的讀取
apply(target, thisArg, arguments)監聽目標函數(作為目標對象)的調用行為
construct(target, arguments, newTarget)監聽目標構造函數(作為目標對象)利用 new 而生成實例的行為
getPrototypeOf(target)監聽 Objext.getPrototypeOf() 的讀取
setPrototypeOf(target, prototype)監聽 Objext.setPrototypeOf() 的調用
isExtensible(target)監聽 Objext.isExtensible() 的讀取
preventExtensions(target)監聽 Objext.preventExtensions() 的讀取
getOwnPropertyDescriptor(target, prop)監聽 Objext.getOwnPropertyDescriptor() 的調用
defineProperty(target, property, descriptor)監聽 Object.defineProperty() 的調用

has

可以通過為 Proxy 的 handler 定義 has 監聽方法,來監聽程序通過 in 語句來檢查一個字符串或數字是否為該 Proxy 的目標對象中某個屬性的屬性鍵的過程。

const p = new Proxy({}, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return true;
    }
})

console.log('foo' in p);
// Checking "foo" is in the target or not
// true

該監聽方法有兩個需要注意的地方,如果遇到這兩種情況,便會拋出 TypeError 錯誤。

1、當目標對象被其他程序通過 Object.preventExtensions() 禁用了屬性拓展 (該對象無法再增加新的屬性,只能對當前已有的屬性進行操作,包括讀取、操作和刪除,但是一旦刪除就無法再定義) 功能,且被檢查的屬性鍵確實存在與目標對象中,該監聽方法便不能返回 false。

const obj = {foo: 1};

Object.preventExtensions(obj);

const p = new Proxy(obj, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return false; 
    }
})

console.log('foo' in p);   
//拋出Uncaught TypeError:

2.當被檢查的屬性鍵存在與目標對象中,且該屬性的 configurable 配置是 false 時,該監聽方法不能返回 false。

const obj = {};

Object.defineProperty(obj, 'foo', {
    configurable: false,
    value: 10
})

const p = new Proxy(obj, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return false;
    }
})

console.log('foo' in p);
//拋出Uncaught TypeError:

get

Getter只能對已知的屬性鍵進行監聽,而無法對所有屬性讀取行為進行攔截,而 Proxy 可以通過設定 get 監聽方法,攔截和干涉目標對象的所有屬性讀取行為。

const obj = {foo: 1};
const p = new Proxy(obj, {
    get(target, prop){
        console.log(`Program is trying to fetch the property "${prop}".`);
        return target[prop];
    }
})

alert(p.foo);  // Program is trying to fetch the property "foo".
alert(p.something);    // Program is trying to fetch the property "something".

??這個監聽方法也存在需要注意的地方——當目標對象被讀取屬性的 configurable 和 writable 屬性都為 false 時,監聽方法最后返回的值必須與目標對象的原屬性值一致。

const obj = {};

Object.defineProperty(obj, 'foo', {
    configurable: false,
    value: 10,
    writable: false
})

const p = new Proxy(obj, {
    get(target, prop){
        return 20;
    }
})

console.log(p.foo);

set

??handler.set 用于監聽目標對象的所有屬性賦值行為。注意,如果目標對象自身的某個屬性是不可寫也不可配置的,那么 set 不得改變這個屬性的值,只能返回同樣的值,否則報錯。

const obj = {};
const p = new Proxy(obj, {
    set(target, prop, value){
        console.log(`Setting value "${value}" on the key "${prop}" in the target object`);
        target[prop] = value;
        return true;
    }
})

p.foo = 1;  
// Setting value "1" on the key "foo" in the target object

apply

handler.apply , Proxy 也為作為目標對象的函數提供了監聽其調用行為的屬性。

const sum = function(...args) {
  return args
    .map(Number)
    .filter(Boolean)
    .reduce((a, b) => a + b);

}

const p = new Proxy(sum, {
  apply(target, thisArg, args) {
    console.log(`Function is being called with arguments [${args.join()}] and context ${thisArg}`);
    return target.call(thisArg, ...args);
  }
})

console.log(p(1, 2, 3));
// Function is being called with arguments [1,2,3] and context undefined
// 6

construct

??handler.construct, Proxy 也可以將類作為目標監聽對象,并監聽其通過 new 語句來生產新實例的行為,這同樣可以使用再作為構造器的構造函數上。

class Foo{};

const p = new Proxy(Foo, {
    construct(target, args, newTarget){
        return {arguments: args}    // 這里返回的結果會是 new 所得到的實例
    }
});

const obj = new p(1, 2, 3);
console.log(obj.arguments);  // [1, 2, 3]

創建可解除 Proxy 對象

用法:Proxy.revocable(target, handler) : (proxy, revoke)。

const obj = {foo: 10};
const revocable = Proxy.revocable(obj, {
    get(target, prop){
        return 20;
    }
})
const proxy = revocable.proxy;
console.log(proxy.foo); // 20
revocable.revoke();
console.log(proxy.foo); 
// TypeError: Cannot perform 'get' on a proxy that has been revoked

Proxy.revocable(target, handler) 會返回一個帶有兩個屬性的對象,其中一個 proxy 便是該函數所生成的可解除 Proxy 對象,而另一個 revoke 則是將剛才的 Proxy 對象解除的解除方法。

關于JavaScript中Proxy是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汉源县| 通化县| 高邑县| 璧山县| 年辖:市辖区| 鱼台县| 巩义市| 桃园市| 河源市| 板桥市| 胶南市| 江安县| 太原市| 辉南县| 东方市| 辽源市| 鸡西市| 瑞昌市| 广德县| 邹城市| 沙洋县| 洛隆县| 达州市| 枣阳市| 望奎县| 吉木萨尔县| 罗山县| 平乐县| 定陶县| 高州市| 靖西县| 香河县| 泾阳县| 栾川县| 双柏县| 罗田县| 赤水市| 阳春市| 彩票| 泌阳县| 蒲城县|