SlideShare une entreprise Scribd logo
1  sur  53
Télécharger pour lire hors ligne
Metaprogramming in
JavaScript
Web Directions Summit | November 17
Hello!
I am Mehdi Valikhani
Software Engineer at Autopilot
Metaprogramming?!
“Metaprogramming is a programming technique in
which computer programs have the ability to treat
programs as their data. It means that a program can
be designed to read, generate, analyse or transform
other programs or itself while running
source: Wikipedia
“Metaprogramming is a programming technique in
which computer programs have the ability to treat
programs as their data. It means that a program can
be designed to read, generate, analyse or transform
other programs or itself while running
source: Wikipedia
Reflection
“In computer science,reflection is the ability of a
computer program to examine,introspect, and modify
its own structure and behaviour at runtime. Reflection
is a valuable language feature and it facilitates
metaprogramming.
source: Wikipedia
Language features that enables
reflection
1.
Evaluate a string as if it
were a source code
statement at runtime.
2.
Convert a string matching
the symbolic name of a class
or function into a reference
to or invocation of that class
or function.
3.
Discover and modify source
code constructions (such as
code blocks, classes,
methods, protocols, etc.) as
first-class objects at
runtime.
source: Wikipedia
Reflective JavaScript
Metaprogramming
Reflective
JavaScript
Metaprogramming
Using ES5 features
Metaprogramming features of ES5
Code Evaluation
eval()
Examination
➔ instanceof
➔ typeof
➔ Object.getOwnPropertyNames()
Modification
Getter, setter
Reflective
JavaScript
Metaprogramming
Using ES6 features
Symbol ReflectProxy
Symbols
The new type in JavaScript
➔ The seventh type of values in JavaScript
Symbol
➔ The Symbol() function returns a value of type symbol
➔ Symbol() always returns unique values
➔ They may be used as an identifier for object properties
source: MDN
Example: Using Symbol as property identifier
const nameField = Symbol('beer name');
const beer = {
[nameField]: 'VB!'
};
console.log(beer[nameField]); // -> VB!
Example: Using Symbol as property identifier
const nameField = Symbol('beer name');
const beer = {
[nameField]: 'VB!'
};
console.log(beer[nameField]); // -> VB!
Example: Using Symbol as property identifier
const nameField = Symbol('beer name');
const beer = {
[nameField]: 'VB!'
};
console.log(beer[nameField]); // -> VB!
Example: Using Symbol as property identifier
const nameField = Symbol('beer name');
const beer = {
[nameField]: 'VB!'
};
console.log(beer[nameField]); // -> VB!
Well-known
Symbols
➔ A set of built-in JavaScript symbols
➔ Represent internal language behaviours
➔ They were not exposed to developers before
source: MDN
Symbols are used by ES6 to enable
“Reflection within implementation”.
Developers include them on their existing
classes and objects to change the default
behaviour of an operation or action.
source: keithcirkel.co.uk
What can be done using well-known symbols
➔ Control the behaviour of instanceof for an implemented class
➔ Manipulate the behaviour of for of when iterated over a class
➔ Control over Array.concat
➔ Custom matches for String.match(), String.replace(),
String.search() and String.split()
➔ Control the behaviour of Javascript when converting objects
to primitive types
Check MDN for a list of well-known symbols
Example: Using well-known Symbol.hasInstance to modify behaviour of “instanceof”
class MyArray {
}
const friends = ['foo', 'bar'];
console.log(friends instanceof MyArray); // -> false
class MyArray {
static [Symbol.hasInstance](object) {
return Array.isArray(object);
}
}
const friends = ['foo', 'bar'];
console.log(friends instanceof MyArray); // -> true
Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class
class ShoppingBasket {
constructor() {
this.items = [];
}
add(title, quantity, price) {
this.items.push({ title, quantity, price});
}
total() {
return this.items.reduce(function(accumulator, item) {
return accumulator + (item.price * item.quantity);
}, 0);
}
}
}
const basket = new ShoppingBasket();
basket.add('bread', 2, 2.5);
basket.add('milk', 1, 1.4);
Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class
class ShoppingBasket {
constructor() {
this.items = [];
}
add(title, quantity, price) {
this.items.push({ title, quantity, price});
}
total() {
return this.items.reduce(function(accumulator, item) {
return accumulator + (item.price * item.quantity);
}, 0);
}
[Symbol.toPrimitive](hint) {
if (hint === 'number') return this.total();
return this;
}
}
const basket = new ShoppingBasket();
basket.add('bread', 2, 2.5);
basket.add('milk', 1, 1.4);
console.log(+basket); // -> 6.4
console.log(new Number(basket)); // -> 6.4
Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class
class ShoppingBasket {
constructor() {
this.items = [];
}
add(title, quantity, price) {
this.items.push({ title, quantity, price});
}
total() {
return this.items.reduce(function(accumulator, item) {
return accumulator + (item.price * item.quantity);
}, 0);
}
[Symbol.toPrimitive](hint) {
if (hint === 'number') return this.total();
return this;
}
}
const basket = new ShoppingBasket();
basket.add('bread', 2, 2.5);
basket.add('milk', 1, 1.4);
console.log(+basket); // -> 6.4
console.log(new Number(basket)); // -> 6.4
Proxy
Proxy, as the name indicates, provides
“Reflection through interception”.
It wraps objects and intercepts their
behaviours through traps.
source: keithcirkel.co.uk
What can be done using Proxy
➔ A trap for delete operator
➔ Manipulate the behaviour of in operator
➔ Control over getting and setting property values
➔ A trap for function calls
➔ A trap for new operator
Check MDN for a list of Proxy features
Example: Implementation of a virtual field using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
get: function(object, fieldName) {
if (fieldName === 'fullName') {
return `${object.firstName} ${object.lastName}`;
}
return object[fieldName];
}
};
const proxiedStudent = new Proxy(student, studentProxy);
console.log(proxiedStudent.fullName); // -> Jackson Rowe
Example: Implementation of a virtual field using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
get: function(object, fieldName) {
if (fieldName === 'fullName') {
return `${object.firstName} ${object.lastName}`;
}
return object[fieldName];
}
};
const proxiedStudent = new Proxy(student, studentProxy);
console.log(proxiedStudent.fullName); // -> Jackson Rowe
Example: Implementation of a virtual field using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
get: function(object, fieldName) {
if (fieldName === 'fullName') {
return `${object.firstName} ${object.lastName}`;
}
return object[fieldName];
}
};
const proxiedStudent = new Proxy(student, studentProxy);
console.log(proxiedStudent.fullName); // -> Jackson Rowe
Example: Implementation of a virtual field using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
get: function(object, fieldName) {
if (fieldName === 'fullName') {
return `${object.firstName} ${object.lastName}`;
}
return object[fieldName];
}
};
const proxiedStudent = new Proxy(student, studentProxy);
console.log(proxiedStudent.fullName); // -> Jackson Rowe
Example: Value validation using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
set: function(object, fieldName, value) {
// validation logic for the “age” field
if (fieldName === 'age') {
if (typeof value !== 'number') {
throw TypeError('only numbers are accepted');
}
if (value <= 0) throw TypeError('that is impossible');
}
object[fieldName] = value;
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
proxiedStudent.age = 'a'; // errors
proxiedStudent.age = -1; // errors
proxiedStudent.age = 12; // does not error
Example: Value validation using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
set: function(object, fieldName, value) {
// validation logic for the “age” field
if (fieldName === 'age') {
if (typeof value !== 'number') {
throw TypeError('only numbers are accepted');
}
if (value <= 0) throw TypeError('that is impossible');
}
object[fieldName] = value;
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
proxiedStudent.age = 'a'; // errors
proxiedStudent.age = -1; // errors
proxiedStudent.age = 12; // does not error
Example: Value validation using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
set: function(object, fieldName, value) {
// validation logic for the “age” field
if (fieldName === 'age') {
if (typeof value !== 'number') {
throw TypeError('only numbers are accepted');
}
if (value <= 0) throw TypeError('that is impossible');
}
object[fieldName] = value;
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
proxiedStudent.age = 'a'; // errors
proxiedStudent.age = -1; // errors
proxiedStudent.age = 12; // does not error
Example: Value validation using Proxy
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
set: function(object, fieldName, value) {
// validation logic for the “age” field
if (fieldName === 'age') {
if (typeof value !== 'number') {
throw TypeError('only numbers are accepted');
}
if (value <= 0) throw TypeError('that is impossible');
}
object[fieldName] = value;
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
proxiedStudent.age = 'a'; // errors
proxiedStudent.age = -1; // errors
proxiedStudent.age = 12; // does not error
Example: Protect “id” field from deletion using a Proxy
const student = {
id: 'jackson-rowe',
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
deleteProperty: function(object, fieldName) {
if (fieldName === 'id') return false;
delete object[fieldName];
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
delete proxiedStudent.id // -> false
console.log(proxiedStudent.id); // jackson-rowe
Example: Protect “id” field from deletion using a Proxy
const student = {
id: 'jackson-rowe',
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
deleteProperty: function(object, fieldName) {
if (fieldName === 'id') return false;
delete object[fieldName];
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
delete proxiedStudent.id // -> false
console.log(proxiedStudent.id); // jackson-rowe
Example: Protect “id” field from deletion using a Proxy
const student = {
id: 'jackson-rowe',
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
deleteProperty: function(object, fieldName) {
if (fieldName === 'id') return false;
delete object[fieldName];
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
delete proxiedStudent.id // -> false
console.log(proxiedStudent.id); // jackson-rowe
Example: Protect “id” field from deletion using a Proxy
const student = {
id: 'jackson-rowe',
firstName: 'Jackson',
lastName: 'Rowe',
};
const studentProxy = {
deleteProperty: function(object, fieldName) {
if (fieldName === 'id') return false;
delete object[fieldName];
return true;
}
};
const proxiedStudent = new Proxy(student, studentProxy);
delete proxiedStudent.id // -> false
console.log(proxiedStudent.id); // jackson-rowe
Reflect
JavaScript’s new built-in object
Reflect is all about “Reflection through
introspection” - provides API to discover very
low level information about code.
source: keithcirkel.co.uk
What can be done using Reflect
➔ Call a function using Reflect.apply()
➔ Define a property using Reflect.defineProperty()
➔ Delete a property using Control over Reflect.deleteProperty()
➔ Get a property value using Reflect.get()
➔ Set property value using Reflect.set()
➔ Check if a property exist using Reflect.has()
Check MDN for a list of Reflect features
What Reflect object offers are either a
newer versions of existing methods or
entirely new methods - allowing new levels
of Reflection within JavaScript.
source: keithcirkel.co.uk
Example: Deleting a property using Reflect.deleteProperty()
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
console.log(student.firstName); // -> Jackson
Reflect.deleteProperty(student, 'firstName');
console.log(student.firstName); // -> undefined
Example: Deleting a property using Reflect.deleteProperty()
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
console.log(student.firstName); // -> Jackson
Reflect.deleteProperty(student, 'firstName');
console.log(student.firstName); // -> undefined
Example: Deleting a property using Reflect.deleteProperty()
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
console.log(student.firstName); // -> Jackson
Reflect.deleteProperty(student, 'firstName');
console.log(student.firstName); // -> undefined
Example: Deleting a property using Reflect.deleteProperty()
const student = {
firstName: 'Jackson',
lastName: 'Rowe',
};
console.log(student.firstName); // -> Jackson
Reflect.deleteProperty(student, 'firstName');
console.log(student.firstName); // -> undefined
100%Modern Browsers (Edge, Firefox, Safari, Chrome)
0%IE 11
100%Node 8
source: http://kangax.github.io/compat-table/es6/
Native support
Resources
● Wikipedia - Metaprogramming
● Wikipedia - Reflection in Computer Science
● Mozilla - Metaprogramming
● Metaprogramming in ES6 by Keith Cirkel
Credits
Special thanks to all the people who made and
released these awesome resources for free:
▷ MDN web docs
▷ Wikipedia and the contributors
▷ Keith Cirkel for the Metaprogramming series
▷ Presentation template by SlidesCarnival
Thanks!
Any questions?
You can find me at:
➔ @mehdivk
➔ linkedin.com/in/valikhani/
➔ hi@mv.id.au

Contenu connexe

Tendances

JavaScript in Object-Oriented Way
JavaScript in Object-Oriented WayJavaScript in Object-Oriented Way
JavaScript in Object-Oriented Way
Chamnap Chhorn
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
Adieu
 
Object Oriented Programming in JavaScript
Object Oriented Programming in JavaScriptObject Oriented Programming in JavaScript
Object Oriented Programming in JavaScript
zand3rs
 

Tendances (20)

Bottom Up
Bottom UpBottom Up
Bottom Up
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best Practices
 
Javascript basics for automation testing
Javascript  basics for automation testingJavascript  basics for automation testing
Javascript basics for automation testing
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Java script
Java scriptJava script
Java script
 
Javascript 101
Javascript 101Javascript 101
Javascript 101
 
JavaScript 101
JavaScript 101JavaScript 101
JavaScript 101
 
JavaScript in Object-Oriented Way
JavaScript in Object-Oriented WayJavaScript in Object-Oriented Way
JavaScript in Object-Oriented Way
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScript
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
Basics of JavaScript
Basics of JavaScriptBasics of JavaScript
Basics of JavaScript
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Object Oriented Programming in JavaScript
Object Oriented Programming in JavaScriptObject Oriented Programming in JavaScript
Object Oriented Programming in JavaScript
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
 
Object Oriented Programming In JavaScript
Object Oriented Programming In JavaScriptObject Oriented Programming In JavaScript
Object Oriented Programming In JavaScript
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 

Similaire à Metaprogramming in JavaScript

Javascriptinobject orientedway-090512225827-phpapp02
Javascriptinobject orientedway-090512225827-phpapp02Javascriptinobject orientedway-090512225827-phpapp02
Javascriptinobject orientedway-090512225827-phpapp02
Sopheak Sem
 
11. session 11 functions and objects
11. session 11   functions and objects11. session 11   functions and objects
11. session 11 functions and objects
Phúc Đỗ
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
Piyush Katariya
 

Similaire à Metaprogramming in JavaScript (20)

Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
Reversing JavaScript
Reversing JavaScriptReversing JavaScript
Reversing JavaScript
 
JavaScript Misunderstood
JavaScript MisunderstoodJavaScript Misunderstood
JavaScript Misunderstood
 
Javascriptinobject orientedway-090512225827-phpapp02
Javascriptinobject orientedway-090512225827-phpapp02Javascriptinobject orientedway-090512225827-phpapp02
Javascriptinobject orientedway-090512225827-phpapp02
 
Week3
Week3Week3
Week3
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
 
Javascript
JavascriptJavascript
Javascript
 
HSC INFORMATION TECHNOLOGY CHAPTER 3 ADVANCED JAVASCRIPT
HSC INFORMATION TECHNOLOGY CHAPTER 3 ADVANCED JAVASCRIPTHSC INFORMATION TECHNOLOGY CHAPTER 3 ADVANCED JAVASCRIPT
HSC INFORMATION TECHNOLOGY CHAPTER 3 ADVANCED JAVASCRIPT
 
ES6 metaprogramming unleashed
ES6 metaprogramming unleashedES6 metaprogramming unleashed
ES6 metaprogramming unleashed
 
11. session 11 functions and objects
11. session 11   functions and objects11. session 11   functions and objects
11. session 11 functions and objects
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 
Web Host_G4.pptx
Web Host_G4.pptxWeb Host_G4.pptx
Web Host_G4.pptx
 
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...
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript Basics
 
JavaScript Basics - GameCraft Training
JavaScript Basics - GameCraft TrainingJavaScript Basics - GameCraft Training
JavaScript Basics - GameCraft Training
 
Backbone js
Backbone jsBackbone js
Backbone js
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
 
Oop Constructor Destructors Constructor Overloading lecture 2
Oop Constructor  Destructors Constructor Overloading lecture 2Oop Constructor  Destructors Constructor Overloading lecture 2
Oop Constructor Destructors Constructor Overloading lecture 2
 
Ajax and JavaScript Bootcamp
Ajax and JavaScript BootcampAjax and JavaScript Bootcamp
Ajax and JavaScript Bootcamp
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1
 

Dernier

result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
Tonystark477637
 

Dernier (20)

Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptx
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 

Metaprogramming in JavaScript

  • 2. Hello! I am Mehdi Valikhani Software Engineer at Autopilot
  • 4. “Metaprogramming is a programming technique in which computer programs have the ability to treat programs as their data. It means that a program can be designed to read, generate, analyse or transform other programs or itself while running source: Wikipedia
  • 5. “Metaprogramming is a programming technique in which computer programs have the ability to treat programs as their data. It means that a program can be designed to read, generate, analyse or transform other programs or itself while running source: Wikipedia
  • 7. “In computer science,reflection is the ability of a computer program to examine,introspect, and modify its own structure and behaviour at runtime. Reflection is a valuable language feature and it facilitates metaprogramming. source: Wikipedia
  • 8. Language features that enables reflection 1. Evaluate a string as if it were a source code statement at runtime. 2. Convert a string matching the symbolic name of a class or function into a reference to or invocation of that class or function. 3. Discover and modify source code constructions (such as code blocks, classes, methods, protocols, etc.) as first-class objects at runtime. source: Wikipedia
  • 11. Metaprogramming features of ES5 Code Evaluation eval() Examination ➔ instanceof ➔ typeof ➔ Object.getOwnPropertyNames() Modification Getter, setter
  • 14. Symbols The new type in JavaScript
  • 15. ➔ The seventh type of values in JavaScript Symbol ➔ The Symbol() function returns a value of type symbol ➔ Symbol() always returns unique values ➔ They may be used as an identifier for object properties source: MDN
  • 16. Example: Using Symbol as property identifier const nameField = Symbol('beer name'); const beer = { [nameField]: 'VB!' }; console.log(beer[nameField]); // -> VB!
  • 17. Example: Using Symbol as property identifier const nameField = Symbol('beer name'); const beer = { [nameField]: 'VB!' }; console.log(beer[nameField]); // -> VB!
  • 18. Example: Using Symbol as property identifier const nameField = Symbol('beer name'); const beer = { [nameField]: 'VB!' }; console.log(beer[nameField]); // -> VB!
  • 19. Example: Using Symbol as property identifier const nameField = Symbol('beer name'); const beer = { [nameField]: 'VB!' }; console.log(beer[nameField]); // -> VB!
  • 20. Well-known Symbols ➔ A set of built-in JavaScript symbols ➔ Represent internal language behaviours ➔ They were not exposed to developers before source: MDN
  • 21. Symbols are used by ES6 to enable “Reflection within implementation”. Developers include them on their existing classes and objects to change the default behaviour of an operation or action. source: keithcirkel.co.uk
  • 22. What can be done using well-known symbols ➔ Control the behaviour of instanceof for an implemented class ➔ Manipulate the behaviour of for of when iterated over a class ➔ Control over Array.concat ➔ Custom matches for String.match(), String.replace(), String.search() and String.split() ➔ Control the behaviour of Javascript when converting objects to primitive types Check MDN for a list of well-known symbols
  • 23. Example: Using well-known Symbol.hasInstance to modify behaviour of “instanceof” class MyArray { } const friends = ['foo', 'bar']; console.log(friends instanceof MyArray); // -> false class MyArray { static [Symbol.hasInstance](object) { return Array.isArray(object); } } const friends = ['foo', 'bar']; console.log(friends instanceof MyArray); // -> true
  • 24. Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class class ShoppingBasket { constructor() { this.items = []; } add(title, quantity, price) { this.items.push({ title, quantity, price}); } total() { return this.items.reduce(function(accumulator, item) { return accumulator + (item.price * item.quantity); }, 0); } } } const basket = new ShoppingBasket(); basket.add('bread', 2, 2.5); basket.add('milk', 1, 1.4);
  • 25. Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class class ShoppingBasket { constructor() { this.items = []; } add(title, quantity, price) { this.items.push({ title, quantity, price}); } total() { return this.items.reduce(function(accumulator, item) { return accumulator + (item.price * item.quantity); }, 0); } [Symbol.toPrimitive](hint) { if (hint === 'number') return this.total(); return this; } } const basket = new ShoppingBasket(); basket.add('bread', 2, 2.5); basket.add('milk', 1, 1.4); console.log(+basket); // -> 6.4 console.log(new Number(basket)); // -> 6.4
  • 26. Example: Using well-known Symbol.toPrimitive for a ShoppingBasket class class ShoppingBasket { constructor() { this.items = []; } add(title, quantity, price) { this.items.push({ title, quantity, price}); } total() { return this.items.reduce(function(accumulator, item) { return accumulator + (item.price * item.quantity); }, 0); } [Symbol.toPrimitive](hint) { if (hint === 'number') return this.total(); return this; } } const basket = new ShoppingBasket(); basket.add('bread', 2, 2.5); basket.add('milk', 1, 1.4); console.log(+basket); // -> 6.4 console.log(new Number(basket)); // -> 6.4
  • 27. Proxy
  • 28. Proxy, as the name indicates, provides “Reflection through interception”. It wraps objects and intercepts their behaviours through traps. source: keithcirkel.co.uk
  • 29. What can be done using Proxy ➔ A trap for delete operator ➔ Manipulate the behaviour of in operator ➔ Control over getting and setting property values ➔ A trap for function calls ➔ A trap for new operator Check MDN for a list of Proxy features
  • 30. Example: Implementation of a virtual field using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { get: function(object, fieldName) { if (fieldName === 'fullName') { return `${object.firstName} ${object.lastName}`; } return object[fieldName]; } }; const proxiedStudent = new Proxy(student, studentProxy); console.log(proxiedStudent.fullName); // -> Jackson Rowe
  • 31. Example: Implementation of a virtual field using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { get: function(object, fieldName) { if (fieldName === 'fullName') { return `${object.firstName} ${object.lastName}`; } return object[fieldName]; } }; const proxiedStudent = new Proxy(student, studentProxy); console.log(proxiedStudent.fullName); // -> Jackson Rowe
  • 32. Example: Implementation of a virtual field using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { get: function(object, fieldName) { if (fieldName === 'fullName') { return `${object.firstName} ${object.lastName}`; } return object[fieldName]; } }; const proxiedStudent = new Proxy(student, studentProxy); console.log(proxiedStudent.fullName); // -> Jackson Rowe
  • 33. Example: Implementation of a virtual field using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { get: function(object, fieldName) { if (fieldName === 'fullName') { return `${object.firstName} ${object.lastName}`; } return object[fieldName]; } }; const proxiedStudent = new Proxy(student, studentProxy); console.log(proxiedStudent.fullName); // -> Jackson Rowe
  • 34. Example: Value validation using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { set: function(object, fieldName, value) { // validation logic for the “age” field if (fieldName === 'age') { if (typeof value !== 'number') { throw TypeError('only numbers are accepted'); } if (value <= 0) throw TypeError('that is impossible'); } object[fieldName] = value; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); proxiedStudent.age = 'a'; // errors proxiedStudent.age = -1; // errors proxiedStudent.age = 12; // does not error
  • 35. Example: Value validation using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { set: function(object, fieldName, value) { // validation logic for the “age” field if (fieldName === 'age') { if (typeof value !== 'number') { throw TypeError('only numbers are accepted'); } if (value <= 0) throw TypeError('that is impossible'); } object[fieldName] = value; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); proxiedStudent.age = 'a'; // errors proxiedStudent.age = -1; // errors proxiedStudent.age = 12; // does not error
  • 36. Example: Value validation using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { set: function(object, fieldName, value) { // validation logic for the “age” field if (fieldName === 'age') { if (typeof value !== 'number') { throw TypeError('only numbers are accepted'); } if (value <= 0) throw TypeError('that is impossible'); } object[fieldName] = value; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); proxiedStudent.age = 'a'; // errors proxiedStudent.age = -1; // errors proxiedStudent.age = 12; // does not error
  • 37. Example: Value validation using Proxy const student = { firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { set: function(object, fieldName, value) { // validation logic for the “age” field if (fieldName === 'age') { if (typeof value !== 'number') { throw TypeError('only numbers are accepted'); } if (value <= 0) throw TypeError('that is impossible'); } object[fieldName] = value; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); proxiedStudent.age = 'a'; // errors proxiedStudent.age = -1; // errors proxiedStudent.age = 12; // does not error
  • 38. Example: Protect “id” field from deletion using a Proxy const student = { id: 'jackson-rowe', firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { deleteProperty: function(object, fieldName) { if (fieldName === 'id') return false; delete object[fieldName]; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); delete proxiedStudent.id // -> false console.log(proxiedStudent.id); // jackson-rowe
  • 39. Example: Protect “id” field from deletion using a Proxy const student = { id: 'jackson-rowe', firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { deleteProperty: function(object, fieldName) { if (fieldName === 'id') return false; delete object[fieldName]; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); delete proxiedStudent.id // -> false console.log(proxiedStudent.id); // jackson-rowe
  • 40. Example: Protect “id” field from deletion using a Proxy const student = { id: 'jackson-rowe', firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { deleteProperty: function(object, fieldName) { if (fieldName === 'id') return false; delete object[fieldName]; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); delete proxiedStudent.id // -> false console.log(proxiedStudent.id); // jackson-rowe
  • 41. Example: Protect “id” field from deletion using a Proxy const student = { id: 'jackson-rowe', firstName: 'Jackson', lastName: 'Rowe', }; const studentProxy = { deleteProperty: function(object, fieldName) { if (fieldName === 'id') return false; delete object[fieldName]; return true; } }; const proxiedStudent = new Proxy(student, studentProxy); delete proxiedStudent.id // -> false console.log(proxiedStudent.id); // jackson-rowe
  • 43. Reflect is all about “Reflection through introspection” - provides API to discover very low level information about code. source: keithcirkel.co.uk
  • 44. What can be done using Reflect ➔ Call a function using Reflect.apply() ➔ Define a property using Reflect.defineProperty() ➔ Delete a property using Control over Reflect.deleteProperty() ➔ Get a property value using Reflect.get() ➔ Set property value using Reflect.set() ➔ Check if a property exist using Reflect.has() Check MDN for a list of Reflect features
  • 45. What Reflect object offers are either a newer versions of existing methods or entirely new methods - allowing new levels of Reflection within JavaScript. source: keithcirkel.co.uk
  • 46. Example: Deleting a property using Reflect.deleteProperty() const student = { firstName: 'Jackson', lastName: 'Rowe', }; console.log(student.firstName); // -> Jackson Reflect.deleteProperty(student, 'firstName'); console.log(student.firstName); // -> undefined
  • 47. Example: Deleting a property using Reflect.deleteProperty() const student = { firstName: 'Jackson', lastName: 'Rowe', }; console.log(student.firstName); // -> Jackson Reflect.deleteProperty(student, 'firstName'); console.log(student.firstName); // -> undefined
  • 48. Example: Deleting a property using Reflect.deleteProperty() const student = { firstName: 'Jackson', lastName: 'Rowe', }; console.log(student.firstName); // -> Jackson Reflect.deleteProperty(student, 'firstName'); console.log(student.firstName); // -> undefined
  • 49. Example: Deleting a property using Reflect.deleteProperty() const student = { firstName: 'Jackson', lastName: 'Rowe', }; console.log(student.firstName); // -> Jackson Reflect.deleteProperty(student, 'firstName'); console.log(student.firstName); // -> undefined
  • 50. 100%Modern Browsers (Edge, Firefox, Safari, Chrome) 0%IE 11 100%Node 8 source: http://kangax.github.io/compat-table/es6/ Native support
  • 51. Resources ● Wikipedia - Metaprogramming ● Wikipedia - Reflection in Computer Science ● Mozilla - Metaprogramming ● Metaprogramming in ES6 by Keith Cirkel
  • 52. Credits Special thanks to all the people who made and released these awesome resources for free: ▷ MDN web docs ▷ Wikipedia and the contributors ▷ Keith Cirkel for the Metaprogramming series ▷ Presentation template by SlidesCarnival
  • 53. Thanks! Any questions? You can find me at: ➔ @mehdivk ➔ linkedin.com/in/valikhani/ ➔ hi@mv.id.au