ES6指北【4】——ES6的函數參數處理,超乎你想象

1、函數的默認參數值

1. ES6以前,咱們如何實現函數默認參數

1.1 方式一:使用邏輯運算符【||】

function test(x) {
  x = x || '默認值' // 使用||設置默認值
  console.log(x) 
}

test() // '默認值'

但這樣作有個很是明顯的缺陷
若是x的值爲null/+0或-0/NaN/''/false中的一個,x都會被設置爲默認值,但咱們的本意是在不傳值的時候才設置爲默認值javascript

所以有了第二種處理方式java

1.2 方式二:對參數是否爲undefined進行判斷

ES5其實原本就有函數默認參數, 只不過這個默認參數只能是undefined,沒法設置
function test(x) {
  console.log(x)
}

test() // undefined
因此咱們只要對傳入的值 是否爲undefined進行判斷就能夠實現自由設置默認參數了
function test(x) {
  if(!(Object.prototype.toString.call(x) === "[object Undefined]")) {
    console.log('默認值')
  } else {
    console.log(x) 
  }

}

test() // '默認值'

2. ES6實現函數默認參數

2.1 基本用法

其實很是簡單,直接在參數後面加個 = 號就行啦,看栗子吧
function test(x = '默認值') {
  console.log(x) 
}

test() // '默認值'
若是要給多個參數賦值,就像下面這樣寫
function test(x = '默認值1',y = '默認值2') {
  console.log(x,y) 
}

test() // 默認值1 默認值2
但這本質上其實仍是對 undefined作判斷,是 1.2小節的語法糖
function f(x = 1) {
    console.log(x)
}
f(undefined) // 1

2.2 參數默認值的惰性求值

參數默認值是不記錄值的,每次都會 從新計算參數默認表達式的值
// 阮一峯老師 ES6深刻淺出 的例子
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101 而不是 100
// mdn的例子
function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2] 而不是 [1, 2]
有同窗必定會有疑問,這不是廢話嗎?其實否則,好比 Python的參數默認值不必定是惰性求值,好比下面這個例子
>>> def f1(data=[]):
...     data.append(1)
...     return data
...
>>> f1()
[1]
>>> f1()
[1, 1]
>>> f1()
[1, 1, 1]

2、剩餘參數

函數剩餘參數的英文爲 —— Functions Rest Parameters,通常咱們剩餘參數爲 rest參數

1. 基本概念

注:概念摘自阮一峯老師的《ECMAScript 6 入門》
ES6 引入 rest 參數(形式爲 ...變量名),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。

從上面的概念中,咱們至少能夠知道以下三個信息python

  1. 語法——...+變量。這個變量的數據類型是數組,用來存放多餘的參數
  2. 做用——用於獲取函數的多餘參數
  3. 語法糖——rest參數必定是arguments對象的語法糖

1.1 基本用法

首先咱們要搞清楚什麼是多餘參數數組

function sum(x, y) {
  return x + y
}

sum(1, 2, '多餘1', '多餘2', '多餘3') // 3

從上面的例子咱們能夠看到,sum函數接受兩個參數的傳遞,可是用戶傳遞了五個參數,後面的三個參數即便傳遞也是沒法被sum函數使用,顯得有些多餘app

這裏的多餘並非無用的意思,而是相對於被使用到了的參數顯得多餘而已函數

那麼,若是咱們也想對這些多餘參數進行處理的話就須要使用rest參數prototype

// 用rest參數改寫以後
function sum(x, y, ...paraArr) {
  console.log(paraArr)
  return x + y
}

sum(1, 2, '多餘1', '多餘2', '多餘3') 
// ["多餘1", "多餘2", "多餘3"] 3

1.2 何時咱們會用到rest參數?

既然rest參數是arguments的語法糖,那麼咱們只要搞清楚以往arguments的應用場景是什麼,那麼天然就懂得如何使用rest參數了。rest

下面看一個使用arguments的例子code

// 建立一個sum函數,實現以下功能
// sum() // 0
// sum(1) // 1
// sum(2,10,2) // 14
// sum(0,0,200,1) // 201
// sum(1,10,3,2,100) // 116

function sum() {
  let total = 0
  for (let i = 0; i < arguments.length; i++) {
      total += arguments[i]
  }
  return total
}

從上面的例子咱們能夠發現其最大的特色是參數個數不肯定,因此若是遇到函數參數個數不肯定的狀況,就要優先考慮使用rest參數,並且因爲rest參數真數組,你用起來會比arguments舒服太多
下面是用rest參數進行改寫對象

// 建立一個sum函數,實現以下功能
// sum() // 0
// sum(1) // 1
// sum(2,10,2) // 14
// sum(0,0,200,1) // 201
// sum(1,10,3,2,100) // 116

function sum(...paraArr) {
  let total = 0
  paraArr.forEach(e => total += e)
  return total
}

2. 拓展:把arguments轉換爲真數組的三種方式

arguments由於能獲取到全部參數因此仍是有它的不可替代性的,可是其僞數組的特性實在有點噁心,下面教你們三種方法轉換,第一種是ES5的方法,剩下兩種是ES6的方法
function sum() {
  let arr1 = Array.prototype.slice.call(arguments)
  let arr2 = Array.from(arguments)
  let arr3 = [...arguments] // 這個是展開語法【spread syntax】 我會在ES6指北的下一章講解,敬請關注~~
}
相關文章
相關標籤/搜索