js中this的指向问题总结
1.全局的this和普通函数中的this
- ES5非严格模式 全局中this和普通函数中this都指向window
- ES5严格模式,ES6,全局中this仍然指向window,普通函数中this指向undefined
ES5非严格模式
console.log(this); //window
function fn(){
console.log(this); //window
}
fn();
ES5严格模式 ES6
"use strict";
console.log(this); //window
function fn(){
console.log(this); //undefined
}
fn();
2.对象中的this
- 对象方法中的this指向此对象,直接this指向对象外this的指向
var obj={
a:1,
b:function(){
console.log(this); // this指向当前对象自身obj
},
c:this.a // this指向对象外this的指向
}
3.回调函数中的this 3种情况
- 如果直接指向的回调函数,this指向最外层window
- 如果通过arguments直接使用参数指向函数,this则指向执行当前函数的arguments
- 如果回调函数通过call,apply,bind重新指向了新的对象时,this就是指向新对象
var obj = {
a: function () {
console.log(this,"____");
var self=this;
function fn1(fn) {
console.log(this)//对象方法内的函数相当普通函数的执行 指向window
fn();
// arguments[0](); //arguments
// fn.call(self); //obj
}
function fn2() {
console.log(this);//window 回调函数中
}
fn1(fn2);
},
};
obj.a();
var obj={
b:1,
a:function(){
setTimeout(function(){
console.log(this); //window 尽管在setTimeout中,但是依旧是回调函数中的this指向
}, 2000);
setTimeout(function(obj){
console.log(this) //window 回调函数
console.log(obj); //obj 这个是外部传参,this作为参数传进来.this指向的是obj
}, 2000,this);
}
}
obj.a();
4.事件中的this
var obj={
b:1,
a:function(){
// console.log(this);
// 特殊的回调函数
document.addEventListener("click",this.clickHandler);
// document.attachEvent("onclick",this.clickHandler);
},
clickHandler:function(e){
console.log(this===document);//addEventListener事件侦听的对象 e.currentTarget
// console.log(this===window);//IE8 attachEvent侦听事件时,this指向window
}
}
obj.a();
5.ES6类中的this
- 任何的静态方法中this都是当前类,也是构造函数
- 静态方法中无法获取到实例化对象的this的
class Box{
static _instance;
constructor(){
console.log(this);//指向被实例化的对象
}
static getInstance(){ //单例模式
if(!Box._instance){
Box._instance=new Box();
}
return Box._instance;
}
play(){
console.log(this,"|");//指向被实例化的对象
}
static run(){
// console.log(this);
console.log(this===Box,"____");
return this;
}
static plays(){
this.getInstance().play();
var o=this.getInstance(); //单例模式的效果,获得的实例化都相同
var o1=this.getInstance();
console.log(o===o1);
}
}
var b=new Box();//会执行构造函数,这是构造函数中this就是这个b对象
b.play();//b对象下的方法play,因此play方法中this被指向b,谁执行play,this指向谁
console.log(Box.run()===b);//false
console.log(Box.run()===b.constructor);//true
6.ES5 面向对象中的this
function Box(){
console.log(this);
}
Box.prototype.play=function(){ //相当于ES6中类中的动态方法中的this
console.log(this);//this是指向执行该方法的实例化对象
}
Box.run=function(){ //相当于ES6中类中的静态方法中的this
console.log(this);//Box
}
Box();//this是window或者undefined
var b=new Box();// this是实例化后b对象
b.play();
7.箭头函数
var obj = {
a: function () {
setTimeout(() => {
console.log(this);//this是箭头函数外this的指向 所以this指向obj
// 上下文环境中this的指向
}, 2000);
},
};
obj.a();
8.绑定this指向
call apply bind
function fn(){
console.log(this);
}
var obj={a:1}
fn.call(obj);//fn中this指向obj
fn.apply(obj);//fn中this 指向obj
fn.bind(obj)();//fn中this指向obj