ECMAScript 6.0基础入门教程(一)
1、ES6简介
1.1 ES6的历史
ECMAScript简称ECMA或ESECMAScript与JavaScript的关系
ECMA是European Computer Manufacturers Association的缩写,即欧洲计算机制造商协会。欧洲计算机制造商协会是制定信息传输与通讯的国际化标准组织。
1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给ECMA,希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。
该标准从一开始就是针对JavaScript语言制定的,但之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。
因此,ECMAScript和JavaScript的关系是,ECMA是JavaScript的标准,JavaScript是ECMA的一种实现。
历史版本
1.2 ES6兼容性
ES6兼容性问题是怎样产生的?由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性进行兼容,那么浏览器肯定无法识别我们的ES6代码,好比浏览器根本看不懂我写的let和const是什么东西?只能报错了。这就是浏览器对ES6的兼容性问题。对ES6新特性最友好的浏览器有:IE10+、Chrome、FireFox、移动端、NodeJsES5兼容性查看:http://kangax.github.io/compat-table/es5/
ES6兼容性查看:http://kangax.github.io/compat-table/es6/
使用Babel解决ES6兼容性问题
在线转换:/repl/
提前编译
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而使ES6在低版本浏览器环境运行。 这种方法是实时在网页中将ES6代码转为ES5,对性能会有影响。生产环境需要将ES6转码完成再进行载入。
首先我们创建一个html文件,在里面输入ES6的新语法,用低版本浏览器运行这个文件。
<script>let a = 1;console.log(a);</script>
这样我们的低版本浏览器会报错:
这次我们引入在线的babel.min.js,我们还要在script脚本中声明类型为”text/babel”,这样就可以在低版本浏览器中运行ES6的新语法了。
<script src="/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script><script type="text/babel">let a = 1;console.log(a);</script>
这次我们成功得到了console.log的结果:
2、变量
2.1 var的缺点
1.可以重复声明,在团队协作时很容易造成冲突
var a = 1;var a = 2;
2.无法限制修改,没有常量的概念
var a = 1;a = 2;
3.不支持块级作用域,属于函数级作用域
if ( true ) {var a = 1;}alert(a);
2.2 let和const
const是常量,常量命名要用大写字母,值只能定义一次不可更改let和const的区别是:let是变量可以修改,const是常量不可以修改let和const的相同点:1.都不能重复声明
let a = 1;let a = 2;const a = 1;const a = 2;
2. 支持块级作用域,在作用域内定义的变量或常量只能在作用域内使用
if ( true ) {let c = 1;}console.log(c);
if ( true ) {const PI = 3.14;}console.log(PI);
2.3 解构赋值
在ES5里想要将数组内容分别赋值给变量必须单独来写var arr = [1, 2, 3];var a = arr[0];var b = arr[1];var c = arr[2];console.log(a, b, c);
通过ES6的解构赋值就可以这样来写
let [a, b, c] = [1, 2, 3];console.log(a, b, c);
解构赋值注意事项
变量和数据必须一一对应右侧数据必须是合法的数据类型声明和赋值不能分开,必须在一句话里完成
3、函数
3.1 箭头函数
ES5的函数写法function fn(a){return a * 2;}console.log(fn(5));//10
ES6箭头函数
let fn = (a) => {return a * 2;}console.log(fn(5));//10
箭头函数简写,如果只有一个参数可以省略(),如果只有一个return可以省略{}和return
let fn = a => a * 2;console.log(fn(5));//10
3.2 函数参数
收集剩余参数在参数最后添加形参…args获取剩余参数
let fn = (a, b, ...args) => {console.log(a);//1console.log(b);//2console.log(args); //[3, 4, 5]}fn(1, 2, 3, 4, 5);
数组展开
let arr1 = [1, 2, 3];let arr2 = [4, 5, 6];let arr = [...arr1, ...arr2];console.log(arr); //[1, 2, 3, 4, 5, 6]
默认参数
将形参直接赋值,如果没有传入对应实参那就使用默认值,如果传入对应实参,那就使用实参
let fn = (a, b=2, c=3) => {console.log(a, b, c); //1, 5, 3}fn(1, 5);
4、数组
ES6新增了4个数组方法:map、reduce、filter、forEach
4.1 map(映射)
检查分数是否及格
let arr = [59, 60, 99, 31, 85];let result = arr.map(item => item >= 60 ? "及格" : "不及格");console.log(result); //["不及格", "及格", "及格", "不及格", "及格"]
4.2 reduce(汇总)
求和tmp参数为上一次相加的结果,item参数是当前要相加的值,index参数是当前要相加值的下标,arr参数指向的是数组本身
let arr = [10, 20, 30, 40];let result = arr.reduce((tmp, item, index) => tmp + item);console.log(result); //100
求平均数
let arr = [1, 2, 3, 4, 5];let result = arr.reduce((tmp, item, index, arr) => {if ( index != arr.length-1 ) {//不是最后一次先求和return tmp + item;} else { //最后一次求平均数return (tmp + item)/arr.length;}});console.log(result); //3
4.3 filter(过滤器)
根据条件判断,去掉不想要的数据,返回想保留的数据
let arr = [5, 7, 10, 13, 15, 20, 25];let result1 = arr.filter(item => {if ( item%5 == 0 ) { //判断可不可以被5整除return true;//保留可以被5整除的数} else {return false;//去掉不能被5整除的数}});//可以简写成下面这种方式,直接通过布尔值判断,为true的保留,为false的去掉let result2 = arr.filter(item => item%5 == 0); //保留可以被5整除的数//这样得到的结果是一样的console.log(result1); //[5, 10, 15, 20, 25]console.log(result2); //[5, 10, 15, 20, 25]
4.4 forEach(迭代)
遍历数组,第一个参数是数组的值,第二个参数是数组的下标
let arr = [2, 5, 6, 9, 7, 54];arr.forEach((item, index) => {console.log(index + ":" + item); //0:2, 1:5, 2:6, 3:9, 4:7, 5:54});
5、字符串
ES6新增了2个字符串方法:startsWith、endsWith
5.1 startsWith(判断字符串开始字符)
let str = "/";console.log(str.startsWith("https://")); //true
5.2 endsWith(判断字符串结尾字符)
let str = "1.txt";console.log(str.endsWith(".txt")); //true
5.3 字符串模板
用反单引号将字符串和变量拼接,变量用${}包裹,字符串可以换行。ES5的字符串拼接很麻烦var title = "标题";var content = "内容";var str = "<div>\<h2>title:"+title+"</h2>\<p>content:"+content+"</p>\</div>";
使用ES6字符串模板可以更方便更简洁
let title = "标题";let content = "内容";let str = `<div><h2>title:${title}</h2><p>content:${content}</p></div>`;
6、面向对象
ES5的面向对象写法很繁琐,其实就是构造函数伪装成一个类来使用,代码维护起来也比较麻烦。function My(name, age){//构造函数伪装成类来使用this.name = name;this.age = age;}/*函数需要用prototype来追加,与主体分离,比较分散不便于维护*/My.prototype.showName = function (){alert(this.name);}My.prototype.showAge = function (){alert(this.age);}var my = new My('Sain', 26);my.showName(); //Sainmy.showAge(); //26
在ES6里增加了class关键字可以区分类和构造函数,代码都在同一个class作用域代码方便管理
class My{ //使用class关键字定义一个类constructor(name, age){this.name = name;this.age = age;}showName(){alert(this.name);}showAge(){alert(this.age);}}var my = new My('Sain', 26);my.showName(); //Sainmy.showAge(); //26
ES5的继承方式
function addMyWeight(name, age, weight){//如果想在刚才My这个类的基础上增加新的属性就要使用继承My.call(this, name, age);//通过call来继承父级this.weight = weight;}addMyWeight.prototype = new My();addMyWeight.prototype.constructor = addMyWeight;addMyWeight.prototype.showWeight = function (){alert(this.weight);}var my = new addMyWeight('Sain', 26, '80kg');my.showName();//Sainmy.showAge(); //26my.showWeight(); //80kg
ES6的继承方式
class addMyWeight extends My{//使用ES6的extend来继承My这个类constructor(name, age, weight){super(name, age); //等同于call继承父级this.weight = weight //增加新属性}showWeight(){ //增加新方法alert(this.weight);}}var my = new addMyWeight('Sain', 26, '80kg');my.showName();//Sainmy.showAge(); //26my.showWeight(); //80kg
7、json
7.1 JSON对象
json数据串行化用JSON.stringify()
方法将json数据转化成字符串
let json = {"a":10, "b": 5};let str = JSON.stringify(json);console.log(str); //{"a":10, "b": 5}console.log(typeof str); //"string"
字符串转换成json
用JSON.parse()
方法将字符串转换成json,字符串必须严格遵守json格式要求,key和value要用双引号包起来,value如果是数字的情况下可以不使用双引号。
let str = '{"a": 10, "b": "hello"}';let json = JSON.parse(str);console.log(json);//Object {a: 10, b: "hello"}console.log(typeof json); //object
7.2 json简写
key和value的名字一样的时候,可以省略valuelet a = 1;let b = 2;let json = {a: a, b: b, c: 3};let json = {a, b, c: 3}; //简写
json内函数简写,可以将函数的:function去掉,直接用函数名()的写法
let json = {a: "hello",say: function(){//可以省略:和function,简写成say()alert(this.a);}}json.say();//hello