js中的this指向

函数中的this指向

到es6,javascript中新增了箭头函数。而对于函数的this指向问题,我自己的理解就是对于普通函数来说,什么时候调用普通函数,普通函数当中的this指向才能确认;而对于箭头函数来说,当箭头函数被声明的时候,其函数体内部使用到的this的指向就已经确定了。

普通函数

函数声明的方式:
function test () {};
匿名函数表达式:
const test = function () {};
命名函数表达式:
const test = function testName () {};

普通函数的this指向

对于普通函数来说,它内部的this是在该函数执行的时候确认的(你也可以理解为被谁调用)。
普通函数没有被显示修改其this指向(包括apply或者对象调用等),那普通函数内部的this在非严格模式下是指向windows,在严格模式下指向undefined。

普通函数直接执行

普通函数内部的this指向Global(windows是在浏览器环境下的,windows对Global实现了代理)

function test1 () {
	console.log(this)
}

在这里插入图片描述
只要普通函数没有通过bind,apply,call或者对象调用等强制修改函数的this指向,那普通函数执行时内部的this在浏览器环境当中就指向windows,无论是在哪个作用域当中(非严格模式下)。

let obj = {name: 'lxh'};
function test () {
    function fn () {
        console.log('我的this', this);
    }
    fn();
}
test.call(obj);

在这里插入图片描述

对于命名函数表达式与匿名函数表示来说也是一样的

let obj = {name: 'lxh'};
function test () {
    const fn = function () {
        console.log('匿名函数表达式this', this);
    }
    fn();
    const fn2 = function fnName () {
        console.log('命名函数表达式的this', this);
    }
    fn2();
}
test.call(obj);

在这里插入图片描述

普通函数被显示修改this指向

通过call、apply或者bind这种来强制修改普通函数当中的this的指向

//通过call、apply或者bind这种来强制修改普通函数当中的this的指向
let obj1 = {
    age: 11,
}
const test = function () {
    console.log('我被修改this指向了', this);
}

test.call(obj1);

在这里插入图片描述

作为对象属性被调用

//或者作为对象属性被调用
const test = function () {
    console.log('我被修改this指向了', this);
}
let obj2 = {
    test: test,
}

obj2.test()

在这里插入图片描述
像一些经常使用到的api其内部都是修改了你函数的this指向了(想到了回来更新)

  1. addEventListener(callback) => 将你传入的callback函数的this指向修改为了对应的DOM元素

箭头函数

对于箭头函数内部的this指向来说,在箭头函数被定义的时候就已经确定了。我自己的理解就是箭头函数内部的this会指向最近的作用域当中的this。
全局作用域下

const test = () => {
    console.log('箭头函数的this指向', this);
}
test();

在这里插入图片描述

看到这里你可能好奇为啥普通函数指向的this指向global,但是箭头函数的this指向了一个空对象

全局下的箭头函数与普通函数为什么内部调用的this不一样呢

对于普通函数来说,其实你在函数体内调用的this是函数的一个属性,就和arguments一样,这个this保存着一个指向,对于普通函数直接执行来说,函数的this属性会保存windows或undefined。但对于箭头函数来说函数对象当中没有this这个属性,所以会沿着作用域链去寻找这个this,而全局中的this不一定指向windows。这也就是为什么普通函数能够通过bind或者对象调用来改变this的指向,但箭头函数没作用。


let obj = {
    name: 'lxh'
}
function fn1 () {
    console.log('fn1函数的this指向', this);
    const fn2 = function fn2Name () {
        console.log('fn2函数的this指向', this);
        const fn3 = () => {
            console.log('箭头函数的this指向是什么', this);
        }
        fn3()
    }
    fn2()
}
fn1.call(obj);

重点看一下打印的结果是不是与上面的解释重合
在这里插入图片描述
这也说明了箭头函数的this内部使用的this是在声明的时候就确认了,因为作用域链已经确定了

总结

普通函数有一个this属性,这个this属性保存着一个引用,当函数内部使用this的时候,会读取这个this。
箭头函数没有this属性,所以在箭头函数内部使用this的时候其实是沿着作用域链去寻找这个this的。
这也同样解释了普通函数为什么可以通过bind或者对象等方式来修改this指向,而箭头函数不可以。前者是一个自有属性,被修改的话内部调用this也会反应出变化;但是后者没有this属性,箭头函数是通过作用域链去寻找这个this的,这也就是为什么箭头函数的this与最近的作用域当中的this是同一个!

个人理解,如有错误请批评指正。谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值