es6 使用了默认参数的函数无法被 currying,坑啊!

2017-03-20 00:08:45 +08:00
 sunjourney

记得之前看 MDN 文档,上面写在 es6 之前要给函数默认参数的写法是:

var add = function (x, y) {
  x = (typeof b !== 'undefined') ?  x : 1
  return x + y
}

在 node 下给 var add = function (x = 1, y) blabla 做 currying ,报错了。。。怎么会呢?

百思不得骑姐,用 babel 试试吧,结果竟然是:

var add = function add() {
  var x = arguments.length <= 0 || arguments[0] === undefined ? 'oo' : arguments[0];
  var y = arguments[1];
  return x + y;
};

难怪不能 currying 。大呼 MDN 误我!赶紧去翻 MDN ,准备发贴开喷!!!

OMG , MDN 文档才发现写的居然是“一种常用的策略”:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters

好吧,我认栽了!但是转念一想, es6 和 bebel 的默认参数写法为啥不直接用 typeof 的思路呢?这样就不能做 currying 了

2451 次点击
所在节点    JavaScript
11 条回复
ctsed
2017-03-20 01:21:59 +08:00
var add = function (y, x=1) {
x = (typeof b !== 'undefined') ? x : 1
return x + y
}

-- or --

var add_c = function (y) {
return add(x=1, y)
}
sunjourney
2017-03-20 08:48:19 +08:00
@ctsed 这是手动 currying , 用 curry function 就不行了呢
lovedebug
2017-03-20 10:00:09 +08:00
默认参数柯里化? add 是个函数表达式,做柯里化不是应该对带参数的 add 做吗?
sunjourney
2017-03-20 10:06:59 +08:00
@lovedebug #3 如果默认参数是用 typeof 去实现,不消弥掉 arguments 的参数, underscore, lodash 的 curry 就可以对函数做 currying ,但如果是 babel 这种消弥掉默认 arguments 的方法,就无法判断 fn.length, currying 库的方法就不能用了,自己实现 currying 目前也没找到能用的方法
lujjjh
2017-03-20 10:47:33 +08:00
https://lodash.com/docs/4.17.4#curry

_.curry(func, [arity=func.length])

The arity of func may be specified if func.length is not sufficient.

不过话说回来,有默认参数做 currying 的感觉很奇怪
sunjourney
2017-03-20 11:00:56 +08:00
@lujjjh #5 Thanks ,没仔细看文档,原来还可以通过指定 arity 实现,哎,我自己写的 currying 想支持 curry function with partial arguments (ex: const add100 = curry(add, 100),看来是没法做 lodash arity 的支持,如果真的用 typeof 的方法做默认参数就没问这种烦恼。问题来了 typeof 和 arguments.length 两种优劣如何呢?何以最终实现是用 arguments.length 呢
sunjourney
2017-03-20 11:10:48 +08:00
@lujjjh #5 真遇到那种有默认参数的函数,没看源码, currying 又不报错,调用来报错,很无语
lujjjh
2017-03-20 11:13:08 +08:00
@sunjourney 你举的「 curry function with partial arguments 」的例子,完全可以写成
const add100 = curry(add)(100)

不用 arguments.length 没法区分是没传还是传了 undefined
sunjourney
2017-03-20 11:54:39 +08:00
@lujjjh #8 感谢解惑!
8qwe24657913
2017-03-28 17:38:49 +08:00
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/length
length 是必须传入的参数个数,默认参数是可选的,所以其之后的参数也是可选的,不算在 length 里
sunjourney
2017-03-28 17:43:55 +08:00
@8qwe24657913 #10 嗯呢,大部分的 es6 的书或文档貌似都没有提这些规范,总想给人 es6 有大动作的新鲜感,深入点的细节变动都不涉及,这些坑不踩踩都不行呢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/348702

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX