马轩

个人主页

欢迎来到我的个人站~


API实现

实现reduce compose bind call apply

1.实现Reduce

«««< HEAD ​ ======= Reduce 的第一个参数是核心,它对数组的每一项进行”叠加操作“ 然后最后返回一个值,作为reduce方法的返回值。callback包含以下4个参数。

  1. previousValue 表示 callback函数上一次的返回值
  2. currentValue表示 数组遍历中正在处理的元素。
  3. currentIndex表示可选参数,表示currentValue在数组中对应的索引,如果提供了initialValue则起始索引值为0,否则为1。
  4. array是可选参数,表示调用reduce方法的数组。

下面我来展示一个顺序调用promise的代码:

const runPromiseInSequence = (array, vlaue) => array.reduce(
	(promiseChain,currentFunction) => promiseChain.then(currentFunction),
	Promise.resolve(value)
)
const f1 = ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      console.log("p1 is running!")
      resolve()
    },1000)
  })
}
const f2 = ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      console.log("p2 is running!")
      resolve()
    },1000)
  })
}
runPromiseInSequence([f1(),f2()],"init")

手写实现一个reduce:

Array.prototype.myreduce = function(func, initialValue){
	let arr = this
	let base = typeof initialValue === "undefined" ? arr[0] : arr[1]
	let startPoint = typeof initialValue === "undefined" ? 1 : 0
	arr.slice(startPoint).forEach(function(var, index)=>{
		base = func(base, val, index + startPoint, arr)
	})
	return base	
}

2.compose方法

Compose 方法主要目的就是为了执行一连串的不定长度的任务。

let funcs = [fn1,fn2,fn3,fn4]
let composeFunc = compose(funcs)

composeFunc(args)
=======> 相当于
fn1(fn2(fn3(fn4(args))))

下面来实现一下compose

const compose = (...funcs)=>{
 let init = funcs.pop()
 return (...args)=>{
   funcs.reverse().reduce((result,func)=>{
     chain.then(result => func.apply(null,result))
   },Promise.resolve(init.apply(null,args)))
 }
}

下面展示一下redux中compose写法:

function  compose(...funcs){
	if(funcs.length === 0){
		return args => args
	}
	if(funcs.length ===  1){
		return. funcs[0]
	}
	return funcs.reduce((a,b)=>(...args)=> a(b(...args)))
	// 这个实现真的是非常的巧妙
}

3.apply 和 bind 的实现

我先来写一下之前我自己实现的bind哈

Function.protoType.mybind = function(context,...args1){
	let func = this
	return function(...args2){
		return func.apply(context,[...args1,...args2])
	}
}

这个bind实现似乎已经还算可以了,但是实际上还是有一定的问题的,原因呢,就是我们在前面this的指向问题的时候,说到就是bind之后的函数配合new使用的时候,会忽略掉原来绑定的this,按照正常的new走向去进行。所以下面我们来实现新的bind函数。

Function.prototype.mybind = function(context,...args1){
	let func = this
	return function(...args2){
		return func.apply(this instanceof func ? this : context,[...args1,...args2])
	}
}

apply和call的实现就比较简单了

Function.prototype.mycall = function(targetObject,...argsArray){
	if(typeof targetObject === "undefined" || targetObject === null){
		targetObject = window
	}
	targetObject = new Object(targetObject)
	const targetFnKey = "targetFnKey"
	targetObject[targetFnKey] = this
	
	const result = targetObject[targetFnKey](...argsArray)
	delete targetObject[targetFnKey]
	return result
}

Function.prototype.mycall = function(targetObject,argsArray){
  if(typeof argsArray === "undefined" || argsArray === null){
		argsArray = []
	}
	if(typeof targetObject === "undefined" || targetObject === null){
		targetObject = window
	}
	targetObject = new Object(targetObject)
	const targetFnKey = "targetFnKey"
	targetObject[targetFnKey] = this
	
	const result = targetObject[targetFnKey](...argsArray)
	delete targetObject[targetFnKey]
	return result
}

4db3b043ec229eeeb6ea0fcafb33f19eaf3fb0b9

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦