目前开发环境已经普及使用,如vue,react等,但浏览器环境却支持不好,所以需要开发环境编译,下面介绍下开发环境的使用和常用语法:
一,ES6模块化
1,模块化的基本语法
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。
模块功能主要由两个命令构成:export和import(注意有无default)。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

2,开发环境配置(babel编译ES6语法,模块化可用webpack和rollup)
(1)开发环境 babel-语法层面(编译) https://babeljs.cn/ (淘宝npm镜像 http://npm.taobao.org/)
电脑有node环境,运行npm init(创建package.json文件)----输入相关信息,默认即可,不要和工具名一样就行
npm init
使用淘宝npm镜像更快地安装babel依赖:
npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest --registry=https://registry.npm.taobao.org
创建 .babelrc 文件
1{ 2 "presets": ["es2015","latest"], 3}
全局安装babel-cli:
npm install -g babel-cli
检验版本是否安装成功:
babel --version
创建./src/index.js
输入内容:
[1,2,3].map(item => item + 1);
运行:
babel ./src/index.js,
编译结果如下:
1[1, 2, 3].map(function (item) { 2 return item + 1; 3});
(2)开发环境 webpack(现代 JavaScript 应用程序的 静态模块打包器(module bundler)),功能强大
安装webpack和babel编译:
npm install webpack babel-loader --save-dev --registry=https://registry.npm.taobao.org
配置webpack.config.js
1// var path = require('path'); 2 3module.exports = { 4 entry: './src/index.js', 5 output: { 6 path: __dirname, 7 filename: './build/bundle.js' 8 }, 9 module:{ 10 rules:[{ 11 test:/\.js?$/, 12 exclude:/(node_modules)/, 13 loader:'babel-loader' 14 }] 15 } 16};
配置 package.json中的scripts
1{ 2 "name": "es6", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "test": "echo \"Error: no test specified\" && exit 1", 8 "start": "webpack" 9 }, 10 "author": "", 11 "license": "ISC", 12 "devDependencies": { 13 "babel-core": "^6.26.0", 14 "babel-loader": "^7.1.4", 15 "babel-polyfill": "^6.26.0", 16 "babel-preset-es2015": "^6.24.1", 17 "babel-preset-latest": "^6.24.1", 18 "webpack": "^4.5.0", 19 "webpack-cli": "^2.0.14" 20 } 21}
运行
npm start
(3)开发环境-rollup,只将需要的代码提取出来打包,能大大减小代码体积
npm init 创建一个package.json。
npm init
安装
npm i rollup rollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest --save-dev
配置.babelrc
1{ 2 "presets": [ 3 ["latest", 4 { 5 "es2015": 6 { 7 "modules": false 8 } 9 } 10 11 ] 12 ], 13 "plugins": ["external-helpers"] 14}
配置 rollup-config.js
1import babel from 'rollup-plugin-babel' 2import resolve from 'rollup-plugin-node-resolve' 3 4export default { 5 input: 'src/index.js', 6 output: { 7 file: 'build/bundle.js', 8 format: 'umd' //通用模块定义,兼容AMD,CommonJS和一般的全局定义 9 }, 10 plugins:[ 11 resolve(), 12 babel({ 13 exclude:'node_modules/**' 14 }) 15 ], 16};
修改package.json的scripts
1{ 2 "name": "rollup-xiaosili", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "start": "rollup -c rollup.config.js" 8 }, 9 "author": "", 10 "license": "ISC", 11 "devDependencies": { 12 "babel-core": "^6.26.0", 13 "babel-plugin-external-helpers": "^6.22.0", 14 "babel-preset-latest": "^6.24.1", 15 "rollup": "^0.57.1", 16 "rollup-plugin-babel": "^3.0.3", 17 "rollup-plugin-node-resolve": "^3.3.0" 18 } 19}
新建相关文件,输入内容
运行
npm start
3,关于JS众多模块化标准
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的 require、Python 的 import,甚至就连 CSS 都有 @import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。(现状是,nodejs积极支持,浏览器尚未统一)
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
二,Class和普通构造函数有何区别
1,js构造函数
1function MathHandle(x, y) { 2 this.x = x; 3 this.y = y; 4} 5 6MathHandle.prototype.add = function() { 7 return this.x + this.y; 8}; 9 10var m = new MathHandle(1, 2); 11console.log(m.add()); //3
2,Class基本语法
1class MathHandle1 { 2 constructor(x, y) { 3 this.x = x; 4 this.y = y; 5 } 6 add() { 7 return this.x + this.y; 8 } 9} 10var m1 = new MathHandle1(1,2); 11console.log(m1.add()); //3 12console.log(typeof MathHandle1); //function 13console.log(MathHandle1 === MathHandle1.prototype.constructor); //true 14console.log(m1.__proto__ === MathHandle1.prototype); //true
3,二者区别
(1) class在语法上更加贴合面向对象的写法
(2) class实现继承更易读,易理解
(3) 更易于写java等后端语言的使用
(4) 本质是语法糖,还是使用prototype继承方式
附:class继承实现

三,Promise的基本语法
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。
先看js的一个例子:
1function loadImg(src, callback, fail) { 2 var img = document.createElement('img'); 3 img.onload = function() { 4 callback(img); 5 } 6 img.onerror = function() { 7 fail(); 8 } 9 img.src = src; 10} 11 12var src = "https://shared-https.ydstatic.com/dict/v2016/result/logo.png"; 13loadImg(src, function(img) { //加载图片,异步请求 14 console.log(img.width); //164 15}, function() { 16 console.log('failed'); 17})
使用Promise:
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
例:
1 function loadImg(src) { 2 const promise = new Promise(function(resolve, reject) { //new Promise实例 3 var img = document.createElement('img'); 4 img.src = src; 5 img.onload = function() { 6 resolve(img); 7 } 8 img.onerror = function() { 9 reject('图片加载失败'); 10 } 11 }); 12 return promise; //返回 Promise实例 13 } 14 var src = "https://shared-https.ydstatic.com/dict/v2016/result/logo.png"; 15 var result = loadImg(src); //Promise实例 16 result.then(function(img) { //then监听结果,成功时执行resolve(), 失败时执行reject() 17 console.log(1, img.width); //1 164 18 return img; 19 }, function(img) { 20 console.log('failed'); 21 return img; 22 }).then(function(img) { 23 console.log(2, img.height) //2 36 24 })
四,ES6其他常用的功能(简单常用的)
1,let/const(let定义变量,不存在变量提升,const定义常量)
1let i = 10; 2i = 100; 3const j = 20; 4j = 200;
编译如下:
1SyntaxError: ./src/index1.js: "j" is read-only 2 2 | i = 100; 3 3 | const j = 20; 4> 4 | j = 200;
2,多行字符串/模版变量
1const name = 'zs',age = 20; 2const html = `<div><p>${name}</p><p>${age}</p></div>`; //注意这里是反引号
编译如下:
1var name = 'zs', 2 age = 20; 3var html = '<div><p>' + name + '</p><p>' + age + '</p></div>'; //注意这里是反引号
3,解构赋值
1const arr = ['xxx','yyy','zzz','hhh']; 2const [x,y,z] = arr; 3 4const obj = {a:1,b:2,c:3}; 5const {a,c} = obj;
编译如下:
1var arr = ['xxx', 'yyy', 'zzz', 'hhh']; 2var x = arr[0], 3 y = arr[1], 4 z = arr[2]; 5 6 7var obj = { a: 1, b: 2, c: 3 }; 8var a = obj.a, 9 c = obj.c;
4,块级作用域
1const obj = {a:10,b:20}; 2for(let item in obj) { 3 console.log(item); 4} 5console.log(item);//报错 item is not defined
编译如下:
1var obj = { a: 10, b: 20 }; 2for (var _item in obj) { 3 console.log(_item); 4} 5console.log(item); //报错 item is not defined
5,函数默认参数
1function fn(a,b=0) { 2 3}
编译如下:
1function fn(a) { 2 var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 3}
6,箭头函数
1var arr = [1, 2, 3]; 2arr.map((item, index) => { 3 return item + index; 4})
编译如下:
1var arr = [1, 2, 3]; 2arr.map(function (item, index) { 3 return item + index; 4});
箭头函数中的this:this 其实是包含该箭头函数最近的一个 function 上下文中的 this(如果没有最近的 function,就是全局)
1function fn() { 2 console.log('real',this);//this === {a:100} 3 var arr = [1,2,3]; 4 5 // 普通JS 6 arr.map(function(item) { 7 console.log('js',this);//this === window 8 return item + 1; 9 }) 10 11 // 箭头函数 12 arr.map(item => { 13 console.log('es6',this);//this === {a:100} 14 return item + 1; 15 }) 16} 17fn.call({a:100});
编译如下:
1function fn() { 2 var _this = this; 3 4 console.log('real', this); //this === {a:100} 5 var arr = [1, 2, 3]; 6 7 // 普通JS 8 arr.map(function (item) { 9 console.log('js', this); //this === window 10 return item + 1; 11 }); 12 13 // 箭头函数 14 arr.map(function (item) { 15 console.log('es6', _this); //this === {a:100} 16 return item + 1; 17 }); 18} 19fn.call({ a: 100 });