以下内容学习摘录自《ECMAScript 6 入门》1-8章
一、let和const命令 (与var的区别)
● 不存在变量提升问题
// var 的情况
console.log(foo); // 输出undefined
varfoo=2;
// let 的情况
console.log(bar); // 报错
letbar=2;
● 不允许重复声明
function func(arg){
let arg; // 报错
}
function func(arg){
{
letarg; // 不报错
}
}
● 块级作用域
在for循环中 用for(let i of array)而不用for(var i of array),因为用let的话,i的作用域只会在for循环内,如果在for循环外调用则会报错。而用var的话,var在全局范围内都有效,会有可能出现一些问题。
二、变量的解构赋值
● 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
● 提取 JSON 数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number); // 42, "OK", [867, 5309]
● 遍历 Map 结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
三、字符串的扩展
● 模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
ES5
'There are ' + basket.count + ' ' + 'items in your basket, ' + '' + basket.onSale + ' are on sale!'
ES6
`There are ${basket.count} items in your basket, ${basket.onSale} are on sale!`
四、函数的扩展
1.函数参数的默认值
ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
2. 箭头函数
● ES6 允许使用“箭头”(=>)定义函数,如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。箭头函数可以使得表达更加简洁,如简化回调函数。
// 正常函数写法
var result = values.sort(function (a, b) {
return a - b;
});
// 箭头函数写法
var result = values.sort((a, b) => a - b);
● 注意点:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
● 不适合场景
● 第一个场合是定义函数的方法,且该方法内部包括this。
● 第二个场合是需要动态this的时候,也不应使用箭头函数。
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});
上面代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this就是全局对象。如果改成普通函数,this就会动态指向被点击的按钮对象。
五、数组的扩展
1.扩展运算符
● 扩展运算符(spread)是三个点(...),它将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3
2.替代函数的 apply 方法
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
3.扩展运算符的应用
● 复制数组
// ES5 的写法
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1 // [1, 2]
// ES6 的写法
const a1=[1,2];
const a2=[...a1];
● 合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3); // [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
let temp = [...arr1, ...arr2, ...arr3]
console.log(temp) // [ 'a', 'b', 'c', 'd', 'e' ]
4.Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map) 。
实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).filter(p => {
return p.textContent.length > 100;
})
上面代码中,querySelectorAll方法返回的是一个类似数组的对象,可以将这个对象转为真正的数组,再使用filter方法。同时只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。
5.Array.of()
Array.of方法用于将一组值,转换为数组。Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。
Array.of() // [ ]
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2, 5) // [1, 2, 5]
6.数组实例的 find() 和 findIndex()
● 数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
[1, 4, -5, 10].find((n) => n < 0)
// -5
● 数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
7.数组实例的 fill()
fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。下面代码表示,fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束。
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
8.数组实例的 includes()
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值。
if (arr.indexOf(el) !== -1) {
// ...
}