My JSConf.eu talk about next-gen JavaScript metaprogramming features, starting with ES5's new Object APIs and then focusing on the forthcoming Proxy object, approved for the next ECMA-262 Edition. This is beautiful work from Tom Van Cutsem and Mark Miller, with Andreas Gal helping on the implementation front -- proxies are already shipping in Firefox 4 betas.
1 of 88
Downloaded 231 times
More Related Content
Proxies are Awesome!
1. Proxies
are Awesome!
Brendan Eich
(w/ Mark Miller & Tom Van Cutsem)
Tuesday, September 28, 2010
9. Dynamic Proxies
• Generic handling of property access:
• Generic wrappers: security, aspects, logging, profiling, ...
• Stratified form of SpiderMonkey’s __noSuchMethod__
js> o = {__noSuchMethod__: function (id, args) { print(id, args); }}
({__noSuchMethod__:(function (id, args) {print(id, args);})})
js> o.m(1,2,3)
m 1,2,3
• Generic handling of other operations applicable to objects:
• Virtual objects: persistent objects, remote objects, ...
• Emulate the dreaded “host objects”
Tuesday, September 28, 2010
10. Example w/ just ES5: logging
function makePoint(x, y) {
return {
x: x,
y: y,
...
};
}
Tuesday, September 28, 2010
11. Example w/ just ES5: logging
function makePoint(x, y) {
return {
x: x,
y: y,
...
};
}
function makeLoggedPoint(p) {
return {
get x() {
log(‘get’,‘x’,p); return p.x;
},
set x(v) {
log(‘set’,‘x’,p,v); p.x = v;
},
// get y, set y, ...
};
}
var lp = makeLoggedPoint(makePoint(1,2));
Tuesday, September 28, 2010
12. Example w/ just ES5: logging
function makePoint(x, y) {
return {
x: x,
y: y,
...
};
}
function makeLoggedPoint(p) {
return { Too ad hoc. What about:
get x() { • logging other data types
},
log(‘get’,‘x’,p); return p.x;
• profiling, persistence,
set x(v) { access control, ...
log(‘set’,‘x’,p,v); p.x = v;
},
// get y, set y, ...
};
}
var lp = makeLoggedPoint(makePoint(1,2));
Tuesday, September 28, 2010
17. Stratified API
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy
Tuesday, September 28, 2010
18. Stratified API
var proxy = Proxy.create(handler, proto);
handler.get(proxy, ‘foo’)
handler
meta
base
proxy.foo
proxy
Tuesday, September 28, 2010
19. Stratified API
var proxy = Proxy.create(handler, proto);
handler.get(proxy, ‘foo’)
handler
handler.set(proxy, ‘foo’, 42)
meta
base
proxy.foo
proxy.foo = 42
proxy
Tuesday, September 28, 2010
20. Stratified API
var proxy = Proxy.create(handler, proto);
handler.get(proxy, ‘foo’)
handler
handler.set(proxy, ‘foo’, 42)
handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])
meta
base
proxy.foo
proxy.foo = 42
proxy.foo(1,2,3) proxy
Tuesday, September 28, 2010
21. Stratified API
var proxy = Proxy.create(handler, proto);
handler.get(proxy, ‘foo’)
handler
handler.set(proxy, ‘foo’, 42)
handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])
handler.get(proxy, ‘get’) meta
base
proxy.foo
proxy.foo = 42
proxy.foo(1,2,3) proxy
proxy.get
Tuesday, September 28, 2010
22. Stratified API
var proxy = Proxy.create(handler, proto);
handler.get(proxy, ‘foo’)
handler
handler.set(proxy, ‘foo’, 42)
handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])
handler.get(proxy, ‘get’) meta
base
proxy.foo
proxy.foo = 42
proxy.foo(1,2,3) proxy proto
proxy.get
Tuesday, September 28, 2010
23. Not just property accesses
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy
Tuesday, September 28, 2010
24. Not just property accesses
var proxy = Proxy.create(handler, proto);
handler.has(‘foo’)
handler
meta
base
‘foo’ in proxy
proxy
Tuesday, September 28, 2010
25. Not just property accesses
var proxy = Proxy.create(handler, proto);
handler.has(‘foo’)
handler.delete(‘foo’)
handler
meta
base
‘foo’ in proxy
delete proxy.foo proxy
Tuesday, September 28, 2010
26. Not just property accesses
var proxy = Proxy.create(handler, proto);
handler.has(‘foo’)
handler.delete(‘foo’)
var props = handler.enumerate();
handler
for (var i=0;i<props.length;i++) {
var prop = props[i]; ...
}
meta
base
‘foo’ in proxy
delete proxy.foo proxy
for (var prop in proxy) { ... }
Tuesday, September 28, 2010
27. Not just property accesses
var proxy = Proxy.create(handler, proto);
handler.has(‘foo’)
handler.delete(‘foo’)
var props = handler.enumerate();
handler
for (var i=0;i<props.length;i++) {
var prop = props[i]; ...
}
handler.defineProperty(‘foo’, pd) meta
base
‘foo’ in proxy
delete proxy.foo proxy
for (var prop in proxy) { ... }
Object.defineProperty(proxy,‘foo’, pd)
Tuesday, September 28, 2010
28. But not quite everything, either
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy
Tuesday, September 28, 2010
29. But not quite everything, either
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy === obj
proxy
Tuesday, September 28, 2010
30. But not quite everything, either
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy === obj
Object.getPrototypeOf(proxy) => proto proxy proto
Tuesday, September 28, 2010
31. But not quite everything, either
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy === obj
Object.getPrototypeOf(proxy) => proto proxy proto
proxy instanceof SomeFunction
Tuesday, September 28, 2010
32. But not quite everything, either
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy === obj
Object.getPrototypeOf(proxy) => proto proxy proto
proxy instanceof SomeFunction
typeof proxy => “object”
Tuesday, September 28, 2010
33. Full Handler API
handler
proxy
Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name)
Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name)
Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd)
Object.getOwnPropertyNames(proxy) handler.getOwnPropertyNames()
delete proxy.name handler.delete(name)
for (name in proxy) { ... } handler.enumerate()
Object.{freeze|seal|...}(proxy) handler.fix()
name in proxy handler.has(name)
({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name)
receiver.name handler.get(receiver, name)
receiver.name = val handler.set(receiver, name, val)
Object.keys(proxy) handler.keys()
for (name in proxy) { ... } handler.iterate()
Tuesday, September 28, 2010
34. Fundamental vs Derived Traps
handler
proxy
Fundamental traps
Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name)
Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name)
Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd)
Object.getOwnPropertyNames(proxy) handler.getOwnPropertyNames()
delete proxy.name handler.delete(name)
for (name in proxy) { ... } handler.enumerate() -> [string]
Object.{freeze|seal|...}(proxy) handler.fix()
Derived traps
name in proxy handler.has(name)
({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name)
receiver.name handler.get(receiver, name)
receiver.name = val handler.set(receiver, name, val)
Object.keys(proxy) handler.keys()
for (name in proxy) { ... } handler.iterate() -> iterator
Tuesday, September 28, 2010
35. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
handler
call construct
funproxy
Tuesday, September 28, 2010
36. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
call(1,2,3) handler
call construct
funproxy(1,2,3)
funproxy
Tuesday, September 28, 2010
37. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
call(1,2,3) handler
call construct
construct(1,2,3)
funproxy(1,2,3)
new funproxy(1,2,3)
funproxy
Tuesday, September 28, 2010
38. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
call(1,2,3) handler
call construct
construct(1,2,3)
handler.get(funproxy,‘prototype’)
funproxy(1,2,3)
new funproxy(1,2,3)
funproxy.prototype funproxy
Tuesday, September 28, 2010
39. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
call(1,2,3) handler
call construct
construct(1,2,3)
handler.get(funproxy,‘prototype’)
funproxy(1,2,3)
new funproxy(1,2,3)
funproxy.prototype funproxy
typeof funproxy => “function”
Tuesday, September 28, 2010
40. Function Proxies
JavaScript functions are objects. Additionally,
they are also callable and constructible
var call = function() { ... };
var construct = function() { ... };
var funproxy = Proxy.createFunction(handler, call, construct);
call(1,2,3) handler
call construct
construct(1,2,3)
handler.get(funproxy,‘prototype’)
funproxy(1,2,3)
new funproxy(1,2,3)
funproxy.prototype funproxy
typeof funproxy => “function”
Object.getPrototypeOf(funproxy) => Function.prototype
Tuesday, September 28, 2010
41. Dilemma: Invoke vs Get+Call
• Fundamental vs derived traps = tradeoff in
performance (method allocation or caching)
vs. consistency
var p = Proxy.create({
get: function(receiver, name) { ... },
invoke: function(receiver, name, args) { ... },
...
});
p.x; // get(p,'x')
p.m(a); // invoke(p, 'm', [a])
• invoke can intercept arguments
• but notably, JS methods can be extracted as
functions and called later (functional FTW!)
• breaks invariant o.m.call(o) <=> o.m()
Tuesday, September 28, 2010
43. Selective Interception
VM territory (C++)
meta
base
object
JavaScript territory
Tuesday, September 28, 2010
44. Selective Interception
VM territory (C++)
VM handler
meta
base
object
JavaScript territory
Tuesday, September 28, 2010
45. Selective Interception
VM territory (C++)
VM handler VM handler
meta
base
host object object
JavaScript territory
Tuesday, September 28, 2010
46. Selective Interception
VM territory (C++)
VM handler VM handler handler
meta
base
host object object proxy
JavaScript territory
Tuesday, September 28, 2010
47. Selective Interception
VM territory (C++)
VM handler VM handler handler
meta
base
host object object proxy
JavaScript territory
Tuesday, September 28, 2010
48. Selective Interception
VM territory (C++) Self-hosted
VM handler VM handler handler
meta
base
host object object proxy
JavaScript territory
Tuesday, September 28, 2010
49. Selective Interception
VM territory (C++) Self-hosted
VM handler VM handler handler
meta
base
host object object proxy
JavaScript territory
Tuesday, September 28, 2010
50. Example: no-op forwarding proxy
handler
function ForwardingHandler(obj) {
this.target = obj; proxy target
}
ForwardingHandler.prototype = {
has: function(name) { return name in this.target; },
get: function(rcvr,name) { return this.target[name]; },
set: function(rcvr,name,val) { this.target[name]=val;return true; },
delete: function(name) { return delete this.target[name]; }
enumerate: function() {
var props = [];
for (name in this.target) { props.push(name); };
return props;
},
...
}
var proxy = Proxy.create(new ForwardingHandler(o),
Object.getPrototypeOf(o));
Tuesday, September 28, 2010
51. Example: counting property access
function makeSimpleProfiler(target) {
var forwarder = new ForwardingHandler(target);
var count = Object.create(null);
forwarder.get = function(rcvr, name) {
count[name] = (count[name] || 0) + 1;
return this.target[name];
};
return {
proxy: Proxy.create(forwarder,
Object.getPrototypeOf(target)),
get stats() { return count; }
}
}
Tuesday, September 28, 2010
52. Example: counting property access
function makeSimpleProfiler(target) {
var forwarder = new ForwardingHandler(target);
var count = Object.create(null);
forwarder.get = function(rcvr, name) {
count[name] = (count[name] || 0) + 1;
return this.target[name];
};
return {
proxy: Proxy.create(forwarder,
Object.getPrototypeOf(target)),
get stats() { return count; }
}
}
var subject = { ... };
var profiler = makeSimpleProfiler(subject);
runApp(profiler.proxy);
display(profiler.stats);
Tuesday, September 28, 2010
53. Fixing a Proxy
var proxy = Proxy.create(handler, proto);
handler
meta
base
proxy
Tuesday, September 28, 2010
54. Fixing a Proxy
var proxy = Proxy.create(handler, proto);
handler
meta
base
Object.freeze(proxy)
Object.seal(proxy)
proxy
Object.preventExtensions(proxy)
Tuesday, September 28, 2010
55. Fixing a Proxy
var proxy = Proxy.create(handler, proto);
var pdmap = handler.fix();
if (pdmap === undefined) throw TypeError(); handler
become(proxy,
Object.freeze(
Object.create(proto, pdmap)));
meta
base
Object.freeze(proxy)
Object.seal(proxy)
proxy
Object.preventExtensions(proxy)
Tuesday, September 28, 2010
56. Fixing a Proxy
var proxy = Proxy.create(handler, proto);
var pdmap = handler.fix();
if (pdmap === undefined) throw TypeError(); handler
become(proxy,
Object.freeze(
Object.create(proto, pdmap)));
meta
base
Object.freeze(proxy)
Object.seal(proxy)
proxy
Object.preventExtensions(proxy)
fix
Trapping Fixed
Tuesday, September 28, 2010
57. Fixing a Proxy
var proxy = Proxy.create(handler, proto);
var pdmap = handler.fix();
if (pdmap === undefined) throw TypeError();
become(proxy,
Object.freeze(
Object.create(proto, pdmap)));
meta
base
Object.freeze(proxy)
Object.seal(proxy)
proxy
Object.preventExtensions(proxy)
fix
Trapping Fixed
Tuesday, September 28, 2010
58. Meta-level Shifting
handler
proxy
Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name)
Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name)
Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd)
Object.getOwnPropertyNames(proxy) handler.getOwnPropertyNames()
delete proxy.name handler.delete(name)
for (name in proxy) { ... } handler.enumerate()
Object.{freeze|seal|...}(proxy) handler.fix()
name in proxy handler.has(name)
({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name)
receiver.name handler.get(receiver, name)
receiver.name = val handler.set(receiver, name, val)
Object.keys(proxy) handler.keys()
for (name in proxy) { ... } handler.iterate()
base-level: many operations meta-level: all operations reified as
on objects invocations of traps
Tuesday, September 28, 2010
59. Meta-level Shifting
a proxy whose μhandler
handler is a proxy
handler
handler.getOwnPropertyDescriptor(name) μhandler.get(handler, ‘getOwnP..’)(name)
handler.getPropertyDescriptor(name) μhandler.get(handler, ‘getProp..’)(name)
handler.defineOwnProperty(name, pd) μhandler.get(handler, ‘define...’)(name,pd)
handler.delete(name) μhandler.get(handler, ‘delete’)(name)
handler.getOwnPropertyNames() μhandler.get(handler, ‘getOwnP..’)()
handler.enumerate() μhandler.get(handler, ‘enumerate’)()
handler.fix() μhandler.get(handler, ‘fix’)()
handler.has(name) μhandler.get(handler, ‘has’)(name)
handler.hasOwn(name) μhandler.get(handler, ‘hasOwn’)(name)
handler.get(receiver, name) μhandler.get(handler, ‘get’)(receiver,name)
handler.set(receiver, name, val) μhandler.get(handler, ‘set’)(receiver,name,val)
handler.keys() μhandler.get(handler, ‘keys’)()
handler.iterate() μhandler.get(handler, ‘iterate’)()
meta-level: all operations reified as meta-meta-level: all operations
invocations of traps reified as invocations of ‘get’ trap
Tuesday, September 28, 2010
60. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
61. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
62. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
63. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
64. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
65. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
66. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
67. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
68. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
69. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
70. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
71. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
72. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
73. Example: Membranes
• Firefox security wrappers (anti-XSS, XUL, etc.)
• Google Caja: capability-secure subset
• Object-capability model: an object is powerless
unless given a reference to other objects
• References can be made revocable through a
membrane
Tuesday, September 28, 2010
74. Example: Membranes
function makeSimpleMembrane(initTarget) {
var enabled = true;
}
Tuesday, September 28, 2010
75. Example: Membranes
function makeSimpleMembrane(initTarget) {
var enabled = true;
return {
wrapper: wrap(initTarget),
revoke: function() { enabled = false; }
};
}
Tuesday, September 28, 2010
76. Example: Membranes
function makeSimpleMembrane(initTarget) {
var enabled = true;
function wrap(target) {
if (Object.isPrimitive(target)) { return target; }
var baseHandler = new ForwardingHandler(target);
var revokeHandler = Proxy.create({
get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
});
}
return {
wrapper: wrap(initTarget),
revoke: function() { enabled = false; }
};
}
Tuesday, September 28, 2010
77. Example: Membranes
function makeSimpleMembrane(initTarget) {
var enabled = true;
function wrap(target) {
if (Object.isPrimitive(target)) { return target; }
var baseHandler = new ForwardingHandler(target);
var revokeHandler = Proxy.create({
get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
});
if (typeof target === “function”) {
return Proxy.createFunction(revokeHandler, wrapFunction(target));
}
return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));
}
return {
wrapper: wrap(initTarget),
revoke: function() { enabled = false; }
};
}
Tuesday, September 28, 2010
78. Example: Membranes
function makeSimpleMembrane(initTarget) {
var enabled = true;
function wrapFunction(f) {
return function() { // variable-argument function
if (!enabled) { throw new Error("revoked"); }
return wrap(f.apply(wrap(this), arguments.map(wrap)));
}
}
function wrap(target) {
if (Object.isPrimitive(target)) { return target; }
var baseHandler = new ForwardingHandler(target);
var revokeHandler = Proxy.create({
get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
});
if (typeof target === “function”) {
return Proxy.createFunction(revokeHandler, wrapFunction(target));
}
return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));
}
return {
wrapper: wrap(initTarget),
revoke: function() { enabled = false; }
};
}
Tuesday, September 28, 2010
79. Prior Work
handler
meta
base
proxy
Tuesday, September 28, 2010
80. Prior Work
handler mirror ProxyHandler InvocationHandler
meta
base
proxy mirage proxy java.lang.reflect.Proxy
Tuesday, September 28, 2010
81. Prior Work
handler mirror ProxyHandler InvocationHandler
meta
base
proxy mirage proxy java.lang.reflect.Proxy
# traps 13 30 3 1
Tuesday, September 28, 2010
82. Making JavaScript Extensible
• Extending JavaScript today: “Host objects”
(the IE DOM; anything implemented in C++)
• Proxies are sufficiently powerful to emulate most
of the behavior of host objects in JavaScript itself
• Two possible avenues to close the gap:
• Make proxies even more powerful
• Make host objects only as powerful as proxies
Tuesday, September 28, 2010
83. Status
• Presented at ECMA TC-39 meetings
• Approved for inclusion in ES-Harmony
• http://wiki.ecmascript.org/doku.php?
id=harmony:proxies
• In Firefox 4 already, thanks to Andreas Gal!
• The basis of all of Gecko’s security wrappers
• Used by Zaphod (Narcissus as JS engine add-on,
source at http://github.com/taustin/Zaphod/)
Tuesday, September 28, 2010
84. Lessons for Web Standards
• Standards need savvy academic research
• Standards must evolve quickly on the Web
• They can’t evolve without prototype trials
• These experiments need tons of user-testing
• To reach users at scale, prototypes must ship
• Ecma TC39 committed to prototyping specs
before finalizing standards
• Committee members work together, no
blind-siding, to uphold Harmony (it’s social!)
Tuesday, September 28, 2010
87. Proxies: Summary
• Proxies enable:
• Generic wrappers: access control, profiling,
adaptors, test injection, etc.
• Virtual objects: persistent objects, remote objects,
emulated host objects, ...
• API:
• Robust: stratified, not all operations intercepted
• Secure: can’t trap non-proxy or fixed objects
• Performance: no overhead for non-proxy objects
Tuesday, September 28, 2010
88. Conclusions
• ES5 provides new meta-programming APIs
• ES-Harmony Proxies: robust dynamic meta-
programming for virtual objects, wrappers
• Proxies help put developers in control of
extending JavaScript, instead of Ecma TC39
• JavaScript: the Revenge of Smalltalk!
Tuesday, September 28, 2010