本博客基于《你不知道的JavaScript》这本书,是我对this相关问题的总结。
一、第一章:关于this
1.两个误解
● 误解一:this指向函数自身
函数中的this是根据函数调用时的上下文所决定的,该上下文不一定是函数自身。
举个例子
function a(){
console.log(this);
console.log(this.a);
}
a()
console.log('分*************界****************线');
a.bind(a)()
对于上面这个例子就很好的说明了误解一,a()函数this指向window,使用bind()函数绑定的this指向函数a本身。
● 误解二:this指向函数的作用域
this的指向是根据函数的执行顺序动态确定的,函数作用域是根据代码的书写顺序决定的(词法作用域)。什么是词法作用域?见我上一篇文章
举个例子
var a = 1;
function foo() {
var a = 2;
this.bar()
}
function bar() {
console.log(this.a);
}
foo(); // 1
2.this究竟是什么?
this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
当一个函数调用时,会创建一个上下文对象,这个上下文对象包括函数的调用栈、函数的方法、函数的参数等信息,this就是函数上下文中的一个属性。
二、第二章:this全面解析
1.调用位置
函数调用栈是指当函数嵌套调用时,函数会以栈的方式进行存储。函数的调用位置就在当前正在执行的函数的前一个调用中。
2.绑定规则
(1)默认绑定
默认绑定是当其他绑定规则不满足时,启用默认绑定规则。
举个例子
function a() {
console.log(this); // window
}
a()
注意:当函数内部或全局启用严格模式('use strict')的时候,默认绑定并不会绑定到window,会绑定到undefined。
举个例子
function foo1() {
"use strict";
console.log(this); // undefined
}
foo1();
"use strict";
function foo2() {
console.log(this); // window
}
foo2();
(2)隐式绑定
隐式绑定是指函数是在哪个作用域进行调用的,函数的this就指向哪个作用域的this,也可以说是调用当前函数的前一个调用栈。
举个例子
function foo() {
console.log(this.a); // 1,this指向 obj2,foo函数的调用栈是 obj2
console.log(a) // 3,词法作用域(只与函数书写位置有关),函数书写在全局作用域
}
var a = 3;
var obj2 = {
a: 1,
foo: foo
};
var obj1 = {
a: 2,
obj2: ob