常常会有人问一些像 "我应该使用对象来传递函数参数吗" 这类问题。我确定你知道这种模式,因为这在许多库中很常见:
- $.post({
- a: 'lot',
- of: 'properties',
- live: 'in',
- here: 'yep'
- })`
但是我想说,这实际上不是一个好主意。
让我们看看再 JavaScript 中定义函数参数列表最佳的实践。
把对象当作参数传递给函数的问题是你要传入的值指向不清。
像 jQuery 这样的库,这不是一个大问题——就是看看文档然后就知道你要怎么做了。但是在自定义代码中,你会在工作中碰到?看看文档…… 啊!等等!哪来的文档!Yeah。
尽可能多的文档当然好,自定义代码库永远不会有这种你需要的文档。如果你需要弄清一些方法需要的参数,你需要深入了解源代码。
这个问题可以用一个例子来解释。这里有一个用于控制其他函数之间间隔的函数。
- function throttle(o) {
- o.threshhold || (o.threshhold = 250);
- var last,
- deferTimer;
- return function () {
- var context = o.scope || this;
- var now = +new Date,
- args = arguments;
- if (last && now < last + threshhold) {
- // hold on to it
- clearTimeout(deferTimer);
- deferTimer = setTimeout(function () {
- last = now;
- o.fn.apply(context, args);
- }, o.threshhold);
- } else {
- last = now;
- o.fn.apply(context, args);
- }
- };
- }
快!你往参数对象中放入了什么值?
没有浏览整个函数的话,你是找不到关于参数的恼人线索的,甚至之后,你可能会出错。
这里是原始的注释:
- function throttle(fn, threshhold, scope)`
快!函数取了什么参数??
如果你拆解了这个炸弹,然后你需要回答那个问题或者爆炸,并且你只有几秒钟的时间思考…… 我肯定具有独立的参数会比较好。
好啦,那么第一个最佳尝试是:给你的函数使用单独命名的参数
此外,单独的参数如果在一个函数式编程风格中同样很有帮助。在 FP 中一个常见的事是调用函数,如果你的函数使用对象作为参数,那么会非常苦逼。
单独的参数是一个很好的开始,那么我们将会在函数有可选参数的时候遇到问题。
对于只有一个可选参数的函数来说,解决方案很简单:
function stuff(requiredA, requiredB, optional)
最佳实践:可选项放在最后
然而,如果你有多于一个的可选项,问题…… 如果我们只传 个可选参数如何?
- function foo(required, optionalA, optionalB) {
- /* something */
- }
- foo('hello', undefined, 1337);
啊!需要填充类似于 undefined 的值,这真的是越来越复杂了——同样需要调用他们,并且需要在函数中处理这些参数
在多可选参数的情况下,我们可以使用对象。这并没有真正地解决问题,但是这意味着我们不需要处理额外的值。
foo('hello', {optionalB: 1337});
最佳实践:如果有超过一个可选参数时,使用对象
最后,如果你使用 ES6 或者 TypeScript,我们可以使用一些新的语法。
对于有可选参数的函数,我们并不清楚这个参数是否可选。有了 ES6,我们能够提供一个默认值让这个变得明显:
- function something(a, b = 'default value') {
- //if b is not passed, its value becomes 'default value'
- }
最佳实践:给可选参数提供默认值
我们可以使用解构参数列表中对象和它的默认值。
- function foo(required, {
- optionalA,
- optionalB
- } = {}) {
- //available variables:
- //required, optionalA, optionalB
- }
- foo('hi', {
- optionalA: 1,
- optionalB: 1337
- });
这给了你两全其美的办法。你可以方便地使用对象作为参数,但是对象的属性能够从函数的注释中看到。
最佳实践:使用 ES6 解构重要的地方
对于上述建议的补充,在函数声明前使用注释是另一个有用的习惯。这对于读者来说非常有用,能够迅速了解大概,不仅仅是函数的参数,还有他们的类型和其他注意点。
总结:
这是另一个你可以用 ES6 默认参数做的有趣事情。通常情况下,如果你不传递一个必要的参数,什么事都不会发生。但是有了默认值,我们可以让代码自动抛出一个缺少必要参数的错误!David Walsh 有一个 。
来源: