Template Literals
Template literals make working with strings easier than ever. They start with a backquote, and variables can be inserted using ${variable}. Compare these two lines of code:
var fName = 'Peter', sName = 'Smith', age = 43, job= 'photographer';
var a = 'Hi, I\'m ' + fName + ' ' + sName + ', I\'m ' + age + ' and work as a ' + job + '.';
var b = `Hi, I'm ${ fName } ${ sName }, I'm ${ age } and work as a ${ job }.`;Copy the code
This makes the job easier and the code easier to read. You can put anything in curly braces: variables, equations, or function calls. I’ll use them in examples throughout this article.
Syntax Block scoping
JavaScript has always been limited by function scope, which is why the entire JavaScript file is wrapped in an empty call-immediate-function expression (IIFE). This is done to isolate all variables in the file, so there is no variable conflict.
Now we have the block scope and two new variable declarations bound to the block.
Let the statement
This is similar to VAR, but with some significant differences. Because it is a block scope, new variables with the same name can be declared without affecting external variables.
var a = 'car' ;
{
let a = 5;
console.log(a) // 5
}
console.log(a) // carCopy the code
Because it is bound to a block scope, it solves the classic interview question: “What is the output, and how do you make it work as you expect?”
for (var i = 1; i < 5; i++){
setTimeout(() => { console.log(i); }, 1000);
}Copy the code
In this case, it prints “5, 5, 5” because the variable I changes with each iteration.
If you replace var with let, everything changes. Each loop now creates a new block scope with the value bound to that loop. You could write it like this:
{let i = 1; setTimeout(() => { console.log(i) }, 1000)}
{let i = 2; setTimeout(() => { console.log(i) }, 1000)}
{let i = 3; setTimeout(() => { console.log(i) }, 1000)}
{let i = 4; setTimeout(() => { console.log(i) }, 1000)} Copy the code
Another difference between var and let is that let is not promoted like VAR.
{
console.log(a); // undefined
console.log(b); // ReferenceError
var a = 'car';
let b = 5;
}Copy the code
Because of its more compact scope and more predictable behavior, some say you should use let instead of VAR, unless you specifically need a boost to var declarations or a looser scope.
Const statement
If you want to declare a constant variable in JavaScript, the convention used to name the variable with block capitalization. However, this does not keep the variable safe-it just lets other developers know that it is a constant and should not be changed.
Now we can use const.
{
const c = "tree";
console.log(c); // tree
c = 46; // TypeError!
}Copy the code
Const does not make a variable immutable, only locks its assignment. If you have a complex assignment (object or array), the value can still be modified.
{
const d = [1, 2, 3, 4];
const dave = { name: 'David Jones', age: 32};
d.push(5);
dave.job = "salesman";
console.log(d); // [1, 2, 3, 4, 5]
console.log(dave); // { age: 32, job: "salesman", name: 'David Jones'}
}Copy the code
Block scope function problems
Function declarations are now specified to bind to the block scope.
{
bar(); // works
function bar() { /* do something */ }
}
bar(); // doesn't workCopy the code
The problem comes when you declare a function in an if statement.
Consider this:
if ( something) { function baz() { console.log('I passed') } } else { function baz() { console.log('I didn\'t pass') } } baz();Copy the code
Prior to ES6, both function declarations were enhanced, regardless of what something was, resulting in ‘I didn’t \’t pass’. Now we get ‘ReferenceError’ because baz is always bound by block scope.
Expansion operator (Spread)
ES6 introduces… Operator, which is called the “expansion operator.” It has two main uses: propagating an array or object into a new array or object, and merging multiple arguments into an array.
The first use case is the most you’re likely to encounter, so let’s look at it first.
let a = [3, 4, 5];
let b = [1, 2, ...a, 6];
console.log(b); // [1, 2, 3, 4, 5, 6]Copy the code
This is useful for passing elements from an array to a function as a set of variables.
function foo(a, b, c) { console.log(`a=${a}, b=${b}, c=${c}`)} let data = [5, 15, 2]; foo( ... data); // a=5, b=15, c=2Copy the code
It can also expand the object, entering each key-value pair into the new object. (Object expansion is actually phase 4 of the proposal and will officially roll out in ES2018, currently only supported with Chrome 60 or later, Firefox 55 or later, and Node 6.4.0 or later)
let car = { type: 'vehicle ', wheels: 4}; let fordGt = { make: 'Ford', ... car, model: 'GT'}; console.log(fordGt); // {make: 'Ford', model: 'GT', type: 'vehicle', wheels: 4}Copy the code
Another feature of the expansion operator is that it creates a new array or object. The following example creates a new array for B, but C just points to the same array.
let a = [1, 2, 3]; let b = [ ...a ]; let c = a; b.push(4); console.log(a); // [1, 2, 3] console.log(b); // [1, 2, 3, 4] references different arrays c.ush (5); console.log(a); // [1, 2, 3, 5] console.log(c); // [1, 2, 3, 5] references the same arrayCopy the code
The second use case is to collect variables together into an array. This is useful when you don’t know how many variables are passed to the function.
function foo(... args) { console.log(args); } foo( 'car', 54, 'tree'); // [ 'car', 54, 'tree' ]Copy the code
The default parameters
Functions can now be defined using default parameters. Missing or undefined values are initialized with default values. Note in particular that null and false values are forced to be 0.
function foo( a = 5, b = 10) {
console.log( a + b);
}
foo(); // 15
foo( 7, 12 ); // 19
foo( undefined, 8 ); // 13
foo( 8 ); // 18
foo( null ); // 10 as null is coerced to 0Copy the code
Default values can be more than just values – they can also be expressions or functions.
function foo( a ) { return a * 4; } function bar( x = 2, y = x + 4, z = foo(x)) { console.log([ x, y, z ]); } bar(); // [ 2, 6, 8 ] bar( 1, 2, 3 ); //[ 1, 2, 3 ] bar( 10, undefined, 3 ); // [10, 14, 3]Copy the code
Deconstruction (Destructuring)
Deconstruction is the process of breaking up the array or object to the left of the equals sign. Arrays or objects can come from variables, functions, or equations.
let [ a, b, c ] = [ 6, 2, 9];
console.log(`a=${a}, b=${b}, c=${c}`); //a=6, b=2, c=9
function foo() { return ['car', 'dog', 6 ]; }
let [ x, y, z ] = foo();
console.log(`x=${x}, y=${y}, z=${z}`); // x=car, y=dog, z=6Copy the code
Object deconstruction lets you list the key of an object in braces to extract the key-value pair.
function bar() { return {a: 1, b: 2, c: 3}; }
let { a, c } = bar();
console.log(a); // 1
console.log(c); // 3
console.log(b); // undefinedCopy the code
Sometimes you want to extract values, but assign them to a new variable. This is done by pairing ‘key: variable’ to the left of the equal sign.
function baz() {
return {
x: 'car',
y: 'London',
z: { name: 'John', age: 21}
};
}
let { x: vehicle, y: city, z: { name: driver } } = baz();
console.log(
`I'm going to ${city} with ${driver} in their ${vehicle}.`
); // I'm going to London with John in their car. Copy the code
It is also important to note that object deconstruction allows multiple variables to be assigned.
let { x: first, x: second } = { x: 4 }; console.log( first, second ); / / 4, 4Copy the code
Object literals and shorthand patterns
When you create an object literal from a variable, ES6 allows you to omit the key if it is the same as the variable name.
let a = 4, b = 7;
let c = { a: a, b: b };
let concise = { a, b };
console.log(c, concise) // {a: 4, b: 7}, {a: 4, b: 7}Copy the code
This can also be used in conjunction with deconstruction to make your code simpler and cleaner.
function foo() { return { name: 'Anna', age: 56, job: { company: 'Tesco', title: 'Manager' } }; } // ES6 let a = foo(), name = a.name, age = a.age, company = a.job.pany; Let {name, age, job: {company}} = foo();Copy the code
It can also be used to deconstruct objects passed to functions. Methods 1 and 2 are how you do it before ES6, and method 3 uses the deconstruction and object literal shorthand patterns.
let person = { name: 'Anna', age: 56, job: { company: 'Tesco', title: 'Manager' } }; Function old1(person) {var yearOfBirth = 2018-person.age; console.log( `${ person.name } works at ${ person.job.company } and was born in ${ yearOfBirth }.`); Function old1(person) {var age = person. Age, yearOfBirth = 2018-age, name = person. company = person.job.company; console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`); Function es6({age, name, job: {company}}) {var yearOfBirth = 2018-age; console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`); }Copy the code
With ES6, we can extract age, name, and company without additional variable declarations.
Dynamic property name
ES6 adds the ability to create or add attributes using dynamically allocated keys.
let city= 'sheffield_';
let a = {
[ city + 'population' ]: 350000
};
a[ city + 'county' ] = 'South Yorkshire';
console.log(a); // {sheffield_population: 350000, sheffield_county: 'South Yorkshire' }Copy the code
Arrow Functions
Arrow functions have two main aspects: structure and this binding.
They can have a simpler structure than traditional functions because they don’t need the function keyword, and they automatically return anything after the arrow.
var foo = function( a, b ) {
return a * b;
}
let bar = ( a, b ) => a * b;Copy the code
If the function needs more than a simple calculation, you can use curly braces, and the function can return anything in the block scope.
let baz = ( c, d ) => {
let length = c.length + d.toString().length;
let e = c.join(', ');
return `${e} and there is a total length of ${length}`;
}Copy the code
One of the most useful places for arrow functions is in array functions like.map,.foreach, or.sort.
et arr = [ 5, 6, 7, 8, 'a' ];
let b = arr.map( item => item + 3 );
console.log(b); // [ 8, 9, 10, 11, 'a3' ]Copy the code
In addition to having a shorter syntax, it also fixes a frequent problem with the this binding behavior around it. The previous ES6 function fixed this by storing the this reference as the self variable.
var clickController = { doSomething: function (..) { var self = this; btn.addEventListener( 'click', function() { self.doSomething(..) }, False ); }};Copy the code
This had to be done before ES6 because the binding of this was dynamic. This means that this in the event listener and this in doSomething do not refer to the same thing.
In the arrow function, this is lexically bound, not dynamically bound. This is the main design feature of arrow functions.
While the lexical binding of this can be handy, sometimes it’s not what you want.
let a = {
oneThing: ( a ) => {
let b = a * 2;
this.otherThing(b);
},
otherThing: ( b ) => {....}
};
a.oneThing(6);Copy the code
When we use a.onthing (6), the this.otherthing (b) reference fails because this does not point to an object a, but to the surrounding scope. Be aware of this if you are rewriting legacy code using ES6 syntax.
The for… Of circulation
ES6 adds a way to iterate over each value in an array. This is different from the existing for… The in loop is different, for… The in loop uses a key/index loop.
let a = ['a', 'b', 'c', 'd' ]; // ES6 for ( var val of a ) { console.log( val ); } for (var idx in a) {console.log(idx); } // 0 1 2 3Copy the code
Use the new for… The of loop is equivalent to adding a let val = a[IDx] within each loop.
Arrays, strings, generators, and collections can all iterate in standard JavaScript. A normal object cannot iterate unless you have defined an iterator for it.
For loop methods in JavaScript see: forEach, for… In the for… of
Number literals
ES5 code handles decimal and hexadecimal number formats well, but does not specify octal format. In fact, it’s banned under strict rules.
ES6 adds a new format that starts with 0, followed by an O that declares the number as octal. Binary formats have also been added.
Number(29) // 29 Number(035) // 35 in old octal form Number(0o35) // 29 in new octal form Number(0x1D) // 29 in hexadecimal form Number( 0b11101) // 29 In binary formatCopy the code
And more…
ES6 gives us more features to make our code cleaner, shorter, easier to read and more powerful. My goal is to write a sequel to this article that will cover lesser-known parts of ES6.
I recommend reading the latest articles on ECMAScript
- Modern JavaScript Reference
- Ten features of ECMAScript 2015 (ES6)
- Getting Started with JavaScript ES6 (ES2015) – Overview of core features
- Examples of new ES6 features
- Five ES6 features you can use now
- Object-oriented JavaScript – Learn more about ES6 classes
- Use Async functions and Await in ES2017
- Quick list of JavaScript ECMAScript 2015 (ES6) and ECMAScript 2016 (ES7) new features
- ECMAScript 6 Modules system and syntax details
- Learn new ES2015 features
- Object inheritance pattern in JavaScript ES2015
- New JavaScript: Exploring ES2016 and ES2017(includes the latest features of ES2016 and ES2017)
The original link: medium.freecodecamp.org/make-your-c…