call()、apply()、bind()都能改变函数this的指向
call()、apply()调用以后立即执行,bind()调用后返回一个新的函数
call()和bind()能传参数或者数组,apply只能传数组
call()
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.call(obj, '李四', '王五')
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.call(obj, ['李四', '王五'])
实现
简单讲就是给对象新增一个方法,然后调用该对象的方法
Function.prototype.myCall = function(obj, ...args) {
let target = obj || window;
let key = Symbol();
target[key] = this;
let res = target[key](...args);
delete target[key];
return res;
}
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.myCall(obj, ['李四', '王五']);
apply()
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.apply(obj, ['李四', '王五'])
实现
和call区别是入参变成了数组
Function.prototype.myApply = function(obj, args) {
let target = obj || window;
let key = Symbol();
target[key] = this;
let res = target[key](...args);
delete target[key];
return res;
}
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.myApply(obj, ['李四', '王五']);
bind()
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.bind(obj, '李四', '王五')();
function test(a, b) {
console.log(a, b, this.name);
}
let obj = {
name: '张三'
};
test.bind(obj, ['李四', '王五'])()
实现
把新增函数方法和调用的步骤封装到函数返回了,这里用到了闭包
Function.prototype.myBind = function(obj, ...args) {
let target = obj || window;
const key = Symbol();
return (...innerArgs) = >{
target[key] = this;
let res = target[key](...args, ...innerArgs) delete target[key];
return res;
}
}
function test(a, b, c) {
console.log(a, b, c, this.name)
}
let obj = {
name: '张三'
}
let fun = test.myBind(obj, '李四');
fun('王五', '麻六');
fun('王五五', '麻六六');