ES6 你可能不知道的事 – 基础篇

ES6 你可能不知道的事 – 基础篇

转载

作者:淘宝前端团队(FED)- 化辰

链接:taobaofed.org/blog/2016/07/22/es6-basics/

ES6,或许应该叫 ES2015(2015 年 6 月正式发布),对于大多数前端同学都不陌生。

首先这篇文章不是工具书,不会去过多谈概念,而是想聊聊关于每个特性 你可能不知道的事,希望能为各位同学 正确使用 ES6,提供一些指导。

对于 ES6,有些同学已经在项目中有过深入使用了,有些则刚刚开始认识他,但不论你是属于哪一类,相信这篇文章都有适合你的部分。针对文章中的问题或不同意见,欢迎随时拍砖、指正。

正文

Let + Const

这个大概是开始了解 ES6 后,我们第一个感觉自己完全明白并兴致勃勃的开始使用的特性。

以如下方式使用的同学请举下手?

// 定义常量

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时最喜欢的特性之一,他语法简洁,语义明确,而且很好的解决了之前字符串拼接麻烦的问题。

因为他并不是 “必须” 的,而且原有的字符串拼接思维根深蒂固,导致我们很容易忽视掉他。

使用实例

我们先来看看他的一般使用场景:

const start = ‘hi all‘;

const getName = () => {

return ‘jelly‘;

};

const conf = {

fav: ‘Coding‘

};

// 模板

const msg = `${start}, my name is ${getName()}, ${conf.fav} is my favourite`;

你可能不知道的事

// 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 中的升华功能,他设计了很多简写,这些简写不但保留了明确的语义,还减少了我们多余的代码量。

当他的使用成为一个习惯时,我们会看到自己代码变得更为优雅。

你可能不知道的事

const _bookNum = 4;

const basicConfig = {

level: 5

}

const config = {

// 直接指定原型对象

__proto__: basicConfig,

// 属性简写

_bookNum,

// 方法简写

getBookNum() {

return this.bookNum;

}

}

Arrows and Lexical This(箭头函数)

箭头函数是ES6中的一个新的语法特性,他的用法简单,形态优雅,备受人们青睐。

大多数同学初识这个特性时,更多的仅仅用它作为函数定义的简写,这其实就有些屈才了。

// 未使用箭头函数的写法

{

...

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 的函数。

你可能不知道的事

  1. 箭头函数不但没有独立 this,他也没有独立的 arguments,所以如果需要取不定参的时候,要么使用 function,要么用 ES6 的另一个新特性 rest(具体在 rest 中会有详解)。
  2. 箭头函数语法很灵活,在只有一个参数或者只有一句表达式做方法体时,可以省略相应括号。

// 完整写法

const getOptions = (name, key) => {

...

}

// 省略参数括号

const getOptions = key => {

...

}

// 省略参数和方法体括号

const getOptions = key => console.log(key);

// 无参数或方法体,括号不能省略

const noop = () => {};

有个简单小栗子,这一灵活的语法在写连续的Promise链式调用时,可以使代码更加优雅

gitPromise

.then(() => git.add())

.then(() => git.commit())

.then(() => git.log())

.then((msg) => {

...

})

.then(() => git.push())

.catch((err) => {

utils.error(err);

});

Destructuring(解构)

解构这个特性可以简单解读为分别定义,用于一次定义多个变量,常常用于分解方法返回对象为多个变量,分别使用。

使用过ES6的同学应该或多或少接触过这个特性,但是你可能不知道它如下几个用法:

你可能不知道的事

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 主要是应用 ... 运算符,完成值的聚合和分解。

你可能不知道的事

// 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 应有的特点。

但是就我自己观点来看,还是感觉这样一种写法确实比原有的原型继承的写法语义更清晰、明确,而且语法更简单。

同样,可能有些用法是你之前容易忽略掉的,在此做个补充。

你可能不知道的事

// 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 究竟用的对么?有什么需要注意的点呢?

你可能不知道的事

// 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 有所帮助。

参考资料

  • https://www.stackoverflow.com
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript
  • https://babeljs.io/docs/learn-es2015/
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript
  • https://ponyfoo.com/articles/es6-spread-and-butter-in-depth
  • http://12devs.co.uk/articles/promises-an-alternative-way-to-approach-asynchronous-javascript/
  • http://www.2ality.com/2015/01/es6-destructuring.html
  • http://www.datchley.name/es6-rest-spread-defaults-and-destructuring/
时间: 2024-08-09 06:23:15

ES6 你可能不知道的事 – 基础篇的相关文章

Android生命周期里你或许不知道的事

Android生命周期估计连初学者都再熟悉不过的东西了,但这里我抛出几个问题,或许大家以前没有想过或者可能认识的有些错误. 一.当A启动B时,A和B生命周期方法执行的先后顺序是怎样的?当按返回键返回时,又是怎样的?(读者可以先想想,可能会跟你的答案不一致) A--->B时,打印结果如下: 按返回键B--->A,打印结果如下: 结论:先执行当前显示Activity的onPause方法,接着执行完将要显示Activity的生命周期方法,最后再执行当前显示Activity的其它生命周期方法 二.生命

网站细节优化,你不得不知道的事

你怎么做优化的?这句话问到许多人的时分他们都是一个回答."文章,外链",其实,搜索引擎优化真的并不是如此.下面天津搜索引擎优化小编举个简略的比方,就好比咱们买了个新房子,文章即是你房子中的家私,外链即是你需求来观赏的兄弟.你的家私多,而且异乎寻常,也即是说你的文章多,自创,当然可以很招引你需求到来的兄弟们的眼球.可是,如果你的房子地没扫,各种规划不合理,很有可能会给别人形成肮脏的印象.所以,做搜索引擎优化并不是只要文章还有外链,还需要你进行仔细的润饰,也即是咱们做的网站细节优化.下面我

overflow:hidden 你所不知道的事

overflow:hidden 你所不知道的事 overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. 一提到清除浮动,我们就会想到另外一个CSS样式:clear:both,我相信对于这个属性的理解大家都不成问题的.但是对于“浮动”这个词到底包含什么样的含义呢?我们下面来详细的阐述一下. <div id="wai"> <div id="nei">

openssh你所不知道的事

前几天在公司看到有人使用"ssh-agent /bin/bash -c 'ssh-add ~/.ssh/identity; git pull sth'"这样的命令从gitlab上面拉应用.第一次见到这样的使用感觉好高端啊!(其实是本人孤陋寡闻了),于是抱着好奇的心使用man科普一下(这里装了一下逼,md结果什么都没看懂,这逼装得真失败还是直接百度吧),找到了两篇介绍挺详细的文章. http://www.ibm.com/developerworks/cn/linux/security/o

关于微服务架构,你不得不知道的事

现如今随着新一代IT技术的发展,业务需求变的日益复杂,企业对于IT的敏捷性有了更高的要求,需要快速部署.开发.上线.迭代.传统的IT架构面临巨大挑战,往往系统还未搭建好需求就已改变.所以,以云计算.大数据.移动互联网和物联网等新一代IT技术作为技术支撑,微服务架构模式应运而出,为敏捷部署以及复杂企业应用实施提供巨大的帮助. 微服务架构不是凭空而来,互联网的连接正在变革一个个的应用场景,(2C端)比如说拼车.滴滴打车,出门前就可以把车叫好,在北京还有回家吃饭的app,在周边的人做了饭就给你送过来,

移动开发不能不知道的事- css3复选框样式自定义

样式化复选框(Styling Checkbox) 复选框 Checkbox 是 Web 应用常用控件,随处可见,原生的复选框控件一般就像下面这样: 选中状态  未选状态 这取决于操作系统和浏览器,有些时候,这种样子并不能满足设计要求,这时需要更为精致的复选框样式.以往只有少数浏览器才支持对这类控件应用样式,比如拿到这样一张设计图: blue.png 在过去,想要通过简单地修改样式达成这种设计效果根本不行,不过,现在借助强大的 CSS3 属性 appearance 可以对该类控件有空前的样式控制能

详解php中switch你可能不知道的事

switch的常规用法是传递一个参数然后逐一跟case对比: switch (variable) {     case 'value':         // code...         break;          default:         // code...         break; } 在分支比较多的时候:switch要比if else if好用:比如: if('value'){     // code... }else if('value2'){     // cod

Java你可能不知道的事系列1

概述 本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解.如果有不对的地方还请各位观众拍砖. 今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟悉不过了,今天我们就来和她再次邂逅,好了下面开始. 先来说说String特点 String是不可变的常量,每当我们创建一个字符串对象的时候,如果堆区的常量池里不存在这个字符串,就会创建一个存储在常量池里(String存的地方叫String pool),如果存在了,就直接把变量的地址指向常量池里,比如

移动开发不能不知道的事-meta

webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用 <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" /> <meta content="yes" name="apple-mobile-web-app-capa