这篇文章翻译自ES6 tips and tricks to make your code cleaner, shorter, and easier to read!. 文章就代码整洁方面对es6进行了总结。如有错误欢迎指出。
template literals 模板字符串
模板字符串使字符串的使用变得比以前更简单了,他们以反引号开始(`),并且能过使用${变量}来插入变量。我们来比较一下下面两行代码。
var fName = 'Peter', sName = 'Smith', age = 43, job= 'photographer'; var a = 'Hi, I\'m ' + fName + ' ' + sName + ', I\'m ' + age + ' and work as a ' + job + '.'; var b = `Hi, I'm ${ fName } ${ sName }, I'm ${ age } and work as a ${ job }.`;
一切都变得很美好了是不是,代码更易读了是不是?你可以在大括号内放入任何东西:变量,等式,或者函数的调用。 我将会在后面的整个文章的示例中使用这些方式。
块级作用域语法
JavaScript是使用函数作用域的,这就是为什么我们是为什么我们越来越频繁的使用匿名的立即执行函数表达式(iife)来实现整个JavaScript文件的封装。我们这么做是为了把所有的变量隔离在文件内从而避免变量冲突。
现在我们有了块级作用域和两个崭新的块级作用域的变量声明
let declaration let命令
这个命令和var很相似但却又有着显著的不同。因为他是有块级作用域的,声明一个相同名字的新变量可以完全不影响外部的变量。
var a = 'car' ; { let a = 5; console.log(a) // 5 } console.log(a) // car
因为他是被限制在块级作用域的,他解决了那道非常经典的面试题:“下面这个代码的输出是什么,如何修改让他运行之后成为你想的那个样子?”
for (var i = 1; i < 5; i++){ setTimeout(() => { console.log(i); }, 1000); }
这个例子中,输出是“5 5 5 5 5”因为变量i在每次迭代中都会改变。
如果我们把var变为let,一切都变了。 现在,每次循环都会创建一个全新的块级作用域吧i限制在当前的循环,他可以理解为这样:
{let i = 1; setTimeout(() => { console.log(i) }, 1000)} {let i = 2; setTimeout(() => { console.log(i) }, 1000)} {let i = 3; setTimeout(() => { console.log(i) }, 1000)} {let i = 4; setTimeout(() => { console.log(i) }, 1000)} {let i = 5; setTimeout(() => { console.log(i) }, 1000)}
var 和 let的另外一个区别是 let 不会像 var一样被变量提升
{ console.log(a); // undefined console.log(b); // ReferenceError var a = 'car'; let b = 5; }
因为他有更为局限的作用域,以及更能被预测的行为,因此一些人甚至认为你应该使用let来代替var, 除非当你真的特别需要变量提升或者更宽松的作用域范围,你再使用var
Const
在以前,如果你想在JavaScript中声明一个常量, 习惯性的做法是使用全大写来命名。然鹅,这不是真的去保护了这个变量不能被更改---只是让其他的开发者知道,这是一个常量,它不应该被更改。
现在我们有了const命令.
const没有让变量完全不可变,只是锁定他的赋值,当你有一个复杂的变量(数组或者对象)的时候,值还是可以被修改的。
{ const d = [1, 2, 3, 4]; const dave = { name: 'David Jones', age: 32}; d.push(5); dave.job = "salesman"; console.log(d); // [1, 2, 3, 4, 5] console.log(dave); // { age: 32, job: "salesman", name: 'David Jones'} }
Problem with block scoping functions函数块级作用域化带来的问题
函数的声明也可以限制在块级作用域中。
{ bar(); // works function bar() { /* do something */ } } bar(); // doesn't work
但是当你在一个if语句中声明一个函数的时候问题来了。
想一下这种情况:
if ( something) { function baz() { console.log('I passed') } } else { function baz() { console.log('I didn\'t pass') } } baz();
在ES6之前,这两个函数声明都被变量提升,而且结果一定是I didn't pass 不论条件中的something是什么。但现在我们会得到输出ReferenceError, 因为 baz一直被限定在块级作用域内。
Spread 扩展运算符
ES6介绍了...操作符,这个操作符指的就是‘扩展运算符‘。他的主要用途有两个:1. 将一个数组或者对象放到一个新的数组或者对象中 2. 将数组中的多个参数合并在一起
第一个用途可能是你将会使用的最多的。所以我们先来看他。
let a = [3, 4, 5]; let b = [1, 2, ...a, 6]; console.log(b); // [1, 2, 3, 4, 5, 6]
如果我们想把一个数组内的一组参数传递给函数,这个时候扩展运算符就十分的有用了。
function foo(a, b, c) { console.log(`a=${a}, b=${b}, c=${c}`) } let data = [5, 15, 2]; foo( ...data); // a=5, b=15, c=2