解决this指向的输出问题

最近总是遇到这种this指向的题,下面进行分享并进行扩展,希望可以帮助到可能会有困惑的同学。

题目

     var User = {
            count: 1,
            getCount: function(){
                console.log(this);
                return this.count;
            }
        };
        console.log(User.getCount()); // ?
        var func = User.getCount;
        console.log(func()); // ?

输出:

alt

解释:

getCount是正常函数,谁调用this就绑定在谁身上(隐式绑定),输出user对象的count属性值1; func = User.getCount只是将地址赋值给了func,在console里执行,这里func相当于一个全局的函数,等于window.func(),window没有count属性,输出undefined;

将getCount函数换成箭头函数

     var User = {
            count: 1,
            getCount: () => {
                console.log(this);
                return this.count;
            }
        };
        console.log(User.getCount()); // ?
        var func = User.getCount;
        console.log(func()); // ?

输出:

alt

解释:

箭头函数的this是在声明的时候就绑定了,不能隐式调用,所以User.getCount这样调用,this也不是指向User。它只会从自己的作用域链的上一层继承this。箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量window。

扩展一下:建议将一些需要传参并且不作为对象方法使用的函数写作箭头函数会更适合一些

在箭头函数外层套个普通函数

     var User = {
            count: 1,
            getCount:function(){
                return() => {
                    console.log(this)
                    return this.count;
                }
            }   
        };
        console.log(User.getCount()()); // ?
        var func = User.getCount;
        console.log(func()()); // ?

输出:

alt

解释:

注意这里的箭头函数的this指向User并不是因为是User.getCount这种隐式调用才指向的,是从自己的作用域链的上一层继承this,也就是getCount这个普通函数的this,这个普通函数的this就是调用时就指向User啦,所以箭头函数继承了。

箭头函数this输出问题

function fun() {
    return () => {
        return () => {
            return () => {
                console.log(this.name)
            }
        }
    }
}
var f = fun.call({ name: 'foo' })
var t1 = f.call({ name: 'bar' })()()
var t2 = f().call({ name: 'baz' })()
var t3 = f()().call({ name: 'qux' })

输出:

alt

解释:

fun是正常函数,调用call方法让this指向{name: 'foo'}对象。箭头函数没有自己的this也并不能使用call,apply以及bind去绑定this,但函数还是会调用的,会自己的作用域链的上一层继承this,所以后面几次的call实际上是失败的,箭头函数一直往上一层寻找name,只会在最外层的fun函数作用域中找到this指向{name: 'foo'}对象的name属性

进阶问题

如果理解了就试试这道题吧!


const User = {
    count: 1,
    action: {
        getCount: () => {
            return this.count;
        },
    },
};

const action = User.action;
const getCount = User.action.getCount;

Promise.resolve().then(() => {
    setTimeout(() => {
        console.log(action.getCount() + '@@'); 
    });
});

setTimeout(() => {
    console.log(User.action.getCount() + '@@@');
});

console.log(getCount() + '@'); 

输出: alt 他们的this都指向window噢

关于输出顺序问题有疑惑的可以看搞清async await、微任务,宏任务执行顺序

全部评论

相关推荐

01-07 15:50
四川大学 Java
明远湖摸鱼:同年级的同学,,简历可以大一点,这个有点太密集了,实习技术可以量化的尽量量化
点赞 评论 收藏
分享
2024-12-08 18:59
东北大学 Java
Java抽象带篮子:外卖项目可以看看我的详细的外卖话术,里面还写了怎么描述项目,还为了提高含金量额外增加了很多技术亮点呢。另外我这边还有个7000多字的轮子项目话术,可以狠狠的速成,需要的似我
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务