因为要兼容IE,跑了一下Babel文档,发现。。恩?兼容IE,不就是把ES6语法转换成ES5语法吗!果断解锁考点!
1. 简介 Babel是一个Javascript编译器,用于将ES5+的代码转换为向后兼容的JS语法,以便能够运行在当前和旧版本的浏览器或其他环境中。官方Demo
Babel 的功能很纯粹,它只是一个编译器,大多数编译器的工作过程可以分为三部分:
解析(Parsing):将代码字符串解析成抽象语法树。
转换(Transformation):对抽象语法树进行转换操作。
生成(Code Generation): 根据变换后的抽象语法树再生成代码字符串。
组成
作用
@babel/core
实现语法解析,转换
@babel/preset-env
plugins是一些js程序,用来指导babel如何对代码执行转换。你可以写自己的插件。preset是多个plugins的组合。
@babel/cli
允许你在终端用命令行实现语法转换。把src目录下的所有js文件,编译输出到lib目录。./node_modules/.bin/babel src --out-dir lib
@babel/polyfill
Babel默认只转换新的JS语法,而不转换新的API,如Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise等全局对象。当运行环境(IE )并没有实现一些全局对象时,babel-polyfill会给其做兼容。
1.1 Babel职责范围 Babel 只是转译新标准引入的语法,比如:
哪些在 Babel 范围外?对于新标准引入的全局变量、部分原生对象新增的原型链上的方法:
全局变量
Promise
Symbol
WeakMap
Set
includes
generator 函数
对于上面的这些 API,Babel 是不会转译的,需要引入 polyfill 来解决。
要想知道babel怎么实现ES6语法,直接到Babel官网的REPL在线编辑器 ,配置好preset
和plugins
后,输入你想要转化的代码,babel自动会给你输出转化后的代码。
2.1 let, const
cosnt
1 2 3 4 5 6 7 8 9 const a = 1 ;a = 2 ; function _readOnlyError (name ) { throw new Error ("\"" + name + "\" is read-only" ); }var a = 1 ;a = (_readOnlyError("a" ), 2 );
块级作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function f ( ) { var x = 'foo' ; { var x = 'bar' ; console .log(x); } console .log(x); } function f ( ) { var x = 'foo' ; { var _x = 'bar' ; console .log(_x); } console .log(x); }
2.2 箭头函数 1 2 3 4 5 6 7 const a = [1 ,2 ,3 ].map(v => v + 1 );var a = [1 , 2 , 3 ].map(function (v ) { return v + 1 ; });
2.3 函数默认参数 1 2 3 4 5 6 7 8 9 10 function f (x, y = 12 ) { return x + y } function f (x ) { var y = arguments .length > 1 && arguments [1 ] !== undefined ? arguments [1 ] : 12 ; return x + y; }
2.4 解构 1 2 3 4 5 6 7 8 9 10 11 12 13 const [a, ,b] = [1 ,2 ,3 ];const { c, d, e : { f } } = { c : 1 , d : 2 , e : { f : 3 } }var _ref = [1 , 2 , 3 ], a = _ref[0 ], b = _ref[2 ]; var _c$d$e = const { c, d, e : { f } } = { c : 1 , d : 2 , e : { f : 3 } }, c = _c$d$e.c, d = _c$d$e.d, f = _c$d$e.e.f;
2.5 模板字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 const name = '小明' const time = 'today' const b = `hello ${name} ` ;const c = `hello ${name} , how are you ${today} ` var name = '小明' ;var time = 'today' ;var b = "hello " .concat(name);var c = "hello " .concat(name, ",\n\thow are you " ).concat(today);
2.6 Class 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 class Arr { constructor () { this .arr = [1 ,2 ,3 ] } push(val) { this .arr.push(val) } getVal(index) { return this .arr[index] } } const arr = new Arr();arr.push(1 ) arr.getVal() "use strict" ;function _classCallCheck (instance, Constructor ) { if (! (instance instanceof Constructor)) { throw new TypeError ("Cannot call a class as a 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); } } function _createClass (Constructor, protoProps, staticProps ) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var Arr = function ( ) { function Arr ( ) { _classCallCheck(this , Arr); this .arr = [1 , 2 , 3 ]; } _createClass(Arr, [{ key: "push" , value: function push (val ) { this .arr.push(val); } }, { key: "getVal" , value: function getVal (index ) { return this .arr[index]; } }]); return Arr; } (); var arr = new Arr();arr.push(1 ); arr.getVal();
3. babel 和 polyfill 有了babel,为什么要polyfill? Babel默认只转换新的JS语法,而ES6新特性像Promise, async/await,则是通过core-js 实现。
Promise, aysnc/await, Generator, Set, Map, Proxy
参考资料