JavaScript 中的参数处理

栏目: JavaScript · 发布时间: 6年前

内容简介:首先我们知道,js 当中是没有函数重载的,在我们处理可变函数的参数的时候,需要使用一些小技巧。arguments 是存在于函数(箭头函数除外)中的一个内部变量。arguments 包含了传递给函数的参数的信息。可以通过 arguments[0] 访问函数的第一个参数,arguments[1]访问函数的第二个函数,以此类推。即便如此,arguments 并不是一个数组对象,它仅仅是只能访问索引和有 length 属性。我们可以将 arguments 转化为真正的数组:arguments 会存在引擎的优化问题

首先我们知道,js 当中是没有函数重载的,在我们处理可变函数的参数的时候,需要使用一些小技巧。

arguments

arguments 是存在于函数(箭头函数除外)中的一个内部变量。arguments 包含了传递给函数的参数的信息。可以通过 arguments[0] 访问函数的第一个参数,arguments[1]访问函数的第二个函数,以此类推。即便如此,arguments 并不是一个数组对象,它仅仅是只能访问索引和有 length 属性。我们可以将 arguments 转化为真正的数组:

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
var args = Array.from(arguments);
var args = [...arguments];
复制代码

arguments 会存在引擎的优化问题,在后续的操作技巧中,我们不会使用 arguments 对象,而使用 ES6 的语法代替。

不定参数

定义函数 function func([params][,...args]) 。表示可以该函数可以接收不定长度的参数。

function func(...args) {
  // 解构赋值
  console.log(`arguments: ${args}`); // args 是数组
  let [params1, params2, ...paramsRest] = args; // 拿到传入第一个参数 params1 和第二个参数 params2 和剩余参数的数组 paramsRest
}
复制代码

现在我们来实现一个函数,它会在内部调用另外一个函数。

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 可以直接接收参数数组
};
复制代码

同理,部分参数确定,部分参数可变的写法:

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);
};
复制代码

默认参数

最基本的语法

function func(a, b = 0) {
  return a + b;
}
func(5); // b 默认为 0
复制代码

结合对象解构和展开

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();
  }
}
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网络、群体与市场

网络、群体与市场

大卫·伊斯利(David Esley)、乔恩·克莱因伯格(Jon Kleinberg) / 李晓明、王卫红、杨韫利 / 清华大学出版社 / 2011-10-1 / CNY 69.00

过去十年来,现代社会中复杂的连通性向公众展现出与日俱增的魅力。这种连通性在许多方面都有体现并发挥着强大的作用,包括互联网的快速成长、全球通信的便捷,以及新闻与信息(及传染病与金融危机)以惊人的速度与强度传播的能力。这种现象涉及网络、动机和人们的聚合行为。网络将人们的行为联系起来,使得每个人的决定可能对他人产生微妙的后果。 本书是本科生的入门教材,同时也适合希望进入相关领域的高层次读者。它从交......一起来看看 《网络、群体与市场》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具