函数柯里化
柯里化
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数;目的是为了缩小适用范围,创建一个针对性更强的函数,核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余函数;
数学和理论计算机中的柯里化函数一次只能传递 一个参数,js实际应用中则可以传递一个或多个参数
简单版
function Curry(fn, ...args) {
return (..._args)=>{
return fn(...args, ..._args)
}
}
function V(l,w,h){
return l*w*h
}
const hcy = Curry(V,10)
console.log(hcy);
console.log(hcy(5, 8));
复杂版(通过闭包把初步参数给保存下来,继续收集参数,最后再执行)
代码是不是有点眼熟?没错!去看之前写的bind()方法的实现,就是用了柯里化机制;先保存原来的函数,返回一个新函数,执行新函数的时候就会调用这个保存的函数,这也是为什么bind()和call()、apply()不一样,它可以不立刻执行;
function Curry(fn, args) {
const self = this;
const len = fn.length;
const args = args || [];
return function () {
const newArgs = Array.prototype.slice.call(arguments);
Array.prototype.push.apply(args, newArgs);
if (newArgs.length < len) {
return Curry.call(self, fn, newArgs);
}
return fn.apply(this, newArgs);
}
}
反柯里化
意义和用法跟函数柯里化相比正好相反,扩大适用范围,创建一个应用范围更广的函数。使本来只有特定对象才适用的方法,扩展到更多的对象
Function.prototype.unCurrying = function(){
const self = this
return function(...rest) {
return Function.prototype.call.apply(self, rest)
}
}
new操作符的实现
new操作符实际上就是调用这个构造函数,同时将构造函数prototype上的属性挂上去;
- 新建一个对象
- 对象继承构造函数的原型链
- 将构造函数的this指向这个对象
- 根据构造函数的返回值返回结构
function myNew(fn) {
let obj = {}
obj = Object.create(fn.prototype) //{}
let args = Array.prototype.slice.call(arguments, 1)
//或者[..arguments].slice
let result = fn.call(obj, ...args)
return typeof result === 'object' || result instanceof Function ? result : obj
}
function myNew () {
let obj = {}
Constructor = [].shift.call(arguments)
obj.__proto__ = Constructor.prototype
let result = Constructor.apply(obj, arguments)
return typeof result === 'object'?result:obj
}
function Foo(name,arg) {
this.name = name
this.arg = arg
}
Foo.prototype.callName = function() {
console.log(this.name);
}
//test
let test = myNew(Foo,'zhangshan', 'is','22')
test.callName()
console.log(test.arg);
标签:function,return,函数,args,操作符,柯里化,new,prototype,fn
From: https://www.cnblogs.com/rain111/p/17206132.html