首页 > 其他分享 >函数柯里化和new操作符的实现

函数柯里化和new操作符的实现

时间:2023-03-12 21:58:27浏览次数:40  
标签:function return 函数 args 操作符 柯里化 new prototype fn

函数柯里化

柯里化

在计算机科学中,柯里化(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

相关文章