ES6: プロキシの概念と使用法

プロキシは、その名前が示すように、オブジェクトとその属性値の間にプロキシを設定し、オブジェクトの値を取得または設定し、インスタンス化やその他の多くの操作をインターセプトします。この後、次の処理を行うことができます。 1 つのレイヤーを統合して「エージェント」と考えることができます。

問題の紹介:

//问题: 能够在obj.data修改成222之前拦截到这个操作
/*
  本质上, 我们想要在修改属性值的同时, 去修改DOM值, 即做到同步更新页面
*/
let obj = {
  data: "111"
}
obj.data = "222"

ES6 以前の方法で解決する場合は、Object.defineProperty(object, property, {}) を使用します。

let obj = {}
Object.defineProperty(obj, "data", {
  get() {
    console.log("get"); // 属性被访问时调用
  },
  set() {
    console.log("set"); // 属性被修改时调用
  }
})
console.log(obj.data); // get undefined <-此时调用get
obj.data = "test" // set <-此时调用set

実用的なアプリケーション: オブジェクトのプロパティを更新し、ページを同時に更新する

let obj = {}
Object.defineProperty(obj, "data", {
  get() {
    console.log("get");
    return box.innerHTML
  },
  set(value) {
    console.log("set");
    box.innerHTML = value
  }
})
console.log(obj.data); 
obj.data = "test"

注: vue3 以降、Object.defineProperty は Proxy に置き換えられます。

Object.defineProperty の欠点を要約すると、次のようになります。

1 - 一度にインターセプトできる属性は 1 つだけです

2- オブジェクトのみを傍受できます


プロキシのメソッドは次のとおりです。

get メソッド: プロパティにアクセスするとトリガーされます

let target = {}
let proxy = new Proxy(target,{
    get(target,prop){
        return target[prop]
    }
})

set メソッド: プロパティが変更されたときにトリガーされます

let target = {}
let proxy = new Proxy(target,{
    get(target,prop){
        return target[prop]
    },
    set(target,prop,value){
        if(prop==="data"){
            box.innerHTML = value
        }
        target[prop] = value;
    }
})

has メソッド: 特定の属性があるかどうかを判断します (プロキシの下で使用し、”属性” in proxy判定に渡す必要があります**)**

let target = {
    _prop: "内部数据"
}
let proxy = new Proxy(target, {
    get(target, prop) {
        return target[prop]
    },
    set(target, prop, value) {
        if (prop === "data") {
            box.innerHTML = value
        }
        target[prop] = value;
    },
    has(target, key) {
        if (key[0] === '_') {
            return false;
        }
        return key in target;
    }
})

注:”属性” in proxyメソッドを使用して、オブジェクトに属性があるかどうかを判断できます。

 

この質問

プロキシの get と set の this はプロキシを指しているため、オブジェクト メソッドの場合は this を変更する必要があります。

let s = new Set()

let proxy = new Proxy(s, {
  get(target, key) {
    // 如果是方法, 需要修正this指向
    let value = target[key]
    if(value instanceof Function) {
      return value.bind(target)
    }
    return value
  },
  set() {
    console.log("set");
  }
})
//proxy.add(1) // Uncaught TypeError: Method Set.prototype.add called on incompatible receiver #<Set>
//修改后:
console.log(proxy.add(1)); // Set(1) {1}

プロキシは本質的にメタプログラミングの非破壊的なデータハイジャックであり、元のオブジェクトに影響を与えることなく、元のオブジェクトに基づいて関数を派生するものであり、疎結合と高凝集性の設計概念に準拠しています。

参照:  015-ES6-Proxy_哔哩哔哩_bilibili 

おすすめ

転載: blog.csdn.net/CaptainDrake/article/details/131649120