JavaScript中this指向问题

相信很多小伙伴,初学js的时候都会被this弄的焦头烂额。this关键字是一个非常非常重要的点,毫不夸张的说,如果不了解this,基本上所有的开发任务都不能完成。
首先:你要记住this的重点,这会帮你理解下面的内容
1、this永远指向一个对象
2、this对象,通过不同的方式调用函数,this的指向就不同
核心一句话 - 哪个对象调用函数,函数里面的this指向哪个对象。

针对第一点,无论在什么地方使用this,this必然指向某个对象;剩下的就剩一个问题,this到底指向哪,在javaScript中,万物皆对象,所有的函数都是在某个对象下运行,而this就是指向函数所运行的对象,这本来很好理解,可是this随着函数的使用场景不同,this的值就会发生变化。这也就是说,this的指向是动态的,很难事先确定好this指向哪个对象,这才上让我们感到困惑的地方。

function fn(){
            console.log(this.age)
            console.log(this)
        }
        let obj = {
            age : 20,
            f : fn
        }
        var age = 10;
        fn()        //调用fn()this指向window,age为10
        obj.s()  //通过对象调用fn(),age为20

上面,this被调用了两次,结果也是不一样的。
在全局作用域下调用fn()fn()指向全局作用域对象window
obj.s()运行在对象内运行,this指向当前对象;

而我们要清除的是this的指向为什么会发生改变,this的指向改变是怎么发生的
函数、对象、数组,都是(复合)引用数据类型,引用数据类型在栈内存中实际保存的是对象在堆内存的引用地址,通过这个引用地址可以快速找到保存在堆内存中的对象。
上方obj有两个属性,但是属性的值类型却是不一样的,所有在内存中储存方式的也不一样。

this.png

因为函数既可以当做值传递也是一个对象和构造函数。所以函数在运行的时候确定了当前的运行环境,this是函数体自带的一个对象指针,而this指向调用对象。所以,this会根据运行环境的改变而改变,同时this也只能在运行时才能确认运行环境。

事件绑定的三种方式:行内绑定、动态绑定、事件监听

行内绑定分为两种情况



function fn(obj) {
            console.log(this) // 此函数的运行环境在全局window对象下,因此this指向window;
            console.log(obj)  //this作为实参传递,this指向当前节点对象
        }

动态绑定和事件监听

因为动态绑定的事件本就是为节点对象的属性(事件名称前面加'on')重新赋值为一个匿名函数,因此函数在执行时就是在节点对象的环境下,this自然就指向了本节点对象;

下面是this在各个不同环境下的具体指向

一、this指向window
(1)this如果单独使用,this 表示全局对象。

var x = this
        document.querySelector('body').innerHTML = x  //[object Window]

输出结果是 [object Window];

(2)在函数中,this 表示全局对象

function fn(){
            console.log(this) 
        }
fn()  //window

(3)定时器调用函数,this指向window

setInterval(function(){
            console.log(this)   //这里this指向window
        }, 1000)

(4)行内绑定事件(DOM0级)通过函数名+()形式调用this指向window


    

this指向当前
(2)行内绑定事件时通过函数名+(this)形式,this指向调用的节点对象


    

this指向
(3)DOM2级事件调用,this指向调用的节点对象


    

三、this指向对象

let obj = {
            name: '张三',
            say(){
               console.log(this) 
            }
        }
        obj.say()  //obj

this指向对象obj
四、this指向数组

let arr = ['张三','李四','小甜甜',fn]

        function fn(){
            console.log(this)
        }
arr[3]() //arr

五、构造函数中的this指向

function Fn(){
            this.name = '张三'
            this.say = function(){
                console.log(this)
            }
        }
        let res = new Fn();
        res.say()
        console.log(res)

构造函数中的this指向new创建的新对象
六、箭头函数=>的this指向
箭头函数本身上面是没有this,它的this可以去上一层去找,正是因为箭头函数没有this绑定,所有箭头函数不能用于构造函数。
箭头函数中this指向宿主对象


    

定时器原本this指向window,使用箭头函数this去上一层,this指向

你可能感兴趣的:(JavaScript中this指向问题)