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

Proxy - JavaScript | MDN

MDN Web Docs

View in English Always switch to English

Proxy

Baseline

20169

Proxy

Proxy Object

Proxy 2

  • target:
  • handler:

target

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

const handler1 = {};

const proxy1 = new Proxy(target, handler1);

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

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

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

const proxy2 = new Proxy(target, handler2);

get()

handler2

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

Reflect Proxy Reflect Reflect.get

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

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

const proxy3 = new Proxy(target, handler3);

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

Reflect Reflect Reflect

Proxy 2

TypeError

obj.x

  • x
  • x value
  • x

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

length length [[DefineOwnProperty]] length length

[[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]] 2 [[Set]] [[DefineOwnProperty]] obj.x = 1 [[Set]] Object.defineProperty() [[DefineOwnProperty]] [[DefineOwnProperty]]

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
const target = {};
const 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+/, "[REDACTED]");
  }
}

const secret = new Secret("123456");
console.log(secret.secret); // [REDACTED]
// 
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 secret proxy #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-recovering"

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

2 Proxy 2

selected view set()

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

js
const view = new Proxy(
  {
    selected: null,
  },
  {
    set(obj, prop, newVal) {
      const 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");

// select item1:
view.selected = item1;

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

// selecting item2 de-selects item1:
view.selected = item2;

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

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

products latestBrowser

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

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

      // 
      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


Web Proxy Viewer  |  New URL  |  Original Page