ECMAScript 6
Neste versjon av JavaScript- Mål
- Designprosess
- Funksjoner
- Når kan jeg bruke det?
Begreper
- TC39 (Ecma Technical Committee 39): komiteen som utvikler JavaScript.
- Medlemmer: bedrifter (bl.a. alle store browserleverandører).
- Ansatte og inviterte eksperter deltar på møtene.
- ECMAScript: språkets offisielle navn
- Versjoner: ECMAScript 5 er forkortelse for "ECMAScript Language Specification 5".
- ECMAScript Harmony: forbedringer etter ECMAScript 5 (ECMAScript 6 og 7)
JavaScript
- Folkemunne: språket
- Formelt: en implementasjon av ECMAScript
ECMAScript i seg selv er ikke bundet til nettlesere. For eksempel er NodeJS en implementasjon av ECMAScript.
JavaScript er blitt "farligere"
- Brukes overalt, browsere, servere, "devicer" osv.
- Brukes til mye mer enn det var laget for.
Mål
-
Være et bedre språk for å skrive:
- komplekse applikasjoner
- biblioteker for disse applikasjonene
- kodegeneratorer
Utforming av nye features
-
Unngå "design by committe":
- "design by champions" (1-2 eksperter).
- Feedback fra TC39 og community
- TC39 har siste ord for om/når nye funksjoner inkluderes
- Steg for å utforme en ny funksjon
- Strawman-forslag
- TC39 er interessert => forslag
- Field-testing via en eller flere implementasjoner
- TC39 godkjenner funksjonen => inkludert i ECMAScript utkast
- Inkludert i spesifikasjon => standard
Nye funksjoner
Block scope
// Function scoped var
function order(x, y) {
if (x > y) {
var tmp = x;
x = y;
y = tmp;
}
console.log(tmp === x);
// true
return [x, y];
}
// Block scoped let
function order(x, y) {
if (x > y) {
let tmp = x;
x = y;
y = tmp;
}
console.log(tmp === x);
// ReferenceError:
// tmp is not defined
return [x, y];
}
Konstanter
const PI = 3.14;
PI = 10;
console.log(PI); // 3.14
Destructing
Destructing: Objekter
Hent ut data (mer enn en verdi) via patterns:
let obj = { first: "Jane", last: "Doe" };
let { first: f, last: l } = obj;
console.log(f + " " + l); // Jane Doe
Brukes til:
- Variabel-deklarasjon
- Tilordning
- Parameter-definisjon
Destructing: Forkortelse
{x, y} er det samme som {x: x, y: y}.
let obj = { first: "Jane", last: "Doe" };
let { first, last} = obj;
console.log(first + " " + last); // Jane Doe
Destructing: Flere returverdier
function returnMultipleValues() {
return {
foo: 1,
bar: 2
};
}
var { foo, bar } = returnMultipleValues();
Destructing: Arrays
let [ x, y ] = [ "a", "b" ];
// x="a", y="b"
[ x, y ] = [ y, x ] // Swap values
var [,,third] = [1, 2, 3];
console.log(third);
// 3
var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]
Destructing: Refutable by default
Refutable (default):
{ a: x, b: y } = { a: 3 } // fails
Default Value:
{ a: x, b: y=5 } = { a: 3 } // x=3, y=5
{ a: x, b: y=5 } = { a: 3, b: undefined } // x=3, y=5
Funksjonsparametre
Funksjonsparametre:
Standardverdier
Kan sette standardverdi for parametre som mangler
function func1(x, y=3) {
return [x, y];
}
Console:
# func1(1, 2);
[1, 2]
# func1(1);
[1, 3]
# func1();
[undefined, 3]
Funksjonsparametre: Restparametre
Legge etterfølgende parametre i en array:
function func2(arg0, ...others) {
return others;
}
Console:
# func2(0, 1, 2, 3);
[1, 2, 3]
#func2(0);
[]
#func2();
[]
Fjerner behov for "arguments"
Funksjonsparametre: Spread operator (...)
Omgjøre en array til funksjon-/metodeparametre:
# Math.max(7, 4, 11);
11
# Math.max(...[ 7, 4, 11 ]);
11
- Det motsatte av restparameter
- Erstatter Function.prototype.apply()
Kan også brukes til å slå sammen arrays
var parts = ['shoulder', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
Navngitte parametre
Bruk av destructing for navngitte parametre opt1 og opt2:
function func3(arg0, { opt1, opt2 }) {
return [opt1, opt2];
}
func3(0, {opt1: "a", opt2: "b"});
// ["a", "b"]
Arrow-funksjoner
Arrow-funksjoner: syntax
Kortere syntaktisk form (function () {} vs () => {})
let squares = [1, 2, 3].map(function(x) { return x * x });
vslet squares = [1, 2, 3].map(x => x * x);
Arrow-funksjoner:
Slutt på that = this
`=>` har leksikalsk `this` istedenfor dynamisk`this`
var that = this,
button = document.getElementById("myButton");
button.addEventListener("click", function() {
that.handleClick();
});
let button = document.getElementById("myButton");
button.addEventListener("click", () => {
this.handleClick();
});
Arrow-funksjoner
Generell form:
(arg1, arg2, ...) => expr
(arg1, arg2, ...) => { statment1; statment2; ...}
Kortversjon - kun en parameter
arg => expr
arg => { statment1; statment2; ...}
Objektorientering
OO: Objektlitteraler
__proto__ gjør det mulig å definere prototypisk arv:
// ECMAScript 6
let obj = {
__proto__: someObject, // special property
myMethod(arg1, arg2) { // method definition
...
}
};
// ECMAScript 5
var obj = Object.create(someObject);
obj.myMethod = function (arg1, arg2) {
...
};
OO: Klasser
ECMAScript 6
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return "(" + this.x + ", " + this.y + ")";
}
}
ECMAScript 5
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return "(" + this.x + ", " + this.y + ")";
};
OO: Subklasser
ECMAScript 6
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color;
}
toString() {
return this.color + " " + super();
}
}
ECMAScript 5
function ColorPoint(x, y, color) {
Point.call(this, x, y);
this.color = color;
}
ColorPoint.prototype = Object.create(Point.prototype);
ColorPoint.prototype.constructor = ColorPoint;
ColorPoint.prototype.toString = function() {
return this.color + " " + Point.prototype.toString.call(this);
};
OO: Statiske metoder
class Point {
static zero() {
return new Point(0, 0);
}
constructor(x, y) {
this.x = x;
this.y = y;
}
}
let p = Point.zero();
Moduler
Moduler: Import og export
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import {sum, pi} from 'lib/math';
alert("2π = " + sum(pi, pi));
// app.js
module Math from 'lib/math';
alert("2π = " + Math.sum(Math.pi, Math.pi));
Moduler: Bundling
module 'lib/math' {
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
}
module 'lib/string' {
export function capitalize(string) {
return string.charAt(0).toUpperCase() + string.substr(1);
}
}
import {sum, pi} from 'lib/math';
import {capitalize} from 'lib/string';
alert("2π = " + sum(pi, pi));
alert(capitalize("evry"));
Moduler: API
- I tillegg til deklarativ syntax finnes det et API for å laste moduler programatisk.
- System.load laster script-filer.
- System.import importerer moduler.
- Syntax ligner AMD
System.import([
'module1',
'module2'
], function (module1, module2) { // success
...
}, function (err) { // failure
...
});
Moduler: Konfigurasjon
APIet har forksjellige "hooks" man kan bruke til f.eks.:
- Tilpasse hvordan modulIDer blir mappet til modulfiler.
- Kjøre f.eks. JSHint på moduler som importeres.
- Automatisk oversette moduler, f.eks. CoffeeScript eller TypeScript
- Bruke f.eks. AMD- eller Nodejsmoduler.
Loader : function(options = {}) -> Loader
options: {
global: Object = Object.create(null),
intrinsics: Loader | null = null,
strict: boolean = false,
normalize: function,
resolve: function,
fetch: function,
translate: function,
link: function
}
Templatestrings
Templatestrings:
Forsøker å løse flere problemer
- Strenger over flere linjer
- Formatering
- HTML-escaping
- Lokalisering
Templatestrings: Syntax
`literal${substitution}literal`
Substitusjon skjer mot variabler tilgjengelig i samme scope som templatestrengen
var name = "Evry",
msg = `Hello, ${name}!`;
console.log(msg); // "Hello, Evry!"
Kan gjøre mer avanserte substitusjoner
var total = 30,
msg = `The total is ${total} (${total*1.25} with tax)`;
console.log(msg); // "The total is 30 (37.5 with tax)"
Templatestrings: Tags
- Forslaget inneholder flere innebygde tags
- safehtml, msg, raw...
- Tag er en funksjon som endrer templatestrengen
- Mulig å lage egne tags
tag`literal${substitution}literal`
someFunc`literal${substitution}literal`
Symboler
Symboler
- Ny primitiv verdi
- Inspirert av bl.a. Lisp, Smalltalk.
- Hvert symbol er unikt
> let sym = Symbol();
> typeof sym
'symbol'
Symboler:
Enum-style-verdier
let red = Symbol();
let green = Symbol();
let blue = Symbol();
function handleColor(color) {
switch(color) {
case red:
...
case green:
...
case blue:
...
}
}
Symboler: Property keys
let specialMethod = Symbol();
let obj = {
// computed property key
[specialMethod]: function (arg) {
...
}
};
obj[specialMethod](123);
- Ingen navnekonflikter
- Konfigurering av objekter for ECMAScript og rammeverk via kjente symboler.
Standardbibliotek
Standardbibliotek: Maps
Enkel lagringsmekanisme for å lagre verdier knyttet til unike nøkler
let map = new Map();
let obj = {};
map.set(obj, 123);
console.log(map.get(obj)); // 123
console.log(map.has(obj)); // true
map.delete(obj);
console.log(map.has(obj)); // false
- Kan iterere over keys, values og items.
- Nøkler må ikke være strenger
Standardbibliotek: Sets
En samling av verdier uten duplikater
let set1 = new Set();
set1.add('hello');
console.log(set1.has('hello')); // true
console.log(set1.has('world')); // false
let set2 = new Set([3,2,1,3,2,3]);
console.log(set2.values()); // 1,2,3
Standardbibliotek: Object.assign
Gir mulighet for å slå sammen objekter
class Point {
constructor(x, y) {
Object.assign(this, { x, y });
}
}
Standardbibliotek:
Nye strengmetoder
# 'abc'.repeat(3)
'abcabcabc'
# 'abc'.startsWith('ab')
true
# 'abc'.endsWith('bc')
true
# 'foobar'.contains('oo')
true
Standardbibliotek:
Nye arraymetoder
# [13, 7, 8].find(x => x % 2 === 0)
8
# [1, 3, 5].find(x => x % 2 === 0)
undefined
# [13, 7, 8].findIndex(x => x % 2 === 0)
2
# [1, 3, 5].findIndex(x => x % 2 === 0)
-1
Standardbibliotek: for-of
- Erstatter
- for-in
- Array.prototype.forEach()
- Virker for iterabler
- Arrays, Maps, Sets
Standardbibliotek: for-of Arrays
let arr = [ 'hello', 'world' ];
for (let elem of arr) {
console.log(elem);
}
Output - elementer, ikke indekser
hello
world
Standardbibliotek: for-of Objekter
key-value
import items from "@iter";
let obj = { first: "Jane", last: "Doe" };
for (let [k,v] of items(obj)) {
console.log(k + " = " + v);
}
Sets
var s = Set([1, 3, 4, 2, 3, 2, 17, 17, 1, 17]);
for (var v of s) {
console.log(v);
}
Maps
let m = new Map;
m.set("one", 1);
m.set("two", 2);
for (let [name, value] of m) {
console.log(`the value of ${name} is ${value}`);
}
Standardbibliotek:
Array comprehension
Brukes for å gjøre en array om til en annen.
let numbers = [1,2,3];
let squares = [for (x of numbers) x * x];
[for (i of document.querySelectorAll('.item'))
i.textContent]
[for (x of a) for (y of b) if (x > y) [x,y]]
tilsvarer
function arrayComprehension() {
let result = [];
for (let x of a) {
for (let y of b) {
if (x > y) {
result.push([x,y]);
}
}
}
return result;
}
Annet
-
Også en del av ECMAScript 6
- Promises
- Bedre støtte for Unicode (strenger, regulæruttrykk)
- Standardmoduler (@iter...)
- Sannsynligvis i ECMAScript 7
- Håndtering av binærdata
- Object.observe()
- Integers (64 bits, 32 bits, osv)
Når?
Tidsplan
- November 2013: siste gjennomgang av utkastet
- July 2014: redaksjonelt ferdig
- Desember 2014: Godkjennes av ECMA
Bruke ECMAScript 6 i dag
- Noen features er allerede på plass i browsere i dag. Flere kommer senere i 2014.
- Traceur fra Google: kompilerer ECMAScript 6 til ECMAScript 5
- Dynamisk on the fly
- statisk via tools
- TypeScript fra Microsoft
- es6-shim: funskjoner fra ECMAScript 6 biblioteket backported til ECMAScript 5.
ECMAScript 6
By Thomas Thorbjørnsen
ECMAScript 6
- 668