ES6 你可能不知道的事 – 基础篇
序
ES6,或许应该叫 ES2015(2015 年 6 月正式发布),对于大多数前端同学都不陌生。
首先这篇文章不是工具书,不会去过多谈概念,而是想聊聊关于每个特性 你可能不知道的事,希望能为各位同学 正确使用 ES6,提供一些指导。
对于 ES6,有些同学已经在项目中有过深入使用了,有些则刚刚开始认识他,但不论你是属于哪一类,相信这篇文章都有适合你的部分。针对文章中的问题或不同意见,欢迎随时拍砖、指正。
正文
Let + Const
这个大概是开始了解 ES6 后,我们第一个感觉自己完全明白并兴致勃勃的开始使用的特性。
以如下方式使用的同学请举下手?
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// 定义常量
const REG_GET_INPUT = /^\d{1,3}$/;
// 定义配置项
let config = {
isDev : false,
pubDir: './admin/'
}
// 引入 gulp
let gulp = require('gulp');
// 引入gulp相关插件
let concat = require('gulp-concat');
let uglify = require('gulp-uglify');
let cssnano = require('gulp-cssnano');
|
很多人看完概念之后,第一印象都是:“const
是表示不可变的值,而 let
则是用来替换原来的 var
的。”
所以就会出现上面代码中的样子;一段代码中出现大量的 let
,只有部分常量用 const
去做定义,这样的使用方式是错误的。
你可能不知道的事
const
的定义是不可重新赋值的值,与不可变的值(immutable value)不同;const
定义的 Object,在定义之后仍可以修改其属性。
所以其实他的使用场景很广,包括常量、配置项以及引用的组件、定义的 “大部分” 中间变量等,都应该以const
做定义。反之就 let
而言,他的使用场景应该是相对较少的,我们只会在 loop(for,while 循环)及少量必须重定义的变量上用到他。
猜想:就执行效率而言,
const
由于不可以重新赋值的特性,所以可以做更多语法静态分析方面的优化,从而有更高的执行效率。
所以上面代码中,所有使用 let
的部分,其实都应该是用 const
的。
Template Strings(字符串模板)
字符串模板是我刚接触ES6时最喜欢的特性之一,他语法简洁,语义明确,而且很好的解决了之前字符串拼接麻烦的问题。
因为他并不是 “必须” 的,而且原有的字符串拼接思维根深蒂固,导致我们很容易忽视掉他。
使用实例
我们先来看看他的一般使用场景:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
|
const start = 'hi all';
const getName = () => {
return 'jelly';
};
const conf = {
fav: 'Coding'
};
// 模板
const msg = `${start}, my name is ${getName()}, ${conf.fav} is my favourite`;
|
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// 1. 与引号混用
const wantToSay = `I'm a "tbfed"`;
// 2. 支持多行文本
const slogan =
`
I have a dream today!
`;
// 比较适合写HTML
const resultTpl =
`
<section>
<div>...</div>
</section>
`;
|
Enhanced Object Literals(增强的对象字面量)
增强的对象字面量是 ES6 中的升华功能,他设计了很多简写,这些简写不但保留了明确的语义,还减少了我们多余的代码量。
当他的使用成为一个习惯时,我们会看到自己代码变得更为优雅。
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
const _bookNum = 4;
const basicConfig = {
level: 5
}
const config = {
// 直接指定原型对象
__proto__: basicConfig,
// 属性简写
_bookNum,
// 方法简写
getBookNum() {
return this.bookNum;
}
}
|
Arrows and Lexical This(箭头函数)
箭头函数是ES6中的一个新的语法特性,他的用法简单,形态优雅,备受人们青睐。
大多数同学初识这个特性时,更多的仅仅用它作为函数定义的简写,这其实就有些屈才了。
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// 未使用箭头函数的写法
{
...
addOptions: function (options) {
var self = this;
options.forEach(function(name, opts){
self[name] = self.addChild(name, opts);
});
}
}
// 使用箭头函数后的写法
{
...
addOptions: function (options) {
options.forEach((name, opts) => {
this[name] = this.addChild(name, opts);
});
}
}
|
可以注意到上下两段代码的区别。
在未使用箭头函数前,我们在过程函数中使用父级 this
,需要将其显式缓存到另一个中间变量中,因为过程函数有独立的 this
变量,会覆盖父级;使用箭头函数后,不但简写了一个过程函数( forEach
的参数),还省略掉了 this
的中间变量的定义。
原因:箭头函数没有独立执行上下文( this
),所以其内部引用 this
对象会直接访问父级。
插播:原来我们定义这个中间变量还有一个有趣的现象,就是明明千奇百怪,例如
self, that, me, _that, _me, Self...
,快站出来说说你用过哪个,还是哪几个~
当然,从这块我们也可以看出,箭头函数是无法替代全部 function
的使用场景的,例如我们需要有独立 this
的函数。
你可能不知道的事
- 箭头函数不但没有独立
this
,他也没有独立的arguments
,所以如果需要取不定参的时候,要么使用function
,要么用 ES6 的另一个新特性 rest(具体在 rest 中会有详解)。 - 箭头函数语法很灵活,在只有一个参数或者只有一句表达式做方法体时,可以省略相应括号。
JavaScript
123456789101112131415// 完整写法const getOptions = (name, key) => {...}// 省略参数括号const getOptions = key => {...}// 省略参数和方法体括号const getOptions = key => console.log(key);// 无参数或方法体,括号不能省略const noop = () => {};
有个简单小栗子,这一灵活的语法在写连续的Promise链式调用时,可以使代码更加优雅
JavaScript
1
2
3
4
5
6
7
8
9
10
11
|
gitPromise
.then(() => git.add())
.then(() => git.commit())
.then(() => git.log())
.then((msg) => {
...
})
.then(() => git.push())
.catch((err) => {
utils.error(err);
});
|
Destructuring(解构)
解构这个特性可以简单解读为分别定义,用于一次定义多个变量,常常用于分解方法返回对象为多个变量,分别使用。
使用过ES6的同学应该或多或少接触过这个特性,但是你可能不知道它如下几个用法:
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const bookSet = ['UED', 'TB fed', 'Not find'];
const bookCollection = () => {
return {book1: 'UED', book2: 'TB fed'};
};
// 1. 解构也可以设置默认值
const {book1, book3 = 'Not find'} = bookCollection();
// 2. 解构数组时候是可以跳过其中某几项的
const [book1,,book3] = bookSet; // book1 = 'UED', book3 = 'Not find'
// 3. 解构可以取到指定对象的任何属性,包括它包含的方法
const {length: setLength} = bookSet; // setLength = 3
|
Rest + Spread
Rest 和 Spread 主要是应用 ...
运算符,完成值的聚合和分解。
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// 1. rest 得到的是一个真正的数组而不是一个伪数组
const getOptions = function(...args){
console.log(args.join); // function
};
// 2. rest 可以配合箭头函数使用,达到取得所有参数的目的
const getOptions = (...args) => {
console.log(args); // array
};
// 3. spread 可以用于解构时,聚合所得的值
const [opt1, ...opts] = ['one', 'two', 'three', 'four'];
// 4. spread 可以用于数组定义
const opts = ['one', 'two', 'three', 'four'];
const config = ['other', ...opts];
|
Classes
ES6 中实现的一个语法糖,用于简化基于原型集成实现类定义的场景。
虽然有很多人不太喜欢这个特性,认为它作为一个简单增强扩展,并没有其他语言 class 应有的特点。
但是就我自己观点来看,还是感觉这样一种写法确实比原有的原型继承的写法语义更清晰、明确,而且语法更简单。
同样,可能有些用法是你之前容易忽略掉的,在此做个补充。
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 1. 静态变量
// ES6 的类定义实现了静态方法的定义,但静态变量呢?
// 可以用如下方式实现:
class TbFedMembers{
static get HuaChen(){
return 'jelly';
}
}
TbFedMembers.HuaChen; // "化辰"
// 2. 私有属性(私有属性有多种实现方式,只谈及其中一种)
// 闭包
const TbFedMembers = (() => {
const HuaChen = 'jelly';
return class{
getOneMemberName(){
return HuaChen;
}
};
})();
|
Promises
Promise 不只是一个对象、一个语法,他更是一种异步编程方式的变化
相信使用过 ES6 的同学都已经开始尝试了 Promise,甚至在不支持ES6的时候,已经开始使用一些基于 Promise 思想的开源框架。
那么我们之前用 Promise 究竟用的对么?有什么需要注意的点呢?
你可能不知道的事
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
// 1. 多个异步任务同时执行用 Promise.all,顺序执行使用链式调用
// Promise.all
Promise
.all([jsBuildPromise, cssBuildPromise])
.then(() => {
...
});
// chain
jsBuildPromise
.then(() => cssBuildPromise)
.then(() => {
...
});
// 2. Promise 的链式调用需要每一个过程返回一个 Promise 对象才能保证顺序执行
gitPromise
.then(() => git.add()) // 正确,箭头函数简写
.then(() => {
git.commit(); // 错误,函数返回 undefined,会立即执行下一过程
})
.then(() => {
return git.log(); // 正确
});
// 3. Promise 需要调用 catch 方法来捕获错误,而且过程内的错误不会阻塞后续代码执行
new Promise(() => {
f; // not define error !
})
.catch((err) => {
console.log(err) // show 'f is not define'
});
console.log('error test'); // 此行可以被正常执行
|
结语
基础篇主要是讲了我们最常用的一些特性,后续如果大家感兴趣,还可以再来个 “进阶篇”,最后,希望文章中的部分内容可以对大家理解和使用 ES6 有所帮助。
ES6 你可能不知道的事 – 基础篇的更多相关文章
- Java你可能不知道的事(3)HashMap
概述 HashMap对于做Java的小伙伴来说太熟悉了.估计你们每天都在使用它.它为什么叫做HashMap?它的内部是怎么实现的呢?为什么我们使用的时候很多情况都是用String作为它的key呢?带着 ...
- java你可能不知道的事(2)--堆和栈
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- overflow:hidden 你所不知道的事
overflow:hidden 你所不知道的事 overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. ...
- Spring中你可能不知道的事(一)
Spring作为Java的王牌开源项目,相信大家都用过,但是可能大家仅仅用到了Spring最常用的功能,Spring实在是庞大了,很多功能可能一辈子都不会用到,今天我就罗列下Spring中你可能不知道 ...
- java你可能不知道的事(2)--堆和栈<转>
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- [麦先生]TP3.2之微信开发那点事[基础篇](获取access_token)
在微信文档中一共提供了两个access_token:一个是伪全局配置的Access_token;一个是在微信网页授权时的小Access_token 很多刚刚接触微信开发的人经常会混淆这两个的作用: 我 ...
- 【Java基础】关于枚举类你可能不知道的事
目录 谈谈枚举 1. 枚举类的定义 2. 枚举类的底层实现 3. 枚举类的序列化实现 4. 用枚举实现单列 5. 枚举实例的创建过程是线程安全的 谈谈枚举 如果一个类的对象个数是有限的而且是不变的,我 ...
- SSH Config 那些你所知道和不知道的事 (转)
原文地址:https://deepzz.com/post/how-to-setup-ssh-config.html SSH(Secure Shell)是什么?是一项创建在应用层和传输层基础上的安全协议 ...
- 关于JavaScript对象,你所不知道的事(一)- 先谈对象
这篇博文的主要目的是为了填坑,很久之前我发表了一篇名为关于JavaScript对象中的一切(一) - 对象属性的文章,想要谈一谈JavaScript对象,可那时只是贴了一张关于这个主题的思维导图,今天 ...
随机推荐
- MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引
本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...
- A*寻路初探 GameDev.net
A*寻路初探 GameDev.net MulinB按:经典的智能寻路算法,一个老外写的很透彻很清晰,很容易让人理解神秘的A*算法.以下是一个中文翻译版. A*寻路初探 GameDev.net 作者: ...
- C# HttpWebRequest 绝技 转至 http://www.sufeinet.com/
转至: 在线测试工具http://www.sufeinet.com/thread-3690-1-1.htmlc# HttpWebRequest与HttpWebResponse 绝技 如果你想做一 ...
- Netty关闭客户端
在启动客户端的时候,我们一般会 channelFuture.channel().closeFuture().sync(); 这是一段阻塞的代码,除非链路断了,否则是不会终止的,我们可以在handler ...
- STL整理
sort 升序排列: iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素. iterator up ...
- VelocityTracker
VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch event, VelocityTracker通过跟踪一连串事件实时计算出 当前的速度,这样的用法在androi ...
- Linux Linux程序练习八
题目:自己动手实现一个守护进程,当控制台窗口关闭时还可以在后台运行.每隔一秒钟向my.log文件中插入一条记录,记录格式如下:yyyy-mm-dd hh:mi:se 记录内容,其中yyyy为年,mm为 ...
- C语言 野指针与空指针
//野指针与空指针的区别 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> //野指针是 ...
- no.3 base64
tool.chinaz.com的base64有的无法解密: 如:ZXZhbCgkX1BPU1RbcDRuOV96MV96aDNuOV9qMXVfU2gxX0oxM10pNTU2NJC3ODHHYWJI ...
- MySQL基础 - mysql命令行客户端
在Linux系统当中,mysql作为一个客户端命令程序,在很大程度上连接数据库都是使用mysql,因此很有必要熟悉mysql命令行的使用. 这里假设数据库用户为icebug,密码为icebug_pas ...