apply,call,bind是javascript提供的,三者的作用都是为了改变本身函数的this的指向,如果没有指定对象的话this自动指向全局对象,浏览器是windows,在node环境是global。
一、三个方法的的简单使用
- call()
function foo(a,b){
console.log(a+b) //3
console.log(this.name)//jennry
}
let obj = {
name:'jennry',
age:'23'
}
foo.call(obj,1,2)`
2.apply()
`function foo(a,b){
console.log(a+b) //3
console.log(this.name)//jennry
}
let obj = {
name:'jennry',
age:'23'
}
foo.apply(obj,[1,2])`
3.bind()
`function foo(a,b){
console.log(a+b) //3
console.log(this.name)/jennry
}
let obj = {
name:'jennry',
age:'23'
}
foo.bind(obj,1,3)()
二、三个方法的区别
call()传的参数是以逗号分隔的,apply()传的参数是以数组的形式传的,bind()方法是返回一个函数需要再次调用才会执行。
三、使用JS模拟实现call,apply,bind三个方法
1、call():
function call(fn, obj, ...args) {
//如果obj没有或者为空,则obj指向全局对象
if (!obj) {
obj = globalThis;
}
//将方法绑定到指定的obj对象上
obj.temp = fn;
//执行绑定的对象的方法并返回结果
obj.temp(...args);
//console.log(result)
//删除绑定到对象的属性方法
delete obj.temp;
//return result
}
//全局对象下绑定一个属性,测试obj为null时打印的name值
window.name = "tony";
let obj = { name: "jenny", age: 22 };
function foo(a, b) {
console.log(this.name,this); //jenny { name: "jenny", age: 22 }
console.log(a + b); //3
}
call(foo, obj, 1, 2);
2、apply()
function apply(fn, obj, args) {
//如果obj没有或者为空,则obj指向全局对象
if (!obj) {
obj = globalThis;
}
//将方法绑定到指定的obj对象上
obj.temp = fn;
//执行绑定的对象的方法并返回结果
const result = obj.temp(...args);
//删除绑定到对象的属性方法
delete obj.temp;
return result
}
window.name = "tony";
let obj = { name: "jenny", age: 22 };
function foo(a, b) {
console.log(this.name, this); //jenny { name: "jenny", age: 22 }
console.log(a+b);//3
}
apply(foo, obj,[1, 2]);
3、bind()
function call(fn, obj, ...args) {
//如果obj没有或者为空,则obj指向全局对象
if (!obj) {
obj = globalThis;
}
//将方法绑定到指定的obj对象上
obj.temp = fn;
//执行绑定的对象的方法并返回结果
obj.temp(...args);
//console.log(result)
//删除绑定到对象的属性方法
delete obj.temp;
//return result
}
window.name = "tony";
let obj = { name: "jenny", age: 22 };
function foo(a, b) {
console.log(this.name, this); //jenny { name: "jenny", age: 22 }
console.log(a+b);//3
}
function bind(fn,obj,...args){
return function(){
call(fn,obj,...args)
}
}
bind(foo,obj,1,2)()