1 误解
1.1 误解一:this 理解成指向函数自身
function foo(num) {
console.log( "foo: " + num );
// 记录 foo 被调用的次数
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
// foo 被调用了多少次?
console.log( foo.count ); // 0
//因为this并不指向函数本身
1.2 误解二:this 指向函数的作用域
function foo() {
var a = 2;
this.bar();
}
function bar() {
console.log( this.a );
}
foo(); // ReferenceError: a is not defined
//bar中的this不指向bar所在的foo,所以取不到a
划重点:
- this 是在运行时进行绑定的,并不是在编写时绑定。
- 它的上下文取决于函数调用时的各种条件。
- this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
2 调用位置
this最终指向的是调用它的对象。只能调用位置有关,和创建位置无关。
- 一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window
function a(){
let user = "Hello";
console.log(this.user); //undefined
console.log(this); //Window--指向调用位置,全局
}
a(); //全局没有user,所以undefined
- 一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象
let o = {
user:"Hello",
fn:function(){
console.log(this.user); //Hello
}
}
o.fn(); //this指向o
- 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
let o = {
a:1,
b:{
a:2,
fn:function(){
console.log(this.a); //2
//多层调用a.b.c,指向上一级b而非最外层a
}
}
}
o.b.fn();
拓展一下:
let o = {
a:1,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
易错点:
let o = {
a:1,
b:{
a:2,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
let j = o.b.fn;
j(); //j指向fn,this指向window
构造函数可以改变this的指向。
- new关键字改变this的指向,将this指向创建的对象
function Fn(){
this.user = "Hello";
}
var a = new Fn();
console.log(a.user); //Hello
- 如果构造函数返回一个对象,那么this指向返回的对象
function fn()
{
this.user = 'Hello';
return {};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = 'Hello';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
- 如果返回值不是一个对象那么this还是指向函数的实例。
function fn()
{
this.user = 'Hello';
return 1;
}
var a = new fn;
console.log(a.user); //Hello
function fn()
{
this.user = 'Hello';
return undefined;
}
var a = new fn;
console.log(a.user); //Hello
- 特例:null也是对象,但是this还是指向函数的实例。
function fn()
{
this.user = '追梦子';
return null;
}
var a = new fn;
console.log(a.user); //追梦子
- new关键字会创建一个空的对象,然后自动调用apply方法,将this指向这个空对象,然后函数内部的this就会被这个空的对象替代。
function fn(){
this.num = 1;
}
var a = new fn();
console.log(a.num); //1