JavaScript 中的參數處理

首先咱們知道,js 當中是沒有函數重載的,在咱們處理可變函數的參數的時候,須要使用一些小技巧。javascript

arguments

arguments 是存在於函數(箭頭函數除外)中的一個內部變量。arguments 包含了傳遞給函數的參數的信息。能夠經過 arguments[0] 訪問函數的第一個參數,arguments[1]訪問函數的第二個函數,以此類推。即使如此,arguments 並非一個數組對象,它僅僅是隻能訪問索引和有 length 屬性。咱們能夠將 arguments 轉化爲真正的數組:java

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
var args = Array.from(arguments);
var args = [...arguments];
複製代碼

arguments 會存在引擎的優化問題,在後續的操做技巧中,咱們不會使用 arguments 對象,而使用 ES6 的語法代替。node

不定參數

定義函數 function func([params][,...args])。表示能夠該函數能夠接收不定長度的參數。數組

function func(...args) {
  // 解構賦值
  console.log(`arguments: ${args}`); // args 是數組
  let [params1, params2, ...paramsRest] = args; // 拿到傳入第一個參數 params1 和第二個參數 params2 和剩餘參數的數組 paramsRest
}
複製代碼

如今咱們來實現一個函數,它會在內部調用另一個函數。app

const foo = (params1, params2, params3) => {
  return params1 + params2 + params3;
};

// 咱們不須要知道 foo 的形參列表。使用解構操做任意的形參列表。
const func = (...args) => {
  foo(...args); // 函數調用時候展開
  foo.call(null, ...args); // 使用 call 改變 this 的值。
  foo.apply(null, args); // apply 能夠直接接收參數數組
};
複製代碼

同理,部分參數肯定,部分參數可變的寫法:ide

function func(params1, ...args) {
  console.log(`arguments: ${args}`); // 剩餘參數的數組
}
複製代碼

按照 node.js 中的習慣,callback 通常是做爲最後一個參數,若是中間參數是不定的話,此時須要經過 typeof 判斷:函數

// 判斷參數
function func(err, params1, params2, callback) {
  if (typeof params1 === 'function') {
    callback = params1;
    params1 = null;
    params2 = null;
  } else if (typeof params2 === 'function') {
    callback = params2;
    params1 = null;
  } else if (typeof callback !== 'function') {
    throw new Error('參數錯誤');
  }
}

// 一些小伎倆
function func(err, ...args) {
  // 回調函數是數組 args 的最後一項
  const callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
  const [params1 = null, params2 = null] = args;
}
複製代碼

原生 js 中,有些函數是能同時接收  參數列表或參數數組做爲參數的,好比說 concat。咱們也能夠利用 concat 的這一特性編寫這樣的函數:優化

const func = (...args) => {
  const params = [].concat(...args); // 利用 concat 能同時接受多個參數或單個數組的特性
  console.log(params);
};
複製代碼

默認參數

最基本的語法ui

function func(a, b = 0) {
  return a + b;
}
func(5); // b 默認爲 0
複製代碼

結合對象解構和展開this

function func(a, { opt1 = '1', opt2 = '2' }) {
  console.log(a, opt1, opt2);
}
func(0, { opt1: '4' }); // 0 "4" "2"
func(0); // 錯誤! 由於第二參數沒定義

function func1(a, { opt1 = '1', opt2 = '2' } = {}) {
  console.log(a, opt1, opt2);
}
func1(0); // 能夠正確運行 0 "1" "2"
複製代碼

也能夠在函數內部進行處理

function func(a, opts) {
  opts = Object.assign(
    {
      opt1: '1',
    },
    opts
  ); // 使用 Object.assign 賦予默認值

  opts = {
    opt1: '1',
    ...opts,
  }; // 和 Object.assign 相似

  const { opts1 = '1', opts2 = '2' } = opts; // 解構賦值,給予默認值。
}
複製代碼

錯誤處理

結合默認參數的語法,咱們能夠實現一些錯誤檢測,好比說要求參數是必須傳入的:

function mandatory() {
  throw new Error('Missing parameter');
}
function foo(mustBeProvided = mandatory()) {
  return mustBeProvided;
}

foo(); // Error: Missing parameter
複製代碼

檢查參數最大長度

function func(x, y, ...extra) {
  if (extra.length > 0) {
    throw new Error();
  }
}
複製代碼
相關文章
相關標籤/搜索