这三者非常有意思,也非常常用,即相似又不相似。
apply,call,bind的区别
共同点:三者都可以重定向this,
不同点:最大不同:bind()不会马上调用,而是返回一个新函数,称为绑定函数,
apply()与call()区别
apply:可以两个参数——新this对象和一个数组Array。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。
call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。
如果你的参数是数组或对象建议使用apply;如果是多个参数则使用call
/*apply()方法*/
function.apply(Obj,[1,2,3])
/*call()方法*/
function.call(Obj,1,2,3,4,5);
复制代码
手写apply,call,bind
Function.prototype.myapply = function (context) {
const fn = Symbol();
context[fn] = this;
let args = [...arguments].splice(1)
let result;
// if(args){
result = context[fn](args)
// }else {
// result = context[fn]()
// }
delete context[fn]
return result
}
Function.prototype.mycall = function (context){
if(typeof context !== 'object'){
//作用域对象应为一个object
throw new TypeError('TypeError, Expected for object');
}
if(context == undefined || context == null){
context = window;
}
let fn = Symbol();
context[fn] = this;
let args = [...arguments].splice(1);
let result = context[fn](...args);
delete context[fn];
return result;
}
Function.prototype.mybind = function (context){
let fn = this;
let args = [...arguments].splice(1);
return function () {
let newarg = args.concat([...arguments])
return fn.myapply(context,newarg)
}
}
复制代码
调用手写的函数
const per = {
fullName:function () {
console.log(this.firstName + "----halo---" + this.lastName )
}
}
const per2 = {
firstName: "Bill",
lastName: "Gates"
}
per.fullName.mycall(per2) //Bill----halo---Gates
per.fullName.myapply(per2) //Bill----halo---Gates
per.fullName.mybind(per2)() //Bill----halo---Gates
复制代码