[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy [Back]  [Original]

Proxy - JavaScript | MDN

MDN Web Docs

View in English Always switch to English

Proxy

20169

Proxy

Proxy Object

Proxy

  • target
  • handler

target

js
const target = {
  message1: "",
  message2: "",
};

const handler1 = {};

const proxy1 = new Proxy(target, handler1);

handler

js
console.log(proxy1.message1); // 
console.log(proxy1.message2); // 

handler

js
const target = {
  message1: "",
  message2: "",
};

const handler2 = {
  get(target, prop, receiver) {
    return "";
  },
};

const proxy2 = new Proxy(target, handler2);

get()

handler2

js
console.log(proxy2.message1); // 
console.log(proxy2.message2); // 

Reflect Proxy Reflect Reflect.get

js
const target = {
  message1: "",
  message2: "",
};

const handler3 = {
  get(target, prop, receiver) {
    if (prop === "message2") {
      return "";
    }
    return Reflect.get(...arguments);
  },
};

const proxy3 = new Proxy(target, handler3);

console.log(proxy3.message1); // 
console.log(proxy3.message2); // 

Reflect Reflect

handler

Proxy

trap

target

TypeError

obj.x

  • x
  • x value
  • x

[[Get]] obj.x [[Get]]

length length [[DefineOwnProperty]] length length Proxy

[[GetPrototypeOf]] getPrototypeOf()
[[SetPrototypeOf]] setPrototypeOf()
[[IsExtensible]] isExtensible()
[[PreventExtensions]] preventExtensions()
[[GetOwnProperty]] getOwnPropertyDescriptor()
[[DefineOwnProperty]] defineProperty()
[[HasProperty]] has()
[[Get]] get()
[[Set]] set()
[[Delete]] deleteProperty()
[[OwnPropertyKeys]] ownKeys()

[[Call]] apply()
[[Construct]] construct()

delete obj.x "x" in obj false [[Delete]] [[HasProperty]] delete obj.x

JavaScript Reflect / push() get() set()

[[Set]] [[DefineOwnProperty]] setter[[Set]] [[DefineOwnProperty]] obj.x = 1 [[Set]] Object.defineProperty() [[DefineOwnProperty]] [[DefineOwnProperty]] setter

Proxy()

Proxy

Proxy.prototype Proxy

Proxy.revocable()

Proxy

37 get()

js
const handler = {
  get(obj, prop) {
    return prop in obj ? obj[prop] : 37;
  },
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined

console.log("c" in p, p.c); // false, 37

JavaScript

js
let target = {};
let p = new Proxy(target, {});

p.a = 37; // 

console.log(target.a); // 37. 

JavaScript DOM Map

js
class Secret {
  #secret;
  constructor(secret) {
    this.#secret = secret;
  }
  get secret() {
    return this.#secret.replace(/\d+/, "[]");
  }
}

const secret = new Secret("123456");
console.log(secret.secret); // []
// ...
const proxy = new Proxy(secret, {});
console.log(proxy.secret); // TypeError: Cannot read private member #secret from an object whose class did not declare it

get this proxy secret #secret secret this

js
const proxy = new Proxy(secret, {
  get(target, prop, receiver) {
    //  Reflect.get(target, prop, receiver)
    //  `this` 
    return target[prop];
  },
});
console.log(proxy.secret);

this

js
class Secret {
  #x = 1;
  x() {
    return this.#x;
  }
}

const secret = new Secret();
const proxy = new Proxy(secret, {
  get(target, prop, receiver) {
    const value = target[prop];
    if (value instanceof Function) {
      return function (...args) {
        return value.apply(this === receiver ? target : this, args);
      };
    }
    return value;
  },
});
console.log(proxy.x());

JavaScript JavaScript Map [[MapData]]

js
const proxy = new Proxy(new Map(), {});
console.log(proxy.size); // TypeError: get size method called on incompatible Proxy

this

Proxy set()

js
const validator = {
  set(obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("");
      }
      if (value > 200) {
        throw new RangeError("");
      }
    }

    // 
    obj[prop] = value;

    // 
    return true;
  },
};

const person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = "young"; // 
person.age = 300; // 

DOM

Proxy

view selected set()

HTML view.selected 'aria-selected' true view.selected 'aria-selected' true 'aria-selected' false

js
const view = new Proxy(
  {
    selected: null,
  },
  {
    set: function (obj, prop, newval) {
      let oldval = obj[prop];

      if (prop === "selected") {
        if (oldval) {
          oldval.setAttribute("aria-selected", "false");
        }
        if (newval) {
          newval.setAttribute("aria-selected", "true");
        }
      }

      // 
      obj[prop] = newval;

      // 
      return true;
    },
  },
);

const item1 = document.getElementById("item-1");
const item2 = document.getElementById("item-2");

//  item1:
view.selected = item1;

console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: true

//  item2  item1:
view.selected = item2;

console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: false

console.log(`item2: ${item2.getAttribute("aria-selected")}`);
// item2: true

products latestBrowser getter setter

js
const products = new Proxy(
  {
    browsers: ["Firefox", "Chrome"],
  },
  {
    get: function (obj, prop) {
      // 
      if (prop === "latestBrowser") {
        return obj.browsers[obj.browsers.length - 1];
      }

      // 
      return obj[prop];
    },
    set: function (obj, prop, value) {
      // 
      if (prop === "latestBrowser") {
        obj.browsers.push(value);
        return;
      }

      // 
      if (typeof value === "string") {
        value = [value];
      }

      // 
      obj[prop] = value;

      // 
      return true;
    },
  },
);

console.log(products.browsers);
//  ['Firefox', 'Chrome']

products.browsers = "Safari";
// 

console.log(products.browsers);
// ['Safari'] <- 

products.latestBrowser = "Edge";

console.log(products.browsers);
//  ['Safari', 'Edge']

console.log(products.latestBrowser);
//  'Edge'

ECMAScript 2027 LanguageSpecification
# sec-proxy-objects

  • Proxy Brendan Eich JSConf 2014

Web Proxy Viewer  |  New URL  |  Original Page