this全面总结

this在javascript中是比较特别的关键字,被自动定义在所有的函数作用域中,不过对它的理解确实让我煞费苦心···在这里总结下我对js中this的理解。

我们为什么要使用this呢?简单来说,this可以隐式的传递一个对象的引用,因此可以将API设计的更加简洁并且易于使用。要是没有this 我们必须显示的给每个函数传递一个上下文对象,这样会让代码变得越来越乱,而函数可以自动引用合适的上下文对象在javascript中是很重要的。

理解this首先要明白每个函数的this是在调用时被绑定的,完全取决于函数的调用位置(也就是函数的调用方法)

四条绑定规则

正如上面所说,你必须找到函数的调用位置,然后应用下面的四条规则来判断。

默认绑定

这个是最常用的函数调用类型,也就是独立函数的调用,其他规则不适用时就会用默认规则。来看下代码:

function foo(){
    console.log(this.a);
}
var a=2;
foo();  //2

可以看到全局调用foo()后this.a被解析成了全局变量上的a,这就是默认绑定,this也就是指向了全局对象。

隐式绑定

接下来要考虑函数调用位置是否有上下文对象,或者说被某个对象所拥有,来看下面的代码

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
    foo:foo
};
obj.foo();//2

可以看到我们把foo当做引用属性添加到了obj中,当函数引用有上下文对象时,隐式绑定规则就会把函数调用中的this绑定到这个上下文对象,其中的this.a和obj.a 是一样的。

不过隐式绑定有有一种现象就是隐式丢失,导致最后绑定到了默认规则上,来看如下代码

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
    foo:foo
};
var bar=obj.foo;
var a=1;
bar();  //1

可以看到最后被绑定到了全局对象上的a变量上去了,以上bar引用的是foo函数的本身,因此被应用了默认绑定。值得一提的是若是传入回调函数也会发生上面的隐式丢失,例如setTimeout(obj.foo,1000) 执行结果也会是1。this的改变总是出乎人意料。在显式绑定中会介绍如何固定this修复这个问题。

显式绑定

在上面的隐式绑定中,我们可以看到每次都要在一个对象内部包含一个指向函数的属性。并通过这个属性间接引用函数。显示绑定会使用call()和apply()两个方法,这两个方法第一个参数是一样的,都是this所指向的对象,差别在第二个参数,call必须把传入函数的参数一个个写出来,apply支持参数数组形式或者arguments关键词,不过在这里第二个参数我们不必深究,使用哪个都一样。来看下代码:

function foo(){
    console.log(this.a);
}
var obj={
    a:2
};
foo.call(obj);//2

通过call方法我们可以在调用foo时强制把它的this绑定到obj上。不过这个还是不能解决我们前面说的隐式丢失问题,不过硬绑定可以解决,来看代码

function foo(){
    console.log(this.a);
}
var obj={
    a:2
};
var bar=function(){
    foo.call(obj);
};
bar();//2
var a=1;
setTimeout(bar,1000);//2

可以看到解决问题了,我们看下是怎么解决得,函数bar内部手动调用了foo.call(obj),无论之后如何调用函数bar,它总会手动在obj上调用foo,这就是显示的一种强制绑定。

new绑定

直接看代码

function foo(a){
    this.a=a;
}
var bar =new foo(2);
console.log(bar.a);//2

要说明的是在函数调用之前加个new关键词,就说发生了构造调用,在这之前foo只是一个普通的函数而已,不要与Java中的构造函数混淆。那么发生构造调用有什么特别之处呢,它会自动执行下面的操作:
1. 创建一个全新的对象。
2. 新对象会被执行原型链接。
3. 这个新对象会被绑定到函数调用的this。
4. 如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象。

以上就是this绑定的规则,当然,凡事总有例外,有些情况下this的绑定行为会出乎意料。

另外ES6中的箭头函数是根据外层作用域来决定this的。其实和我们常常使用的self=this 机制一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值