当一个函数被调用时,会创建一个活动记录(执行上下文)。
这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。
this就是记录的其中一个属性,会在函数执行的过程中用到。
this既不指向函数自身也不指向函数的作用域。
this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
你必须找到调用位置,然后判断需要应用下面四条规则中的哪一条。
1)默认绑定
最常用的函数调用类型:独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则。
2)隐式绑定
隐式绑定的规则是调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。
但有时候会出现隐式丢失。
虽然bar是obj.foo的一个引用,但是实际上,它引用的是foo函数本身。
因此此时的bar()其实是一个不带任何修饰的函数调用,应用了默认绑定。
3)显式绑定
使用函数的call(..)和apply(..)方法。
在很多库中经常能看到bind方法,这是一种硬绑定,一种显式的强制绑定,下面是一种bind实现。
4)new绑定
使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:
1. 创建(或者说构造)一个全新的对象。
2. 这个新对象会被执行[[原型]]连接。
3. 这个新对象会绑定到函数调用的this。
4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。
默认绑定的优先级是四条规则中最低的。
1)显式绑定优先级比隐式绑定要更高
2)new绑定比隐式绑定优先级高
3)new绑定会修改显示绑定中this
4)判断this
1. 函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象。
2. 函数是否通过call、apply(显式绑定)或者硬绑定调用?如果是的话,this绑定的是指定的对象。
3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this绑定的是那个上下文对象。
4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到全局对象。
1)被忽略的this
如果你把null或者undefined作为this的绑定对象传入call、apply或者bind。
这些值在调用时会被忽略,实际应用的是默认绑定规则。
2)间接引用
你有可能(有意或者无意地)创建一个函数的“间接引用”。
在这种情况下,调用这个函数会应用默认绑定规则。
赋值表达式p.foo = o.foo的返回值是目标函数的引用,因此调用位置是foo()而不是p.foo()或者o.foo()。
3)软绑定
如果可以给默认绑定指定一个全局对象和undefined以外的值。
那就可以实现和硬绑定相同的效果,同时保留隐式绑定或者显式绑定修改this的能力。
可以通过一种被称为软绑定的方法来实现我们想要的效果。
软绑定版本的foo()可以手动将this绑定到obj2或者obj3上。
但如果应用默认绑定,则会将this绑定到obj。
本文转自 咖啡机(K.F.J) 博客园博客,原文链接:http://www.cnblogs.com/strick/p/5813749.html,如需转载请自行联系原作者