-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaScript专题之偏函数 #43
Comments
大佬有公众号吗 |
@syzq 没有哎~ |
第二版 while(position < arguments.length) args.push(argumetns[position++]); 中后一个arguments拼成argumetns了 |
@SilenceZeng 非常感谢指出~ 已修改~ o( ̄▽ ̄)d |
总结得很棒! |
大佬开个公众号吧,这样可以有更大的动力~~ 赏你一杯咖啡,哈哈~~ |
@evanzlj 我现在维护三个平台就已经有点忙不过来啦,公众号就更麻烦了,而且我觉得还是 PC 端更适合学习一些,可以边看文章边动手试验代码。 |
可不可以这样理解,偏函数的一种特殊情况就是curry |
那这样说来 |
var _ = {}; |
大佬,这个偏函数是不是有点问题,subFrom20(5),subFrom20(4)都输出15,那个args被污染拉,是不是该拷贝一份 |
es6简化版 function partial(func, ...argsBound) {
return function(...args) {
return func.call(this, ...argsBound, ...args);
};
} |
你写错了吧。没有被污染啊 |
占位符用在里面有什么用 |
while(position < arguments.length) args.push(arguments[position++]); 直接换成 下面这样会不会好点 if(position < arguments.length) args = args.concat([].slice.call(arguments, position)); |
while(position < arguments.length) args.push(arguments[position++]) |
不一样吧,原文的意思是:将arguments[position]这个值放入到args中;你改后的意思是:将arguments从position位置截取到数组最后一项的所有值放入到args中;原文放入了一个值,你放入了从position位置到最后一个位置的好几个值 |
强烈建议大佬把博客文章整理一下搞个类似阮一峰老师的ES6微信小程序 |
您好,我最近一直在学习您编写的文章,在这一章中我实在分辨不出柯里化和偏函数的区别,还有能说明下这两者的应用场景吗? |
这段就是bind的实现呀 所以可以理解成 Function.prototype.bind函数也是一个偏函数啦 |
你可能没有注意到 第二个替换 while 改成了 if |
function partical(fn: Function, ...args: any[]): Function {
return function (...moreArgs: any[]) {
return fn(...args, ...moreArgs)
}
} |
更加函数式的实现: const _ = Symbol('_')
const partial = (fn, ...outerArgs) => {
return function (...innerArgs) {
return fn.call(this, ...outerArgs.map(arg => arg === _ ? innerArgs.shift() : arg), ...innerArgs)
}
}
partial._ = _ |
我认为应该这样比较好,占位符可以由编写成员自定义 function partial(fn, holder = partial, ...args) {
return function (...params) {
return fn.call(this, ...args.map((arg) => (arg === holder ? (arg = params.shift()) : arg)), ...params)
}
}~~~
这样看起来就完美了 |
“局部应用”翻译也有问题。逻辑上讲应该是 |
while(position < arguments.length) args.push(arguments[position++]); |
大佬 bind 和 局部应用 晕了 不太明白呢 |
定义
维基百科中对偏函数 (Partial application) 的定义为:
翻译成中文:
在计算机科学中,局部应用是指固定一个函数的一些参数,然后产生另一个更小元的函数。
什么是元?元是指函数参数的个数,比如一个带有两个参数的函数被称为二元函数。
举个简单的例子:
个人觉得翻译成“局部应用”或许更贴切些,以下全部使用“局部应用”。
柯里化与局部应用
如果看过上一篇文章《JavaScript专题之柯里化》,实际上你会发现这个例子和柯里化太像了,所以两者到底是有什么区别呢?
其实也很明显:
柯里化是将一个多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数。
局部应用则是固定一个函数的一个或者多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数。
如果说两者有什么关系的话,引用 functional-programming-jargon 中的描述就是:
partial
我们今天的目的是模仿 underscore 写一个 partial 函数,比起 curry 函数,这个显然简单了很多。
也许你在想我们可以直接使用 bind 呐,举个例子:
然而使用 bind 我们还是改变了 this 指向,我们要写一个不改变 this 指向的方法。
第一版
根据之前的表述,我们可以尝试着写出第一版:
我们来写个 demo 验证下 this 的指向:
第二版
然而正如 curry 函数可以使用占位符一样,我们希望 partial 函数也可以实现这个功能,我们再来写第二版:
我们验证一下:
写在最后
值得注意的是:underscore 和 lodash 都提供了 partial 函数,但只有 lodash 提供了 curry 函数。
专题系列
JavaScript专题系列目录地址:https://github.com/mqyqingfeng/Blog。
JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: