ES6(函数扩展、数组扩展)

一、 函数扩展

1. 参数可以默认

  • ES5调用函数:如果给参数设置默认需要进行判断

  • ES6可以直接给参数设置默认

//ES5
function log(x, y) {
  //两种判断方法(传统分支判断、利用逻辑符)
  if (typeof y === 'undefined') {
  y = 'World';
  }
  //
  y = y || 'World';
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World
//ES6直接设置默认参数值
function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

参数变量是默认声明的,所以不能用letconst再次声明

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

2. 配合解构

参数默认值可以与解构赋值的默认值,结合起来使用

function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined

 以下代码参数值先生效:然后对这个默认值进行解构

// 写法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0]

// x 和 y 都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

// x 有值,y 无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

// x 和 y 都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined]

m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

 3. 参数的位置

默认值的参数都不是尾参数。这时,无法只省略该参数,而不省略它后面的参数,除非显式输入undefined

  • 如果传入undefined,将触发该参数等于默认值,null则没有这个效果
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]
function foo(x = 5, y = 6) {
  console.log(x, y);
}

foo(undefined, null)
// 5 null

4.reset()剩余参数

 ...变量名:直接生成新数组

用于获取函数的多余参数,这样就不需要使用arguments对象了

//对比一下argument和生产与参数的优势
// arguments变量的写法(先将伪数组变成真数组)
function sortNumbers() {
  return Array.from(arguments).sort();
}

// rest参数的写法(直接使用剩余参数然后变量排序)
const sortNumbers = (...numbers) => numbers.sort();

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

5.  严格模式

只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能设定为严格模式

// 报错
function doSomething(a, b = a) {
  'use strict';
  // code
}

// 报错
const doSomething = function ({a, b}) {
  'use strict';
  // code
};

// 报错
const doSomething = (...a) => {
  'use strict';
  // code
};

const obj = {
  // 报错
  doSomething({a, b}) {
    'use strict';
    // code
  }
};

 解决严格模式引起的麻烦

  • 设定全局性的严格模式
  • 函数包在一个无参数的立即执行函数里面
//设置全局严格
'use strict';

function doSomething(a, b = a) {
  // code
}
//把函数抱在午餐的立即执行函数
const doSomething = (function () {
  'use strict';
  return function(value = 42) {
    return value;
  };
}());

6.箭头函数 (简化回调函数)

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

var f = () => 5;
// 等同于
var f = function () { return 5 };

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

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

箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错 

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

 箭头函数注意点:

  • 箭头函数没有自己的this
  • 不可当作构造函数
  • 不能使用伪数组,可以使用剩余参数

二、数组扩展 

1. 扩展运算符

好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42

如果扩展运算符后面是一个空数组,则不产生任何效果。 

[...[], 1]
// [1]

函数调用时,扩展运算符才可以放在圆括号中,否则会报错。 

(...[1, 2])
// Uncaught SyntaxError: Unexpected number

console.log((...[1, 2]))
// Uncaught SyntaxError: Unexpected number

console.log(...[1, 2])
// 1 2

 2. 应用扩展运算符

复制数组

数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组

const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]
//a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化

 解决

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
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 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

 3.Array.from()

类似数组的对象和可遍历对象转为数组

let 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']
// arguments 对象
function foo() {
  var args = Array.from(arguments);
  // ...
}

4.Array.of() 

Array.of()方法用于将一组值,转换为数组

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]

 5. copyWithin()

Array.prototype.copyWithin(target, start = 0, end = this.length)

  • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
  • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
  • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]

// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]

// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]

6. find(),findIndex(),findLast(),findLastIndex() 

 find()方法找出数组中第一个小于 0 的成员:没有符合条件的成员,则返回undefined

[1, 4, -5, 10].find((n) => n < 0)
// -5

 findIndex()方法返回第一个符合条件的数组成员的位置:不符合条件,则返回-1

[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

 弥补indexOf查找不出 NaN

[NaN].indexOf(NaN)
// -1

[NaN].findIndex(y => Object.is(NaN, y))
// 0

 7. flat(参数)

拉平一个数组,参数(Infinity:全部)代表层数

[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]

[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]

[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]

 

 

你可能感兴趣的:(es6,javascript,开发语言)