> this 是在运行时绑定的,并不是在编写时绑定的.它的上下文取决于函数调用时的各种条件.
## 首先明白
1. this 既不指向函数自身,也不指向函数的词法作用域
## this绑定规则
1. 默认绑定
独立函数调用
```javascript
function foo(){
console.log(this.a);
}
var a = 2;
//函数调用时应用了this的默认绑定,因此this指向全局对象.
foo(); //2
```
2. 隐式绑定
调用的位置是否有上下文对象,或者说被某个对象拥有或包含,不过这种说法可能造成一些误导.
```javascript
function foo(){
consle.log(this.a);
}
var obj = {
a:2,
foo:foo
}
obj.foo(); //2
```
隐式丢失: 函数别名和参数传递 ,最经常遇见的setTimeout(fn,delay)函数,会发生隐式丢失,this指向window
```javascript
//函数别名
function foo(){
console.log(this.a);
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo;
var a = "oops,global";
bar();//"oops,global"
```
```javascript
//参数传递
function foo(){
console.log(this.a);
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo;
var a = "oops,global";
function doFoo(fn){
fn();
}
doFoo(obj.foo);//"oops,global"
```
3. 显示绑定
1. 硬绑定
使用call(...) apply(...)
2. API调用的"上下文"
如[1,2,3].forEach(foo,obj) ,当执行回调函数时用作this的值(参考对象)。
4. new绑定
1. 创建(或者说构造)一个全新的对象
2. 这个新对象都会被执行[[Prototype]]
3. 这个新对象会绑定到函数调用的this
4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回一个新对象.
5. =>(箭头函数)
箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。即`箭头函数没有自己的this,其中的this会自动从上一级继承`
函数参数会使其丢失this,从而指向window, 使用箭头函数可以修改this指向,this是词法作用域由上下文确定
```javascript
let a = {
x: 1,
y: function() {
setTimeout(() => {
console.log('this', this)
}, 1000)
}
}
a.y() // this a
```
```javascript
let a = {
x: 1,
y:() => { // y:() => {}, this继承上一级, this = window
setTimeout(() => {
console.log('this', this)
}, 1000)
}
}
a.y() // this window
```
你需要知道JavaScript:this指向问题