前端之家收集整理的这篇文章主要介绍了call、aplly、bind 实现 && this理解 ,前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
call、aplly、bind 本质都是改变 this 的指向,不同点 call、aplly 是直接调用函数,bind 是返回一个新的函数。call 跟 aplly 就只有参数上不同。
// bind 实现
Function.prototype.djBind = function (thisArg) {
if (typeof this !== "function") {
throw TypeError("Bind must be called on function");
}
// 拿到参数args,为了传给调用者
const args = Array.prototype.slice.call(arguments,1),self = this,nop = function () {},bound = function () {
// this instanceof nop,判断是否使用 new 来调用 bound
// 如果是 new 来调用的话,this的指向就是其实例,
// 如果不是 new 调用的话,就改变 this 指向到指定的对象 o
return self.apply(
this instanceof nop ? this : thisArg,args.concat(Array.prototype.slice.call(arguments))
);
};
// 箭头函数没有 prototype,箭头函数this永远指向它所在的作用域
if (this.prototype) {
nop.prototype = this.prototype;
}
// 修改绑定函数的原型指向
bound.prototype = new nop();
return bound;
};
const bar = function() {
console.log(this.name,arguments);
};
bar.prototype.name = 'bar';
const foo = {
name: 'foo'
};
const bound = bar.djBind(foo,22,33,44);
new bound(); // bar,[22,44] this指向bar
bound(); // foo,44
Function.prototype.djCall = function(thisArg) {
if(typeof this !== 'function') {
throw TypeError("call must be called on function");
}
const args = Array.prototype.slice.call(arguments,1);
thisArg = thisArg || window;
// 将调用call函数的对象添加到thisArg的属性中
thisArg.fn = this;
// 执行该属性,在thisArg上调用this方法;
const result = thisArg.fn(...args);
delete thisArg.fn;
return result;
}
Function.prototype.djApply = function(thisArg) {
if(typeof this !== 'function') {
throw TypeError("call must be called on function");
}
const args = arguments[1];
thisArg = thisArg || window;
// 将调用call函数的对象添加到thisArg的属性中
thisArg.fn = this;
// 执行该属性
const result = thisArg.fn(...args);
delete thisArg.fn;
return result;
}
const bar = function() {
console.log(this.name,arguments);
};
bar.prototype.name = 'bar';
const foo = {
name: 'foo'
};
bar.mycall(foo,1,2,3); // foo [1,3]
bar.myaplly(foo,[1,3]); // foo [1,3]
JS中的this是一个非常简单的东西,只需要理解它的执行规则;
call/apply/bind可以显式绑定,这里就不说了;如上所述;
主要这些场隐式绑定的场景讨论:
let obj = {
a: function() {
console.log(this);
}
}
let func = obj.a;
func();
这种情况是直接调用。this相当于全局上下文的情况。
这就是对象.方法的情况,this指向这个对象
let obj = {
a: function() {
let do = () => {
console.log(this);
}
do();
}
}
obj.a(); // 找到最近的非箭头函数a,a现在绑定着obj,因此箭头函数中的this是obj
优先级: new > call、apply、bind > 对象.方法 > 直接调用。
以上是前端之家为你收集整理的call、aplly、bind 实现 && this理解 全部内容,希望文章能够帮你解决call、aplly、bind 实现 && this理解 所遇到的程序开发问题。
如果觉得前端之家网站内容还不错,欢迎将前端之家网站推荐给前端开发程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。