SlideShare a Scribd company logo
1 of 66
Download to read offline
Beyond JavascriptBeyond Javascript
Using the features of tomorrowUsing the features of tomorrow
Spread syntaxSpread syntax
"Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero
or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to
be expanded in places where zero or more key-value pairs (for object literals) are expected."
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
const arr = [
'one',
'two',
'three',
];
console.log(arr[0], arr[1], arr[2]);
const arr = [
'one',
'two',
'three',
];
console.log(arr[0], arr[1], arr[2]);
console.log.apply(console, arr);
const arr = [
'one',
'two',
'three',
];
console.log(arr[0], arr[1], arr[2]);
console.log(...arr);
Rest syntaxRest syntax
Reverses the effect of the spread operator to collect all other (the rest) of the arguments into a single
variable.
let pokedex = {
"Ash": [],
"Gary": ["Machoke"],
}
function catchem(trainer, ...pokemon) {
pokemon.forEach((p) => pokedex[trainer].push(p));
console.log(trainer, "has now caught", pokedex[trainer])
}
catchem('Ash', 'Pikachu');
> Ash has now caught ["Pikachu"]
let pokedex = {
"Ash": [],
"Gary": ["Machoke"],
}
function catchem(trainer, ...pokemon) {
pokemon.forEach((p) => pokedex[trainer].push(p));
console.log(trainer, "has now caught", pokedex[trainer])
}
catchem('Ash', 'Pikachu');
> Ash has now caught ["Pikachu"]
catchem('Gary', 'Charmander', 'Squirtle', 'Bulbasaur');
> Gary has now caught ["Machoke", "Charmander", "Squirtle", "Bulbasaur"]
let pokedex = {
"Ash": [],
"Gary": ["Machoke"],
}
function catchem(trainer, ...pokemon) {
pokemon.forEach((p) => pokedex[trainer].push(p));
console.log(trainer, "has now caught", pokedex[trainer])
}
catchem('Ash', 'Pikachu');
> Ash has now caught ["Pikachu"]
catchem('Gary', 'Charmander', 'Squirtle', 'Bulbasaur');
> Gary has now caught ["Machoke", "Charmander", "Squirtle", "Bulbasaur"]
const fibonacci = [ 1, 1, 2, 3, 5, 8, 13, 21 ];
const [ first, second, third, ...others] = fibonacci;
console.log("Starts like", first, second, third);
console.log("Then goes", others);
> Starts like 1 1 2
> Then goes [3, 5, 8, 13, 21]
Works mostly everywhere except Internet Explorer.
StringString LiteralsLiterals
StringString LiteralsLiterals
console.log("Hello, World");
> Hello World
StringString LiteralsLiterals
const greeting = "John";
console.log("Hello, " + greeting);
> Hello John
TemplateTemplate LiteralsLiterals
const greeting = "John";
console.log(`Hello, ${greeting}`);
> Hello John
TemplateTemplate LiteralsLiterals
Global: 92.49% + 0% = 92.49%
ES6 Template Literals (Template Strings)
Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. Formerly known as template strings.
✓ ✗ Partial Support
Data from caniuse.com | Embed from caniuse.bitsofco.de Enable accessible colours
IE Edge Firefox Chrome Safari iOS Safari Opera Mini Chrome for Android Android Browser Samsung Internet
9 16 68 76 12 12.1 4.4 8.2
10 17 69 77 12.1 12.4 4.4.4 9.2
11 18 70 78 13 13.1 all 78 76 10.1
76 71 79 TP
const greeting = "John";
console.log(`Hello, ${greeting}`);
> Hello John
TranslationsTranslations
/**
* Translates a string and escapes arguments.
*
* @param string str
* The string with placeholders ({n}) to translate.
* @param array args
* The arguments to replace in the translated string.
*
* @return string
* A translated string with escaped arguments.
*/
function t(str, args) {
let translated = loadTranslation(str);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
TranslationsTranslations
/**
* Translates a string and escapes arguments.
*
* @param string str
* The string with placeholders ({n}) to translate.
* @param array args
* The arguments to replace in the translated string.
*
* @return string
* A translated string with escaped arguments.
*/
function t(str, args) {
let translated = loadTranslation(str);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
t("Hello, {0}", "Javascript");
> Hoi, Javascript
TranslationsTranslations
/**
* Translates a string and escapes arguments.
*
* @param string str
* The string with placeholders ({n}) to translate.
* @param array args
* The arguments to replace in the translated string.
*
* @return string
* A translated string with escaped arguments.
*/
function t(str, args) {
let translated = loadTranslation(str);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
t("Hello, {0}", "Javascript");
> Hoi, Javascript
t("On a scale from {0} to {1}, what do you think of {2}?", 1, 10, t("French Fries"));
> Op een schaal van 1 to 10, wat vindt u van Franse frietjes?
TranslationsTranslations
/**
* Translates a string and escapes arguments.
*
* @param string str
* The string with placeholders ({n}) to translate.
* @param array args
* The arguments to replace in the translated string.
*
* @return string
* A translated string with escaped arguments.
*/
function t(str, args) {
let translated = loadTranslation(str);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
t("Hello, {0}", "Javascript");
> Hoi, Javascript
t("On a scale from {0} to {1}, what do you think of {2}?", 1, 10, t("French Fries"));
> Op een schaal van 1 to 10, wat vindt u van Franse frietjes?
t(`On a scale from ${1} to ${10}, what do you think of ${t("French Fries")}?`);
> On a scale from 1 to 10, what do you think of Franse frietjes?
/**
* Retrieves the translation for a given string.
*
* @param string str
* The string to translate
* @return string
* The translated string or the original string
* if no translation is available.
*/
function loadTranslation(str) {
const language = window.navigator.userLanguage
|| window.navigator.language;
return
str in translations && language in translations[str]
? translations[str][language]
: str;
}
const translations = {
"Hello World!": {
"en-US": "Hello America!",
"en-GB": "Hello World!",
"nl": "Hallo Wereld!",
},
"Hello, {0}": {
"en-US": "Howdy, {0}",
"en-GB": "Hello, {0}",
"nl": "Hoi, {0}",
},
"Do you like {0}?": {
"en-US": "Who doesn't like football?",
"en-GB": "Do you like {0}?",
"nl": "Houd jij van {0}?",
},
"On a scale from {0} to {1}, what do you think of {2}?":
"en-US": "On a scale from {0} to {1}, what do you think of {2}?",
"en-GB": "On a scale from {0} to {1}, what do you think of {2}?",
"nl": "Op een schaal van {0} to {1}, wat vindt u van {2}?",
},
"French Fries": {
"en-US": "French Fries",
"en-GB": "Chips",
"nl": "Franse frietjes",
},
};
/**
* Uses a fake element to escape HTML entities.
*/
function htmlEscape(str) {
let d = document.createElement('div');
d.innerHtml = str;
return d.innerText;
}
Tagged Template LiteralsTagged Template Literals
`On a scale from ${1} to ${10}, what do you think of ${ `French Fries`}?`
Tagged Template LiteralsTagged Template Literals
trans`On a scale from ${1} to ${10}, what do you think of ${trans`French Fries`}?`
function trans() {
console.log(arguments);
}
Tagged Template LiteralsTagged Template Literals
trans`On a scale from ${1} to ${10}, what do you think of ${trans`French Fries`}?`
function trans() {
console.log(arguments);
}
> [Arguments] { '0': [ 'French Fries' ] }
> [Arguments] {
'0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ],
'1': 1,
'2': 10,
'3': 'French Fries'
}
> [Arguments] {
'0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ],
'1': 1,
'2': 10,
'3': 'French Fries'
}
/**
* Translates a string and escapes arguments.
*
* @return string
* A translated string with escaped arguments.
*/
function trans(literals, args) {
let translated = loadTranslation(literals);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
> [Arguments] {
'0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ],
'1': 1,
'2': 10,
'3': 'French Fries'
}
/**
* Translates a string and escapes arguments.
*
* @param array literals
* An array of string literals that surround the expressions
* @param {...} args
* The arguments to replace in the translated string.
*
* @return string
* A translated string with escaped arguments.
*/
function trans(literals, ...args) {
// Add our placeholders for the translation loading.
// idx starts at 0 if an initial value is provided to reduce.
const translatableString = strings.slice(1).reduce(
(acc, val, idx) => `${acc} {${idx}} ${val}`,
strings[0]
);
let translated = loadTranslation(translatableString);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
function trans(literals, ...args) {
// Add our placeholders for the translation loading.
// idx starts at 0 if an initial value is provided to reduce.
const translatableString = strings.slice(1).reduce(
(acc, val, idx) => `${acc} {${idx}} ${val}`,
strings[0]
);
let translated = loadTranslation(translatableString);
for (const [key, value] of Object.entries(args)) {
translated = translated.replace(`{${k}}`, htmlEscape(value));
}
return translated;
}
// Alternate our rating type.
const getRateType = (() => { let i = 0; return () => ++i % 2 ? 'food' : 'drink'; })();
trans`On a scale from ${1} to ${10}, what do you think of ${getRateType() === 'food' ? trans`French Fries` : 'Coca Cola'}?`
> Op een schaal van 1 tot 10, wat vindt u van Franse frietjes?
trans`On a scale from ${1} to ${10}, what do you think of ${getRateType() === 'food' ? trans`French Fries` : 'Coca Cola'}?`
> Op een schaal van 1 tot 10, wat vindt u van Coca Cola?
Works out of the box in Chrome
Internet Explorer?
Unsupported function? Use Modernizr!
Unsupported function? Use Modernizr!
console.log(...arguments);
> Syntax Error
Unsupported function? Use Modernizr!
console.log(...arguments);
> Syntax Error
Unsupported function? Syntax? Use Modernizr!
console.log(...arguments);
> Syntax Error
Unsupported function? Syntax? Use Modernizr! Babel!
console.log(...arguments);
> Syntax Error
Babel is a JavaScript compiler.
Put in next-gen JavaScript. Get browser-compatible JavaScript out
Babel is a JavaScript compiler.
Put in next-gen JavaScript. Get browser-compatible JavaScript out
console.log(...arguments);
Babel is a JavaScript compiler.
Put in next-gen JavaScript. Get browser-compatible JavaScript out
console.log(...arguments);
var _console;
(_console = console).log.apply(_console, arguments);
Need a Babel configuration quick-start?
@babel/preset-env is for you.
Use the latest JavaScript without micromanaging syntax transforms
Use browserlist expressions
> 0,25%, not dead
Compile to work in any browser with more than 0,25% marketshare (according to Can I Use)
Some next-gen JavaScriptSome next-gen JavaScript
DecoratorsDecorators
DecoratorsDecorators
A proposal for ESNext by Ecma Technical Committee (TC) 39
https://github.com/tc39/proposal-decorators/
DecoratorsDecorators
A proposal for ESNext by Ecma Technical Committee (TC) 39
https://github.com/tc39/proposal-decorators/
Makes metaprogramming in JavaScript more explicit
Replaces code such as Object.defineProperty
DecoratorsDecorators
A proposal for ESNext by Ecma Technical Committee (TC) 39
https://github.com/tc39/proposal-decorators/
Makes metaprogramming in JavaScript more explicit
Replaces code such as Object.defineProperty
Can also manipulate private fields/methods
Manipulations run at time of definition
Can be used for a whole class or an individual element
Why?Why?
class Counter {
count = 0;
handleClick() {
this.count++;
console.log(this, this.count);
}
render() {
let button = document.createElement('button');
button.innerText = "Increment";
button.onclick = this.handleClick;
document.body.append(button);
}
}
let counter = new Counter();
counter.render();
Why?Why?
class Counter {
count = 0;
handleClick() {
this.count++;
console.log(this, this.count);
}
render() {
let button = document.createElement('button');
button.innerText = "Increment";
button.onclick = this.handleClick;
document.body.append(button);
}
}
let counter = new Counter();
counter.render();
> <button>Increment</button> NaN
Why?Why?
class Counter {
count = 0;
constructor() {
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.count++;
console.log(this, this.count);
}
render() {
let button = document.createElement('button');
button.innerText = "Increment";
button.onclick = this.handleClick;
document.body.append(button);
}
}
let counter = new Counter();
counter.render();
> Counter {count: 1, handleClick: ƒ} 1
> Counter {count: 2, handleClick: ƒ} 2
Why?Why?
class Counter {
count = 0;
@bound
handleClick() {
this.count++;
console.log(this, this.count);
}
render() {
let button = document.createElement('button');
button.innerText = "Increment";
button.onclick = this.handleClick;
document.body.append(button);
}
}
let counter = new Counter();
counter.render();
> Counter {count: 1, handleClick: ƒ} 1
> Counter {count: 2, handleClick: ƒ} 2
How?How?
The documentation1 is better than my funny code snippets.
1. https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#basic-usage
A decorator is a function. Usable in three places
/**
* A counter element.
*
* Use in your HTML
*/
class Counter extends HTMLElement {
count = 0;
constructor() {
super();
this.onclick = this.handleClick;
}
connectedCallback() { this.render(); }
handleClick() {
this.count++;
}
render() {
this.textContent = this.count.toString();
}
}
A decorator is a function. Usable in three places
Class
/**
* A counter element.
*
* Use in your HTML
*/
@defineElement
class Counter extends HTMLElement {
count = 0;
constructor() {
super();
this.onclick = this.handleClick;
}
connectedCallback() { this.render(); }
handleClick() {
this.count++;
}
render() {
this.textContent = this.count.toString();
}
}
A decorator is a function. Usable in three places
Class
/**
* A counter element.
*
* Use in your HTML as <num-counter />.
*/
@defineElement('num-counter')
class Counter extends HTMLElement {
count = 0;
constructor() {
super();
this.onclick = this.handleClick;
}
connectedCallback() { this.render(); }
handleClick() {
this.count++;
}
render() {
this.textContent = this.count.toString();
}
}
A decorator is a function. Usable in three places
Class
Property
/**
* A counter element.
*
* Use in your HTML as <num-counter />.
*/
@defineElement('num-counter')
class Counter extends HTMLElement {
@logged
count = 0;
constructor() {
super();
this.onclick = this.handleClick;
}
connectedCallback() { this.render(); }
handleClick() {
this.count++;
}
render() {
this.textContent = this.count.toString();
}
}
A decorator is a function. Usable in three places
Class
Property
Method
/**
* A counter element.
*
* Use in your HTML as <num-counter />.
*/
@defineElement('num-counter')
class Counter extends HTMLElement {
@logged
count = 0;
constructor() {
super();
this.onclick = this.handleClick;
}
connectedCallback() { this.render(); }
@bound
handleClick() {
this.count++;
}
@bound
render() {
this.textContent = this.count.toString();
}
}
MethodMethod
// arguments
{
kind: "method"
key: String, Symbol or Private Name,
placement: "static", "prototype" or "own",
descriptor: Property Descriptor (argument to Object.defineProperty),
}
// return
{ kind, key, placement, descriptor, , extras?, finisher? }
https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
FieldField
// arguments
{
kind: "field"
key: String, Symbol or Private Name,
placement: "static", "prototype" or "own",
descriptor: Property Descriptor (argument to Object.defineProperty),
initializer: A method used to set the initial state of the field,
}
// return
{ kind, key, placement, descriptor, initializer, extras?, finisher? }
https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
FieldField
// arguments
{
kind: "field"
key: String, Symbol or Private Name,
placement: "static", "prototype" or "own",
descriptor: Property Descriptor (argument to Object.defineProperty),
initializer: A method used to set the initial state of the field,
}
// return
{ kind, key, placement, descriptor, initializer, extras?, finisher? }
extras : [ { kind, key, placement, descriptor, initializer?}, ... ]
https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
FieldField
Property descriptor documentation:
// arguments
{
kind: "field"
key: String, Symbol or Private Name,
placement: "static", "prototype" or "own",
descriptor: Property Descriptor (argument to Object.defineProperty),
initializer: A method used to set the initial state of the field,
}
// return
{ kind, key, placement, descriptor, initializer, extras?, finisher? }
extras : [ { kind, key, placement, descriptor, initializer?}, ... ]
https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description
ClassClass
// arguments
{
kind: "class"
elements: Array of all class elements
}
// return
{
kind: "class"
elements: Possibly modified class elements (can include additional class elements)
finisher: (optional) A callback that is called at the end of class creation
}
Logging property changesLogging property changes
class Counter {
@logged
count = 0;
}
let counter1 = new Counter();
counter1.count++;
counter1.count++;
counter1.count++;
let counter2 = new Counter();
counter2.count++;
counter2.count++;
// Logs the new value of a variable to the console whenever it changes.
function logged({kind, key, placement, descriptor, initializer}) {
assert(kind == "field");
assert(placement == "own");
// Create a new private name as a key for a class element
let storage = Symbol(key);
let underlyingDescriptor = { enumerable: false, configurable: false, writable: true };
let underlying = { kind, key: storage, placement, descriptor: underlyingDescriptor, initializer };
return {
kind: "method",
key,
placement,
descriptor: {
get() { return this[storage]; },
set(value) {
this[storage] = value;
// Log the change of value
console.log("Value of", key, "changed to", value);
},
enumerable: descriptor.enumerable,
configurable: descriptor.configurable
},
extras: [underlying]
};
}
Value of count changed to 1
Value of count changed to 2
Value of count changed to 3
Value of count changed to 1
Value of count changed to 2
This won't even run in Chrome (yet)This won't even run in Chrome (yet)
Babel to the rescueBabel to the rescue
@babel/plugin-proposal-decorators
@babel/plugin-proposal-class-properties
Note: In your config add the classProperties plugin after decorators.
@babel/plugin-proposal-*@babel/plugin-proposal-* vsvs
@babel/plugin-syntax-*@babel/plugin-syntax-*
Have fun!Have fun!
With great power comes great responsibility.

More Related Content

What's hot

Introduction to python
Introduction to pythonIntroduction to python
Introduction to pythonMarian Marinov
 
String in python use of split method
String in python use of split methodString in python use of split method
String in python use of split methodvikram mahendra
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin IGuixing Bai
 
Avro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAvro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAlexandre Victoor
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In PythonMarwan Osman
 
An Intro to Python in 30 minutes
An Intro to Python in 30 minutesAn Intro to Python in 30 minutes
An Intro to Python in 30 minutesSumit Raj
 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: DeanonymizingDavid Evans
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)Pedro Rodrigues
 
Advanced python
Advanced pythonAdvanced python
Advanced pythonEU Edge
 
Python于Web 2.0网站的应用 - QCon Beijing 2010
Python于Web 2.0网站的应用 - QCon Beijing 2010Python于Web 2.0网站的应用 - QCon Beijing 2010
Python于Web 2.0网站的应用 - QCon Beijing 2010Qiangning Hong
 
Learning sed and awk
Learning sed and awkLearning sed and awk
Learning sed and awkYogesh Sawant
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick referenceArduino Aficionado
 
Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fuclimatewarrior
 
Basic NLP with Python and NLTK
Basic NLP with Python and NLTKBasic NLP with Python and NLTK
Basic NLP with Python and NLTKFrancesco Bruni
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Paulo Morgado
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to PigChris Wilkes
 

What's hot (20)

Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
String in python use of split method
String in python use of split methodString in python use of split method
String in python use of split method
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin I
 
Avro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAvro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSON
 
Python
PythonPython
Python
 
Python
PythonPython
Python
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
 
An Intro to Python in 30 minutes
An Intro to Python in 30 minutesAn Intro to Python in 30 minutes
An Intro to Python in 30 minutes
 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: Deanonymizing
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
Python于Web 2.0网站的应用 - QCon Beijing 2010
Python于Web 2.0网站的应用 - QCon Beijing 2010Python于Web 2.0网站的应用 - QCon Beijing 2010
Python于Web 2.0网站的应用 - QCon Beijing 2010
 
Learning sed and awk
Learning sed and awkLearning sed and awk
Learning sed and awk
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick reference
 
Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fu
 
Basic NLP with Python and NLTK
Basic NLP with Python and NLTKBasic NLP with Python and NLTK
Basic NLP with Python and NLTK
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
 
Unit vii wp ppt
Unit vii wp pptUnit vii wp ppt
Unit vii wp ppt
 

Similar to Beyond javascript using the features of tomorrow

More on Lex
More on LexMore on Lex
More on LexTech_MX
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to pythonAhmed Salama
 
Os Vanrossum
Os VanrossumOs Vanrossum
Os Vanrossumoscon2007
 
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/ibrettflorio
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDr. Jan Köhnlein
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607Kevin Hazzard
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 

Similar to Beyond javascript using the features of tomorrow (20)

More on Lex
More on LexMore on Lex
More on Lex
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
PHP Web Programming
PHP Web ProgrammingPHP Web Programming
PHP Web Programming
 
C# - What's next
C# - What's nextC# - What's next
C# - What's next
 
Os Vanrossum
Os VanrossumOs Vanrossum
Os Vanrossum
 
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i
/Regex makes me want to (weep|give up|(╯°□°)╯︵ ┻━┻)\.?/i
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
 
Json the-x-in-ajax1588
Json the-x-in-ajax1588Json the-x-in-ajax1588
Json the-x-in-ajax1588
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
Python basic
Python basicPython basic
Python basic
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Start
 
Javascript 101
Javascript 101Javascript 101
Javascript 101
 
C tutorial
C tutorialC tutorial
C tutorial
 
C tutorial
C tutorialC tutorial
C tutorial
 
C tutorial
C tutorialC tutorial
C tutorial
 
Python lecture 05
Python lecture 05Python lecture 05
Python lecture 05
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 

Recently uploaded

Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 

Beyond javascript using the features of tomorrow

  • 1. Beyond JavascriptBeyond Javascript Using the features of tomorrowUsing the features of tomorrow
  • 2. Spread syntaxSpread syntax "Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected." https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
  • 3. const arr = [ 'one', 'two', 'three', ]; console.log(arr[0], arr[1], arr[2]);
  • 4. const arr = [ 'one', 'two', 'three', ]; console.log(arr[0], arr[1], arr[2]); console.log.apply(console, arr);
  • 5. const arr = [ 'one', 'two', 'three', ]; console.log(arr[0], arr[1], arr[2]); console.log(...arr);
  • 6. Rest syntaxRest syntax Reverses the effect of the spread operator to collect all other (the rest) of the arguments into a single variable.
  • 7. let pokedex = { "Ash": [], "Gary": ["Machoke"], } function catchem(trainer, ...pokemon) { pokemon.forEach((p) => pokedex[trainer].push(p)); console.log(trainer, "has now caught", pokedex[trainer]) } catchem('Ash', 'Pikachu'); > Ash has now caught ["Pikachu"]
  • 8. let pokedex = { "Ash": [], "Gary": ["Machoke"], } function catchem(trainer, ...pokemon) { pokemon.forEach((p) => pokedex[trainer].push(p)); console.log(trainer, "has now caught", pokedex[trainer]) } catchem('Ash', 'Pikachu'); > Ash has now caught ["Pikachu"] catchem('Gary', 'Charmander', 'Squirtle', 'Bulbasaur'); > Gary has now caught ["Machoke", "Charmander", "Squirtle", "Bulbasaur"]
  • 9. let pokedex = { "Ash": [], "Gary": ["Machoke"], } function catchem(trainer, ...pokemon) { pokemon.forEach((p) => pokedex[trainer].push(p)); console.log(trainer, "has now caught", pokedex[trainer]) } catchem('Ash', 'Pikachu'); > Ash has now caught ["Pikachu"] catchem('Gary', 'Charmander', 'Squirtle', 'Bulbasaur'); > Gary has now caught ["Machoke", "Charmander", "Squirtle", "Bulbasaur"] const fibonacci = [ 1, 1, 2, 3, 5, 8, 13, 21 ]; const [ first, second, third, ...others] = fibonacci; console.log("Starts like", first, second, third); console.log("Then goes", others); > Starts like 1 1 2 > Then goes [3, 5, 8, 13, 21]
  • 10. Works mostly everywhere except Internet Explorer.
  • 13. StringString LiteralsLiterals const greeting = "John"; console.log("Hello, " + greeting); > Hello John
  • 14. TemplateTemplate LiteralsLiterals const greeting = "John"; console.log(`Hello, ${greeting}`); > Hello John
  • 15. TemplateTemplate LiteralsLiterals Global: 92.49% + 0% = 92.49% ES6 Template Literals (Template Strings) Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. Formerly known as template strings. ✓ ✗ Partial Support Data from caniuse.com | Embed from caniuse.bitsofco.de Enable accessible colours IE Edge Firefox Chrome Safari iOS Safari Opera Mini Chrome for Android Android Browser Samsung Internet 9 16 68 76 12 12.1 4.4 8.2 10 17 69 77 12.1 12.4 4.4.4 9.2 11 18 70 78 13 13.1 all 78 76 10.1 76 71 79 TP const greeting = "John"; console.log(`Hello, ${greeting}`); > Hello John
  • 16. TranslationsTranslations /** * Translates a string and escapes arguments. * * @param string str * The string with placeholders ({n}) to translate. * @param array args * The arguments to replace in the translated string. * * @return string * A translated string with escaped arguments. */ function t(str, args) { let translated = loadTranslation(str); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; }
  • 17. TranslationsTranslations /** * Translates a string and escapes arguments. * * @param string str * The string with placeholders ({n}) to translate. * @param array args * The arguments to replace in the translated string. * * @return string * A translated string with escaped arguments. */ function t(str, args) { let translated = loadTranslation(str); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; } t("Hello, {0}", "Javascript"); > Hoi, Javascript
  • 18. TranslationsTranslations /** * Translates a string and escapes arguments. * * @param string str * The string with placeholders ({n}) to translate. * @param array args * The arguments to replace in the translated string. * * @return string * A translated string with escaped arguments. */ function t(str, args) { let translated = loadTranslation(str); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; } t("Hello, {0}", "Javascript"); > Hoi, Javascript t("On a scale from {0} to {1}, what do you think of {2}?", 1, 10, t("French Fries")); > Op een schaal van 1 to 10, wat vindt u van Franse frietjes?
  • 19. TranslationsTranslations /** * Translates a string and escapes arguments. * * @param string str * The string with placeholders ({n}) to translate. * @param array args * The arguments to replace in the translated string. * * @return string * A translated string with escaped arguments. */ function t(str, args) { let translated = loadTranslation(str); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; } t("Hello, {0}", "Javascript"); > Hoi, Javascript t("On a scale from {0} to {1}, what do you think of {2}?", 1, 10, t("French Fries")); > Op een schaal van 1 to 10, wat vindt u van Franse frietjes? t(`On a scale from ${1} to ${10}, what do you think of ${t("French Fries")}?`); > On a scale from 1 to 10, what do you think of Franse frietjes?
  • 20. /** * Retrieves the translation for a given string. * * @param string str * The string to translate * @return string * The translated string or the original string * if no translation is available. */ function loadTranslation(str) { const language = window.navigator.userLanguage || window.navigator.language; return str in translations && language in translations[str] ? translations[str][language] : str; }
  • 21. const translations = { "Hello World!": { "en-US": "Hello America!", "en-GB": "Hello World!", "nl": "Hallo Wereld!", }, "Hello, {0}": { "en-US": "Howdy, {0}", "en-GB": "Hello, {0}", "nl": "Hoi, {0}", }, "Do you like {0}?": { "en-US": "Who doesn't like football?", "en-GB": "Do you like {0}?", "nl": "Houd jij van {0}?", }, "On a scale from {0} to {1}, what do you think of {2}?": "en-US": "On a scale from {0} to {1}, what do you think of {2}?", "en-GB": "On a scale from {0} to {1}, what do you think of {2}?", "nl": "Op een schaal van {0} to {1}, wat vindt u van {2}?", }, "French Fries": { "en-US": "French Fries", "en-GB": "Chips", "nl": "Franse frietjes", }, };
  • 22. /** * Uses a fake element to escape HTML entities. */ function htmlEscape(str) { let d = document.createElement('div'); d.innerHtml = str; return d.innerText; }
  • 23. Tagged Template LiteralsTagged Template Literals `On a scale from ${1} to ${10}, what do you think of ${ `French Fries`}?`
  • 24. Tagged Template LiteralsTagged Template Literals trans`On a scale from ${1} to ${10}, what do you think of ${trans`French Fries`}?` function trans() { console.log(arguments); }
  • 25. Tagged Template LiteralsTagged Template Literals trans`On a scale from ${1} to ${10}, what do you think of ${trans`French Fries`}?` function trans() { console.log(arguments); } > [Arguments] { '0': [ 'French Fries' ] } > [Arguments] { '0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ], '1': 1, '2': 10, '3': 'French Fries' }
  • 26. > [Arguments] { '0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ], '1': 1, '2': 10, '3': 'French Fries' } /** * Translates a string and escapes arguments. * * @return string * A translated string with escaped arguments. */ function trans(literals, args) { let translated = loadTranslation(literals); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; }
  • 27. > [Arguments] { '0': [ 'On a scale from ', ' to ', ', what do you think of ', '?' ], '1': 1, '2': 10, '3': 'French Fries' } /** * Translates a string and escapes arguments. * * @param array literals * An array of string literals that surround the expressions * @param {...} args * The arguments to replace in the translated string. * * @return string * A translated string with escaped arguments. */ function trans(literals, ...args) { // Add our placeholders for the translation loading. // idx starts at 0 if an initial value is provided to reduce. const translatableString = strings.slice(1).reduce( (acc, val, idx) => `${acc} {${idx}} ${val}`, strings[0] ); let translated = loadTranslation(translatableString); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; }
  • 28. function trans(literals, ...args) { // Add our placeholders for the translation loading. // idx starts at 0 if an initial value is provided to reduce. const translatableString = strings.slice(1).reduce( (acc, val, idx) => `${acc} {${idx}} ${val}`, strings[0] ); let translated = loadTranslation(translatableString); for (const [key, value] of Object.entries(args)) { translated = translated.replace(`{${k}}`, htmlEscape(value)); } return translated; } // Alternate our rating type. const getRateType = (() => { let i = 0; return () => ++i % 2 ? 'food' : 'drink'; })(); trans`On a scale from ${1} to ${10}, what do you think of ${getRateType() === 'food' ? trans`French Fries` : 'Coca Cola'}?` > Op een schaal van 1 tot 10, wat vindt u van Franse frietjes? trans`On a scale from ${1} to ${10}, what do you think of ${getRateType() === 'food' ? trans`French Fries` : 'Coca Cola'}?` > Op een schaal van 1 tot 10, wat vindt u van Coca Cola?
  • 29. Works out of the box in Chrome
  • 32. Unsupported function? Use Modernizr! console.log(...arguments); > Syntax Error
  • 33. Unsupported function? Use Modernizr! console.log(...arguments); > Syntax Error
  • 34. Unsupported function? Syntax? Use Modernizr! console.log(...arguments); > Syntax Error
  • 35. Unsupported function? Syntax? Use Modernizr! Babel! console.log(...arguments); > Syntax Error
  • 36. Babel is a JavaScript compiler. Put in next-gen JavaScript. Get browser-compatible JavaScript out
  • 37. Babel is a JavaScript compiler. Put in next-gen JavaScript. Get browser-compatible JavaScript out console.log(...arguments);
  • 38. Babel is a JavaScript compiler. Put in next-gen JavaScript. Get browser-compatible JavaScript out console.log(...arguments); var _console; (_console = console).log.apply(_console, arguments);
  • 39. Need a Babel configuration quick-start? @babel/preset-env is for you. Use the latest JavaScript without micromanaging syntax transforms Use browserlist expressions > 0,25%, not dead Compile to work in any browser with more than 0,25% marketshare (according to Can I Use)
  • 40. Some next-gen JavaScriptSome next-gen JavaScript
  • 42. DecoratorsDecorators A proposal for ESNext by Ecma Technical Committee (TC) 39 https://github.com/tc39/proposal-decorators/
  • 43. DecoratorsDecorators A proposal for ESNext by Ecma Technical Committee (TC) 39 https://github.com/tc39/proposal-decorators/ Makes metaprogramming in JavaScript more explicit Replaces code such as Object.defineProperty
  • 44. DecoratorsDecorators A proposal for ESNext by Ecma Technical Committee (TC) 39 https://github.com/tc39/proposal-decorators/ Makes metaprogramming in JavaScript more explicit Replaces code such as Object.defineProperty Can also manipulate private fields/methods Manipulations run at time of definition Can be used for a whole class or an individual element
  • 45. Why?Why? class Counter { count = 0; handleClick() { this.count++; console.log(this, this.count); } render() { let button = document.createElement('button'); button.innerText = "Increment"; button.onclick = this.handleClick; document.body.append(button); } } let counter = new Counter(); counter.render();
  • 46. Why?Why? class Counter { count = 0; handleClick() { this.count++; console.log(this, this.count); } render() { let button = document.createElement('button'); button.innerText = "Increment"; button.onclick = this.handleClick; document.body.append(button); } } let counter = new Counter(); counter.render(); > <button>Increment</button> NaN
  • 47. Why?Why? class Counter { count = 0; constructor() { this.handleClick = this.handleClick.bind(this); } handleClick() { this.count++; console.log(this, this.count); } render() { let button = document.createElement('button'); button.innerText = "Increment"; button.onclick = this.handleClick; document.body.append(button); } } let counter = new Counter(); counter.render(); > Counter {count: 1, handleClick: ƒ} 1 > Counter {count: 2, handleClick: ƒ} 2
  • 48. Why?Why? class Counter { count = 0; @bound handleClick() { this.count++; console.log(this, this.count); } render() { let button = document.createElement('button'); button.innerText = "Increment"; button.onclick = this.handleClick; document.body.append(button); } } let counter = new Counter(); counter.render(); > Counter {count: 1, handleClick: ƒ} 1 > Counter {count: 2, handleClick: ƒ} 2
  • 49. How?How? The documentation1 is better than my funny code snippets. 1. https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#basic-usage
  • 50. A decorator is a function. Usable in three places /** * A counter element. * * Use in your HTML */ class Counter extends HTMLElement { count = 0; constructor() { super(); this.onclick = this.handleClick; } connectedCallback() { this.render(); } handleClick() { this.count++; } render() { this.textContent = this.count.toString(); } }
  • 51. A decorator is a function. Usable in three places Class /** * A counter element. * * Use in your HTML */ @defineElement class Counter extends HTMLElement { count = 0; constructor() { super(); this.onclick = this.handleClick; } connectedCallback() { this.render(); } handleClick() { this.count++; } render() { this.textContent = this.count.toString(); } }
  • 52. A decorator is a function. Usable in three places Class /** * A counter element. * * Use in your HTML as <num-counter />. */ @defineElement('num-counter') class Counter extends HTMLElement { count = 0; constructor() { super(); this.onclick = this.handleClick; } connectedCallback() { this.render(); } handleClick() { this.count++; } render() { this.textContent = this.count.toString(); } }
  • 53. A decorator is a function. Usable in three places Class Property /** * A counter element. * * Use in your HTML as <num-counter />. */ @defineElement('num-counter') class Counter extends HTMLElement { @logged count = 0; constructor() { super(); this.onclick = this.handleClick; } connectedCallback() { this.render(); } handleClick() { this.count++; } render() { this.textContent = this.count.toString(); } }
  • 54. A decorator is a function. Usable in three places Class Property Method /** * A counter element. * * Use in your HTML as <num-counter />. */ @defineElement('num-counter') class Counter extends HTMLElement { @logged count = 0; constructor() { super(); this.onclick = this.handleClick; } connectedCallback() { this.render(); } @bound handleClick() { this.count++; } @bound render() { this.textContent = this.count.toString(); } }
  • 55. MethodMethod // arguments { kind: "method" key: String, Symbol or Private Name, placement: "static", "prototype" or "own", descriptor: Property Descriptor (argument to Object.defineProperty), } // return { kind, key, placement, descriptor, , extras?, finisher? } https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
  • 56. FieldField // arguments { kind: "field" key: String, Symbol or Private Name, placement: "static", "prototype" or "own", descriptor: Property Descriptor (argument to Object.defineProperty), initializer: A method used to set the initial state of the field, } // return { kind, key, placement, descriptor, initializer, extras?, finisher? } https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
  • 57. FieldField // arguments { kind: "field" key: String, Symbol or Private Name, placement: "static", "prototype" or "own", descriptor: Property Descriptor (argument to Object.defineProperty), initializer: A method used to set the initial state of the field, } // return { kind, key, placement, descriptor, initializer, extras?, finisher? } extras : [ { kind, key, placement, descriptor, initializer?}, ... ] https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api
  • 58. FieldField Property descriptor documentation: // arguments { kind: "field" key: String, Symbol or Private Name, placement: "static", "prototype" or "own", descriptor: Property Descriptor (argument to Object.defineProperty), initializer: A method used to set the initial state of the field, } // return { kind, key, placement, descriptor, initializer, extras?, finisher? } extras : [ { kind, key, placement, descriptor, initializer?}, ... ] https://github.com/tc39/proposal-decorators/blob/master/METAPROGRAMMING.md#api https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description
  • 59. ClassClass // arguments { kind: "class" elements: Array of all class elements } // return { kind: "class" elements: Possibly modified class elements (can include additional class elements) finisher: (optional) A callback that is called at the end of class creation }
  • 60. Logging property changesLogging property changes class Counter { @logged count = 0; } let counter1 = new Counter(); counter1.count++; counter1.count++; counter1.count++; let counter2 = new Counter(); counter2.count++; counter2.count++;
  • 61. // Logs the new value of a variable to the console whenever it changes. function logged({kind, key, placement, descriptor, initializer}) { assert(kind == "field"); assert(placement == "own"); // Create a new private name as a key for a class element let storage = Symbol(key); let underlyingDescriptor = { enumerable: false, configurable: false, writable: true }; let underlying = { kind, key: storage, placement, descriptor: underlyingDescriptor, initializer }; return { kind: "method", key, placement, descriptor: { get() { return this[storage]; }, set(value) { this[storage] = value; // Log the change of value console.log("Value of", key, "changed to", value); }, enumerable: descriptor.enumerable, configurable: descriptor.configurable }, extras: [underlying] }; }
  • 62. Value of count changed to 1 Value of count changed to 2 Value of count changed to 3 Value of count changed to 1 Value of count changed to 2
  • 63. This won't even run in Chrome (yet)This won't even run in Chrome (yet)
  • 64. Babel to the rescueBabel to the rescue @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties Note: In your config add the classProperties plugin after decorators.
  • 66. Have fun!Have fun! With great power comes great responsibility.