1、ES6简介

1.1 ES6的历史

  • ECMAScript简称ECMA或ES
  • ECMAScript与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的一种实现。

  • 历史版本

    时间 版本 详情
    1996.11 ES 1.0 Netscape将JS提交给ECMA组织,ES正式出现
    1998.06 ES 2.0 ES2正式发布
    1999.12 ES 3.0 ES3被广泛支持
    2007.10 ES 4.0 ES4过于激进被废弃
    2008.07 ES 3.1 4.0退化为严重缩水版的3.1,因为吵的太厉害,所以ES 3.1代号为Harmony(和谐)
    2009.12 ES 5.0 ES 5.0正式发布,同时公布了JavaScript.next也就是后来的ES 6.0
    2011.06 ES 5.1 ES 5.1成为ISO国际标准
    2013.03 ES 6.0 ES 6.0草案定稿
    2013.12 ES 6.0 ES 6.0草案发布
    2015.06 ES 6.0 ES 6.0预计发布正式版,JavaScript开始指向ES 7.0

1.2 ES6兼容性

  • ES6兼容性问题是怎样产生的?
      由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性进行兼容,那么浏览器肯定无法识别我们的ES6代码,好比浏览器根本看不懂我写的let和const是什么东西?只能报错了。这就是浏览器对ES6的兼容性问题。
  • 对ES6新特性最友好的浏览器有:IE10+、Chrome、FireFox、移动端、NodeJs
  • ES5兼容性查看:http://kangax.github.io/compat-table/es5/
  • ES6兼容性查看:http://kangax.github.io/compat-table/es6/

  • 使用Babel解决ES6兼容性问题

    • 在线转换:https://www.babeljs.cn/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="https://cdnjs.cloudflare.com/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);
  • 解构赋值注意事项
    1. 变量和数据必须一一对应
    2. 右侧数据必须是合法的数据类型
    3. 声明和赋值不能分开,必须在一句话里完成

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); //1
console.log(b); //2
console.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 = "https://www.baidu.com/";
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(); //Sain
my.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(); //Sain
my.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(); //Sain
my.showAge(); //26
my.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(); //Sain
my.showAge(); //26
my.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
  • 4

7.2 json简写

  • key和value的名字一样的时候,可以省略value
let 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

8、Promise
Promise——承诺

8.1 异步
操作之间没有关系
同时进行多个操作
回调写法代码复杂(回调地狱)
下面是异步操作代码,如果想要同时读取不同模块的数据,就要写成回调方式。

ajax('/top', function (top_data){
//top读取成功
ajax('/left', function (left_data){
//left读取成功
ajax('/right', function (right_data){
//right读取成功
ajax('/bottom', function (bottom_data){
//bottom读取成功
},function (){
console.log('bottom读取失败');
})
},function (){
console.log('right读取失败');
})
},function (){
console.log('left读取失败');
})
},function (){
console.log('top读取失败');
})

8.2 同步
同时只能做一件事
代码排队执行
代码简单,方便维护
下面是同步代码,不同模块分别调用,代码简洁:

let top_data = ajax_async('/top');
let left_data = ajax_async('/left');
let right_data = ajax_async('/right');
let bottom_data = ajax_async('/bottom');

8.3 Promise使用用法
Promise可以消除异步操作,用同步的方式来书写异步代码
let p = new Promise(resolve,reject){
$.ajax({
url: 'a.txt',
dataType: 'json',
success(data){
resolve(data); //resolve成功
},
error(err){
reject(err); //reject失败
}
})
}
p.then(function(data){
console.log('成功'+data);
}, function (err){
console.log('失败'+err);
});

8.4 Promise.all()的使用方法
我们用Promise创建了两个异步操作,使用Promise.all()来同时执行这两个操作,如果全部成功了就成功了,如果其中有一个失败了就失败了,等同于&&的关系。

除了Promise.all(),还有Promise.race() 方法,这两个方法的使用方法一样,不一样的是Promise.race()只执行成功的,忽略失败的,等同于||的关系。

let p1 = new Promise(resolve,reject){
$.ajax({
url: 'arr.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
let p2 = new Promise(resolve,reject){
$.ajax({
url: 'json.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
Promise.all([
p1, p2
]).then(
function (data){
let [res1,res2] = data; //解构赋值
console.log('全部成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一个失败了就是失败了');
}
)

8.5 封装Promise
function createPromise(url){
return new Promise(resolve,reject){
$.ajax({
url, //key和value一样,留一个就行
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
}
Promise.all([
createPromise('arr.txt');
createPromise('json.txt');
]).then(
function (data){
let [res1,res2] = data; //解构赋值
console.log('全部成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一个失败了就是失败了');
}
)

8.6 jquery的Promise使用
高版本jquery自带Promise支持
先在页面引入最新版本的jQuery<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

$.ajax({url: 'arr.txt, dataType: 'json'});

Promise.all([
$.ajax({url: 'arr.txt, dataType: 'json'});
$.ajax({url: 'json.txt, dataType: 'json'});
]).then(results => {
let [res1,res2] = results; //解构赋值
console.log('全部成功了');
console.log(res1);
console.log(res2);
}, err => {
console.log('有一个失败了就是失败了');
}
)

9、generator
generator生成器

普通函数:执行完才结束
generator函数:中间能暂停
9.1 generator函数的写法
在function和函数名中加上*,可以跟在function后面,也可以在function和函数名中间,也可以在函数名前面。

generator不能写成箭头函数方式。

function* show(){}
function * show(){}
function *show(){}

yield
```
function *show(){
console.log(1);
yield; //放弃执行
console.log(2);
}
let genObj = show(); //创建一个generator对象
genObj.next(); //1,调用next()执行一次

generator原理是生成了一堆小函数:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};

9.2 yield传参、返回
yield传参
function *show(){
let a = yield; //放弃执行
console.log(a); //5
}
let gen = show();
gen.next(10); //第一个next无法传参,第一个传参要写在generator函数参数里
gen.next(5);

根据上面代码我们可以知道generator无法接收到第一个next方法的参数,我们可以将第一个参数直接传入到generator函数参数里:
function *show(num){
console.log(num); //10
let a = yield; //放弃执行
console.log(a); //5
}
let gen = show(10); //第一个next()传参要写在generator函数参数里
gen.next();
gen.next(5);

generator原理是生成了一堆小函数:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};

yield返回
yield返回值有两个参数:
1. value就是generator函数执行到当前yield语句之后得到的值
2. done表示函数是否执行完成,true代表函数全部执行完成,flase代表函数暂停状态未执行完成

function *show(){
console.log(1);
let a = yield; //放弃执行
console.log(2);
return 3;
}
let gen = show();
let res1 = gen.next();
console.log(res1); //{value:1,done:false}
let res2 = gen.next();
console.log(res2); //{value:undefined,done:true}
console.log(res2); //{value:3,done:true} 最后的返回值要通过return返回

9.3 generator的用途
当Promise有逻辑执行的时候会比异步回调写法还麻烦,所以我们在工作中遇到异步需要逻辑判断的时候可以使用generator来写。
generator在有逻辑判断情况下写起来很简单
function *main(){
let data1 = yield $.ajax({url: '', dataType: 'json'});

if(data1.data == true) {
let data2 = yield $.ajax({url: '', dataType: 'json'});
} else {
let data3 = yield $.ajax({url: '', dataType: 'json'});
}
}
let gen = main();

————————————————

JavaScript 极简史

ECMAScript 6.0基础入门教程的更多相关文章

  1. 1.0 Android基础入门教程

    1.0 Android基础入门教程 分类 Android 基础入门教程 本教程于2015年7月开始撰写,耗时半年,总共148节,涵盖了Android基础入门的大部分知识,由于当时能力局限,虽已竭尽全力 ...

  2. React Native基础&入门教程:初步使用Flexbox布局

    在上篇中,笔者分享了部分安装并调试React Native应用过程里的一点经验,如果还没有看过的同学请点击<React Native基础&入门教程:调试React Native应用的一小 ...

  3. Linux基础入门教程

    Linux基础入门教程 --------- Linux学习路径 Linux学习者,常常不知道自己改怎么学习linux:Linux初级,也就是入门linux前提是需要有一些计算机硬件相关的知识或是有一下 ...

  4. Mongodb最基础入门教程

      Mongodb最基础入门教程 如果想了解一下redis的入门教程,可以去看一下我的上一篇博客 Mongodb的安装大家可以参考一下其他博主的博客,这里我就不做介绍了.不过值得注意的是,在Linux ...

  5. WordPress安装:零基础入门教程

    WordPress安装:零基础入门教程 1主机空间要求要运行 WordPress,主机空间需满足以下条件.不过现在网络上的空间基本都可以,而且还让你随意定制Php和Mysql版本,至于空间和数据库大小 ...

  6. [置顶] IOS 基础入门教程

    IOS 基础入门教程 教程列表: IOS 简介 IOS环境搭建 Objective C 基础知识 创建第一款iPhone应用程序 IOS操作(action)和输出口(Outlet) iOS - 委托( ...

  7. Python基础入门教程

    Python基础入门教程 Python基础教程 Python 简介 Python环境搭建 Python 基础语法 Python 变量类型 Python 运算符 Python 条件语句 Python 循 ...

  8. Vue-Router 基础入门教程

    Vue-Router 基础入门教程 前言 这周的计划是用VUE将之前的小demo的前端给重构了,并且做成前后端分离的样式,因为之前的那个聊天室的demo几乎都是在一个路由上完成的,所以学习Vue-ro ...

  9. Python运算符 - Python零基础入门教程

    目录 一.算术运算符 二.赋值运算符 三.比较运算符 四.运算符的优先等级 五.重点总结 六.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python ...

随机推荐

  1. linux上如何删除文件名乱码的文件

    这里写图片描述今天在服务上发现了两个文件名是乱码的文件,如图所示.这里写图片描述于是想用rm命令把它们删掉,但提示没有此文件. 网上搜了一下,找到解决方法,首先执行ls -i命令,此时在文件前面会出现 ...

  2. svn: local unversioned, incoming file add upon update

    svn 文件冲突: D C 文件名 > local unversioned, incoming file add upon update svn revert 文件名 提示: 已恢复“文件名” ...

  3. 云计算/云存储---Ceph和Openstack的cinder模块对接方法

    1.创建存储池 在ceph节点中执行如下语句. #ceph osd pool create volumes 2.配置 OPENSTACK 的 CEPH 客户端 在ceph节点两次执行如下语句,两次{y ...

  4. 使用wc -l 来统计代码行数

    Linux使用wc来统计行数真的好用 如在当前路径下统计一共多少行代码 $ find ./ -name *.c |xargs wc -l #包括了空行 ##-l :lines 如果不包括空行 ¥fin ...

  5. 行为型模式(六) 状态模式(State)

    一.动机(Motivate) 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同.   如何在运行时根据对象的状态 ...

  6. 双向认证下rpc-gateway使用(同时提供rpc和http服务)

    下载go get -v github.com/grpc-ecosystem/grpc-gateway,然后把这个包下面的third-party下面的google文件夹拷贝到Prod.proto的同级目 ...

  7. luoguP3768简单的数学题

    大佬们绕道吧(或跳到错误&启发后下一根横线后) 这道题吧正解是莫比乌斯反演吧,但本人有一种独创玄妙的想法去偏分 这道题是让我们求这个对吧 \((\sum_{i=1}^n\sum_{j=1}^n ...

  8. .net大文件分块上传断点续传demo

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  9. RookeyFrame 模块 线上创建的模块 迁移到 线下来

    1. 把线上创建的model,写在项目的model层里面. 把文件 Rookey.Frame.Web\Config\TempModel\Order_File.code 复制到model层, 用文本编辑 ...

  10. 洛谷 P1152 欢乐的跳 题解

    洛谷 P1152 欢乐的跳 题目描述 一个nn个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了[1,n-1][1,n−1]之间的所有整数,则称之符合"欢乐的跳",如数组1 ...