function createProxy(proxyTarget) { var {proxy, revoke} = Proxy.revocable(proxyTarget, new Proxy({}, { get(target, propertyKey, receiver) { print("trap get:", propertyKey); revoke(); } })); return proxy; } var obj; // [[GetPrototypeOf]] assertEq(Object.getPrototypeOf(createProxy({})), Object.prototype); assertEq(Object.getPrototypeOf(createProxy([])), Array.prototype); // [[SetPrototypeOf]] obj = {}; Object.setPrototypeOf(createProxy(obj), Array.prototype); assertEq(Object.getPrototypeOf(obj), Array.prototype); // [[IsExtensible]] assertEq(Object.isExtensible(createProxy({})), true); assertEq(Object.isExtensible(createProxy(Object.preventExtensions({}))), false); // [[PreventExtensions]] obj = {}; Object.preventExtensions(createProxy(obj)); assertEq(Object.isExtensible(obj), false); // [[GetOwnProperty]] assertEq(Object.getOwnPropertyDescriptor(createProxy({}), "a"), undefined); assertEq(Object.getOwnPropertyDescriptor(createProxy({a: 5}), "a").value, 5); // [[DefineOwnProperty]] obj = {}; Object.defineProperty(createProxy(obj), "a", {value: 5}); assertEq(obj.a, 5); // [[HasProperty]] assertEq("a" in createProxy({}), false); assertEq("a" in createProxy({a: 5}), true); // [[Get]] assertEq(createProxy({}).a, undefined); assertEq(createProxy({a: 5}).a, 5); // [[Set]] assertThrowsInstanceOf(() => createProxy({}).a = 0, TypeError); assertThrowsInstanceOf(() => createProxy({a: 5}).a = 0, TypeError); // [[Delete]] assertEq(delete createProxy({}).a, true); assertEq(delete createProxy(Object.defineProperty({}, "a", {configurable: false})).a, false); // [[OwnPropertyKeys]] assertEq(Object.getOwnPropertyNames(createProxy({})).length, 0); assertEq(Object.getOwnPropertyNames(createProxy({a: 5})).length, 1); // [[Call]] assertEq(createProxy(function() { return "ok" })(), "ok"); // [[Construct]] // This throws because after the "construct" trap on the proxy is consulted, // OrdinaryCreateFromConstructor (called because the |q| function's // [[ConstructorKind]] is "base" per FunctionAllocate) accesses // |new.target.prototype| to create the |this| for the construct operation, that // would be returned if |return obj;| didn't override it. assertThrowsInstanceOf(() => new (createProxy(function q(){ return obj; })), TypeError); if (typeof reportCompare === "function") reportCompare(true, true);