1. call函数的实现
作用:函数调用,常用来给函数绑定指定的this,并执行该函数
参数:接收多个参数,第一个参数为要指定的 this对象
- 如果没有传入指定的对象,或者指定的对象为
undefined
,则默认指定 windows为要绑定的对象
var myObj = { name:'我是前端bug开发攻城狮' } function myFunc(name,age){ console.log('argument.name===',name) console.log('this.name:age==',this.name,':',age) } Function.prototype.myCall = function(context){ context = context || windows; context.fn = this; var args = [...arguments].splice(1,arguments.length-1); var result = context.fn(...args) delete context.fn; return result } myFunc.myCall(myObj,'路人甲',100)
第二版
var myObj = { name:'我是前端bug开发攻城狮' } var name = 'global' function myFunc(name,age){ console.log('argument.name==',name) console.log('this.name:age==',this.name,':',age) } Function.prototype.myCall = function(context){ if(context && typeof context !== 'object'){ return Error('第一个参数必须为对象') } context = context || window; context.fn = this; var args = [...arguments].splice(1,arguments.length-1); var result = context.fn(...args) delete context.fn; return result } // muFunc.myCall(myObj,'路人甲',100) myFunc.myCall(123);
2. apply函数的实现
用法:同 call函数,唯一的区别就是,apply接收两个参数
- 要绑定的this对象
- 参数数组
var myObj = { name:'我是前端bug开发攻城狮' } var name = 'global name'; function myFunc(name,age){ return { name: this.name, age:age, argName:name, } } Function.prototype.myBind = function(context,argArray){ if(context && typeof context !== 'object'){ return Error('第一个参数必须为对象') } context = context || window; context.fn = this; var result; if(argArray){ result = context.fn(...argArray) }else{ result = context.fn() } delete context.fn; return result } myFunc.myBind(myObj,['Kobe',24]);
3. bind函数的实现
用法:用来给调用的函数绑定一个this对象,并返回这个绑定了this之后的函数(只返回函数的引用,并不执行哦)
参数:接收多个参数,第一个参数为要绑定为this的对象,剩下的为函数的形参
注意:
- bind方法返回的函数,还可以继续收参数
- bind方法返回的函数,可以通过 new实例化
- 通过 new 实例化之后,之前绑定的this会失效
function myFunction(name,age){ console.log(this.value,name,age) return { value:this.value, name:name, age:age } } Function.prototype.myBind = function(context){ if(context && typeof context !== 'object'){ return Error('第一个参数必须为对象') } if(typeof this !== 'function'){ return Error('只有函数才能调用myBind函数') } contex = context || window; var args = [...arguments].slice(1) var that = this; var fn = function(){ that.call(this instanceof fn ? this : context,...args,...arguments) } return fn; } var fn1 = myFunction.myBind({value:'James'},'Kobe'); var result = new fn1('24') console.log(result)
4. 总结
相同点:call,apply,bind函数都是用来为函数绑定指定的 this对象的,且三个函数的第一个参数都必须为要绑定的this对象,没传则默认为
window
,传的不是对象则报错不同点:
- call:call函数从第二个参数开始,接收的参数都作为函数的形参,可以有多个
- apply:apply与call唯一的区别就是,apply接收的第二个参数是一个数组,所有函数的形参都包含在数组里面
- bind:bind函数不同于前两个函数,bind函数返回一个绑定
this
之后的函数的引用。而不是直接调用。且调用返回的函数的时候,可以继续传参,作为函数的形参使用(后续传入的参数会对应函数的形参列表,依次对应)。最特别的一点是,bind函数返回的函数的引用,可以通过new
实例化,实例化之后的函数就失去了bind绑定的this。