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…