JS中call()、apply()、bind()改变this指向的原理
大家如果想了解改变this指向的方法,大家可以阅读本人的这篇改变this指向的六种方法
大家有没有想过这三种方法是如何改变this指向的?我们可以自己写吗?
答案是:可以自己写的
让我为大家介绍一下吧!
1.call()方法的原理
Function.prototype.calls = function (context, ...a) {
// 如果没有传或传的值为空对象 context指向window
if (typeof context == null || context == undefined) {
context = window;
}
// 创造唯一的key值 作为我们构造的context内部方法名
let fn = Symbol();
// this指向context[fn]方法
context[fn] = this;
return context[fn](...a);
}
let obj = {
func(a,b){
console.log(this);
console.log(this.age);
console.log(a);
console.log(b);
}
}
let obj1 = {
age:"张三"
}
obj.func.calls(obj1,1,2);
打印结果:
2.apply()方法的原理
// apply与call原理一致 只是第二个参数是传入的数组
Function.prototype.myApply = function (context, args) {
if (!context || context === null) {
context = window;
}
// 创造唯一的key值 作为我们构造的context内部方法名
let fn = Symbol();
context[fn] = this;
// 执行函数并返回结果
return context[fn](...args);
};
let obj = {
func(a, b) {
console.log(this);
console.log(this.age);
console.log(a);
console.log(b);
}
}
let obj1 = {
age: "张三"
}
obj.func.myApply(obj1, [1,2]);
打印结果:
3.bind()方法的原理
Function.prototype.myBind = function (context) {
// 如果没有传或传的值为空对象 context指向window
if (typeof context === "undefined" || context === null) {
context = window
}
let fn = Symbol(context)
context[fn] = this //给context添加一个方法 指向this
// 处理参数 去除第一个参数this 其它传入fn函数
let arg = [...arguments].slice(1) //[...xxx]把类数组变成数组 slice返回一个新数组
context[fn](arg) //执行fn
delete context[fn] //删除方法
}
let obj = {
func(a) {
console.log(this);
console.log(this.age);
}
}
let obj1 = {
age: "张三"
}
obj.func.myBind(obj1);
打印结果:
感谢大家的阅读,如有不对的地方,可以向我提出,感谢大家!