1. 三者的区别
- call和apply都是为了解决函数调用的时候函数内部this指向的问题,默认第一参数是this指向,其余的都是函数的形参。call的形参用逗号隔开,apply的参数用一个数组接收。
- call和apply是改变this指向后立即执行函数,而bind是返回一个绑定上下文的新函数,后续可以通过新函数执行。
- bind函数返回的新函数不可以再通过apply call改变它的this指向。
let a = {value:1};
function foo(name,age) {
console.log(name);
console.log(age);
console.log(this.value);
}
foo.call(a,"lisi",12);
foo.apply(a,["wangwu",13]);
let f = foo.bind(a);
f("zhangsan",15);
2.模拟实现call
Function.prototype.mycall = function(context) {
if (typeof this !== 'function') {
throw new TypeError("Not a Function")
}
context = context || window;
context.fn = this;
let args = Array.from(arguments).slice(1);
let result = context.fn(...args);
delete context.fn;
return result;
}
3.模拟实现apply
Function.prototype.myapply(context) {
if(type this !== 'function') {
throw new TypeError("Not a function");
}
context = context || window
context.fn = this;
let result;
if(arguments[1]) {
result = context.fn(...arguments[1]);
} else {
result = context.fn()
}
delete context.fn;
return result;
}
4. 模拟实现bind
Function.prototype.bind(context) {
if (typeof this !== 'function') {
throw new TypeError("Not a Function")
}
const _this = this;
const args = Array.prototype.slice.call(arguments,1);
return function F () {
if(this instanceof F) {
return new _this(...args,...arguments)
}else{
return _this.apply(context,args.concat(...arguments))
}
}
}