js this的指向 全局this 对象的this 回调函数的this 事件回调的this 箭头函数的this 类的this call/apply/bind的this

概述

从以下几个方面来分析 js 中 this 的指向

  • 全局中的 this ,指向 window
  • 对象方法中的 this,对象属性中使用 this,this 指向外层的 this 指向; 对象方法中使用 this,this 指向该对象本身
  • 回调函数中的 this,都指向 window
  • 事件回调中的 this, 指向 e.currentTarget,即给谁添加的事件侦听,this 就指向谁
  • 箭头函数中的 this,指向箭头函数外层的this
  • 类中的 this, 指实例化的对象,谁调用方法,在类的函数中 this 就是那个实例对象;静态属性和静态方法中的 this 指的是这个类
  • call()/apply()/bind() ,将函数中 this 的指向改变为这里带入的第一个参数,当第一个参数为空或者是null时,表示将函数中 this 重定向到 window;

一、全局的this

全局对象的 this 是window

console.log(this);//window
function abc(){
    console.log(this);//window,严格模式下,会报错
}
abc();

二、对象方法中的 this

  • 对象属性中使用 this,this 指向外层的 this 指向
  • 对象方法中使用 this,this 指向该对象本身

可以理解为,属性描述 this 时,这个时候对象还没有生成,所以属性中的 this 指向外层的 this 指向;当调用对象的方法时,对象已经生成,所以方法中的 this 指向该对象本身。

var a = 10;
var obj1 = {
    a: 100,
    c: this.a, //属性中的this指向该对象的this,即window
    init: function () {
        console.log(this.a);//100 方法中的this指向该对象,即obj1
        console.log(this.c);//10
    }
}
obj1.init();
var a = 10;
var obj1 = {
    a: 100,
    c: this.a, //属性中的this指向上一层的this,即window
    init: function () {
        console.log(this.a);//100,方法中的this指向该对象,即obj1
        var obj = {
            a: 1,
            c: this.a, //属性中的this指向上一层的this,即obj1
            b: function () {
                console.log(this.a);//1,方法中的this指向该对象,即obj
                console.log(this.c);//100,方法中的this指向该对象,即obj
            }
        }
        obj.b();
    }
}
obj1.init();
console.log(obj1.c);//10

三、回调函数中的this

将函数作为参数传入,无法确定该函数的原来的 this 指向,所以统一将回调函数中的 this 都指向 window。

下面的案例中,如果函数 abc() 的 this 指向是 window;函数obj.c() 的 this 指向是 obj;将它们分别作为参数代入 obj.b() 中,obj.b() 无法判读出它们原来的 this 指向,所以统一将 this 都指向了 window。

function abc() {
    console.log(this);
}
var obj = {
    a: function () {
        this.b(this.c);
        // this.b(abc);
    },
    b: function (fn) {
        fn();
        console.log(this); //方法中的this指向该对象,即obj
    },
    c: function () {
        console.log(this); //回调函数中的 this 指向 window
    }
}
obj.a();

同理,forEach()、filter()、map()、some()、every()、promise…中函数都是回调函数,它们的 this 也都指向 window。

var arr=[1,2,3];
arr.forEach(function(){
    console.log(this);//window
})

四、事件回调函数中的this

事件侦听中的 this 指向 e.currentTarget,即给谁添加的事件侦听,this 就指向谁。

// 事件侦听
document.addEventListener("click",clickHandler);
// 事件回调函数
function clickHandler(e){
    // this--->e.currentTarget
    console.log(this);//document
}

五、箭头函数中的this

箭头函数改变了this指向,将指向箭头函数外层的this

var obj={
   a:function(){
        var arr=[1,2,3];
        arr.forEach(function(){
            console.log(this);//window 遵从于回调函数的this指向
        });
        arr.forEach(item=>{
            console.log(this);//obj 因为使用了箭头函数,就会忽略了回调函数的this指向
        })
		document.addEventListener("click",this.clickHandler);//obj
        document.addEventListener("click",e=>{
            console.log(this);//obj 因为使用箭头函数,就会忽略了事件函数中this指向
        })
    },
    clickHandler:function(e){
        console.log(this)//document 遵从于事件函数中this---e.currentTarget
    }
}
obj.a();

使用箭头函数侦听事件回调,因为箭头函数是匿名函数,所以没有办法清除,可以通过自定义箭头函数来进行清除。

//原始的
document.documentElement.addEventListener("click", clickHandler);
function clickHandler(e) {
	console.log(this);//html
}
//document.documentElement.removeEventListener("click", clickHandler);

//普通的箭头匿名函数,因为是匿名函数,所以没有办法清除
document.documentElement.addEventListener("click",e=>clickHandler())
function clickHandler(e) {
	console.log(this);//window
}

//定义的箭头函数,可以removeEventListener
var handler = e => {clickHandler(e)};
document.documentElement.addEventListener("click", handler);
function clickHandler(e) {
    console.log(this);//window
}
//document.documentElement.removeEventListener("click", handler);

六、类中的 this

  • 类中的 this 指实例化的对象,谁调用方法,在类的函数中 this 就是那个实例对象
  • 静态属性和静态方法中的 this 指的是这个类
//ES6中类的写法
class Rect{
    constructor(){
        this.elem=this.createElem();
    }
    createElem(){
        if(this.elem) return this.elem;
        let div=document.createElement("div");
        Object.assign(div.style,{
            width:"50px",
            height:"50px",
            backgroundColor:"red",
            position:"absolute",
            left:"0px"
        });
        div.addEventListener("click",e=>this.clickHandler(e))
        return div;
    }
}
//实例化对象
let rect=new Rect();
//上面代码中的this全都指向rect

ES6中类的写法和ES5中类的写法:

//ES6中类的写法
class Box{
    static a=3;
    b=4;
    static c=this.a;//this指Box,static c=3;
    constructor(){

    }
    play(){
        //this 指实例化对象
    }
    static once(){
		//this 指Box
    }
}

// ES5中没有类,借用原型的概念实现类
function Box(){
	//相当于ES6中constructor()
}
Box.a=3;//相当于ES6中的static a=3;
Box.once=function(){
	//相当于ES6中的static once(){};
}
Box.prototype.b=4;//相当于上述中的b=4;
Box.prototype.play=function(){
	//相当于上述中的play(){};
}

七、call()/apply()/bind() 中的this

将函数中 this 的指向改变为这里带入的第一个参数,当第一个参数为空或者是null时,表示将函数中 this 重定向到 window;

function fn(_a,_b){
   this.a=_a;
   this.b=_b;
}

fn.call();//this指向window
fn.apply();//this指向window

let obj={};
fn.call(obj);//立即执行函数,且this指向obj
fn.apply(obj);//立即执行函数,且this指向obj
fn.bind(obj);//不执行,只是将this指向obj

总结

  • 全局中的 this ,指向 window
  • 对象方法中的 this,对象属性中使用 this,this 指向外层的 this 指向; 对象方法中使用 this,this 指向该对象本身
  • 回调函数中的 this,都指向 window
  • 事件回调中的 this, 指向 e.currentTarget,即给谁添加的事件侦听,this 就指向谁
  • 箭头函数中的 this,指向箭头函数外层的this
  • 类中的 this, 指实例化的对象,谁调用方法,在类的函数中 this 就是那个实例对象;静态属性和静态方法中的 this 指的是这个类
  • call()/apply()/bind() ,将函数中 this 的指向改变为这里带入的第一个参数,当第一个参数为空或者是null时,表示将函数中 this 重定向到 window;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值