一、call和apply是什么?
call 和 apply 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。
除了第一个参数外,call 可以接收一个参数列表,apply 只接受一个参数数组
二、手写call代码以及注释~
//1, call简单应用
// var foo={
// value:'1'
// }
// function bar(){
// console.log(this.value);
// }
// bar.call(foo)
//2,将bar函数挂载到foo对象上,使其成为foo的方法
// var foo={
// value:1,
//
// bar:function(){
// console.log(this.value);
// }
// };
// foo.bar()
//3,模拟call方法可以使函数成为对象的属性,通过调用对象的属性来用该函数
Function.prototype.mycall=function(context){
const fn =Symbol('fn');
context=context||window//context是{e:3}
context.fn=this
// console.log(this);//这里的this是g函数,把g函数绑定到context{e:3}上
const args=[...arguments].slice('1')//把后面的参数分离出来
const result=context.fn(...args)
delete context.fn//删除context.fn属性
return result
}
function g(a,b){
console.log(a,b);
console.log(this.e);
}
g.mycall({e:3},1,2)
三、手写apply代码以及注释
Function.prototype.mycall=function(context){
const fn =Symbol('fn');
context=context||window//context是{e:3}
context.fn=this
// console.log(this);//这里的this是g函数,把g函数绑定到context{e:3}上
const args=[...arguments].slice(1)//把后面的参数分离出来
// console.log(args);
const result=context.fn(args)//apply和call的区别在这,apply传过来的是一个数组
delete context.fn//删除context.fn属性
return result
}
function g(a){
console.log(a);//这里输出的也是一个数组
console.log(this.e);
}
g.mycall({e:3},[1,2])
三、手写bind代码以及注释
bind会返回一个函数
//1,简单应用
// var bar={
// a:1
// }
// function b(){
// console.log(this.a);
// }
// b.bind(bar)()
//2,手写
//先手写一个call
Function.prototype.mycall=function(context){
const fn=Symbol('fn')
context=context||window
context.fn=this
const args=[...arguments].slice(1)
const result=context.fn(...args)
delete context.fn
return result
}
Function.prototype.mybind=function (context){
//这里返回一个函数,箭头函数保证this的指向是Function
return ()=>{
return this.mycall(context)
}
}
var obj={a:1};
function bar(){
console.log(this.a);
}
bar.mybind(obj)()