ECMASCRIPT6 has recently entered the RC phase, and as early as in its community discussions, I have been trying to use ES6 to develop the solution. After the launch of Babel, ES6-based development also has a concrete executable solution, both build and debug can be well supported.
With ample environment and tools, we are faced with the choice and analysis of many new features of ES6, so that we can choose an optimal subset, allowing us to enjoy the convenience of ES6 (reduce the amount of code, improve readability, etc.), but also run smoothly in the current ES3-ES5-based browser environment.
After analysis, this paper tries to find out whether the ES6 is suitable for the application, and explains its usage scene. The ES6 feature List is selected from Es6features.
- ★ Recommended Use
- ★ To be considered for use
- ★ Use wisely
- ☆ Do not use
features |
Recommended Level |
Arrows |
¡ï ★ |
Classes |
¡ï ★ |
Enhanced Object literals |
¡ï ★ |
Template strings |
¡ï ★ |
Destructuring |
★ |
Default + rest + spread |
¡ï ★ |
Let + const |
¡ï ★ |
Iterators + for: Of |
★ |
Generators |
★ |
Unicode |
☆ |
Modules |
★ |
Module Loaders |
☆ |
Map + set + Weakmap + Weakset |
★ |
Proxies |
☆ |
Symbols |
★ |
Subclassable built-ins |
☆ |
Promises |
¡ï ★ |
Math + number + string + Array + object APIs |
¡ï ★ |
Binary and octal literals |
★ |
Reflect API |
☆ |
Tail calls |
★ |
Next, we describe each of these features. One thing to focus on: If you don't want to use the shim library (such as Babel's browser-polyfill.js
and generatorsRuntime.js
) or want to use as few helpers as possible (Babel externalHelpers
configuration), then you need to further reduce the ES6 features you can use, such as Map
, Set
These should not be used.
Syntax Enhancement class arrow function
Arrow functions is a good feature of ES6 's syntax, which features:
- The syntax is more concise.
- A fixed object on a grammar
this
.
We encourage the use of arrow functions in the available scenarios, replacing the original function
keyword.
Of course, arrow functions is not all-powerful, in some special scenes is not very suitable, the most typical is that arrow functions can not provide the function name, so it is not convenient to do recursive merge. Although you can use Y-combinator to implement functional recursion, there is a significant loss of readability.
In conjunction with the object literal enhancements that will be mentioned later, we now define methods/functions in a number of ways, and it is recommended to execute the following specifications:
All arrow functions parameters are wrapped in parentheses ()
, even if there is only one parameter:
// Goodlet foo = (x) => x + 1;// Badlet foo = x => x + 1;
The definition function uses arrow functions instead of the keyword as far as possible function
:
// Goodlet foo = () => { // code};// Badfunction foo() { // code}// Badlet foo = function () { // code}
Unless the current scenario is inappropriate with arrow functions, such as a function expression that requires self-recursion, objects that require runtime variability, this
and so on.
For methods in objects, classes, use enhanced object literals:
// Goodlet foo = { bar() { // code }};// Badlet foo = { bar: () => { // code }};// Badlet foo = { bar: function () { // code }};
Enhanced Object literals
The enhancement of the object literal is mainly embodied in 3 aspects:
You can define the method directly in the object
Let Foo = { Bar () { Code } };
|
We recommend defining methods in this way.
You can use the calculated key value
We recommend that you use the computed key values when needed to complete the declaration of the entire object in a single statement.
Abbreviated with the variable of the same name in the current scope
' Bar '; Let Foo = { Equivalent to Bar:bar };
|
We do not recommend this usage, which is not helpful for readability.
Template string
The main role of a template string is 2:
Multi-line string
Let HTML = ' <div> <P>hello World</p> </div> '
|
As you can see from the code above, alignment is a tricky thing when you actually use a multiline string. If let html
the line itself is indented, it will make the code more uncomfortable.
So we don't recommend using multi-line strings , we can use arrays and mates if necessary join(‘‘)
, and we should try to use the template engine as much as possible to generate HTML scenes.
String variable substitution
Let message = ' Hello ${name}, it's${time} now ';
|
This is a very handy feature that we encourage to use . Note, however, that these variables are not escaped by HTML, so use the template engine or other template functions in a scenario where HTML escaping is required.
Deconstruction
Deconstruction (forgive me for not having a good translation) is a more complicated grammar, such as:
Let [foo, bar] = [2]; Let {ID, name, children} = Gettreeroot ();
|
You can also have more complex documents that can refer to MDN.
For such a complex and changeable syntax, we have to use it selectively, and we recommend the following principles:
- Do not define too many variables at once by deconstructing, no more than 5 are recommended.
- Caution Uses the "residual" function in deconstruction, which is the
let [foo, bar, ...rest] = getValue()
way.
- Do not use the deep level in object deconstruction, it is recommended not to exceed 2 layers.
function parameter Enhancement
ES6 provides functionality for function parameters, such as default values, remaining parameters, and allows you to expand the array to parameters when calling a function, such as:
var foo = (x =1) + = x +1; Foo ();2
var extend = (source, ... args) = = { for (let target in args) { for (let name in Object.keys (target) { if (!source.hasownproperty (name) { Source[name] = Target[name]; " var extensions = [ {name: Span class= "string", "Zhang", 17}, ' hard '} ; extend ({}, ... extensions); |
We encourage the use of these features to make the Declaration and invocation of functions more concise , but there are some details to note:
- When using default parameters, if the default value of the parameter is fixed and not modified, it is recommended to use a constant as the default value to avoid the overhead of each generation.
- Do not
arguments
use an expansion operation on an object, this is not an array.
Keyword class let and const
This is the 2 keyword used to define a variable, which is known to let
represent a block-scoped variable and const
represents a constant.
It is important to note that const
this variable cannot be assigned again, but does not imply that the variable is an object or an array whose contents cannot be changed. If you need an object or array that cannot change the content, use the Object.freeze
method to define a true constant:
However, if you can control the object without modification in the program, it does not have any meaning, Object.freeze
whether it will cause further optimization of the execution engine has not been confirmed.
We recommend using a let
full var
replacement . It is also recommended to use const
only if it is logically constant , and not for any scenarios that are not assigned two times const
.
Iterators and for: Of
Iterators are a good thing, at least we can easily iterate over the group:
But the iterator itself has some minor drawbacks:
- Performance is slightly worse, for the array is roughly the same as
Array.prototype.forEach
, compared to the native for
loop.
- You cannot get the indexed value in the loop body
i
, so you can only use the native loop if you need an index for
.
- It is annoying to judge whether an object can be iterated, there is no native method to provide, and it needs to be judged by itself
typeof o[Symbol.iterator] === ‘function‘
.
For iterators, we encourage the use and substitution of native for
loops , and we recommend the following guidelines:
- For loop operations with only one statement, it is recommended
forEach
to use the method, with arrow functions to write the loop logic in a single line very simply.
- For looping operations on multiple statements, it is recommended that you use
for..of
loops.
- For a looping scenario, you need to be aware of objects that are not arrays but can be iterated, such as and so on, so that in
Map
Set
addition to such arguments
objects, it is recommended that you directly determine whether you can iterate, not the length
property.
Generator
The generator (generators) is also a complex feature that can refer to the documentation for the MDN.
For generators, my advice is to use it with great care for the following reasons:
- The generator is not used to write asynchronously, although he does have such an effect, but this is only a hack. Async in the future must belong
async
await
to and these two keywords, but too many people see the generator is written asynchronously, which can lead to abuse.
- The generator generates more code after the Babel conversion, and it requires
generatorsRuntime
library support at a higher cost.
- Most of the scenarios where we actually write applications are not available for the time being.
The most typical application of a generator is to refer to C # 's LINQ for some experience, and it is its greatest contribution to merging multiple operations of an array into a single loop.
Modules and Module loaders
ES6 finally defines the syntax of the module at the language level, but this does not mean that we can now use the ES6 module because it removes the specification of the module loader when it is actually finalized in ES6. So what we have now is just a module import
and export
syntax, but specifically such as "how module names correspond to URLs", "How to load modules asynchronously/synchronously", "How to load modules on demand" are not explicitly defined.
Therefore, in this piece of module, our recommendation is to use standard grammar writing modules, but using AMD as a runtime module solution features:
- The use
import
and the export
introduction and definition of modules can be safely used to name export
and default export
.
- When using the Babel conversion, the configuration
modules: ‘amd‘
is converted to AMD's module definition.
- Assuming that the module's URL resolution is AMD's standard,
import
the corresponding module name is written in AMD standard.
- Do not rely on
SystemJS
such a ES6 module loader.
While this is likely to lead to the actual module loader specification being trained, our import
module path is not canonical. But for the ES6 module does not match the HTTP/2 can not be finished, AMD must persist for a long period of time, our application is basically not waiting for HTTP/2 actual available days, so don't worry.
Type enhanced class Unicode support
This thing basically has no effect, we rarely encounter these situations and are accustomed to these conditions, so we can think that this feature does not exist and continue to develop.
Map and set
Two very useful types, but for many developers, will be confused with the ordinary object of the difference, after all, we have to take the ordinary objects Map
and Set
play for so many years, and rarely write a type out of their own.
For this, our recommendations are:
- Use and unconditionally when your element or key value is likely not to be a string
Map
Set
.
- When there is a need to remove an operation, use the
Map
and Set
.
- When you need only a non-repeatable collection, use
Set
overrides to the normal object instead of using {foo: true}
such an object.
- When it is necessary to traverse the function, use
Map
and Set
, because it can be used simply to for..of
traverse.
So, in fact, there is only one situation where we use ordinary objects, even if we are using ordinary objects to express an increment only Map
, and this Map
key value is a string.
In addition, WeakMap
and WeakSet
there is no way to simulate the implementation, so do not use .
Proxy
This is not a function that can be emulated and cannot be used, so do not use proxies.
Symbol
Symbol
The simplest explanation is "objects that can be used for key values," and perhaps the most useful is to define some private properties.
We recommend that you Symbol
use it sparingly , and if you use it to define private properties, keep it consistent throughout the project, and do not mix Symbol
and close to define private properties.
Inheritable built-in types
In accordance with the ES6 specification, built-in types such as Array
, Function
, and Date
so on can be inherited and there is no pit. But our code has to run in a es3-5 environment, and obviously this feature is not enjoyable.
Promise
This is really nothing to say, even if it is not ES6, we have been used everywhere Promise
.
It is recommended that all asynchrony be implemented using promise for future enjoyment async
and await
portability of keywords.
In addition, although Babel can be converted async
and await
the code, but not recommended , because the converted code is cumbersome, and depends on generatorsRuntime
.
Method enhancements for each built-in type
such as Array.from
, and String.prototype.repeat
so on, these methods can be supported by the Shim library, so feel free to use.
Binary and octal numeric literals
This feature is basically reserved for the algorithm family, so our advice is not to use it unless the number itself is in the two/eight binary.
Reflection API
Reflect
The object is a reflection object provided by ES6, but there is no method that is necessary.
The delete(name)
and has(name)
methods are equivalent to delete
and in
operators, and so on defineProperty
Object
itself is a set, so it is not recommended to use this object .
Tail recursion
As if it were not there ...
Ext.: http://efe.baidu.com/blog/es6-develop-overview/
Considerations for developing with ES6