SlideShare ist ein Scribd-Unternehmen logo
1 von 55
Downloaden Sie, um offline zu lesen
ES6 metaprogramming unleashed
Javascript metaprogramming?
Metaprogramming is powerful and fun, but remember:
"With great power comes great responsibility"
about me
Javier Arias, senior software engineer at Telefonica.
Technology and software development lover.
@javier_arilos
http://about.me/javier.arilos
the challenge
www.pollingdeck.com
metaprogramming
“The key property of metaprograms is that
manipulate other programs or program
representations.” - Gregor Kiczales
Meta level vs Base level
metaprogramming in real life
Compiler/transpilers: gcc, coffeescript…
Macro languages (eg. C preprocessor)
Using "eval" to execute a string as code
Database scaffolding/ORM: mongoose, …
IDEs: Eclipse, …
reflective metaprogramming
A program that metaprograms itself -
This is the subject of the talk!
Reflective Metaprogramming in JS
MMM… very
interesting … is
there any JS?
do you use metaprogramming?
www.pollingdeck.com
JS metaprogramming up to ES5
object metaprogramming API
- Good
function metaprogramming
- Ugly
eval
- Bad
The Good: Object metapgrming API
● modify property access:
○ getters & setters
○ property descriptors
● Object mutability:
preventExtensions,
seal, freeze
Obj metaprogramming: Test Spy
Test Spy myFunction
[1] myFunction = spy (myFunction)
[5] assert eg. calledOnce
[2] myFunction(1, ‘a’)
Test spy is a function that records calls to a spied function
- SinonJS
[3] store call [4] call
Obj metaprogramming: Test Spy
function functionSpy(func){
Obj metaprogramming: Test Spy
function functionSpy(func){
Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true});
Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1});
Obj metaprogramming: Test Spy
function functionSpy(func){
Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true});
Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1});
var proxyFunc = function () { //intercept and count calls to func
proxyFunc._callCount += 1;
return func.apply(null, arguments);
};
return proxyFunc;
}
The Bad: eval
www.pollingdeck.com
The Bad: eval
avoid using eval in the browser for input from the user or your
remote servers (XSS and man-in-the-middle)
“is sometimes necessary, but in most cases it
indicates the presence of extremely bad coding.”
- Douglas Crockford
The Ugly: func metaprogramming
> Function constructor
> Function reflection
var remainder = new Function('a', 'b', 'return a % b;');
remainder(5, 2); // 1
function constructor
Create functions from Strings…
Similar to eval but differences in scope.
function reflection - length
Function.length: number of parameters of a
function.
Usage example: Express checking middlewares signature
function parameters: reflection
Get informaton about function parameters
Eg: Dependency Injection
function parameters reflection
How do we do that in JS?
Function.toString() + RegExp
This is ugly!
Function.prototype.toString
Defined in ES5 and ES2015 specs.
function getParameters(func) { //The regex is from Angular
var FN_PARAMS = /^functions*[^(]*(s*([^)]*))/m;
var params = func.toString().match(FN_PARAMS)[1].split(',');
return params;
}
function parameters reflection
ES6 - The Zen of JS?
www.pollingdeck.com
ES6 and Proxy
The Proxy can define custom behavior for
fundamental operations.
➔ property lookup
➔ assignment
➔ enumeration
➔ (...)
Proxy explained
handler:
interceptor. traps per operation.
proxy
&
handler
target
A Proxy wraps a target object.
target:
proxied object.
proxy sample: noSuchPropertyze
var myObj = {
a: 1,
b: 'nice'
};
myObj = noSuchPropertyze(myObj); // We want to INTERCEPT access to properties (get)
myObj.b; // nice
myObj.nonExistingProperty; // Error
function noSuchPropertyze(obj) {
var handler = {
get: function(target, name, receiver){
if(name in target) return target[name];
throw new Error('Not found:' + name);
}
};
return new Proxy(obj, handler);
}
var myObj = noSuchPropertyze({a: 1, b: 'nice'});
myObj.b; // nice
myObj.nonExistingProperty; // Error
proxy sample: noSuchPropertyze
proxy
&
handler
target
myObj[name]
function noSuchPropertyze(obj) {
var handler = {
get: function(target, name, receiver){
if(name in target) return target[name];
throw new Error('Not found:' + name);
}
};
return new Proxy(obj, handler);
}
var myObj = noSuchPropertyze({a: 1, b: 'nice'});
myObj.b; // nice
myObj.nonExistingProperty; // Error
proxy sample: noSuchPropertyze
proxy
&
handler
target
myObj[name]
function noSuchPropertyze(obj) {
var handler = {
get: function(target, name, receiver){
if(name in target) return target[name];
throw new Error('Not found:' + name);
}
};
return new Proxy(obj, handler);
}
var myObj = noSuchPropertyze({a: 1, b: 'nice'});
myObj.b; // nice
myObj.nonExistingProperty; // Error
proxy sample: noSuchPropertyze
proxy
&
handler
target
myObj[name]
Proxy usages
virtual objects: persistent or remote objects
do fancy things such as DSLs
DSL with Proxies
to(3).double.pow.get // 36
Overriding the dot (.) operator!!!
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
var to = (function closure() { // closure for containing our context
var functionsProvider = { //Object containing our functions
double: function (n) { return n*2 },
pow: function (n) { return n*n }
};
return function toImplementation(value) { // Magic happens here!
// (...) implementation
return new Proxy(functionsProvider, handler);
}
}());
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
var to = (function closure() { // closure for containing our context
var functionsProvider = { //Object containing our functions
double: function (n) { return n*2 },
pow: function (n) { return n*n }
};
return function toImplementation(value) { // Magic happens here!
// (...) implementation
return new Proxy(functionsProvider, handler);
}
}());
// ==== to(3).double.pow.get ===
var to = (function closure() { // closure for containing our context
var functionsProvider = { //Object containing our functions
double: function (n) { return n*2 },
pow: function (n) { return n*n }
};
return function toImplementation(value) { // Magic happens here!
// (...) implementation
return new Proxy(functionsProvider, handler);
}
}());
DSL with Proxies- implementation
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
return function toImplementation(value) {
var pipe = []; //stores functions to be called
var handler =
{ get(target, fnName, receiver) {
if (fnName in target){ //eg. .double : get the function and push it
pipe.push(target[fnName]);
return receiver;} //receiver is our Proxy object: to(3)
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
throw Error('Method: '+ fnName +' not yet supported');
}, set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
return function toImplementation(value) {
var pipe = []; //stores functions to be called
var handler =
{ get(target, fnName, receiver) {
if (fnName in target){ //eg. .double : get the function and push it
pipe.push(target[fnName]);
return receiver;} //receiver is our Proxy object: to(3)
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
throw Error('Method: '+ fnName +' not yet supported');
}, set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
return function toImplementation(value) {
var pipe = []; //stores functions to be called
var handler =
{ get(target, fnName, receiver) {
if (fnName in target){ //eg. .double : get the function and push it
pipe.push(target[fnName]);
return receiver;} //receiver is our Proxy object: to(3)
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
throw Error('Method: '+ fnName +' not yet supported');
}, set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
return function toImplementation(value) {
var pipe = []; //stores functions to be called
var handler =
{ get(target, fnName, receiver) {
if (fnName in target){ //eg. .double : get the function and push it
pipe.push(target[fnName]);
return receiver;} //receiver is our Proxy object: to(3)
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
throw Error('Method: '+ fnName +' not yet supported');
}, set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
DSL with Proxies- implementation
// ==== to(3).double.pow.get ===
return function toImplementation(value) {
var pipe = []; //stores functions to be called
var handler =
{ get(target, fnName, receiver) {
if (fnName in target){ //eg. .double : get the function and push it
pipe.push(target[fnName]);
return receiver;} //receiver is our Proxy object: to(3)
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
throw Error('Method: '+ fnName +' not yet supported');
}, set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
Composition with Object.assign
Composition: model/create Objects by
“what they do”
const barker = (state) => ({ //factory function barker
bark: () => console.log('woof, woof ' + state.name)
})
const angryHuman = (name) => { //factory function angryHuman
let state = {name}; //state object stays in the closure
return Object.assign( //assign to {} all own properties of barker(state)
{},
barker(state),
talker(state)
)
}
var angryJavi = angryHuman('javi')
angryJavi.bark() //woof, woof javi
Composition with Object.assign
const barker = (state) => ({ //factory function barker
bark: () => console.log('woof, woof ' + state.name)
})
const angryHuman = (name) => { //factory function angryHuman
let state = {name}; //state object stays in the closure
return Object.assign( //assign to {} all own properties of barker(state)
{},
barker(state),
talker(state)
)
}
var angryJavi = angryHuman('javi')
angryJavi.bark() //woof, woof javi
Composition with Object.assign
const barker = (state) => ({ //factory function barker
bark: () => console.log('woof, woof ' + state.name)
})
const angryHuman = (name) => { //factory function angryHuman
let state = {name}; //state object stays in the closure
return Object.assign( //assign to {} all own properties of barker(state)
{},
barker(state),
talker(state)
)
}
var angryJavi = angryHuman('javi')
angryJavi.bark() //woof, woof javi
Composition with Object.assign
That’s all folks!
No animals were harmed in the preparation of
this presentation.
references
● Alex Rauschmayer on Proxies: http://www.2ality.com/2014/12/es6-proxies.html
● About quines: http://c2.com/cgi/wiki?QuineProgram
● Kiczales on metaprogramming and AOP: http://www.drdobbs.com/its-not-metaprogramming/184415220
● Brendan Eich. Proxies are awesome: http://www.slideshare.net/BrendanEich/metaprog-5303821
● eval() isn’t evil, just misunderstood: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-
just-misunderstood/
● On DI: http://krasimirtsonev.com/blog/article/Dependency-injection-in-JavaScript
● Express middlewares: http://expressjs.com/guide/using-middleware.html
● Proxies by Daniel Zautner: http://www.dzautner.com/meta-programming-javascript-using-proxies/
Media
● Storm by Kelly Delay: https://flic.kr/p/seaiyf
● The complete explorer: https://www.flickr.com/photos/nlscotland/
● Record Player by Andressa Rodrigues: http://pixabay.com/en/users/AndressaRodrigues-40306/
● Wall by Nicole Köhler: http://pixabay.com/en/users/Nikiko-268709/
● Remote by Solart: https://pixabay.com/en/users/solart-621401/
● Rocket launch by Space-X: https://pixabay.com/en/users/SpaceX-Imagery-885857/
● Coffee by Skeeze: https://pixabay.com/en/users/skeeze-272447/
● Sleeping Monkey by Mhy: https://pixabay.com/en/users/Mhy-333962/
● Funny Monkey by WikiImages: https://pixabay.com/en/users/WikiImages-1897
● Lemur by ddouk: https://pixabay.com/en/users/ddouk-607002/
● Fire in the sky by NASA: https://flic.kr/p/pznCk1
●
complete code examples
function sayHi(name){ console.log('Hi '+name+'!') }// we define a very interesting function
sayHi = functionSpy(sayHi);// now we Spy on sayHi function.
console.log('calledOnce?', sayHi.once); // false. Note that ‘once’ looks like a property!!
sayHi('Gregor'); // calling our Function!!
console.log('calledOnce?', sayHi.once); // true
function functionSpy(func){
var proxyFunc = function () { //intercept and count calls to func
proxyFunc._callCount += 1;
return func.apply(null, arguments);
};
Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true});
Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1});
return proxyFunc;
}
Test Spy
function constructor vs eval
function functionCreate(aParam) { //Func consctructor cannot access to the closure
var funcAccessToClosure = Function('a', 'b', 'return a + b + aParam');
return funcAccessToClosure(1, 2);
}
functionCreate(3); //ReferenceError: aParam is not defined
function functionInEval(aParam) {//has access to the closure
eval("function funcAccessToClosure(a, b){return a + b + aParam}");
return funcAccessToClosure(1, 2);
}
functionInEval(3); // 6
var aParam = 62; //Now, define aParam.
functionCreate(3); // 65
functionInEval(3); // 6
DI container
● Function reflection (parameters) eg: Dependency Injection
var Injector = {dependencies: {},
add : function(qualifier, obj){
this.dependencies[qualifier] = obj;},
get : function(func){
var obj = Object.create(func.prototype);
func.apply(obj, this.resolveDependencies(func));
return obj;},
resolveDependencies : function(func) {
var args = this.getParameters(func);
var dependencies = [];
for ( var i = 0; i < args.length; i++) {
dependencies.push(this.dependencies[args[i]]);}
return dependencies;},
getParameters : function(func) {//This regex is from require.js
var FN_ARGS = /^functions*[^(]*(s*([^)]*))/m;
var args = func.toString().match(FN_ARGS)[1].split(',');
return args;}};
var aFancyLogger = {
log: function(log){console.log(Date().toString()+" => "+ log);}
};
var ItemController = function(logger){
this.logger = logger;
this.doSomething = function(item){this.logger.log("Item["+item.id+"] handled!");};
};
Injector.add("logger", aFancyLogger); //register logger into DI container
var itemController = Injector.get(ItemController); //get Item controller from DI
itemController.doSomething({id : 5});
proxy sample: DRY REST Client
// DRY REST client
function prepareGetter(resource) {
return function resourceGetter(id) {
console.log('HTTP GET /server/'+resource+( id ? '/'+id : ''));
return 200;
}
}
let proto = new Proxy({}, {
get(target, name, receiver) {
if(name.startsWith('get')) {
return prepareGetter(name.slice(3).toLowerCase());}
return target[name];
}
});
let myRestClient = Object.create(proto); //Prototype is a Proxy
myRestClient.allo = 7;
myRestClient.getClient('kent.beck'); //200 "HTTP GET /server/client/kent.beck"
myRestClient.allo; // 7;
DSL with Proxies
var to = (function closure() {
var functionsProvider = {
double: function (n) { return n*2 },
pow: function (n) { return n*n }
};
return function toImplementation(value) {
var pipe = [];
var handler =
{
get(target, fnName, receiver) {
if (fnName == "get")
return pipe.reduce(function (val, fn) { return fn(val) }, value);
if (fnName in target) {
pipe.push(target[fnName]);
return receiver;}
throw Error('Method: '+ fnName +' not yet supported');
},
set(target, fnName, fn, receiver) {
target[fnName] = fn;} //dynamic declaration of functions
};
return new Proxy(functionsProvider, handler);}}());
console.log('to(3).double.pow.get::',to(3).double.pow.get); // 36
console.log('to(2).triple::', to(2).triple.get); //Error: Method: triple not yet supported
to().triple = function(n) {return n*3};
console.log('to(2).triple::',to(2).triple.get);
Composition with Object.assign
const barker = (state) => ({ //factory function barker
bark: () => console.log('woof, woof ' + state.name)
})
const angryHuman = (name) => { //factory function angryHuman
let state = {name}; //state object stays in the closure
return Object.assign( //assign to {} all own properties of barker(state)
{},
barker(state)
)
}
var angryJavi = angryHuman('javi')
angryJavi.bark() //woof, woof javi
proposal
Description
ES6 delivers some exciting metaprogramming capabilities with its new Proxies feature.
Metaprogramming is powerful, but remember: "With great power comes great responsibility". In the
talk we will shortly revisit Javascript metaprogramming and explain ES6 Proxies with code
examples.
Session type: 40-minute session
Topics: none
Abstract
During the talk we will explain different metaprogramming concepts and techniques with code
samples related to a very simple testing library.
First, we will discuss about what metaprogramming is, what metaprogramming is useful for and a
very light overview of metaprogramming in other programming languages.
Current capacities from Javascript up to ES5 will be revisited with some code examples.
Finally, ES6 and proxies will be covered.

Weitere ähnliche Inhalte

Was ist angesagt?

DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8Dhaval Dalal
 
PHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & ClosuresPHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & Closuresmelechi
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)BoneyGawande
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript FunctionsColin DeCarlo
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharpDhaval Dalal
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Samuel Fortier-Galarneau
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!José Paumard
 
Python Programming Essentials - M25 - os and sys modules
Python Programming Essentials - M25 - os and sys modulesPython Programming Essentials - M25 - os and sys modules
Python Programming Essentials - M25 - os and sys modulesP3 InfoTech Solutions Pvt. Ltd.
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHPWim Godden
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generatorsdantleech
 
What's new in Scala 2.13?
What's new in Scala 2.13?What's new in Scala 2.13?
What's new in Scala 2.13?Hermann Hueck
 
Pl python python w postgre-sql
Pl python   python w postgre-sqlPl python   python w postgre-sql
Pl python python w postgre-sqlPiotr Pałkiewicz
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 

Was ist angesagt? (20)

DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
PHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & ClosuresPHP 5.3 Part 2 - Lambda Functions & Closures
PHP 5.3 Part 2 - Lambda Functions & Closures
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
C++11 Multithreading - Futures
C++11 Multithreading - FuturesC++11 Multithreading - Futures
C++11 Multithreading - Futures
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
 
Php string function
Php string function Php string function
Php string function
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Python Programming Essentials - M25 - os and sys modules
Python Programming Essentials - M25 - os and sys modulesPython Programming Essentials - M25 - os and sys modules
Python Programming Essentials - M25 - os and sys modules
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
Python decorators
Python decoratorsPython decorators
Python decorators
 
What's new in Scala 2.13?
What's new in Scala 2.13?What's new in Scala 2.13?
What's new in Scala 2.13?
 
Pl python python w postgre-sql
Pl python   python w postgre-sqlPl python   python w postgre-sql
Pl python python w postgre-sql
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 

Andere mochten auch

Студия ГрафПром
Студия ГрафПромСтудия ГрафПром
Студия ГрафПромAlina Vilk
 
History of fonts
History of fontsHistory of fonts
History of fontsJo Lowes
 
The State of the Web - Helsinki meetup
The State of the Web - Helsinki meetupThe State of the Web - Helsinki meetup
The State of the Web - Helsinki meetupChristian Heilmann
 
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitos
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitosManual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitos
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitosThiago Huari
 
Presença da vivo na internet social análise da operadora no Twitter
Presença da vivo na internet social análise da operadora no TwitterPresença da vivo na internet social análise da operadora no Twitter
Presença da vivo na internet social análise da operadora no TwitterRute Faria
 
Crescer - Construindo um Brasil de Oportunidades
Crescer - Construindo um Brasil de OportunidadesCrescer - Construindo um Brasil de Oportunidades
Crescer - Construindo um Brasil de OportunidadesMoreira Franco
 
“ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)
 “ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt) “ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)
“ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)Alina Vilk
 
Apple x fbi o que está acontecendo-
Apple x fbi   o que está acontecendo-Apple x fbi   o que está acontecendo-
Apple x fbi o que está acontecendo-Thiago Escobar
 

Andere mochten auch (13)

Студия ГрафПром
Студия ГрафПромСтудия ГрафПром
Студия ГрафПром
 
History of fonts
History of fontsHistory of fonts
History of fonts
 
The State of the Web - Helsinki meetup
The State of the Web - Helsinki meetupThe State of the Web - Helsinki meetup
The State of the Web - Helsinki meetup
 
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitos
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitosManual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitos
Manual de serviço ms nx 4 falcon - 00 x6b-mcg-002 defeitos
 
Social e Web Monitoring
Social e Web MonitoringSocial e Web Monitoring
Social e Web Monitoring
 
RESUME.1
RESUME.1RESUME.1
RESUME.1
 
Locandina1
Locandina1Locandina1
Locandina1
 
Presença da vivo na internet social análise da operadora no Twitter
Presença da vivo na internet social análise da operadora no TwitterPresença da vivo na internet social análise da operadora no Twitter
Presença da vivo na internet social análise da operadora no Twitter
 
Crescer - Construindo um Brasil de Oportunidades
Crescer - Construindo um Brasil de OportunidadesCrescer - Construindo um Brasil de Oportunidades
Crescer - Construindo um Brasil de Oportunidades
 
“ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)
 “ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt) “ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)
“ComputerVision(Ruby && OpenCV)”, Людмила Дежкина ( Senior Ruby, DataArt)
 
Apple x fbi o que está acontecendo-
Apple x fbi   o que está acontecendo-Apple x fbi   o que está acontecendo-
Apple x fbi o que está acontecendo-
 
Creando actividades en Ardora
Creando actividades en ArdoraCreando actividades en Ardora
Creando actividades en Ardora
 
Gestalt theory
Gestalt theoryGestalt theory
Gestalt theory
 

Ähnlich wie OSCON - ES6 metaprogramming unleashed

JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)Piyush Katariya
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascriptDoeun KOCH
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptDonald Sipe
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)Domenic Denicola
 
Intro to ES6 and why should you bother !
Intro to ES6 and why should you bother !Intro to ES6 and why should you bother !
Intro to ES6 and why should you bother !Gaurav Behere
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbJuan Maiz
 
Orlando BarCamp Why Javascript Doesn't Suck
Orlando BarCamp Why Javascript Doesn't SuckOrlando BarCamp Why Javascript Doesn't Suck
Orlando BarCamp Why Javascript Doesn't Suckerockendude
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express jsAhmed Assaf
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: FunctionsAdam Crabtree
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesSiarhei Barysiuk
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.jsdavidchubbs
 
Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run themFilipe Ximenes
 

Ähnlich wie OSCON - ES6 metaprogramming unleashed (20)

6976.ppt
6976.ppt6976.ppt
6976.ppt
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
 
Oojs 1.1
Oojs 1.1Oojs 1.1
Oojs 1.1
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Intro to ES6 and why should you bother !
Intro to ES6 and why should you bother !Intro to ES6 and why should you bother !
Intro to ES6 and why should you bother !
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRb
 
Orlando BarCamp Why Javascript Doesn't Suck
Orlando BarCamp Why Javascript Doesn't SuckOrlando BarCamp Why Javascript Doesn't Suck
Orlando BarCamp Why Javascript Doesn't Suck
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express js
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run them
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
 

Mehr von Javier Arias Losada

Why do lazy developers write beautiful code?
Why do lazy developers write beautiful code?Why do lazy developers write beautiful code?
Why do lazy developers write beautiful code?Javier Arias Losada
 
Europython - Machine Learning for dummies with Python
Europython - Machine Learning for dummies with PythonEuropython - Machine Learning for dummies with Python
Europython - Machine Learning for dummies with PythonJavier Arias Losada
 
Pybcn machine learning for dummies with python
Pybcn machine learning for dummies with pythonPybcn machine learning for dummies with python
Pybcn machine learning for dummies with pythonJavier Arias Losada
 
Elastically scalable architectures with microservices. The end of the monolith?
Elastically scalable architectures with microservices. The end of the monolith?Elastically scalable architectures with microservices. The end of the monolith?
Elastically scalable architectures with microservices. The end of the monolith?Javier Arias Losada
 
Full Stack Bus with Javascript, RabbitMQ and Postal.js
Full Stack Bus with Javascript, RabbitMQ and Postal.jsFull Stack Bus with Javascript, RabbitMQ and Postal.js
Full Stack Bus with Javascript, RabbitMQ and Postal.jsJavier Arias Losada
 
Rabbitmq, amqp Intro - Messaging Patterns
Rabbitmq, amqp Intro - Messaging PatternsRabbitmq, amqp Intro - Messaging Patterns
Rabbitmq, amqp Intro - Messaging PatternsJavier Arias Losada
 
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel Messaging
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel MessagingNoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel Messaging
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel MessagingJavier Arias Losada
 
From Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndromeFrom Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndromeJavier Arias Losada
 

Mehr von Javier Arias Losada (8)

Why do lazy developers write beautiful code?
Why do lazy developers write beautiful code?Why do lazy developers write beautiful code?
Why do lazy developers write beautiful code?
 
Europython - Machine Learning for dummies with Python
Europython - Machine Learning for dummies with PythonEuropython - Machine Learning for dummies with Python
Europython - Machine Learning for dummies with Python
 
Pybcn machine learning for dummies with python
Pybcn machine learning for dummies with pythonPybcn machine learning for dummies with python
Pybcn machine learning for dummies with python
 
Elastically scalable architectures with microservices. The end of the monolith?
Elastically scalable architectures with microservices. The end of the monolith?Elastically scalable architectures with microservices. The end of the monolith?
Elastically scalable architectures with microservices. The end of the monolith?
 
Full Stack Bus with Javascript, RabbitMQ and Postal.js
Full Stack Bus with Javascript, RabbitMQ and Postal.jsFull Stack Bus with Javascript, RabbitMQ and Postal.js
Full Stack Bus with Javascript, RabbitMQ and Postal.js
 
Rabbitmq, amqp Intro - Messaging Patterns
Rabbitmq, amqp Intro - Messaging PatternsRabbitmq, amqp Intro - Messaging Patterns
Rabbitmq, amqp Intro - Messaging Patterns
 
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel Messaging
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel MessagingNoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel Messaging
NoSQL Matters BCN 2013. Sprayer Low Latency, Reliable, Mutichannel Messaging
 
From Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndromeFrom Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndrome
 

Kürzlich hochgeladen

What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 

Kürzlich hochgeladen (20)

What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 

OSCON - ES6 metaprogramming unleashed

  • 2. Javascript metaprogramming? Metaprogramming is powerful and fun, but remember: "With great power comes great responsibility"
  • 3. about me Javier Arias, senior software engineer at Telefonica. Technology and software development lover. @javier_arilos http://about.me/javier.arilos
  • 5. metaprogramming “The key property of metaprograms is that manipulate other programs or program representations.” - Gregor Kiczales Meta level vs Base level
  • 6. metaprogramming in real life Compiler/transpilers: gcc, coffeescript… Macro languages (eg. C preprocessor) Using "eval" to execute a string as code Database scaffolding/ORM: mongoose, … IDEs: Eclipse, …
  • 7. reflective metaprogramming A program that metaprograms itself - This is the subject of the talk! Reflective Metaprogramming in JS MMM… very interesting … is there any JS?
  • 8. do you use metaprogramming? www.pollingdeck.com
  • 9. JS metaprogramming up to ES5 object metaprogramming API - Good function metaprogramming - Ugly eval - Bad
  • 10. The Good: Object metapgrming API ● modify property access: ○ getters & setters ○ property descriptors ● Object mutability: preventExtensions, seal, freeze
  • 11. Obj metaprogramming: Test Spy Test Spy myFunction [1] myFunction = spy (myFunction) [5] assert eg. calledOnce [2] myFunction(1, ‘a’) Test spy is a function that records calls to a spied function - SinonJS [3] store call [4] call
  • 12. Obj metaprogramming: Test Spy function functionSpy(func){
  • 13. Obj metaprogramming: Test Spy function functionSpy(func){ Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true}); Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1});
  • 14. Obj metaprogramming: Test Spy function functionSpy(func){ Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true}); Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1}); var proxyFunc = function () { //intercept and count calls to func proxyFunc._callCount += 1; return func.apply(null, arguments); }; return proxyFunc; }
  • 16. The Bad: eval avoid using eval in the browser for input from the user or your remote servers (XSS and man-in-the-middle) “is sometimes necessary, but in most cases it indicates the presence of extremely bad coding.” - Douglas Crockford
  • 17. The Ugly: func metaprogramming > Function constructor > Function reflection
  • 18. var remainder = new Function('a', 'b', 'return a % b;'); remainder(5, 2); // 1 function constructor Create functions from Strings… Similar to eval but differences in scope.
  • 19. function reflection - length Function.length: number of parameters of a function. Usage example: Express checking middlewares signature
  • 20. function parameters: reflection Get informaton about function parameters Eg: Dependency Injection
  • 21. function parameters reflection How do we do that in JS? Function.toString() + RegExp This is ugly!
  • 23. function getParameters(func) { //The regex is from Angular var FN_PARAMS = /^functions*[^(]*(s*([^)]*))/m; var params = func.toString().match(FN_PARAMS)[1].split(','); return params; } function parameters reflection
  • 24. ES6 - The Zen of JS? www.pollingdeck.com
  • 25. ES6 and Proxy The Proxy can define custom behavior for fundamental operations. ➔ property lookup ➔ assignment ➔ enumeration ➔ (...)
  • 26. Proxy explained handler: interceptor. traps per operation. proxy & handler target A Proxy wraps a target object. target: proxied object.
  • 27. proxy sample: noSuchPropertyze var myObj = { a: 1, b: 'nice' }; myObj = noSuchPropertyze(myObj); // We want to INTERCEPT access to properties (get) myObj.b; // nice myObj.nonExistingProperty; // Error
  • 28. function noSuchPropertyze(obj) { var handler = { get: function(target, name, receiver){ if(name in target) return target[name]; throw new Error('Not found:' + name); } }; return new Proxy(obj, handler); } var myObj = noSuchPropertyze({a: 1, b: 'nice'}); myObj.b; // nice myObj.nonExistingProperty; // Error proxy sample: noSuchPropertyze proxy & handler target myObj[name]
  • 29. function noSuchPropertyze(obj) { var handler = { get: function(target, name, receiver){ if(name in target) return target[name]; throw new Error('Not found:' + name); } }; return new Proxy(obj, handler); } var myObj = noSuchPropertyze({a: 1, b: 'nice'}); myObj.b; // nice myObj.nonExistingProperty; // Error proxy sample: noSuchPropertyze proxy & handler target myObj[name]
  • 30. function noSuchPropertyze(obj) { var handler = { get: function(target, name, receiver){ if(name in target) return target[name]; throw new Error('Not found:' + name); } }; return new Proxy(obj, handler); } var myObj = noSuchPropertyze({a: 1, b: 'nice'}); myObj.b; // nice myObj.nonExistingProperty; // Error proxy sample: noSuchPropertyze proxy & handler target myObj[name]
  • 31. Proxy usages virtual objects: persistent or remote objects do fancy things such as DSLs
  • 32. DSL with Proxies to(3).double.pow.get // 36 Overriding the dot (.) operator!!!
  • 33. DSL with Proxies- implementation // ==== to(3).double.pow.get === var to = (function closure() { // closure for containing our context var functionsProvider = { //Object containing our functions double: function (n) { return n*2 }, pow: function (n) { return n*n } }; return function toImplementation(value) { // Magic happens here! // (...) implementation return new Proxy(functionsProvider, handler); } }());
  • 34. DSL with Proxies- implementation // ==== to(3).double.pow.get === var to = (function closure() { // closure for containing our context var functionsProvider = { //Object containing our functions double: function (n) { return n*2 }, pow: function (n) { return n*n } }; return function toImplementation(value) { // Magic happens here! // (...) implementation return new Proxy(functionsProvider, handler); } }());
  • 35. // ==== to(3).double.pow.get === var to = (function closure() { // closure for containing our context var functionsProvider = { //Object containing our functions double: function (n) { return n*2 }, pow: function (n) { return n*n } }; return function toImplementation(value) { // Magic happens here! // (...) implementation return new Proxy(functionsProvider, handler); } }()); DSL with Proxies- implementation
  • 36. DSL with Proxies- implementation // ==== to(3).double.pow.get === return function toImplementation(value) { var pipe = []; //stores functions to be called var handler = { get(target, fnName, receiver) { if (fnName in target){ //eg. .double : get the function and push it pipe.push(target[fnName]); return receiver;} //receiver is our Proxy object: to(3) if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}());
  • 37. DSL with Proxies- implementation // ==== to(3).double.pow.get === return function toImplementation(value) { var pipe = []; //stores functions to be called var handler = { get(target, fnName, receiver) { if (fnName in target){ //eg. .double : get the function and push it pipe.push(target[fnName]); return receiver;} //receiver is our Proxy object: to(3) if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}());
  • 38. DSL with Proxies- implementation // ==== to(3).double.pow.get === return function toImplementation(value) { var pipe = []; //stores functions to be called var handler = { get(target, fnName, receiver) { if (fnName in target){ //eg. .double : get the function and push it pipe.push(target[fnName]); return receiver;} //receiver is our Proxy object: to(3) if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}());
  • 39. DSL with Proxies- implementation // ==== to(3).double.pow.get === return function toImplementation(value) { var pipe = []; //stores functions to be called var handler = { get(target, fnName, receiver) { if (fnName in target){ //eg. .double : get the function and push it pipe.push(target[fnName]); return receiver;} //receiver is our Proxy object: to(3) if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}());
  • 40. DSL with Proxies- implementation // ==== to(3).double.pow.get === return function toImplementation(value) { var pipe = []; //stores functions to be called var handler = { get(target, fnName, receiver) { if (fnName in target){ //eg. .double : get the function and push it pipe.push(target[fnName]); return receiver;} //receiver is our Proxy object: to(3) if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}());
  • 41. Composition with Object.assign Composition: model/create Objects by “what they do”
  • 42. const barker = (state) => ({ //factory function barker bark: () => console.log('woof, woof ' + state.name) }) const angryHuman = (name) => { //factory function angryHuman let state = {name}; //state object stays in the closure return Object.assign( //assign to {} all own properties of barker(state) {}, barker(state), talker(state) ) } var angryJavi = angryHuman('javi') angryJavi.bark() //woof, woof javi Composition with Object.assign
  • 43. const barker = (state) => ({ //factory function barker bark: () => console.log('woof, woof ' + state.name) }) const angryHuman = (name) => { //factory function angryHuman let state = {name}; //state object stays in the closure return Object.assign( //assign to {} all own properties of barker(state) {}, barker(state), talker(state) ) } var angryJavi = angryHuman('javi') angryJavi.bark() //woof, woof javi Composition with Object.assign
  • 44. const barker = (state) => ({ //factory function barker bark: () => console.log('woof, woof ' + state.name) }) const angryHuman = (name) => { //factory function angryHuman let state = {name}; //state object stays in the closure return Object.assign( //assign to {} all own properties of barker(state) {}, barker(state), talker(state) ) } var angryJavi = angryHuman('javi') angryJavi.bark() //woof, woof javi Composition with Object.assign
  • 45. That’s all folks! No animals were harmed in the preparation of this presentation.
  • 46. references ● Alex Rauschmayer on Proxies: http://www.2ality.com/2014/12/es6-proxies.html ● About quines: http://c2.com/cgi/wiki?QuineProgram ● Kiczales on metaprogramming and AOP: http://www.drdobbs.com/its-not-metaprogramming/184415220 ● Brendan Eich. Proxies are awesome: http://www.slideshare.net/BrendanEich/metaprog-5303821 ● eval() isn’t evil, just misunderstood: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil- just-misunderstood/ ● On DI: http://krasimirtsonev.com/blog/article/Dependency-injection-in-JavaScript ● Express middlewares: http://expressjs.com/guide/using-middleware.html ● Proxies by Daniel Zautner: http://www.dzautner.com/meta-programming-javascript-using-proxies/
  • 47. Media ● Storm by Kelly Delay: https://flic.kr/p/seaiyf ● The complete explorer: https://www.flickr.com/photos/nlscotland/ ● Record Player by Andressa Rodrigues: http://pixabay.com/en/users/AndressaRodrigues-40306/ ● Wall by Nicole Köhler: http://pixabay.com/en/users/Nikiko-268709/ ● Remote by Solart: https://pixabay.com/en/users/solart-621401/ ● Rocket launch by Space-X: https://pixabay.com/en/users/SpaceX-Imagery-885857/ ● Coffee by Skeeze: https://pixabay.com/en/users/skeeze-272447/ ● Sleeping Monkey by Mhy: https://pixabay.com/en/users/Mhy-333962/ ● Funny Monkey by WikiImages: https://pixabay.com/en/users/WikiImages-1897 ● Lemur by ddouk: https://pixabay.com/en/users/ddouk-607002/ ● Fire in the sky by NASA: https://flic.kr/p/pznCk1 ●
  • 49. function sayHi(name){ console.log('Hi '+name+'!') }// we define a very interesting function sayHi = functionSpy(sayHi);// now we Spy on sayHi function. console.log('calledOnce?', sayHi.once); // false. Note that ‘once’ looks like a property!! sayHi('Gregor'); // calling our Function!! console.log('calledOnce?', sayHi.once); // true function functionSpy(func){ var proxyFunc = function () { //intercept and count calls to func proxyFunc._callCount += 1; return func.apply(null, arguments); }; Object.defineProperty(proxyFunc, "_callCount", {value: 0, writable: true}); Object.defineProperty(proxyFunc, "once", {get: function(){return this._callCount==1}); return proxyFunc; } Test Spy
  • 50. function constructor vs eval function functionCreate(aParam) { //Func consctructor cannot access to the closure var funcAccessToClosure = Function('a', 'b', 'return a + b + aParam'); return funcAccessToClosure(1, 2); } functionCreate(3); //ReferenceError: aParam is not defined function functionInEval(aParam) {//has access to the closure eval("function funcAccessToClosure(a, b){return a + b + aParam}"); return funcAccessToClosure(1, 2); } functionInEval(3); // 6 var aParam = 62; //Now, define aParam. functionCreate(3); // 65 functionInEval(3); // 6
  • 51. DI container ● Function reflection (parameters) eg: Dependency Injection var Injector = {dependencies: {}, add : function(qualifier, obj){ this.dependencies[qualifier] = obj;}, get : function(func){ var obj = Object.create(func.prototype); func.apply(obj, this.resolveDependencies(func)); return obj;}, resolveDependencies : function(func) { var args = this.getParameters(func); var dependencies = []; for ( var i = 0; i < args.length; i++) { dependencies.push(this.dependencies[args[i]]);} return dependencies;}, getParameters : function(func) {//This regex is from require.js var FN_ARGS = /^functions*[^(]*(s*([^)]*))/m; var args = func.toString().match(FN_ARGS)[1].split(','); return args;}}; var aFancyLogger = { log: function(log){console.log(Date().toString()+" => "+ log);} }; var ItemController = function(logger){ this.logger = logger; this.doSomething = function(item){this.logger.log("Item["+item.id+"] handled!");}; }; Injector.add("logger", aFancyLogger); //register logger into DI container var itemController = Injector.get(ItemController); //get Item controller from DI itemController.doSomething({id : 5});
  • 52. proxy sample: DRY REST Client // DRY REST client function prepareGetter(resource) { return function resourceGetter(id) { console.log('HTTP GET /server/'+resource+( id ? '/'+id : '')); return 200; } } let proto = new Proxy({}, { get(target, name, receiver) { if(name.startsWith('get')) { return prepareGetter(name.slice(3).toLowerCase());} return target[name]; } }); let myRestClient = Object.create(proto); //Prototype is a Proxy myRestClient.allo = 7; myRestClient.getClient('kent.beck'); //200 "HTTP GET /server/client/kent.beck" myRestClient.allo; // 7;
  • 53. DSL with Proxies var to = (function closure() { var functionsProvider = { double: function (n) { return n*2 }, pow: function (n) { return n*n } }; return function toImplementation(value) { var pipe = []; var handler = { get(target, fnName, receiver) { if (fnName == "get") return pipe.reduce(function (val, fn) { return fn(val) }, value); if (fnName in target) { pipe.push(target[fnName]); return receiver;} throw Error('Method: '+ fnName +' not yet supported'); }, set(target, fnName, fn, receiver) { target[fnName] = fn;} //dynamic declaration of functions }; return new Proxy(functionsProvider, handler);}}()); console.log('to(3).double.pow.get::',to(3).double.pow.get); // 36 console.log('to(2).triple::', to(2).triple.get); //Error: Method: triple not yet supported to().triple = function(n) {return n*3}; console.log('to(2).triple::',to(2).triple.get);
  • 54. Composition with Object.assign const barker = (state) => ({ //factory function barker bark: () => console.log('woof, woof ' + state.name) }) const angryHuman = (name) => { //factory function angryHuman let state = {name}; //state object stays in the closure return Object.assign( //assign to {} all own properties of barker(state) {}, barker(state) ) } var angryJavi = angryHuman('javi') angryJavi.bark() //woof, woof javi
  • 55. proposal Description ES6 delivers some exciting metaprogramming capabilities with its new Proxies feature. Metaprogramming is powerful, but remember: "With great power comes great responsibility". In the talk we will shortly revisit Javascript metaprogramming and explain ES6 Proxies with code examples. Session type: 40-minute session Topics: none Abstract During the talk we will explain different metaprogramming concepts and techniques with code samples related to a very simple testing library. First, we will discuss about what metaprogramming is, what metaprogramming is useful for and a very light overview of metaprogramming in other programming languages. Current capacities from Javascript up to ES5 will be revisited with some code examples. Finally, ES6 and proxies will be covered.