preface

  1. Here “ES6” refers to the new grammar after ES5
  2. By “complete” I mean that this article will be updated continuously
  3. By “use,” I mean that this article will show you a number of ES6 usage scenarios
  4. By “manual” I mean that you can refer to this article to refactor the project more into ES6 syntax

Also note that this is not necessarily formal syntax into the specification.

1. Let and const

At the time of development, we probably thought we should default to let instead of var, in which case we would use const for variables that need write protection.

Another approach, however, is gaining popularity: use const by default, and use let only when you really need to change the value of a variable. This is because most variable values should not change after initialization, and unexpected variable changes are the source of many bugs.

/ / example 1-1

// bad
var foo = 'bar';

// good
let foo = 'bar';

// better
const foo = 'bar';
Copy the code

2. Template characters

1. Template characters

When concatenating strings, try to use template strings instead:

/ / example 2-1

// bad
const foo = 'this is a' + example;

// good
const foo = `this is a ${example}`;
Copy the code

2. Label template

You can use the tag template to optimize the writing:

2-2 / / examples

let url = oneLine `
    www.taobao.com/example/index.html
    ?foo=${foo}
    &bar=${bar}
`;

console.log(url); // www.taobao.com/example/index.html?foo=foo&bar=bar
Copy the code

OneLine source code can refer to “ES6 series of template strings”

3. Arrow function

Use arrow functions preferentially, but avoid them in the following cases:

1. Use arrow functions to define object methods

/ / example 3-1

// bad
let foo = {
  value: 1.getValue: (a)= > console.log(this.value)
}

foo.getValue();  // undefined
Copy the code

2. Define the prototype method

/ / example 3 to 2

// bad
function Foo() {
  this.value = 1
}

Foo.prototype.getValue = (a)= > console.log(this.value)

let foo = new Foo()
foo.getValue();  // undefined
Copy the code

3. As a callback function to the event

/ / example 3 to 3

// bad
const button = document.getElementById('myButton');
button.addEventListener('click', () = > {console.log(this= = =window); // => true
    this.innerHTML = 'Clicked button';
});
Copy the code

4. Symbol

1. The only value

4-1 / / examples


// bad
// 1. The properties created are enumerated by for-in or object.keys ()
// 2. Some libraries may use the same approach in the future, which will conflict with your code
if (element.isMoving) {
  smoothAnimations(element);
}
element.isMoving = true;

// good
if (element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__) {
  smoothAnimations(element);
}
element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__ = true;

// better
var isMoving = Symbol("isMoving"); . if (element[isMoving]) { smoothAnimations(element); } element[isMoving] =true;
Copy the code

2. Magic string

A magic string is a specific string or number that appears multiple times in code and is strongly coupled to the code.

Magic string is not conducive to modification and maintenance, good style of code, should try to eliminate the magic string, replaced by clear meaning of the variable.

4-1 / / examples

// bad
const TYPE_AUDIO = 'AUDIO'
const TYPE_VIDEO = 'VIDEO'
const TYPE_IMAGE = 'IMAGE'

// good
const TYPE_AUDIO = Symbol(a)const TYPE_VIDEO = Symbol(a)const TYPE_IMAGE = Symbol(a)function handleFileResource(resource) {
  switch(resource.type) {
    case TYPE_AUDIO:
      playAudio(resource)
      break
    case TYPE_VIDEO:
      playVideo(resource)
      break
    case TYPE_IMAGE:
      previewImage(resource)
      break
    default:
      throw new Error('Unknown type of resource')}}Copy the code

3. Private variables

Symbol can also be used for private variable implementations.

/ / example 4 to 3

const Example = (function() {
    var _private = Symbol('private');

    class Example {
        constructor() {
          this[_private] = 'private';
        }
        getName() {
          return this[_private]; }}returnExample; }) ();var ex = new Example();

console.log(ex.getName()); // private
console.log(ex.name); // undefined
Copy the code

5. Set and Map

1. De-duplicate arrays

5-1 / / examples

[...new Set(array)]
Copy the code

2. Optimization of conditional statements

/ / example 5-2
// Find the corresponding fruit according to the color

// bad
function test(color) {
  switch (color) {
    case 'red':
      return ['apple'.'strawberry'];
    case 'yellow':
      return ['banana'.'pineapple'];
    case 'purple':
      return ['grape'.'plum'];
    default:
      return [];
  }
}

test('yellow'); // ['banana', 'pineapple']
Copy the code
// good
const fruitColor = {
  red: ['apple'.'strawberry'].yellow: ['banana'.'pineapple'].purple: ['grape'.'plum']};function test(color) {
  return fruitColor[color] || [];
}
Copy the code
// better
const fruitColor = new Map()
  .set('red'['apple'.'strawberry'])
  .set('yellow'['banana'.'pineapple'])
  .set('purple'['grape'.'plum']);

function test(color) {
  return fruitColor.get(color) || [];
}
Copy the code

6. for of

1. Traversal the range

for… The scope of the of loop includes:

  1. An array of
  2. Set
  3. Map
  4. Array-like objects such as arguments object, DOM NodeList object
  5. The Generator object
  6. string

Advantage of 2.

ES2015 introduces for.. Of loop, which combines the brevity of forEach with the ability to break loops:

6-1 / / examples

for (const v of ['a'.'b'.'c']) {
  console.log(v);
}
// a b c

for (const [i, v] of ['a'.'b'.'c'].entries()) {
  console.log(i, v);
}
// 0 "a"
// 1 "b"
// 2 "c"
Copy the code

3. The traverse Map

/ / example 6-2

let map = new Map(arr);

// Iterate over key values
for (let key of map.keys()) {
  console.log(key);
}

// Iterate over the value
for (let value of map.values()) {
  console.log(value);
}

// Iterate over key and value values (1)
for (let item of map.entries()) {
  console.log(item[0], item[1]);
}

// Iterate over key and value (2)
for (let [key, value] of data) {
  console.log(key)
}
Copy the code

7. Promise

1. Basic example

7-1 / / examples

// bad
request(url, function(err, res, body) {
    if (err) handleError(err);
    fs.writeFile('1.txt', body, function(err) {
        request(url2, function(err, res, body) {
            if (err) handleError(err)
        })
    })
});

// good
request(url)
.then(function(result) {
    return writeFileAsynv('1.txt', result)
})
.then(function(result) {
    return request(url2)
})
.catch(function(e){
    handleError(e)
});
Copy the code

2. finally

7 to 2 / / examples

fetch('file.json')
.then(data= > data.json())
.catch(error= > console.error(error))
.finally((a)= > console.log('finished'));
Copy the code

8. Async

1. More concise code

8-1 / / examples

// good
function fetch() {
  return (
    fetchData()
    .then((a)= > {
      return "done"}); }// better
async function fetch() {
  await fetchData()
  return "done"
};
Copy the code
/ / example 8-2

// good
function fetch() {
  return fetchData()
  .then(data= > {
    if (data.moreData) {
        return fetchAnotherData(data)
        .then(moreData= > {
          return moreData
        })
    } else {
      return data
    }
  });
}

// better
async function fetch() {
  const data = await fetchData()
  if (data.moreData) {
    const moreData = await fetchAnotherData(data);
    return moreData
  } else {
    return data
  }
};
Copy the code
/ / example 8-3

// good
function fetch() {
  return (
    fetchData()
    .then(value1= > {
      return fetchMoreData(value1)
    })
    .then(value2= > {
      return fetchMoreData2(value2)
    })
  )
}

// better
async function fetch() {
  const value1 = await fetchData()
  const value2 = await fetchMoreData(value1)
  return fetchMoreData2(value2)
};
Copy the code

2. Error handling

/ / example 8-4

// good
function fetch() {
  try {
    fetchData()
      .then(result= > {
        const data = JSON.parse(result)
      })
      .catch((err) = > {
        console.log(err)
      })
  } catch (err) {
    console.log(err)
  }
}

// better
async function fetch() {
  try {
    const data = JSON.parse(await fetchData())
  } catch (err) {
    console.log(err)
  }
};
Copy the code

3. “Async Hell”

8-5 / / examples

// bad
(async() = > {const getList = await getList();
  const getAnotherList = awaitgetAnotherList(); }) ();// good
(async() = > {const listPromise = getList();
  const anotherListPromise = getAnotherList();
  await listPromise;
  awaitanotherListPromise; }) ();// good
(async() = > {Promise.all([getList(), getAnotherList()]).then(...) ; }) ();Copy the code

9. Class

Constructors use the Class form whenever possible

9-1 / / examples

class Foo {
  static bar () {
    this.baz();
  }
  static baz () {
    console.log('hello');
  }
  baz () {
    console.log('world');
  }
}

Foo.bar(); // hello
Copy the code
9-2 / / examples

class Shape {
  constructor(width, height) {
    this._width = width;
    this._height = height;
  }
  get area() {
    return this._width * this._height; }}const square = new Shape(10.10);
console.log(square.area);    / / 100
console.log(square._width);  / / 10
Copy the code

10.Decorator

1. log

/ / example 10 to 1

class Math {
  @log
  add(a, b) {
    returna + b; }}Copy the code

The implementation of log can be seen in ES6 Series, Let’s talk about Decorators.

2. autobind

/ / example 10-2

class Toggle extends React.Component {

  @autobind
  handleClick() {
    console.log(this)
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        button
      </button>); }}Copy the code

The implementation of Autobind can be seen in ES6 Series: Let’s Talk about Decorators

3. debounce

10-3 / / examples

class Toggle extends React.Component {

  @debounce(500.true)
  handleClick() {
    console.log('toggle')
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        button
      </button>); }}Copy the code

The implementation of Debounce can be seen in ES6 Series: Let’s Talk about Decorators

4. React with the story

/ / example 10-4

// good
class MyReactComponent extends React.Component {}

export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);

// better
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {};
Copy the code

Function of 11.

1. The default value

11-1 / / examples

// bad
function test(quantity) {
  const q = quantity || 1;
}

// good
function test(quantity = 1) {... }Copy the code
11-2 / / examples

doSomething({ foo: 'Hello'.bar: 'Hey! '.baz: 42 });

// bad
function doSomething(config) {
  constfoo = config.foo ! = =undefined ? config.foo : 'Hi';
  constbar = config.bar ! = =undefined ? config.bar : 'Yo! ';
  constbaz = config.baz ! = =undefined ? config.baz : 13;
}

// good
function doSomething({ foo = 'Hi', bar = 'Yo! ', baz = 13 }) {... }// better
function doSomething({ foo = 'Hi', bar = 'Yo! ', baz = 13 } = {}) {... }Copy the code
11-3 / / examples

// bad
const Button = ({className}) = > {
	const classname = className || 'default-size';
	return <span className={classname}></span>
};

// good
const Button = ({className = 'default-size'}) = > (
	<span className={classname}></span>
);

// better
const Button = ({className}) = >
	<span className={className}></span>
}

Button.defaultProps = {
	className: 'default-size'
}
Copy the code
11-4 / / examples

const required = (a)= > {throw new Error('Missing parameter')};

const add = (a = required(), b = required(a)) = > a + b;

add(1.2) / / 3
add(1); // Error: Missing parameter.
Copy the code

12. Expand operators

1. Convert arguments to array

/ / 12-1 example

// bad
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// good
const sortNumbers = (. numbers) = > numbers.sort();
Copy the code

2. Call parameters

12-2 / / examples

// bad
Math.max.apply(null[14.3.77])

// good
Math.max(... [14.3.77])
/ / is equivalent to
Math.max(14.3.77);
Copy the code

3. Build objects

Remove some of the properties and build a new object with the remaining properties

12-3 / / examples
let [a, b, ...arr] = [1.2.3.4.5];

const{ a, b, ... others } = {a: 1.b: 2.c: 3.d: 4.e: 5 };
Copy the code

Conditional build objects

/ / example 12-4

// bad
function pick(data) {
  const { id, name, age} = data

  const res = { guid: id }

  if (name) {
    res.name = name
  }
  else if (age) {
    res.age = age
  }

  return res
}

// good
function pick({id, name, age}) {
  return {
    guid: id, ... (name && {name}), ... (age && {age}) } }Copy the code

Merge objects

12-5 / / examples

let obj1 = { a: 1.b: 2.c: 3 }
let obj2 = { b: 4.c: 5.d: 6}
letmerged = {... obj1, ... obj2};Copy the code

4. React

Pass all objects into the component

/ / example 12-6

const parmas =  {value1: 1.value2: 2.value3: 3} <Test {... parmas} />Copy the code

13. Double colon operator

13-1 / / examples

foo::bar;
/ / is equivalent tobar.bind(foo); foo::bar(... arguments);/ / is equivalent to
bar.apply(foo, arguments);
Copy the code

If the left side of the double colon is empty and the right side is an object’s method, then the method is bound to the object.

13-2 / / examples

var method = obj::obj.foo;
/ / is equivalent to
var method = ::obj.foo;

let log = ::console.log;
/ / is equivalent to
var log = console.log.bind(console);
Copy the code

14. Deconstruct the assignment

1. Basic deconstruction of objects

14-1 / / examples

componentWillReceiveProps(newProps) {
	this.setState({
		active: newProps.active
	})
}

componentWillReceiveProps({active}) {
	this.setState({active})
}
Copy the code
14-2 / / examples

// bad
handleEvent = (a)= > {
  this.setState({
    data: this.state.data.set("key"."value")})};// good
handleEvent = (a)= > {
  this.setState(({data}) = > ({
    data: data.set("key"."value")}}));Copy the code
14-3 / / examples

Promise.all([Promise.resolve(1), Promise.resolve(2)])
.then(([x, y]) = > {
    console.log(x, y);
});
Copy the code

2. Deep deconstruction of objects

14-4 / / examples

// bad
function test(fruit) {
  if (fruit && fruit.name)  {
    console.log (fruit.name);
  } else {
    console.log('unknown'); }}// good
function test({name} = {}) {
  console.log (name || 'unknown');
}
Copy the code
14-5 / / examples

let obj = {
    a: {
      b: {
        c: 1}}};const {a: {b: {c = ' '} = ' '} = ' '} = obj;
Copy the code

3. Array deconstruction

14-6 / / examples

// bad
const spliteLocale = locale.splite("-");
const language = spliteLocale[0];
const country = spliteLocale[1];

// good
const [language, country] = locale.splite(The '-');
Copy the code

4. Rename variables

/ / example 14-8

let { foo: baz } = { foo: 'aaa'.bar: 'bbb' };
console.log(baz); // "aaa"
Copy the code

5. Obtain only some attributes

/ / example 14-9

function test(input) {
  return [left, right, top, bottom];
}
const [left, __, top] = test(input);

function test(input) {
  return { left, right, top, bottom };
}
const { left, right } = test(input);
Copy the code

Enhanced object literals

15-1 / / examples

// bad
const something = 'y'
const x = {
  something: something
}

// good
const something = 'y'
const x = {
  something
};
Copy the code

Dynamic properties

15-2 / / examples

const x = {
  ['a' + '_' + 'b'] :'z'
}

console.log(x.a_b); // z
Copy the code

16. Extension methods for arrays

1. keys

/ / 16-1 example

var arr = ["a"."c"];

var sparseKeys = Object.keys(arr);
console.log(sparseKeys); / / / '0', '2'

var denseKeys = [...arr.keys()];
console.log(denseKeys);  / / [0, 1, 2]
Copy the code

2. entries

16-2 / / examples

var arr = ["a"."b"."c"];
var iterator = arr.entries();

for (let e of iterator) {
    console.log(e);
}
Copy the code

3. values

16-3 / / examples

let arr = ['w'.'y'.'k'.'o'.'p'];
let eArr = arr.values();

for (let letter of eArr) {
  console.log(letter);
}
Copy the code

4. includes

/ / 16-4 examples

// bad
function test(fruit) {
  if (fruit == 'apple' || fruit == 'strawberry') {
    console.log('red'); }}// good
function test(fruit) {
  const redFruits = ['apple'.'strawberry'.'cherry'.'cranberries'];
  if (redFruits.includes(fruit)) {
    console.log('red'); }}Copy the code

5. find

16-5 / / examples

var inventory = [
    {name: 'apples'.quantity: 2},
    {name: 'bananas'.quantity: 0},
    {name: 'cherries'.quantity: 5}];function findCherries(fruit) {
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
Copy the code

6. findIndex

/ / example 16-6

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false; }}return element >1; } console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found console.log([4, 6, 7, 12].findIndex(isPrime)); / / 2Copy the code

I won’t list more.

17. optional-chaining

Here’s an example:

17-1 / / examples

const obj = {
  foo: {
    bar: {
      baz: 42,}}};constbaz = obj? .foo? .bar? .baz;/ / 42
Copy the code

Also support functions:

17-2 / / examples

function test() {
  return 42; } test? . ();/ / 42exists? . ();// undefined
Copy the code

Add @babel/plugin-proposal-optional-chaining plugin support

18. logical-assignment-operators

18-1 / / examples

a ||= b;

obj.a.b ||= c;

a &&= b;

obj.a.b &&= c;
Copy the code

Babel compiles to:

var _obj$a, _obj$a2;

a || (a = b);

(_obj$a = obj.a).b || (_obj$a.b = c);

a && (a = b);

(_obj$a2 = obj.a).b && (_obj$a2.b = c);
Copy the code

Reasons for occurrence:

18-2 / / examples

function example(a = b) {
  // a must be undefined
  if (!a) {
    a = b;
  }
}

function numeric(a = b) {
  // A must be null or undefined
  if (a == null) { a = b; }}// A can be any falsy value
function example(a = b) {
  // Yes, but the setter must be triggered
  a = a || b;

  // Setters are not triggered, but lint errors may result
  a || (a = b);

  // This is the way to write:
  a ||= b;
}
Copy the code

Requires @babel/ plugin-proposal-logical-cellar-Operators plugin support

19. nullish-coalescing-operator

a ?? b

/ / equivalent to(a ! = =null&& a ! = =void 0)? a : bCopy the code

Here’s an example:

var foo = object.foo ?? "default";

/ / equivalent to

varfoo = (object.foo ! =null)? object.foo :"default";
Copy the code

The @babel/plugin-proposal-nullish-coalescing-operator plug-in is required

20. pipeline-operator

const double = (n) = > n * 2;
const increment = (n) = > n + 1;

// Do not use the pipe operator
double(increment(double(5))); / / 22

// After the pipe operator
5 |> double |> increment |> double; / / 22
Copy the code

other

The new zhihu column, you can see my articles on more platforms, welcome to pay attention to oh ~

reference

  1. ES6 Practices
  2. Babel 7 Simple Upgrade Guide
  3. Must know ES6 tips
  4. Delve into ES6: Symbol
  5. When can you not use the arrow function?
  6. A few tips to make JavaScript more concise
  7. 8 JavaScript methods to improve your skills in minutes
  8. How to conditionally construct objects using JavaScript ES6
  9. Here are 5 tips for making conditional statements in JavaScript(ES6) better
  10. A major feature of ES6 — JavaScript Complete Manual (2018 edition)

ES6 series

ES6 series directory address: github.com/mqyqingfeng…

ES6 series is expected to write about 20 articles, aiming to improve the understanding of ES6 part of the knowledge, focusing on block-level scope, tag template, arrow function, Symbol, Set, Map and Promise simulation implementation, module loading scheme, asynchronous processing and other content.

If there are any mistakes or irregularities, please be sure to correct them. Thank you very much. If you like it or have some inspiration, welcome star, which is also a kind of encouragement to the author.