ES6 是 ECMAScript 6简称,也就是新一代的Javascript标准,对原有的Javascript进行了颠覆性的改革,目标是解决Javascript的很多遗留问题,使其可以编写复杂的应用程序,代码可读性也更好,更接近面向对象的思想,与java.C#语法更接近;
Babel: 由于不是所有的浏览器都支持ES6语法,所以就有了Bable转码器,开发ES6程序基本上必不可少的工具,详细的配置大家去网上搜索,我们这里主要讲 ES6学习中的一些思路;
<!--more-->
学习每一门新语言,建议大家都要系统的去读他们的官方文档(我读的是阮一峰的博客);第一次读可能读不懂,没关系,第二次读的写写demo,会理解更深刻,我的这些注意事项就是在读完第一次文档后,实际项目中遇到的问题和感受.
学习ES6我们最好要知道ES5语法有哪些问题,ES6是如避免和解决的;
ES5存在的问题
作用域
异步函数
原型
构造函数
继承
ES6 的语法糖
1:作用域 let 与 var
ES5并不是没有作用域,它也有函数作用域,全局作用域和eval作用域,但是这些作用域存在一个问题,就是变量提升,什么是变量提升:比如我用var声明一个变量,无论声明在何处,都会被视为声明在函数的最顶部;
注意:ES5 也是有函数作用域的,函数内部声明的变量,不会冲突掉全局的变量; 顺便提一下, 如果在函数内未使用var 声明,则解析器认为这个变量是全局变量,所以大家在写代码的一定要用var 或者let声明一下变量;
console.log(a);// 仅仅执行这句话 输出结果 报错 undefined var a; console.log(a);// undefined 但不报错 a='abc'; //**** 以上全部执行就会输出undefined,undefined function test(){ var a = '999'; console.log('内部:'+ a); } test(); console.log('外部:'+ a); //输出结果 内部:999,外部 abc; #如果改为这样 var a='abc'; function test(){ a = '999'; console.log('内部:'+ a); } test(); console.log('外部:'+ a); //输出结果 内部:999,外部 999;
let 定义的变量则不会被变量提升,let也是块级作用域
console.log(a);// a is not defined let a = 'abc';
const:ES6新增了一个const 变量,const声明的变量不可以修改,在声明全局不可变的变量和效率方法可能更好一些;
2:异步函数
原生的Javascript实现起来比较复杂,需要用到XMLHttpRequest对象,使用者很少,后来的以jQuery为代表的中间类库,解决了原生ajax复杂的问题,但是还存在一个比较令人不爽的东西,就是回调函数.每一次异步函数执行之后,都需要通过回调来处理.举例,微信登录,ES5的语法需要这样写,这只是最简单的情况,通常情况下我们需要登录成功后,取得Code,然后再通过code,取得用户的openid,后台系统记录openid,这样的话就需要3层嵌套,阅读起来比较不方便,也容易出错;
//app.js App({ onLaunch: function() { wx.login({ success: function(res) { if (res.code) { //发起网络请求 wx.request({ url: 'https://test.com/onLogin', data: { code: res.code } }) } else { console.log('登录失败!' + res.errMsg) } } }); } })
ES6的async,await,Promise 特性则解决了这些问题,async和Promise的详细特性请大家去阅读文档,这里只做简单说明;async的引用是异步函数的使用更简单,也没有了ES5中无限循环嵌套的问题,这里特别说明的是async的返回对象是Promise,可以使用then命令等,如果函数要返回数据,则需要通过Promise处理一下;下面是ES6语法的微信登录:(这里使用了微信开发框架wepy的语法,用户登录后获取openid的一个方法)
async getUserOpenID(){ let d = await wepy.login().catch( (e) =>{console.log('error:'+e)}); if (d){ //获取用户openid let url = 'https://api.weixin.qq.com/sns/jscode2session?appid=wx203858ba39a7bdf1&secret=eefa8c82e6962e1a22a76a5610a44480&js_code='+ d.code+'&grant_type=authorization_code' ; let data = await wepy.request(url); // return data;// 也可以这样写 if(data.data.openid){ wx.setStorageSync('openid',data.data.openid); console.log(data.data.openid); // return data.data.openid //不可以这样写 注意这种方式外面调用这个方法是获取不到结果值的 return Promise.resolve(data.data.openid);// 可以这样写 } } }
上面一段代码包含两种使用方式
2.1 直接使用Promise.prototype.then(),Promise.prototype.catch(),Promise.prototype.finally(),方式调用.常见的方式是then()方法,then()的第一个参数是resolved 状态的回调函数,第一个参数(可选)是rejected状态的回调函数;
2.2 返回其他对象,如果返回的值不需要回调或者往更高层次调用,直接返回对象操作即可;但是如果返回的对象需要给其他function调用,则需要通过Promise.resolve()函数包装一下;因为await返回的是Promise对象
2.3 直接返回Promise对象,也就是return date;外面可以对这个Promise对象进行处理
大家可以根据具体的业务选择使用哪种方式处理;
语法糖
arrow function 箭头函数
比如一个回调函数需要处理,看起来简化一些,同时如果函数需要返回,也省去了return关键字
#ES6语法 wepy.login().catch( (e) =>{console.log('error:'+e)}); #ES5语法 wepy.login().catch( function(e){console.log('error:'+e)});
template string 模板字符串
这个在面向对象的语言里面基本都有,ES6语法也参考引入进来了,很好懂.关键字是'${}',看起来更雅观了;这个语法在拼接html的时候更方法,否则太多的++容易晕掉
#ES5语法 var str = 'hello'; console.log(str + ' word'); #ES6语法 var str ='hello'; console.log('${str} word');
import,export
这个不知道算不算语法糖,从最早的<script>,到后来的require,到现在的ES6语法的import,使用起来更简单.import和require也有些区别;比如import不能使用url;还有一个比较大的区别是
require 引用是值的copy,import 是值的引用;这样说可能不好理解,可以参考java或者C#里面的值类型和引用类型的 require相当于值类型,引用的时候是copy一个地址过去,你改了原因模块的值,并不会影响到现在我的引用;import相当于引用类型的引用,传输的仅仅是个指针地址,如果原来模块的值改变了,我引用的模块的值也会跟着改变(不知道这样对比对不对)
class,extends
这个后端程序员很好理解,就是面向对象继承的那一套东西,
简化数组操作
let num=[1,2,3]; let [x,y,z]=num; console.log(z);//3
其他的一些内容慢慢待发现,接下来会分享一下闭包函数的问题