writing code that writes code
EVAL
In my opinion, it is Douglas Crockford who is evil
Proxy
The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc)
{ k: "v" }
get
set
myObject.k
Objects have a low-level api
get: retrieve a value associated with a key
set: set a value associated to a key
Enumerate Keys: object.keys, for .. in ..
delete: removes a key and value
{ k: "v" }
get
set
myObject.k
list of hooks into an object through a proxy
[Audience Participation]
getPrototypeOf //Object.getPrototypeOf
setPrototypeOf //Object.setPrototypeOf
isExtensible //Object.isExtensible
defineProperty //Object.defineProperty
has //foo in object
get //object.foo, object[foo]
set //object.foo = bar, object[foo] = bar
deleteProperty //delete object.foo, delete object[foo]
enumerate //for keys in object
ownKeys //Object.keys
apply //Function.prototype.apply
construct //new object(..args)
Reflect
Similar to a Proxy but through a built-in object
Reflect
Also, other reflective stuff from around the language is packaged up in one place
Reflect is effectively a collection of all of those “internal methods” that were available exclusively through the JavaScript engine internals, now exposed in one single, handy object.
Reflect
var ages = [11, 33, 12, 54, 18, 96];
// Function.prototype style:
var youngest = Math.min.apply(Math, ages);
var oldest = Math.max.apply(Math, ages);
var type = Object.prototype.toString.call(youngest);
// Reflect style:
var youngest = Reflect.apply(Math.min, Math, ages);
var oldest = Reflect.apply(Math.max, Math, ages);
var type = Reflect.apply(Object.prototype.toString, youngest);
const myObject = {
foo: 'bar'
}
const myHandler = {
get: (target, property) => 'hello world... of proxies!'
}
const myObjectProxy = new Proxy(myObject, myHandler)
myObjectProxy.anyThingYouWant //'hello world... of proxies!'
new Proxy(target, handler)
const myObject = {
anEmptyVessel: 'Jar'
}
const myHandler = {
get: (target, property) => `${target[property]} ${target[property]}`
}
const myObjectProxy = new Proxy(myObject, myHandler)
myObjectProxy.anEmptyVessel //'Jar Jar'
new Proxy(target, handler)
myObject = {}
Reflect.set(myObject, 'foo', 'bar') //true
myObject.foo //bar
Reflect.has({x: 0}, 'x'); // true
Reflect.has({x: 0}, 'y'); // false
var target = TouchHandler(['longPress', 'swipe', 'force')
var handler = {
set: function (target, property, value) {
if(property === 'force'){
throw new Error("That's not how the force works!");
}
return target[property] = value
}
};
var proxy = new Proxy(target, handler);
function Tree() {
return new Proxy({}, handler);
}
var handler = {
get: function (target, key, receiver) {
if (!(key in target)) {
target[key] = Tree(); // auto-create a sub-Tree
}
return Reflect.get(target, key, receiver);
}
};
const fear = Tree()
fear.anger.hate = "suffering"
//{ anger: { hate: "suffering" } }