call bind apply 实现原理及部分数组实现原理
区别?
call
和apply
的作用都是使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。区别在于call
接受的参数是参数列表,apply
接受的是一个包含多个参数的数组
bind
方法创建一个新的函数,在调用之前,新函数的this
被指定为bind
的第一个参数,其余参数作为新函数的参数。供调用时使用
call 实现
利用的是this
的指向问题是谁调用就指向谁这个特性
// call
const obj={
name:'luo'
}
function allName(firstName:string,lastName:string){
console.log("this",this);
console.log(`我的全名是${firstName}${lastName}`)
}
// allName('qian','yu');
allName.selfCall(obj,'qian','yu')
Function.prototype.selfCall=function(context:any){
if(typeof this !=='function'){
throw new Error('not function');
}
// 当前this指向的是allName,self指向的是当前传递第一个参数,或者window
const selfThis:any=context || Window;
// 赋值给当前第一个参数的fn为allName
selfThis.fn=this;
// 取得剩余参数,剔除第一个参数
let arg=[...arguments].slice(1);
// 用第一个参数调用,allName内部的this指向已经改变
let res=selfThis.fn(...arg);
// 删除参数内部的fn
delete selfThis.fn;
// 返回结果
return res;
}
apply实现
apply 实现和call差不多一致,只不过是接
Function.prototype.selfApply=function(context:any,restParams:any[]){
if(typeof this !=='function'){
throw new Error('not function');
}
if(type)
let selfThis:any=context || Window;
selfThis.fn=this;
let res=selfThis.fn(...restParams);
delete selfThis.fn;
return res;
}
bind实现
可以借助apply
或者call
去改变指向,
Function.prototype.selfBind=function(context:any,...rest:any){
if(typeof this !=='function'){
throw new Error('not function');
}
const _this:Function=this;
return function Fn(){
if(_this instanceof Fn){
return _this(context,...arguments);
}
return _this.apply(context,rest.concat(...arguments))
}
}
Array.filter
filter()
方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
Array.prototype.selfFilter=function(fn:Function){
let res:any[]=[];
for(let i=0;i<this.length;i++){
if(fn(this[i])){
res.push(this[i]);
}
}
return res;
}
Array.map
创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
Array.prototype.selfMap=function(fn:Function){
let res:any[]=[];
for(let i=0;i<this.length;i++){
res.push(fn(this[i],i));
}
return res;
}
Array.reduce
对数组中的每个元素执行一个由您提供的reducer
函数(升序执行),将其结果汇总为单个返回值。
reducer
参数:1. Accumulator (acc) (累计器)Current Value (cur) (当前值)Current Index (idx) (当前索引)Source Array (src) (源数组)
Array.prototype.selfReduce=function(reducer:Function,initVal:any){
for(let i=0;i<this.length;i++){
initVal=reducer(initVal,this[i],i,this);
}
return initVal;
}