Some "rules"
See the Pen WWC ES6 Activity - Solution by Liz Shaw (@anythingcodes) on CodePen.
📄 Standard:
✍ Implementation:
📝 We'll implement the new features from version 6 of ECMAScript using JavaScript
Variables defined inside of a function are not accessible from the outside scope
function myFunctionScope() {
var a = 'alpha';
return a;
}
console.log(a); // undefined
Any variables declared within { }
are accessible only within the { }
var myBlockScope = true;
if (myBlockScope) {
var z = 'zeta';
}
console.log(z); // 'zeta'
What is going on here?!
var
ignores block scope and only respects function scope
Unpredictable and hard to control
Use let
and const
instead of var
const
is for constantslet
is for variables whose value will change (Example »)const
by default, but change to let
when you need to change the valuevar
?No 😊
Only one potential case: If you have code that should be available from the global object (window
in browsers), e.g. if you need to access code across frames or windows
👆 This is rare and should generally be avoided
=>
this
keyword
var getMessage = function(name) {
return 'Hello ' + name;
}
const getMessage = name => 'Hello ' + name;
function
=>
) after parameters()
{ }
and return
(implicit return)this
keywordThe this
keyword determines context
const obj = {
name: 'Zeta',
getName: function() {
console.log(this.name);
}
};
obj.getName(); // Zeta
this
One ProblemBinding and changing this
in functions is one of the most common JavaScript errors
It's possible to mistakenly affect one object when you meant to affect another
var self = this;
var _this = this;
var that = this;
🤦
this
problem?See the Pen Arrow functions and `this` by Liz Shaw (@anythingcodes) on CodePen.
this
🌟this
is lexically fetched from the scope the arrow function sits insideSee the Pen Arrow functions and `this` by Liz Shaw (@anythingcodes) on CodePen.
Allow multi-line strings
Great for use with HTML templates
var html = '' +
'Hello ' + str + '!
' +
'';
becomes
const html = `
Hello ${str}!
`;
const message = `User ${name} scored ${score} on the exam`;
` `
) around the string${ }
around any variable or expression${ userIsYoungerThan21 ? serveGrapeJuice() : serveWine() }
const message = `User ${name} ${score >= 60 ? 'passed' : 'failed'} the exam`;
Using ES5, we could establish default parameter values, but there were some flaws
View CodePen »
function makeRequest(url, timeout, callback) {
timeout = timeout || 2000;
// what if timeout is 0?
callback = callback || function() {};
callback();
}
becomes
function makeRequest(url, timeout, callback) {
timeout = (typeof timeout !== 'undefined') ? timeout : 2000;
callback = (typeof callback !== 'undefined') ? callback || function() {};
callback();
}
function makeRequest(url, timeout = 2000, callback = () => {}) {
callback();
}
It's beautiful
Given the following function:
function makeRequest(url, timeout = 2000, callback = () => {}) {
callback();
}
Only url
is required. The following calls all work:
makeRequest('/api');
makeRequest('/api', 500);
makeRequest('/api', 0, requestData => updateDatabase(requestData));
makeRequest('/api', undefined, requestData => updateDatabase(requestData));
Unpack properties from objects into distinct variables
var person = {
name: 'Whitney',
age: 38
};
var name = person.name;
var age = person.age;
console.log(name, age); // Whitney 38
becomes
const person = {
name: 'Whitney',
age: 38
};
const { name, age } = person;
console.log(name, age); // Whitney 38
=
){ }
=
)Array destructuring operates on positions within an array rather than any named properties
var colors = ['red', 'green', 'blue'];
var first = colors[0];
var second = colors[1];
var third = colors[2];
console.log(first, second, third);
// red green blue
becomes
const colors = ['red', 'green', 'blue'];
const [ first, second, third ] = colors;
console.log(first, second, third);
// red green blue
=
)[]
=
)Tons of new methods that can be applied to arrays
Array Helper | Use it to... | Returns | |
---|---|---|---|
✔️ | arr.forEach((element, index, array) => { }); |
loop through elements in an array | undefined |
️ | arr.every((element, index, array) => { }); |
check if every element passes a test | true||false |
arr.some((element, index, array) => { }); |
check if some (at least 1) arr elements pass a test |
true||false |
|
arr.filter((element, index, array) => { }); |
create a new array by filtering the original array elements | Array |
|
✔️ | arr.map((element, index, array) => { }); |
create a new array by modifying the original array elements | Array |
✔️ | arr.find((element, index, array) => { }); |
find the first element that passes a test | 1 element |
arr.findIndex((element, index, array) => { }); |
find the index of the first element that passes a test | 1 element | |
✔️ | arr.reduce((calculatedValue, element, index, array) => { }, initialValue); |
pass in an initialValue and modify it according to the current element value |
1 reduced value |
Array Helper | Use it to... | Returns |
---|---|---|
arr.forEach((element, index, array) => { }); |
loop through elements in an array | undefined |
var names = ['Morgan', 'Taylor', 'Lesley'];
for (var i = 0; i < names.length; i++) {
console.log(names[i]);
}
const names = ['Morgan', 'Taylor', 'Lesley'];
names.forEach(function(name, index, array) {
console.log(name);
});
arr.forEach(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
numbers.forEach(function(number, index, array) {
console.log(number > 50); // can you get this on one line?
});
The iterator function runs once for each element in the array
Array Helper | Use it to... | Returns |
---|---|---|
arr.map((element, index, array) => { }); |
create a new array by modifying the original array elements | Array |
You can assign the resulting array to a variable:const modifiedArr = arr.map(iteratorFunction);
var numbers = [2, 6, 10];
var halvedNumbers = [];
for (var i = 0; i < numbers.length; i++) {
halvedNumbers.push(numbers[i] / 2);
}
console.log(halvedNumbers); // 1, 3, 5
const numbers = [2, 6, 10];
const halvedNumbers = numbers.map(number => number / 2);
console.log(halvedNumbers); // 1, 3, 5
No need to create an empty array first! 🎉
arr.map(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
const decrementedNumbers = numbers.map(number => number - 1);
console.log(decrementedNumbers); // [ 122, 499, -51, 81, 7 ]
The iterator function runs once for each element in the array
Be sure to return a value each iteration!
Array Helper | Use it to... | Returns |
---|---|---|
arr.find((element, index, array) => { }); |
find the first element that passes a test | 1 element |
const matchingObject = arr.find(iteratorFunction);
var jobs = [
{ title: 'Electrician' },
{ title: 'Developer' },
{ title: 'Barista' }
];
var devJob;
for (var i = 0; i < jobs.length; i++) {
if (jobs[i].title === 'Developer') {
devJob = jobs[i];
break;
}
}
console.log(devJob); // { title: 'Developer' }
const jobs = [
{ title: 'Electrician' },
{ title: 'Developer' },
{ title: 'Barista' }
];
const devJob = jobs.find(job => job.title === 'Developer');
console.log(devJob); // { title: 'Developer' }
arr.find(iteratorFunction)
const jobs = [
{ title: 'Electrician' },
{ title: 'Developer' },
{ title: 'Barista' }
];
const devJob = jobs.find(job => job.title === 'Developer');
console.log(devJob); // { title: 'Developer' }
Runs until the iterator function returns true
. When it does, the element at that index is returned.
find()
Practical ExampleArray Helper | Use it to... | Returns |
---|---|---|
arr.reduce((calculatedValue, element, index, array) => { }, initialValue); |
pass in an initialValue and modify it according to the current element value |
1 reduced value |
const reducedValue = arr.reduce(iteratorFunction, initialValue);
var numbers = [2, 6, 10];
var sum = 0;
for (var i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
console.log(sum); // 18
const numbers = [2, 6, 10];
const sum = numbers.reduce(function(currentSum, number) {
return currentSum + number;
}, 0);
console.log(sum); // 18
arr.reduce(iteratorFunction, initialValue);
const numbers = [1, 5, 10];
const sum = numbers.reduce(function(calculatedValue, number) {
return calculatedValue + number;
}, 0); // 0 is the initialValue
console.log(sum); // 16
The fetch()
helper is used for AJAX requests
The initial return value is the Response object; use chaining and the .json()
method to get the JSON you need
fetch('http://json.com')
.then(serverResponse => serverResponse.json())
.then(json => console.log(json))
.catch(err => console.log(err));
function Vehicle(type) {
this.type = type;
}
Vehicle.prototype.logType = function() {
console.log(this.type);
};
var car = new Vehicle('car');
car.logType(); // 'car'
console.log(car instanceof Vehicle); // true
console.log(car instanceof Object); // true
called "creating a custom type"
class Vehicle {
constructor(type) {
this.type = type;
}
logType() {
console.log(this.type);
}
}
const car = new Vehicle('car');
car.logType(); // 'car'
console.log(car instanceof Vehicle); // true
console.log(car instanceof Object); // true
You don't need commas between the elements of a class
Derived classes: Classes that inherit from other classes
Within the derived class's class {}
definition, use the extends
keyword to specify the base class. Then access the base class constructor by calling super()
.
class Rectangle {
constructor(length, width) {
this.length = length;
this.width = width;
}
getArea() {
return this.length * this.width;
}
}
class Square extends Rectangle {
constructor(length) {
super(length, length); // calls the base class constructor
}
}
const square = new Square(5);
console.log(square.getArea()); // 25
Check the "Workshop Instructions" section of the printed handout, or go to http://tinyurl.com/wwc-activity
const getMessage = () => 'Hello World';
Waiting...
babel-preset-env
instead of babel-preset-latest
)
babel-preset-env
instead of babel-preset-es2015
)