改变this指针的方法

javascript的一大特点:函数存在   定义时上下文 运行时上下文, 并且 上下文是可以改变的。
例1:
function f(){
    console.log(this);
}
f();//window

call、apply

例2:
var aa={
    name:'zdn',
    fun:function(){
        console.log(this.name);
    }
}
var hhh={
    name:'hhh'
}
aa.fun.call(hhh);//hhh
aa.fun.apply(hhh);//hhh
可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中hhh没有fun方法),但是其他的有(本栗子中aa有fun方法),我们可以借助call或apply用其它对象的方法来操作。

call、apply区别

两者作用完全一样,只是接收参数的方式不一样

例3:
var func=function(arg1,arg2){
    
};
func.call(this,arg1,arg2);
func.apply(this,[arg1,arg2]);

 其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

  JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。

  而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。

call、apply常用的用法

1.数组之间的追加
var arr1=[1,2,3,4,5,6];
var arr2=['zdn',8,9];
Array.prototype.push.apply(arr1,arr2);
console.log(arr1);//[1, 2, 3, 4, 5, 6, "zdn", 8, 9]
2.获取数组之间的最大值和最小值
var numbers=[1,23,4,5,677,678,90];
var max1=Math.max.apply(Math,numbers);//678
var max2=Math.max.call(Math,1,23,4,5,677,678,90);//678
3. 定义一个 log 方法,让它可以代理 console.log 方法:
function log(){
    console.log.apply(console,arguments);
}
log(1);//1
log(12,30);//12,30

bind

bind()方法与call和apply 相似,也是可以改 变函 数体内 this 的指向。

bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

例4:
var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3

这里创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

对上面的栗子进行改变:
var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //3
  
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //3
注意:两次输出3,并没有输出4,5。原因是js中,多次bind()是无效的。
更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

call、apply、bind比较

例5:
var o={
    name:'z'
};
var fun={
    sayName:function(){
        console.log(this.name);
    }
}

fun.sayName.bind(o());//有错
fun.sayName.call(o);
fun.sayName.apply(o);
三个输出的都是z,但是注意看使用 bind() 方法的,他后面多了对括号。
区别是,当希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。
 
总结一下:
  • apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
  • apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
  • apply 、 call 、bind 三者都可以利用后续参数传参;
  • bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

还有几个规则:

规则1:如果一个函数,是某个对象的key 值,那么,this就指向这个对象。 
规则2:如果函数new 了一下,那么就会创建一个对象,并且this 指向 新创建的对象。  
规则3:通过call,bind,apply 可以改变this 的指向  
javascript 的this 可以简单的认为是 后期绑定,没有地方绑定的时候,默认绑定window。 



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值