ES6学习笔记--函数与数组的拓展

简介: ES6学习笔记--函数与数组的拓展

函数的拓展

参数的默认值

ES6之前,函数传入的参数没有默认值这一说法,所以我们经常要进行一些参数校验

function log(x, y) {
    if (typeof y === 'undefined') {
        y = 'world'
    }
    console.log(x, y)
}
log('hello')// hello world
log('hello', '') // hello 
log('hello', 'abc')//hello abc

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x, y = 'world') {
    console.log(x, y)
}
log('hello') //hello world
log('hello', '')//hello 
log('hello', 'abc')//hello abc

与解构赋值默认值结合使用

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

function foo({    x,    y = 5}) {
    console.log(x, y)
}
foo({x:1,y:2}) //1,2
foo({})// undefined 5
foo()// TypeError: Cannot destructure property `x` of 'undefined' or 'null'.

函数的length属性

指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2

rest参数

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

function add(...val) {
    let sum = 0 sum = val.reduce(((pre, cru) => {
        return pre + cru    
}))    
console.log(sum)}add(1, 2, 3)
}
add(1,2,3)

name属性

函数的name属性,返回该函数的函数名

function add(...val) {   ···}
add.name //add

箭头函数

let f = v => v
//相当于
let f = function (v) {
    return v
}

如果需要多个参数,则可以把参数放入圆括号中

let add = (num1, num2) => num1 + num2

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

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

注意点

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作 Generator函数。

尾递归

函数调用自身,称为递归。如果尾调用自身,就称为尾递归。

递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

function factorial(n) {
  if (n === 1) return 1;
  return n * factorial(n - 1);
}

factorial(5) // 120

上面代码是一个阶乘函数,计算n的阶乘,最多需要保存n个调用记录,复杂度 O(n)

如果改写成尾递归,只保留一个调用记录,复杂度 O(1)

function factorial(n, total) {
  if (n === 1) return total;
  return factorial(n - 1, n * total);
}

factorial(5, 1) // 120

数组的拓展

拓展运算符

含义

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

复制代码

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

替代apply方法

下面是一个利用Math.max求最大值的例子

//ES5
Math.max.apply(null, [1, 2, 3]),//3
//ES6      
Math.max(...[1, 2, 3])//3

拓展运算符的运用

  • 复制数组
let arr1 = [1,2]
let arr2 = arr1
arr2[1] = 'a'
console.log(arr1,arr2) //[ 1, 'a' ] [ 1, 'a' ]

数组是一个复杂类型,直接用等号赋值的话实际上只是复制了它的指针,即arr1arr2指向的是同一块内存。

//ES5
let arr1 = [1,2]
let arr2 = arr1.concat()
//拓展运算符
let arr1 = [1,2]
let arr2 = [...arr1]
  • 合并数组

扩展运算符提供了数组合并的新写法。

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' ]

不过,这两种方法都是浅拷贝,使用的时候需要注意。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true

Array.from

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set Map)。

下面是一个类似数组的对象,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']

Array.of()

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

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

entries(),keys() 和 values()

ES6 提供三个新的方法——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"
相关文章
|
13天前
|
算法 JavaScript 前端开发
ES6学习笔记--对象的拓展
ES6学习笔记--对象的拓展
|
13天前
|
JavaScript 前端开发 API
ES6学习笔记--字符串与数值的拓展
ES6学习笔记--字符串与数值的拓展
|
5月前
|
网络架构
ES6学习(五)—数组的扩展
ES6学习(五)—数组的扩展
|
5月前
|
网络架构
ES6学习(六)—函数的扩展
ES6学习(六)—函数的扩展
|
6月前
|
JavaScript 前端开发
如何把传统写法改成框架形式 es6
如何把传统写法改成框架形式 es6
29 0
|
11月前
|
JavaScript 前端开发 索引
【ES6】数组新增拓展
【ES6】数组新增拓展
60 0
|
11月前
【ES6】对象相关拓展
【ES6】对象相关拓展
28 0
|
11月前
【ES6】字符串新增拓展
【ES6】字符串新增拓展
51 0
|
11月前
【ES6】数值相关拓展
【ES6】数值相关拓展
46 0
|
11月前
|
JavaScript 前端开发 网络架构
每天3分钟,重学ES6-ES12(四)函数的补充 展开语法
每天3分钟,重学ES6-ES12(四)函数的补充 展开语法
58 0