SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
ES6 metaprogramming unleashed
are we ready?
Metaprogramming is powerful and
fun, but remember:
"With great power comes
great responsibility"
about me
Javier Arias Losada, senior software engineer at Telefonica.
Currently working at EyeOS, helping to create an VDI (Virtual
Desktop Infrastructure) platform.
@javier_arilos
http://about.me/javier.arilos
metaprogramming
“The key property of metaprograms is that
manipulate other programs or program
representations.”
- Gregor Kiczales
metaprogramming levels
Meta level:
program manipulating other program
Base level:
program manipulated
metaprogramming samples
Compiler/transpilers: gcc, coffeescript…
Macro languages (eg. C preprocessor)
Using "eval" to execute a string as code
Database scaffolding/ORM: mongoose, …
IDEs: Webstorm, …
reflective metaprogramming
A program that modifies itself -
Reflective Metaprogramming in JS-
This is the subject of the talk!
MMM… very
interesting … but
when are we
going to JS?
Introspection
Introspection: read the structure of a program.
Object.keys()
var obj = { //Base level
name: 'Santa',
hello: function() {
console.log('Hello', this.name,'!');
}
};
Object.keys(obj).forEach(function(prop) {
console.log(prop); //Meta level
});
Self-modification
Self-modification: change program structure.
function renameProperty(obj, oldName, newName) {
obj[newName] = obj[oldName];
delete obj[oldName];
}
renameProperty(obj, 'hello', 'greet');
Intercession
Intercession: redefine semantics of some language operations.
Object.defineProperty(obj, "roProp", {
value: 101,
writable: false,
enumerable: true});
obj.roProp = 102
obj.roProp //101
‘Cheating’ quine:
(function a(){console.log('('+a+')()')})()
‘Cheating’ quine:
(function a(){console.log('('+a+')()')})()
A real one:
_='"'+";document.write('_=',_[17],_[0],_[17],'+',_,_)";document.write('_=',_[17],_
[0],_[17],'+',_,_)
metaprogramming fun: Quines
Quine: a program that prints a copy of its own
source code (no input allowed)
Caffeine Facts:
A cup of coffee works just 10
minutes after you drink it.
It takes 45 minutes for 99% of
caffeine to be absorbed.
Please… awake people
around you!!
JS metaprogramming up to ES5
THE GOOD:
object metaprogramming API
THE UGLY:
function metaprogramming
THE BAD:
eval
The Good: Object metapgrming API
● modify property access:
○ getters & setters
○ property descriptors
● Object mutability:
preventExtensions,
seal, freeze
Sample: 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
// we define a very interesting function
function sayHi(name){ console.log('Hi '+name+'!') }
// now we Spy on sayHi function.
sayHi = functionSpy(sayHi);
console.log('calledOnce?', sayHi.once); // false. Note that ‘once’ looks like a property!!
sayHi('Gregor'); // calling our Function!!
console.log('calledOnce?', sayHi.once); // true
Sample: Test Spy
accessor properties sample - Spy
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;
}
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:
○ Function.prototype.length
○ Ugly hacks
var remainder = new Function('a', 'b', 'return a % b;');
remainder(5, 2); // 1
function constructor
Seems similar to eval but…
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
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
function reflection - length
Function.length returns the number of parameters
of a function.
Usage example: Express checking middlewares signature
function parameters reflection
We want to get informaton about function
parameters.
Parameters belong to function signature.
Arguments are passed to a function call.
function parameters reflection
Is it a bad joke?
Function.toString() + RegExp
to the rescue!
How do we do that in JS?
DI container implementation
Defined in ES5 and ES2015 specs.
getParameters : function(func) { //The regex is from Angular
var FN_PARAMS = /^functions*[^(]*(s*([^)]*))/m;
var funcParams = func.toString().match(FN_PARAMS)[1].split(',');
return funcParams;
}
fucntion parameters reflection
Some libraries with Dependency Injection, such
as Angular.js use this technique:
Eyes still opened?
Coffee must be working!
ES6 and Proxy
The Proxy can define custom behavior for
fundamental operations.
property lookup, assignment, enumeration, function invocation
Proxy concepts
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]
Proxy usages
Why do we need proxies?
virtual objects: persistent or remote objects
emulate the dreaded "host objects"
do fancy things such as DSLs
proxy sample: DRY REST Client
// REST client
let myRestClient = {
getClient: function(id) {
console.log('HTTP GET /server/client/'( id ? '/'+id : ''));
return 200;
},
getBill: function(id) {
console.log('HTTP GET /server/bill/'( id ? '/'+id : ''));
return 200;
},
// (...) DO YOU SEE THE PATTERN?
}
myRestClient.allo = 7;
myRestClient.getClient('kent.beck'); //200 "HTTP GET
/server/client/kent.beck"
myRestClient.allo; // 7;
proxy sample: 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
to(3).double.pow.get // 36
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 ===
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 - new methods
to(2).triple.get; //Error: Method: triple not yet supported
to().triple = function(n) {return n*3}; //Add new method: triple
to(2).triple.get; // 6
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/
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
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});
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);

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Automatic Reference Counting @ Pragma Night
Automatic Reference Counting @ Pragma NightAutomatic Reference Counting @ Pragma Night
Automatic Reference Counting @ Pragma Night
 
Elegant Solutions For Everyday Python Problems - PyCon Canada 2017
Elegant Solutions For Everyday Python Problems - PyCon Canada 2017Elegant Solutions For Everyday Python Problems - PyCon Canada 2017
Elegant Solutions For Everyday Python Problems - PyCon Canada 2017
 
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina ZakharenkoElegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
 
Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
Doing It Wrong with Puppet -
Doing It Wrong with Puppet - Doing It Wrong with Puppet -
Doing It Wrong with Puppet -
 
Advance JS and oop
Advance JS and oopAdvance JS and oop
Advance JS and oop
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
Foomo / Zugspitze Presentation
Foomo / Zugspitze PresentationFoomo / Zugspitze Presentation
Foomo / Zugspitze Presentation
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
Know yourengines velocity2011
Know yourengines velocity2011Know yourengines velocity2011
Know yourengines velocity2011
 
WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA Austria
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#
 
JavaFXScript
JavaFXScriptJavaFXScript
JavaFXScript
 

Andere mochten auch

Introduction of Machine Learning
Introduction of Machine LearningIntroduction of Machine Learning
Introduction of Machine Learning
Mohammad Hossain
 

Andere mochten auch (20)

7 lessons to learn of Brazil defeat, to your company
7 lessons to learn of Brazil defeat, to your company 7 lessons to learn of Brazil defeat, to your company
7 lessons to learn of Brazil defeat, to your company
 
Data Science For Dummies From a Dummy
Data Science For Dummies From a DummyData Science For Dummies From a Dummy
Data Science For Dummies From a Dummy
 
Data science for advanced dummies
Data science for advanced dummiesData science for advanced dummies
Data science for advanced dummies
 
Quero trabalhar com big data data science, como faço-
Quero trabalhar com big data   data science, como faço-Quero trabalhar com big data   data science, como faço-
Quero trabalhar com big data data science, como faço-
 
Data Science & Big Data, made in Switzerland
Data Science & Big Data, made in SwitzerlandData Science & Big Data, made in Switzerland
Data Science & Big Data, made in Switzerland
 
Introduction to Machine Learning
Introduction to Machine LearningIntroduction to Machine Learning
Introduction to Machine Learning
 
7 historical software bugs
 7 historical software bugs 7 historical software bugs
7 historical software bugs
 
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
 
Introduction of Machine Learning
Introduction of Machine LearningIntroduction of Machine Learning
Introduction of Machine Learning
 
TDC2016SP - Trilha Data Science
TDC2016SP - Trilha Data ScienceTDC2016SP - Trilha Data Science
TDC2016SP - Trilha Data Science
 
Introduction to Machine learning
Introduction to Machine learningIntroduction to Machine learning
Introduction to Machine learning
 
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?
 
[Eestec] Machine Learning online seminar 1, 12 2016
[Eestec] Machine Learning online seminar 1, 12 2016[Eestec] Machine Learning online seminar 1, 12 2016
[Eestec] Machine Learning online seminar 1, 12 2016
 
Introduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventureIntroduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventure
 
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
 
Brief introduction to Machine Learning
Brief introduction to Machine LearningBrief introduction to Machine Learning
Brief introduction to Machine Learning
 
Pivotal Digital Transformation Forum: Data Science
Pivotal Digital Transformation Forum: Data Science Pivotal Digital Transformation Forum: Data Science
Pivotal Digital Transformation Forum: Data Science
 
Machine learning for dummies - Azuges November 2016
Machine learning for dummies - Azuges November 2016Machine learning for dummies - Azuges November 2016
Machine learning for dummies - Azuges November 2016
 
Machine learning for dummies
Machine learning for dummiesMachine learning for dummies
Machine learning for dummies
 
Getting Started with Amazon Machine Learning
Getting Started with Amazon Machine LearningGetting Started with Amazon Machine Learning
Getting Started with Amazon Machine Learning
 

Ähnlich wie ES6 metaprogramming unleashed

JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
Piyush Katariya
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
Alessio Ricco
 
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
Whymca
 
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
Ben Lin
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
Fabrizio Giudici
 

Ähnlich wie ES6 metaprogramming unleashed (20)

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
 
6976.ppt
6976.ppt6976.ppt
6976.ppt
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
 
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
 
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
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
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
 
JavaScript for real men
JavaScript for real menJavaScript for real men
JavaScript for real men
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
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
 
Java script for web developer
Java script for web developerJava script for web developer
Java script for web developer
 
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...
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 

Kürzlich hochgeladen

Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 

Kürzlich hochgeladen (20)

%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 

ES6 metaprogramming unleashed

  • 2. are we ready? Metaprogramming is powerful and fun, but remember: "With great power comes great responsibility"
  • 3. about me Javier Arias Losada, senior software engineer at Telefonica. Currently working at EyeOS, helping to create an VDI (Virtual Desktop Infrastructure) platform. @javier_arilos http://about.me/javier.arilos
  • 4. metaprogramming “The key property of metaprograms is that manipulate other programs or program representations.” - Gregor Kiczales
  • 5. metaprogramming levels Meta level: program manipulating other program Base level: program manipulated
  • 6. metaprogramming samples Compiler/transpilers: gcc, coffeescript… Macro languages (eg. C preprocessor) Using "eval" to execute a string as code Database scaffolding/ORM: mongoose, … IDEs: Webstorm, …
  • 7. reflective metaprogramming A program that modifies itself - Reflective Metaprogramming in JS- This is the subject of the talk! MMM… very interesting … but when are we going to JS?
  • 8. Introspection Introspection: read the structure of a program. Object.keys() var obj = { //Base level name: 'Santa', hello: function() { console.log('Hello', this.name,'!'); } }; Object.keys(obj).forEach(function(prop) { console.log(prop); //Meta level });
  • 9. Self-modification Self-modification: change program structure. function renameProperty(obj, oldName, newName) { obj[newName] = obj[oldName]; delete obj[oldName]; } renameProperty(obj, 'hello', 'greet');
  • 10. Intercession Intercession: redefine semantics of some language operations. Object.defineProperty(obj, "roProp", { value: 101, writable: false, enumerable: true}); obj.roProp = 102 obj.roProp //101
  • 11. ‘Cheating’ quine: (function a(){console.log('('+a+')()')})() ‘Cheating’ quine: (function a(){console.log('('+a+')()')})() A real one: _='"'+";document.write('_=',_[17],_[0],_[17],'+',_,_)";document.write('_=',_[17],_ [0],_[17],'+',_,_) metaprogramming fun: Quines Quine: a program that prints a copy of its own source code (no input allowed)
  • 12. Caffeine Facts: A cup of coffee works just 10 minutes after you drink it. It takes 45 minutes for 99% of caffeine to be absorbed. Please… awake people around you!!
  • 13. JS metaprogramming up to ES5 THE GOOD: object metaprogramming API THE UGLY: function metaprogramming THE BAD: eval
  • 14. The Good: Object metapgrming API ● modify property access: ○ getters & setters ○ property descriptors ● Object mutability: preventExtensions, seal, freeze
  • 15. Sample: 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
  • 16. // we define a very interesting function function sayHi(name){ console.log('Hi '+name+'!') } // now we Spy on sayHi function. sayHi = functionSpy(sayHi); console.log('calledOnce?', sayHi.once); // false. Note that ‘once’ looks like a property!! sayHi('Gregor'); // calling our Function!! console.log('calledOnce?', sayHi.once); // true Sample: Test Spy
  • 17. accessor properties sample - Spy 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; }
  • 18. 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
  • 19. The Ugly: func metaprogramming ● Function constructor ● Function reflection: ○ Function.prototype.length ○ Ugly hacks
  • 20. var remainder = new Function('a', 'b', 'return a % b;'); remainder(5, 2); // 1 function constructor Seems similar to eval but…
  • 21. 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
  • 22. 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
  • 23. function reflection - length Function.length returns the number of parameters of a function. Usage example: Express checking middlewares signature
  • 24. function parameters reflection We want to get informaton about function parameters. Parameters belong to function signature. Arguments are passed to a function call.
  • 25. function parameters reflection Is it a bad joke? Function.toString() + RegExp to the rescue! How do we do that in JS?
  • 26. DI container implementation Defined in ES5 and ES2015 specs.
  • 27. getParameters : function(func) { //The regex is from Angular var FN_PARAMS = /^functions*[^(]*(s*([^)]*))/m; var funcParams = func.toString().match(FN_PARAMS)[1].split(','); return funcParams; } fucntion parameters reflection Some libraries with Dependency Injection, such as Angular.js use this technique:
  • 28. Eyes still opened? Coffee must be working!
  • 29. ES6 and Proxy The Proxy can define custom behavior for fundamental operations. property lookup, assignment, enumeration, function invocation
  • 30. Proxy concepts handler: interceptor. traps per operation. proxy & handler target A Proxy wraps a target object. target: proxied object.
  • 31. 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
  • 32. 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]
  • 33. Proxy usages Why do we need proxies? virtual objects: persistent or remote objects emulate the dreaded "host objects" do fancy things such as DSLs
  • 34. proxy sample: DRY REST Client // REST client let myRestClient = { getClient: function(id) { console.log('HTTP GET /server/client/'( id ? '/'+id : '')); return 200; }, getBill: function(id) { console.log('HTTP GET /server/bill/'( id ? '/'+id : '')); return 200; }, // (...) DO YOU SEE THE PATTERN? } myRestClient.allo = 7; myRestClient.getClient('kent.beck'); //200 "HTTP GET /server/client/kent.beck" myRestClient.allo; // 7;
  • 35. proxy sample: 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;
  • 37. 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); } }());
  • 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. DSL with Proxies - new methods to(2).triple.get; //Error: Method: triple not yet supported to().triple = function(n) {return n*3}; //Add new method: triple to(2).triple.get; // 6
  • 42. That’s all folks! No animals were harmed in the preparation of this presentation.
  • 43. 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/
  • 44. 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/
  • 46. 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
  • 47. 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});
  • 48. 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);

Hinweis der Redaktion

  1. Programs have a domain. Shipping system domain are customers, orders… Metaprograms domain is programs
  2. people need to extend javascript, not only with c++ with a lot of security issues, but with javascript itself in order to continue to extend the language and the libraries in a way that they look as built-in objects. ant that can virtualize/substitute builtin objects. that's very important when you implement libraries. we want to rebuild the world Smalltalk had, we want to get to the very low native code (C++) nirvana. the proxies here are brilliant, otherwise I do not know how we will get there.