那些必会用到的 ES6 精粹(中)

简介: 那些必会用到的 ES6 精粹(中)

6. 函数的扩展


除了在解构中说到的函数参数的默认值,还有不少经常会用到的方法。


6. 1 rest 参数


ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用 arguments 对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。


function add(...values) {
  let sum = 0;
  for (let val of values) {
    sum += val;
  }
  return sum;
}
add(2, 5, 3) // 10


上面代码的 add 函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数。


注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。


// 报错
function f(a, ...b, c) {
  // ...
}


6.2 箭头函数


ES6 允许使用“箭头”(=>)定义函数。


const f = v => v;
console.log('输出值:', f(3)) // 输出值: 3
// 等同于
const f = function (v) {
  return v;
};


如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。


// 等同于
const f = function () { return 5 };
const sum = (num1, num2) => num1 + num2;
// 等同于
const sum = function(num1, num2) {
  return num1 + num2;
};


如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用 return 语句返回。


const sum = (num1, num2) => { return num1 + num2; }


箭头函数的一个用处是简化回调函数。


const square = n => n * n;
// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);


注意: 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。


this 对象的指向是可变的,但是在箭头函数中,它是固定的。


function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
let id = 21;
foo.call({ id: 42 });
// id: 42


上面代码中,setTimeout 的参数是一个箭头函数,这个箭头函数的定义生效是在 foo 函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时 this 应该指向全局对象window,这时应该输出 21。但是,箭头函数导致 this 总是指向函数定义生效时所在的对象(本例是{ id: 42}),所以输出的是 42。


7. 数组的扩展


扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。


7.1 数组合并的新写法。


const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
7.2 函数调用。


function add(x, y) {
  return x + y;
}
const numbers = [4, 4];
add(...numbers) // 8


7.3 复制数组的简便写法。


const a1 = [1, 2];
// 写法一
const a2 = [...a1];
a2[0] = 2;
a1 // [1, 2]
// 写法二
const [...a2] = a1;
a2[0] = 2;
a1 // [1, 2]


上面的两种写法,a2 都是 a1 的克隆,且不会修改原来的数组。


7.4 将字符串转为真正的数组。


[...'hello']
// [ "h", "e", "l", "l", "o" ]


7.5 数组实例的 entries(),keys() 和 values()


用 for...of 循环进行遍历,唯一的区别是 keys() 是对键名的遍历、values() 是对键值的遍历,entries() 是对键值对的遍历。
for (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"


7.6 includes()


Array.prototype.includes 方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似。ES2016 引入了该方法。


[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true


该方法的第二个参数表示搜索的起始位置,默认为 0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为 -4,但数组长度为 3 ),则会重置为从 0 开始。


[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true


8. 对象的扩展


8.1 属性和方法 的简洁表示法


let birth = '2000/01/01';
const Person = {
  name: '张三',
  //等同于birth: birth
  birth,
  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};


8.2 Object.assign()


Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。


const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}


Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。


注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。


const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}


Object.assign 方法实行的是浅拷贝,而不是深拷贝。


const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2


上面代码中,源对象 obj1 的 a 属性的值是一个对象,Object.assign 拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。


9. Set


ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。


Set 本身是一个构造函数,用来生成 Set 数据结构。


// 基本用法
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
  console.log(i);
}
// 2 3 5 4
// 去除数组的重复成员
const array = [1, 1, 2, 3, 4, 4]
[...new Set(array)]
// [1, 2, 3, 4]
相关文章
|
11月前
|
前端开发 JavaScript
ES6(三)
es6补充知识
60 1
|
3月前
|
前端开发 JavaScript 网络架构
|
3月前
ES6常用知识小结
ES6常用知识小结
24 0
|
10月前
|
前端开发 JavaScript API
|
11月前
ES6(二)
es6相关知识
54 0
|
11月前
|
网络架构 索引
ES6(一)
- 使用let,声明的变量仅在块级作用域内有效 - var命令声明的,在全局范围内都有效 - const声明一个只读的常量。一旦声明,常量的值就不能改变。 - const的作用域与let命令相同:只在声明所在的块级作用域内有效。 - let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。 - let不允许在相同作用域内,重复声明同一个变量。 - 什么时候用 let,什么使用用 const——如果不知道用什么的时候,就用 const
44 0
|
前端开发 Java 网络架构
ES6(总结)
ES6(总结)
60 0
初学es6
初学es6
65 0
|
JavaScript 前端开发 Java
【ES6】初识
【ES6】初识
|
前端开发 JavaScript 网络架构
除了ES6,ES还有那些必须要懂得知识?
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值。
98 0
除了ES6,ES还有那些必须要懂得知识?