Article by Imweb Ouven source: imweb community without consent, prohibit republication
After the release of ES6 standard, front-end staff also gradually learned about ES6, but due to compatibility problems, it has not been widely promoted, but the industry has also used some neutral solutions to solve compatibility and development system problems, but everyone is still very confused, using ES6 will have what compatibility problems.
I. Current situation of compatibility problems
In view of the compatibility problem of new ES6 features, the current solution is to use syntax parsing and conversion tools to convert ES6 syntax into ES5 syntax recognized by most browsers. The common conversion schemes include Babel, Traceur, JSX, typescript, and ES6-Shim. Of course, es6 also has compatibility issues on the server side, which will not be discussed here because only the browser side is considered. Here are some common solutions and es6 compatibility comparisons
Github.com/babel/babel… Kangax.github. IO /compat-tabl…
Considering the diversity of solution, I will focus on the following questions: 1, compatibility: whether can solve the current common grammar is compatible with all convert 2, ease of use: to be able to easily access to the build system for the development of the existing 3, generality: the industry a greater recognition, there is no big question 4, sustainability: Have more authoritative team maintenance, and can update constantly
Together, we are still considering Babel as our compatibility solution. Even if you need to replace it later, you only need to replace the tool, and the original code writing method can not be changed. Aside from the last three points, we might be concerned about Babel’s compatibility with ES6. Because es6 has added a lot of content, conversion to ES5 does not have the corresponding syntax, so use special care. There is no good way to determine this, other than to compile new content in ES6 and determine whether it can be converted to ES5 syntax.
A compatibility list of new ES6 features under Babel
ES6 features | compatibility |
---|---|
Arrow function | support |
Class declaration and inheritance | Partial support, IE8 does not support |
Enhanced object literals | support |
String template | support |
deconstruction | Yes, but be careful how you use it |
Parameter Default value, indefinite parameter, extended parameter | support |
Let the const | support |
for of | IE does not support |
iterator, generator | Does not support |
Module, Proxies, Symbol | Does not support |
Map, Set and WeakMap, WeakSet | Does not support |
Promises, Math, Number, String, Object API | Does not support |
export & import | support |
Generator function | Does not support |
Copy an array | support |
Among the new es6 features, complex architectures still do not support compatibility with ES5 transformations, as shown in the following examples
1.1 Arrow operators
The arrow operator can describe a function succinctly
// ES6
var fn= (v=>console.log(v))
Copy the code
After the transformation
"use strict";
var fn = function fn(v) {
return console.log(v);
};
Copy the code
This usage is safe to use.
1.2 Class declaration and inheritance
Constructor (name) {this.name = name; } // Instance method sayName() {console.log('My name is '+this.name); Constructor () {constructor() {constructor() {constructor() {constructor() {constructor() {constructor() {constructor(); } program() { console.log("I'm coding..." ); Var animal=new animal ('dummy'), wayou=new Programmer('wayou'); animal.sayName(); // output 'My name is dummy' wayou.sayname (); // Output 'My name is wayou' wayou.program(); // Output 'I'm coding... 'Copy the code
After the transformation
'use strict'; var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); }}}; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }) (); function _inherits(subClass, superClass) { if (typeof superClass ! == 'function' && superClass ! == null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (! (instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var Animal = (function () { function Animal(name) { _classCallCheck(this, Animal); this.name = name; } _createClass(Animal, [{ key: 'sayName', value: function sayName() { console.log('My name is ' + this.name); } }]); return Animal; }) (); var Programmer = (function (_Animal) { _inherits(Programmer, _Animal); function Programmer(name) { _classCallCheck(this, Programmer); _get(Object.getPrototypeOf(Programmer.prototype), 'constructor', this).call(this, name); } _createClass(Programmer, [{ key: 'program', value: function program() { console.log("I'm coding..."); } }]); return Programmer; })(Animal); var animal = new Animal('dummy'), wayou = new Programmer('wayou'); animal.sayName(); wayou.sayName(); wayou.program();Copy the code
DefineProperty was used during the conversion, which is not compatible with IE8 and can be used anywhere else
1.3 Enhanced object literals
var human = {
breathe() {
console.log('breathing...');
}
};
var worker = {
__proto__: human,
company: 'freelancer',
work() {
console.log('working...');
}
};
human.breathe();
worker.breathe();
Copy the code
After the transformation
'use strict';
var human = {
breathe: function breathe() {
console.log('breathing...');
}
};
var worker = {
__proto__: human,
company: 'freelancer',
work: function work() {
console.log('working...');
}
};
human.breathe();
worker.breathe();
Copy the code
This can be used arbitrarily
1.4 String Templates
var num=Math.random();
console.log(`your num is ${num}`);
Copy the code
After the transformation
"use strict";
var num = Math.random();
console.log("your num is " + num);
Copy the code
1.5 deconstruction
var [name,gender,age]=['wayou','male','secrect'];
console.log('name:'+name+', age:'+age);
Copy the code
After the transformation
'use strict';
var name = 'wayou';
var gender = 'male';
var age = 'secrect';
console.log('name:' + name + ', age:' + age);
Copy the code
This method can be used. But try not to use var [a, b] = getVal(); Although getVal returns an array. IsArray is used, which is not supported on IE8.
1.6 Parameter Default value, indefinite parameter, and extended parameter
function sayHello(age, name='dude'){
console.log(`Hello ${name}`);
}
sayHello(12);
Copy the code
After the transformation
'use strict';
function sayHello(age) {
var name = arguments.length <= 1 || arguments[1] === undefined ? 'dude' : arguments[1];
console.log('Hello ' + name);
}
sayHello(12);
Copy the code
function add(... x){ return x.reduce((m,n)=>m+n); } the console. The log (add (1, 2, 3)); The console. The log (add (1, 2, 3, 4, 5));Copy the code
After the transformation
"use strict";
function add() {
for (var _len = arguments.length, x = Array(_len), _key = 0; _key < _len; _key++) {
x[_key] = arguments[_key];
}
return x.reduce(function (m, n) {
return m + n;
});
}
console.log(add(1, 2, 3));
console.log(add(1, 2, 3, 4, 5));
Copy the code
var people=['Wayou','John','Sherlock']; function sayHello(people1,people2,people3){ console.log(`Hello ${people1},${people2},${people3}`); } sayHello(... people); sayHello.apply(null,people);Copy the code
After the transformation
'use strict';
var people = ['Wayou', 'John', 'Sherlock'];
function sayHello(people1, people2, people3) {
console.log('Hello ' + people1 + ',' + people2 + ',' + people3);
}
sayHello.apply(undefined, people);
sayHello.apply(null, people);
Copy the code
Parameter default value, variable parameter, extended parameter can be used fully
1.7 the let and const
Let and const are fully supported and will both be converted to var, but understand the difference between let, var, and const.
1.8 the for of
var someArray = [ "a", "b", "c" ];
for (v of someArray) {
console.log(v);
}
Copy the code
After the transformation
"use strict";
var someArray = ["a", "b", "c"];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = someArray[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
v = _step.value;
console.log(v);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"]) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
Copy the code
There is no throw under IE, so it cannot be supported
1.9 the iterator, the generator
var ids = { *[Symbol.iterator]: function () { var index = 0; return { next: function () { return { value: 'id-' + index++, done: false }; }}; }};Copy the code
After the transformation
'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var ids = _defineProperty({}, Symbol.iterator, function () { var index = 0; return { next: function next() { return { value: 'id-' + index++, done: false }; }}; });Copy the code
Not recommended. Browser support is still required after conversion
1.10 Module module, Proxies, Symbol
module "point" { export class Point { constructor (x, y) { public x = x; public y = y; }}}Copy the code
It is not supported at all, import is not supported, parsing error, so it is recommended not to use, use the original require
1.11 Map, Set and WeakMap, WeakSet
Map, Set and WeakMap and WeakSet have no corresponding types corresponding to them in ES5, so they do not support conversion, and compatibility is determined by the browser
Promises, Math, Number, String, Object API
No syntax conversions are made and compatibility is determined by the browser
1.13 the export & import
export function myModule(someArg) {
return someArg;
}
Copy the code
After the transformation
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.myModule = myModule;
function myModule(someArg) {
return someArg;
}
Copy the code
import * as baz from 'myModule';
Copy the code
After the transformation
'use strict'; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj ! = null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } var _myModule = require('myModule'); var baz = _interopRequireWildcard(_myModule);Copy the code
Therefore, methods such as export and import can be used for module loading processing dependency, and export uses defineProperty, which causes compatibility problems in IE8.
1.14 Generator functions
function* foo() { };
var bar = foo();
bar.next();
Copy the code
After the transformation
"use strict";
var marked0$0 = [foo].map(regeneratorRuntime.mark);
function foo() {
return regeneratorRuntime.wrap(function foo$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
case "end":
return context$1$0.stop();
}
}, marked0$0[0], this);
};
var bar = foo();
bar.next(); // Object {value: undefined, done: true}
Copy the code
RegeneratorRuntime is not supported in IE, so it is not recommended.
The new ES6 features use these, and the rest is largely up to the browser itself. This part of the code is left untouched by Babel as it is by ES5 code. For some ES6 grammars, Babel will parse the throw error and will not handle it even if it is not thrown. It is recommended not to use it. 1.15 Array Copy
Const items = [1, 2, 3]; const itemsCopy = [...items];Copy the code
After the transformation
"use strict";
var items = [1, 2, 3];
var itemsCopy = [].concat(items);
Copy the code
You can use
ES6 packaging system
Some of the ES6 compatibility conversion issues are addressed using Babel, but ES6 packaging still has to rely on the currently common package management scheme. Gulp is responsible for building and using WebPack packaging and browsify management components. Babel is the most talked about solution at present, because there are a lot of examples on Github. React can be easily supported, but this does not form a complete development system; In addition, it is too unified and differs greatly from the technology used by the team.
This approach was chosen because of both the team’s current primary technology selection and the unique strengths of each tool. This is still a work in progress.
Third, summary
So using ES6 this scheme for actual development necessity still need to consider whether there is a certain, because ES6 higher characteristic in es5 not to replace the corresponding features, even can replace use some complex custom function to do, and some can implement the conversion feature still less, and write up is very concise, This is also a big advantage of the ES6.
In addition, in order to make Babel useful in actual development, we have compiled a specification for the ES6 part:
Github.com/ouvens/ecma…