啊,万恶的this

一、全局下,this一般都指向window

全局下,ES5非严格模式,下面的this都是window。

console.log(this);
function abc(){console.log(this);
}
abc();

在这里插入图片描述

二、对象中的this

1、最常见的this情况:

var a=100;var obj={a:1,b:function(){console.log(this);//这个this是当前对象// 谁调用b方法,this就是谁},// this是当前对象外的this指向,这里应该是windowc:this.a
}
var obj1 = obj;
obj = {};
obj1.b();//浅复制而已,引用没变

在这里插入图片描述
2、如果在对象的属性对象中:

var a=1000;var obj = {a: 1,b: {c: this.a, //运行到此时obj还没生成,this还是指向window  创建时  还没生成d: function () {console.log(this);  //函数被调用的时候才会执行这句话,同样,谁调用指向谁}}}
console.log(obj);
obj.b.d();

在这里插入图片描述
3、如果obj已经创建完,再给obj增加属性,那么此时的obj.b的this还是指向window。

var a=2000;var obj={a:1
}
console.log(obj); obj.b={c:this.a,d:function(){console.log(this);}
}console.log(obj); 

在这里插入图片描述
4、如果是对象中的属性函数下又新建对象,this指向外层对象obj。

var obj = {a: 1,b: function () {// thisvar obj2 = {// this指当前对象外this的指向,这里的this指向是objc: this.a}console.log(obj2.c);}
}obj.b();

在这里插入图片描述

三、回调函数中的this

回调:函数在另一个函数的参数里,然后被调用,就叫回调。

1、一般的回调函数:(this被重定向到window)

function ab(fn) {fn();
}
function cd() {// this指向windowconsole.log(this);
}ab(cd);

在这里插入图片描述
2、对象中的回调:(this被重定向到window)

var obj = {a: function (fn) {fn();},b: function () {// 如果直接执行obj.b() 这里的this应该是obj对象// 如果通过上面a方法回调执行当前b的时候,this被重定向到windowconsole.log(this);}
}obj.a(obj.b);

在这里插入图片描述
3、事件是特殊的回调函数,事件回调函数中的this都是被侦听的对象

document.addEventListener("click", clickHandler);function clickHandler(e) {console.log(this);// this===e.currentTarget
} 

在这里插入图片描述
4、把函数写在方法中(匿名的回调函数),this都重定向到window:(不论这个方法放在哪)

var obj = {a: function () {setTimeout(function () {console.log(this)//window}, 100);// 所有的函数一旦被写在一个方法中,这个函数就是匿名的回调函数,在该函数中this指向windowsetInterval(function () {console.log(this);}, 100)var arr = [1, 2, 3];arr.map(function () {console.log(this);//window// forEach,filter,reduce,some,every,flatMap});new Promise(function (resolve, reject) {console.log(this);//window})}
} 
obj.a();
new Promise(function (resolve, reject) {console.log(this);//window
})

在这里插入图片描述

四、事件函数中的this

事件函数是特殊的回调函数,使用时不会被重定向到window,而是侦听对象;因为太特殊了,单独拿出来再了解了解。
事件侦听的回调函数,this被重新处理,this指向被侦听的对象。

(1)最常用的看上面。
(2)放到其他地方也一样。比如放到对象里:

var obj={a:function(){document.addEventListener("click",this.b);this.b();},b:function(e){// 因为b函数是事件侦听的回调函数,因此这里this指向事件侦听的对象,也就是documentconsole.log(this);console.log(e);//侦听到的事件}
}
obj.a();

在这里插入图片描述

五、ES6类中的this

一般都是指向当前实例对象,但是静态属性、静态方法都可以指向当前类。
但是要注意:对于面向对象语言来说,一般在静态属性和方法中是不允许使用this这个概念的。

class Box{
// 在外面定义,ES7后才有的
// 这里的内容是constructor执行后才赋的值
//其实在这儿定义的,跟在constructor里定义差不多
b=333;
a=this.b;
static b=444;
static a=this.b;//一旦被设为静态属性,this指向都会被设置为当前的类名Box
constructor(){
// this指向当前实例对象console.log(this);console.log(this.a,Box.a);this.b=111;this.a=this.b;Box.b=222;  //也是静态属性Box.a=Box.b;console.log(this.a,Box.a);
}
play(){// 这里的this都是实例化的对象console.log(this.a,Box.a);console.log(this);
}static run(){console.log(this);// 因为使用static定义的方法,this指向为当前类名// 对于面向对象语言来说,一般在静态属性和方法中不允许使用this这个概念
}}
var a=new Box();
a.play();class Ball extends Box{
constructor(){super();
}}
var b=new Ball();
Ball.run();   // 继承后静态方法也会被继承

在这里插入图片描述

六、ES5中类的this

除了静态属性、方法的this指向这个类,其他情况下this一般都指向当前实例化对象。

// 构造函数
function Box(){this.play();// 构造函数中this,指向new出的实例对象
}// 静态的属性、方法,类似于ES6里的静态方法、静态属性定义
Box.a=function(){console.log(this);// this  -->Box
}
Box.b=3;// 写在原型下的属性、方法
Box.prototype.play=function(){console.log(this);// this  就是当前调用该方法的实例对象
}
Box.prototype.c=10; // 静态属性、方法,this指向类
console.log(Box.b);
Box.a();var box=new Box(); 
console.log(box); //与paly中打印的一样
// box对象没有play这个对象属性,因此就去原型链中找到最近的play方法,执行这个play方法是由box这个对象执行
// 静态属性、方法只和类有关系,与实例化的对象没有任何关系,所以不在box对象中显示。
console.dir(Box);  //console.dir()可以显示一个对象的所有属性和方法

在这里插入图片描述

七、ES6箭头函数中的this

所有箭头函数内的this,都是当前函数外层的this指向。

var fn=()=>{};
var obj={a:()=>{console.log(this);//this--->window},b:function(){console.log(this);//this--->当前调用方},// c跟b的一样c(){console.log(this);//this--->当前调用方}
}
var obj1=obj;
obj1.a();
obj1.b();
obj1.c();

在这里插入图片描述

var obj={a:function(){setTimeout(()=>{// 因为本来是回调函数,this统一都会被执行window;// 但是使用了箭头函数,就会全部把这里this重定向到setTimeout外层,也就是obj。console.log(this);},100)setTimeout(function(){console.log(this);// 没有使用箭头函数,this指向window},100);}
}
obj.a();

在这里插入图片描述

八、call、apply、bind

当使用call,apply,bind时,都会将函数中this的指向重新指向到对应的对象。

总结

那么总结一下,都有哪些this:
全局下的this、对象中的this、回调函数中的this(事件函数中的this)、ES6类中的this、ES5中类的this、ES6箭头函数中的this、call,apply,bind中的this。

最后,其实理解了,this也就善良了。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部