块级作用域变量声明关键字 let 、 const
let 、 const 与 var 的对比
- 不存在变量提升;
1
2
3
4
5
6
7// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2; - 暂时性死区(在代码块内,使用let命令声明变量之前,该变量都是不可用的);
1
2typeof x; // ReferenceError
let x; - let 和 const 都只能作为块级作用域变量的声明,且只能在块级作用域内生效,块内声明的变量无法在块级外层引用;
1
2
3
4
5
6{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1 - 使用 const 声明的变量必须进行初始化赋值,而且一旦赋值就不能再进行第二次修改;
1
2const b = 'hello';
b = 'world'; // Uncaught TyperError: Assignment to constant variable. - 使用 let 、 const 在全局作用域下声明的变量不会作为属性添加到全局作用域对象里面;
1
2
3
4
5let a = 1;
var A = 2;
console.log(window.a || global.a); // undefined
console.log(window.A || global.A); // 2 - 用 let 、 const 赋值语句的执行速度比使用 var 快约65%;
使用场景的区分
模块内不变的引用和常量,使用const
定义;可变的变量或引用使用let
声明;var
仅用于声明函数整个作用域内需要使用的变量。
字符串模板
1 | let name = "Bob", time = "today"; |
- 字符串模板可以在有字符串内容和变量混合连接的场景中,使得代码书写更高效与整洁
- 字符串模板不会压缩内部的换行和空格,而是按照原有的格式输出
解构赋值
解决了赋值的编码荣宇和模块按需导出的问题。主要分为数组解构和对象解构。
数组解构
▼ 变量的赋值
1 | let [a, b, c] = [11, 22]; |
▼ 指定默认值
1 | let [foo = true] = []; |
对象解构
▼ 变量的赋值(对象的属性没有次序,变量必须与属性同名,才能取到正确的值)
1 | let { foo, bar } = { foo: "aaa", bar: "bbb" }; |
▼ 指定默认值
1 | var {x = 3} = {}; |
数组的新特性
扩展运算符(...
)
1 | const arr =['hello', 'world']; |
注意点: ...
进行的数组复制是浅拷贝
扩展API
Array.from
: 用于将数组对象转化为真正的数组1
2
3
4
5
6
7
8
9
10
11let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']Array.of
: 将传入的一组参数转换为数组1
Array.of(3, 11, 8) // [3,11,8]
Array.prototype.copyWithin
: 可以在当前数组内部将指定位置的数组项复制到其他位置,然后返回当前数组,使用copyWithin
方法会修改当前数组1
2let colors = ['red', 'blue', 'green', 'green'];
colors.copyWithin(0, 3); // ['green', 'blue', 'green', 'green']Array.prototype.fill
: 使用给定值,填充一个数组,会改变原来的数组1
colors.fill('black'); // ['black', black', black', black']
Arrau.prototype.find
: 用于找出第一个符合条件的数组元素1
2
3
4
5colors.find(function(color) {
if(color === 'green') {
return color;
}
}) // greenArray.prototype.findIndex
: 用来返回某个特定数组元素在数组中的位置1
2
3
4
5colors.findIndex(function(color) {
if(color === 'green') {
return color;
}
}) // 2新的数组迭代方式
entries()
、keys()
和values()
,均可以用来遍历数组。它们都返回一个迭代器对象,也可以用for...of
循环进行遍历,区别是keys()
是对数组键名进行遍历,values()
是对数组键值进行遍历,entries()
是对数组中键值对进行遍历。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
增强函数
函数参数
ES6 对函数参数的改进主要是添加了默认参数、不定参数和拓展参数
▼ 默认参数
1 | function sayHi(name = 'ouven') { |
▼ 不定参数
1 | function sayHi(...name) { |
▼ 扩展参数
1 | let name = ['oven', 'zhang']; |
其中不定参数和扩展参数可以认为恰好是相反的两个模式,不定参数是使用数组来表示多个参数,扩展参数将多个参数映射到一个数组。
▼ 不定参数与 arguments 的对比
不定参数和arguments
都可以使用函数的形参来表示所有的参数组成的列表,但是arguments
不是真正的数组,所有使用数组的方法必须使用Array.prototype.slice.call
先将其转换成数组,所有使用起来不定参数更加的方便。
箭头函数
1 | var sum = (num1, num2) => num1 + num2; |
注意点:箭头函数没有完整的执行上下文,因为其 this 和外层的 this 相同,可以理解为它的执行上下文只有变量对象和作用域链, 没有 this 值。
增强对象
es6 中,对象的使用更加方便。在定义对象时通过属性简写、变量作为属性名或省略对象函数属性的书写等方式可以提高编码的效率。
1 | const name = 'onven'; |
注意点:为了代码便于维护和理解,建议尽量不将变量或对象作为对象的属性名。
学习参考:
ECMAScript 6入门——阮一峰
《现代前端技术解析》