- Published on
ES2015/ES6 features
var/let and const
The difference between var and let is scoping. var is scoped to the nearest function block and let is scoped to the nearest enclosing block (both are global if outside any block), which can be smaller than a function block. Also, variables declared with let are not visible before they are declared in their enclosing block.
var
function varTest() {
var x = 31
if (true) {
var x = 71 // same variable!
console.log(x) // 71
}
console.log(x) // 71
}
let
function letTest() {
let x = 31
if (true) {
let x = 71 // different variable
console.log(x) // 71
}
console.log(x) // 31
}
const
const MY_FAV = 7
MY_FAV = 20 //fails FF, Chrome, not Safari
console.log('my favorite number is: ' + MY_FAV) // 7
const MY_FAV = 20 //throws
var MY_FAV = 20 //throws
console.log('my favorite number is ' + MY_FAV) // 7
You can modify the contents of an object (check the last line of this example).
const FOO; // SyntaxError: missing = in const declaration
const MY_OBJECT = {"key": "value"}; // works
//fails FF, Chrome, not Safari
MY_OBJECT = {"OTHER_KEY": "value"};
// Object attributes are not protected
MY_OBJECT.key = "otherValue";
Arrow functions
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous.
// Arrow functions are all bound to this
(a1, a2, aN) => { foos } // function(a1, a2, aN) { foos }
// implicit return
(a1, a2, aN) => a1 + a2 // function(a1, a2, aN) { return a1 + a2 }
// Parentheses are optional when there's one parameter
(singleParam) => { statements }
singleParam => { statements }
Object Literal Extensions
Object literals are extended to support setting the prototype at construction, shorthand for foo: foo assignments, defining methods, making super calls, and computing property names with expressions. Together, these also bring object literals and class declarations closer together, and let object-based design benefit from some of the same conveniences.
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return 'd ' + super.toString()
},
// Computed (dynamic) property names
['prop_' + (() => 42)()]: 42,
}
String templating
console.log('string text line 1\n string text line 2')
// is equal to
console.log(`string text line 1
string text line 2`)
var a = 5,
b = 10
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`)
Data structures
Set
let s = new Set()
s.add('hello').add('hello').add({ action: 'goodbye' })
s.size === 2
s.has('hello') === true
for (let key of s.values()) // insertion order
console.log(key)
Map
let s = { foo: 'bar' }
let m = new Map()
m.set('hello', 42)
m.set(s, 34)
m.get(s) === 34
m.size === 2
for (let [key, val] of m.entries()) console.log(key + ' = ' + val)
WeakSet
let thingToDelete = {}
let ws = new WeakSet()
ws.set(thingToDelete) //cannot be primitive
ws.has(thingToDelete) === true
thingToDelete = null
ws.has(thingToDelete) === false
There's more
Classes
JavaScript classes are introduced in ECMAScript 6 and are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.
The next example will show the same thing written using the old syntax and then with the new class syntax.
function Animal(name) {
this.name = name
}
Animal.prototype.speak = function () {
console.log(this.name + ' makes a noise.')
}
class Animal {
constructor(name) {
this.name = name
}
speak() {
console.log(this.name + ' makes a noise.')
}
}
Promises
// From Jake Archibald's Promises and Back:
// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest
function get(url) {
// Return a new promise.
return new Promise(function (resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest()
req.open('GET', url)
req.onload = function () {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// Resolve the promise with the response text
resolve(req.response)
} else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText))
}
}
// Handle network errors
req.onerror = function () {
reject(Error('Network Error'))
}
// Make the request
req.send()
})
}
// Use it!
get('story.json').then(
function (response) {
console.log('Success!', response)
},
function (error) {
console.error('Failed!', error)
}
)
Stuff I'll cover later (hopefully)
- Symbols
- Generators
- Destructuring
- Proxies