call/apply/bind改变this指向
版权声明:本文为CSDN博主「韩大璐」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41257563/article/details/89001098
call, apply, bind 三者作用都是改变this指向。
bind与apply、call的区别:
- bind返回一个函数,可以延迟调用。apply、call直接调用
var name = 'window';
var newThis = { name: 'newThis' };
function showName(info1, info2) {
console.log(this.name, info1, info2);
}
showName('a', 'b'); //输出:window a b
// 通过bind改变this指向
var newShowName = showName.bind(newThis, 'hello', 'world');
newShowName(); //输出:newThis hello world
- apply与call的区别在于接受参数的方式不一样。call可以接收多个参数,第一个参数是this(你想指定的上下文),在调用的时候需要把其他参数一个一个按顺序传入
var name = 'window';
var newThis = { name: 'newThis' };
function showName(info1, info2) {
console.log(this.name, info1, info2);
}
showName('a', 'b'); //输出:window a b
//通过call改变this指向
showName.call(newThis, 'hello', 'world'); //输出:newThis hello world
- apply只能接收两个参数,第一个参数是this(你想指定的上下文),第二个参数是一个数组,在调用的时候需要把其他参数都放在这个数组里。
var name = 'window';
var newThis = { name: 'newThis' };
function showName(info1, info2) {
console.log(this.name, info1, info2);
}
showName('a', 'b'); //输出:window a b
//通过apply改变this指向
showName.apply(newThis, ['hello', 'world']); //输出:newThis hello world
bind
bind 会返回一个函数,可以在之后任意时间调用。
bind传递参数问题:
在通过bind改变this指向的时候所传入的参数会拼接在调用返回函数所传参数之前,多余参数不起作用。
var newShowName = showName.bind(newThis, 'hello');
//在通过bind改变this指向的时候只传了“hello”一个参数,
//在调用newShowName这个返回参数的时候,bind传参拼接在其前
newShowName('world'); //输出:newThis hello world
var newShowName = showName.bind(newThis, 'hello');
//在通过bind改变this指向的时候只传了“hello”一个参数,
//在调用newShowName这个返回参数的时候,bind传参拼接在其前,
//这时newShowName的参数为“hello”,“a”,“world”
//而该函数只需要两个参数,则第三个参数被忽略
newShowName('a','world'); //输出:newThis hello a
bind传入的参数和newShowName方法传入的参数会拼接在一起,一齐传给showName方法。
bind无法改变构造函数的this指向
var name = 'window';
var newThis = { name: 'newThis' };
function showName(info1, info2) {
console.log(this.name, info1, info2);
}
showName('a', 'b'); //输出:window a b
// 通过bind改变this指向
var newShowName = showName.bind(newThis, 'hello','1','2');
newShowName('a','world'); //输出:newThis hello world
console.log(new newShowName().constructor); //输出:showName函数体
可以看出,通过bind改变this指向返回函数的构造器还是最开始的showName函数。
new newShowName()实例化了一个新的方法,这个方法的this也不再指向newThis。
通过apply模拟bind源码实现:
Function.prototype.newBind = function(target){
var self = this; //self是调用newBind的方法
var args = [].slice.call(arguments, 1);
var temp = function () {};
var f = function () {
var _arg = [].slice.call(arguments, 0);
return self.apply(this instanceof temp?this:target||window, args.concat(_arg));
};
temp.prototype = self.prototype;
f.prototype = new temp();
return f;
};
记一次requestAnimationFrame导致this指向改变问题,通过bind改回this指向:https://www.cnblogs.com/Lilc20201212/p/16150504.html