开门见山,下面我们直入正题,为大家介绍一下关于javascript的this这一指向,首先我想用一句话来概括js中关于this的指向问题:==this它其实既不指向函数自身也不指向函数的词法作用域,this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。==
在正常情况下,下面我们通过绑定的规则把this分为四个规则来介绍:
1、默认绑定(全局上下文)
1 | function foo(){ |
2、隐式绑定(作为对象的方法调用,闭包)
A、作为对象的方法调用
demo1:
1 | function foo(){ |
demo2:
1 | function foo(){ |
注:对象属性引用链中只有上一层或者说最后一层在调用的位置中起作用
B、闭包(内部函数)
1 | var a = 'foo'; |
这里this的指向跟闭包没有关系,闭包针对于变量来说的。sayHello function is being invoked as a standalone function not attached to any object, and this will refer to the global object.
C、隐式丢失
a、闭包(如上)
b、传入回调函数时
1 | function foo(){ |
注:参数传递其实是一种隐式赋值,所以我们传入函数时也会被隐式赋值,因此应用了默认绑定,就是绑定到全局中去。
3、显式绑定(使用call与apply设置this)
1 | function foo(){ |
A、硬绑定
1 | function foo(){ |
注:Function.prototype.bind有兴趣可以自己去了解,意思差不多
4、new绑定
1 | function foo(a){ |
以上四种就是正常情况下的四个判断规则啦,那么有正常的那也就有所例外嘛?是的,你没猜错,真的有例外。
1、当在默认使用call,apply,bind时把null或者undefined作为this的绑定对象传入呢??
2、间接引用?
1 | function foo(){ |
3、软绑定?
哦,对了,还有一个差点忘记了,就是关于ES6的箭头函数啦。
想必聪明机智的你看完下面的这两个函数就会知道我要讲什么了。
es6 demo:
1 | function foo(){ |
非es6 demo:
1 | function foo(){ |
总结:
以下是根据正常情况下按照优先级排列的四条规则来判断this的绑定对象:
- 1、由new调用?绑定到新建的对象
- 2、由call或者apply(或者bind)调用?绑定到指定的对象
- 3、由上下文对象调用?绑定到那个上下文对象(就近原则)
- 4、默认:在严格模式下绑定到undefined,否则绑定到全局对象
- 还有一些调用可能在无意中使用了默认绑定规则;
- 还有就是es6的箭头函数并不会使用以上四条规则,而是根据当前的词法作用域来决定this,具体来说,就是会继承外层函数调用的this绑定。
第一次整理这种关于技术的文章,各位将就着看,欢迎批评指正哦!附上美女高清图一张。。(文件过大,无法预览)