30分钟快速入门掌握ES6/ES2015的核心内容(上)


Posted in Javascript onApril 18, 2018

前言

ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。

也就是说,ES6就是ES2015。

虽然目前并不是所有浏览器都能兼容ES6全部特性,但越来越多的程序员在实际项目当中已经开始使用ES6了。所以就算你现在不打算使用ES6,但为了看懂别人的你也该懂点ES6的语法了...

在我们正式讲解ES6语法之前,我们得先了解下Babel。

Babel

Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。大家可以选择自己习惯的工具来使用使用Babel,具体过程可直接在Babel官网查看:

30分钟快速入门掌握ES6/ES2015的核心内容(上)

最常用的ES6特性

let, const, class, extends, super, arrow functions, template string, destructuring, default, rest arguments
这些是ES6最常用的几个语法,基本上学会它们,我们就可以走遍天下都不怕啦!我会用最通俗易懂的语言和例子来讲解它们,保证一看就懂,一学就会。

let, const

这两个的用途与var类似,都是用来声明变量的,但在实际运用中他俩都有各自的特殊用途。

首先来看下面这个例子:

var name = 'zach'
while (true) {
 var name = 'obama'
 console.log(name) //obama
 break
}
console.log(name) //obama

使用var 两次输出都是obama,这是因为ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。第一种场景就是你现在看到的内层变量覆盖外层变量。而let则实际上为JavaScript新增了块级作用域。用它所声明的变量,只在let命令所在的代码块内有效。

let name = 'zach'
while (true) {
 let name = 'obama'
 console.log(name) //obama
 break
}
console.log(name) //zach

另外一个var带来的不合理场景就是用来计数的循环变量泄露为全局变量,看下面的例子:

var a = [];
for (var i = 0; i < 10; i++) {
 a[i] = function () {
 console.log(i);
 };
}
a[6](); // 10

上面代码中,变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。而使用let则不会出现这个问题。

var a = [];
for (let i = 0; i < 10; i++) {
 a[i] = function () {
 console.log(i);
 };
}
a[6](); // 6

再来看一个更常见的例子,了解下如果不用ES6,而用闭包如何解决这个问题。

var clickBoxs = document.querySelectorAll('.clickBox')
for (var i = 0; i < clickBoxs.length; i++){
 clickBoxs[i].onclick = function(){
  console.log(i)
 }
}

我们本来希望的是点击不同的clickBox,显示不同的i,但事实是无论我们点击哪个clickBox,输出的都是5。下面我们来看下,如何用闭包搞定它。

function iteratorFactory(i){
 var onclick = function(e){
  console.log(i)
 }
 return onclick;
}
var clickBoxs = document.querySelectorAll('.clickBox')
for (var i = 0; i < clickBoxs.length; i++){
 clickBoxs[i].onclick = iteratorFactory(i)
}

const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。

const PI = Math.PI
PI = 23 //Module build failed: SyntaxError: /es6/app.js: "PI" is read-only

当我们尝试去改变用const声明的常量时,浏览器就会报错。

const有一个很好的应用场景,就是当我们引用第三方库的时声明的变量,用const来声明可以避免未来不小心重命名而导致出现bug:

const monent = require('moment')

class, extends, super

这三个特性涉及了ES5中最令人头疼的的几个部分:原型、构造函数,继承...你还在为它们复杂难懂的语法而烦恼吗?你还在为指针到底指向哪里而纠结万分吗?

有了ES6我们不再烦恼!

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念。新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法,也更加通俗易懂。

class Animal {
 constructor(){
  this.type = 'animal'
 }
 says(say){
  console.log(this.type + ' says ' + say)
 }
}

let animal = new Animal()
animal.says('hello') //animal says hello
class Cat extends Animal {
 constructor(){
  super()
  this.type = 'cat'
 }
}

let cat = new Cat()
cat.says('hello') //cat says hello

上面代码首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。简单地说,constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实例对象可以共享的。

Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。上面定义了一个Cat类,该类通过extends关键字,继承了Animal类的所有属性和方法。

super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

ES6的继承机制,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。

P.S 如果你写react的话,就会发现以上三个东西在最新版React中出现得很多。创建的每个component都是一个继承React.Component的类。详见react文档

arrow function

这个恐怕是ES6最最常用的一个新特性了,用它来写function比原来的写法要简洁清晰很多:

function(i){ return i + 1; } //ES5
(i) => i + 1 //ES6

简直是简单的不像话对吧...

如果方程比较复杂,则需要用{}把代码包起来:

function(x, y) { 
 x++;
 y--;
 return x + y;
}
(x, y) => {x++; y--; return x+y}

除了看上去更简洁以外,arrow function还有一项超级无敌的功能!

长期以来,JavaScript语言的this对象一直是一个令人头痛的问题,在对象方法中使用this,必须非常小心。例如:

class Animal {
 constructor(){
  this.type = 'animal'
 }
 says(say){
  setTimeout(function(){
   console.log(this.type + ' says ' + say)
  }, 1000)
 }
}

 var animal = new Animal()
 animal.says('hi') //undefined says hi

运行上面的代码会报错,这是因为setTimeout中的this指向的是全局对象。所以为了让它能够正确的运行,传统的解决方法有两种:

1.第一种是将this传给self,再用self来指代this

says(say){
  var self = this;
  setTimeout(function(){
   console.log(self.type + ' says ' + say)
  }, 1000)

2.第二种方法是用bind(this),即

says(say){
  setTimeout(function(){
   console.log(this.type + ' says ' + say)
  }.bind(this), 1000)

但现在我们有了箭头函数,就不需要这么麻烦了:

class Animal {
 constructor(){
  this.type = 'animal'
 }
 says(say){
  setTimeout( () => {
   console.log(this.type + ' says ' + say)
  }, 1000)
 }
}
 var animal = new Animal()
 animal.says('hi') //animal says hi

当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。

template string

这个东西也是非常有用,当我们要插入大段的html内容到文档中时,传统的写法非常麻烦,所以之前我们通常会引用一些模板工具库,比如mustache等等。

大家可以先看下面一段代码:

$("#result").append(
 "There are <b>" + basket.count + "</b> " +
 "items in your basket, " +
 "<em>" + basket.onSale +
 "</em> are on sale!"
);

我们要用一堆的'+'号来连接文本与变量,而使用ES6的新特性模板字符串``后,我们可以直接这么来写:

$("#result").append(`
 There are <b>${basket.count}</b> items
 in your basket, <em>${basket.onSale}</em>
 are on sale!
`);

用反引号(\)来标识起始,用${}`来引用变量,而且所有的空格和缩进都会被保留在输出之中,是不是非常爽?!

React Router从第1.0.3版开始也使用ES6语法了,比如这个例子:

<Link to={`/taco/${taco.name}`}>{taco.name}</Link>

React Router

destructuring

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

看下面的例子:

let cat = 'ken'
let dog = 'lili'
let zoo = {cat: cat, dog: dog}
console.log(zoo) //Object {cat: "ken", dog: "lili"}

用ES6完全可以像下面这么写:

let cat = 'ken'
let dog = 'lili'
let zoo = {cat, dog}
console.log(zoo) //Object {cat: "ken", dog: "lili"}

反过来可以这么写:

let dog = {type: 'animal', many: 2}
let { type, many} = dog
console.log(type, many) //animal 2

default, rest

default很简单,意思就是默认值。大家可以看下面的例子,调用animal()方法时忘了传参数,传统的做法就是加上这一句type = type || 'cat' 来指定默认值。

function animal(type){
 type = type || 'cat' 
 console.log(type)
}
animal()

如果用ES6我们而已直接这么写:

function animal(type = 'cat'){
 console.log(type)
}
animal()

最后一个rest语法也很简单,直接看例子:

function animals(...types){
 console.log(types)
}
animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]

而如果不用ES6的话,我们则得使用ES5的arguments。

总结

以上就是ES6最常用的一些语法,可以说这20%的语法,在ES6的日常使用中占了80%...

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript中Eval函数的使用
Mar 23 Javascript
Javascript倒计时代码
Aug 12 Javascript
Kibo 用于处理键盘事件的Javascript工具库
Oct 28 Javascript
JavaScript获取FCK编辑器信息的具体方法
Jul 12 Javascript
jQuery简单设置文本框回车事件的方法
Aug 01 Javascript
如何使用Vuex+Vue.js构建单页应用
Oct 27 Javascript
概述BootStrap中role=&quot;form&quot;及role作用角色
Dec 08 Javascript
使用BootStrap进行轮播图的制作
Jan 06 Javascript
VueJS 集成 Medium Editor的示例代码 (自定义编辑器按钮)
Aug 24 Javascript
Angular学习笔记之集成三方UI框架、控件的示例
Mar 23 Javascript
webpack优化的深入理解
Dec 10 Javascript
实现AJAX异步调用和局部刷新的基本步骤
Mar 17 Javascript
原生js实现拖拽功能基本思路详解
Apr 18 #Javascript
一个基于react的图片裁剪组件示例
Apr 18 #Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 #Javascript
Angular ng-animate和ng-cookies用法详解
Apr 18 #Javascript
JS实现的base64加密解密操作示例
Apr 18 #Javascript
JS实现简单获取最近7天和最近3天日期的方法
Apr 18 #Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
Apr 18 #Javascript
You might like
PHP常用代码大全(新手入门必备)
2010/06/29 PHP
php 中文字符串首字母的获取函数分享
2013/11/04 PHP
浅谈php和.net的区别
2014/09/28 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
指定位置如果有图片显示图片,无图片显示广告的JS
2010/06/05 Javascript
jQuery图片滚动图片的效果(另类实现)
2013/06/02 Javascript
常用js字符串判断方法整理
2013/10/18 Javascript
优化Node.js Web应用运行速度的10个技巧
2014/09/03 Javascript
JQuery实现样式设置、追加、移除与切换的方法
2015/06/11 Javascript
js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
2015/11/09 Javascript
Bootstrap每天必学之滚动监听
2016/03/16 Javascript
jQuery插件扩展测试实例
2016/06/21 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
Vue中自定义全局组件的实现方法
2017/12/08 Javascript
JavaScript实现仿Clock ISO时钟
2018/06/29 Javascript
通过jquery的ajax请求本地的json文件方法
2018/08/08 jQuery
在Vue项目中使用snapshot测试的具体使用
2019/04/16 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
JavaScript数组排序功能简单实现
2020/05/14 Javascript
使用 UniApp 实现小程序的微信登录功能
2020/06/09 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
vue项目查看vue版本及cli版本的实现方式
2020/10/24 Javascript
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
easy_install python包安装管理工具介绍
2013/02/10 Python
python实现字符串加密 生成唯一固定长度字符串
2019/03/22 Python
Python实现某论坛自动签到功能
2019/08/20 Python
计算Python Numpy向量之间的欧氏距离实例
2020/05/22 Python
Python基于pandas绘制散点图矩阵代码实例
2020/06/04 Python
HTML5 video视频字幕的使用和制作方法
2018/05/03 HTML / CSS
阿迪达斯丹麦官网:adidas丹麦
2016/10/01 全球购物
4s客服专员岗位职责
2013/12/01 职场文书
关于期中考试的反思
2014/02/02 职场文书
2014年团队工作总结
2014/11/24 职场文书
女方离婚起诉书
2015/05/18 职场文书
经销商会议开幕词
2016/03/04 职场文书
win10电脑右下角输入法图标不见了?Win10右下角不显示输入法的解决方法
2022/07/23 数码科技