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(); } } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Spring Boot统一异常处理以及参数校验
- 另一个go命令行参数处理器 - cmdr
- 另一个go命令行参数处理器 - cmdr
- cmdr 03 - 用流式接口定义命令行参数处理选项
- 聊一聊 Go 的那些处理命令行参数和配置文件的库
- 手把手带你使用 typescript 实现一个 axios 库(二)url 参数处理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Impractical Python Projects
Lee Vaughan / No Starch Press / 2018-11 / USD 29.95
Impractical Python Projects picks up where the complete beginner books leave off, expanding on existing concepts and introducing new tools that you’ll use every day. And to keep things interesting, ea......一起来看看 《Impractical Python Projects》 这本书的介绍吧!