基于自定义函数下箭头函数`this`指向问题

下一篇关于对象+箭头函数

想法来源

学习ES6视频时,看到老师的举例,如下图所示:
视频中的截图
PPT中的截图如下:
PPT中的截图

一开始其实误以为是函数调用换了位置,就自己尝试了一波,发现了更多的情况,便进行分析整理如下。


已知: 箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this


第一种情况:const+箭头函数

const具有块级属性,必须先声明再使用,所以不考虑声明先后的问题

源码

		//const+箭头函数 
		function fn() {
		    console.log(this);
		     return () => {
		         console.log(this)
		     }
		 }
		 const obj = { name: '张三' };
		 const resFn = fn.call(obj);	// 壹
		 resFn();	//贰
 
// 输出结果为:
//{name: '张三'}
//{name: '张三'}

分析如下

  • 壹:因为call方法让 fn()里的console.log(this) 中的 this 指向obj,即this指向{ name: '张三' };
  • 贰:相当于 fn.call(obj)() 就相当于调用了 fn() 里的匿名函数。但是并没有传入值,所以根据箭头函数的属性,这里的this指向与匿名函数外的this一致,即{ name: '张三' };

第二种情况:var+箭头函数

var具有变量提升和函数提升

1. 先声明变量,再调用函数

源码

		//var+箭头函数 
		var obj = { name: '张三' }
		function fn() {
		    console.log(this);
		   return () => {
		       console.log(this)
		   }
		}
		// var obj = { name: '张三' }
		var resFn = fn.call(obj);	// 壹
		resFn();	// 贰

// 输出结果为:
//{name: '张三'}
//{name: '张三'}

分析如下

  • 壹:与上面一致。因为call方法让 fn()里的console.log(this) 中的 this 指向obj,即this指向{ name: '张三' };
  • 贰:与上面一致。相当于 fn.call(obj)() 就相当于调用了 fn() 里的匿名函数。但是并没有传入值,所以根据箭头函数的属性,这里的this指向与匿名函数外的this一致,即{ name: '张三' };

2. 先调用函数,再声明变量

var中,该操作不会报错,故考虑此情况

源码

		//var+箭头函数 
        var resFn = fn.call(obj);
        function fn() {
            console.log(this);
            return () => {
                console.log(this)
            }
        }
        var obj = { name: '张三' };
        // var resFn = fn.call(obj);
        resFn();
        
//输出结果为:
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}

分析如下

		//var+箭头函数 
        // 实际执行如下
        var resFn
        var obj
        function fn() {
            console.log(this);
            return () => {
                console.log(this)
            }
        }
        resFn = fn.call(obj);   // 这时候obj还没有赋值,指向的就是window
        obj = { name: '张三' };
        resFn();    // 没有传入obj,箭头函数的this指向的就是上下文中的this,就是window

第三种情况:var+普通函数

该方法作为对比项

1. 先声明变量,再调用函数

源码

		// var + 普通函数
        var obj = { name: '张三' }
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        // var obj = { name: '张三' }
        var resFn = fn.call(obj);
        resFn();

// 输出结果:
//{name: '张三'}
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}

分析如下

		// var + 普通函数
		// 实际执行如下
        var obj
        var resFn
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        obj = { name: '张三' }
        resFn = fn.call(obj);   // fn()中的this指向obj,即{ name: '张三' }
        resFn();
        // resFn()相当于fn.call(obj)()调用了fn()中的匿名函数,
        // 此时匿名函数中的this指向window

this都指向obj的方法

		// var + 普通函数
        var obj = { name: '张三' }
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        // var obj = { name: '张三' }
        var resFn = fn.call(obj);
        resFn.call(obj);
// 输出结果:
//{name: '张三'}
//{name: '张三'}

2. 先调用函数,再声明变量

考虑此情况的理由同上

源码

		// var + 普通函数
        var resFn = fn.call(obj);
        var obj = { name: '张三' };
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        // var obj = { name: '张三' }
        // var resFn = fn.call(obj);
        resFn();
//输出结果:
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}

分析如下

		// var + 普通函数
        // 实际执行如下
        var resFn
        var obj
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        resFn = fn.call(obj);   // obj尚未赋值,故 this 指向 window
        obj = { name: '张三' };
        resFn();    // fn.call(obj)(),调用匿名函数,指向window

第四种情况:const+普通函数

我是附录内容啦啦啦啦啦……

此项作为对比项。因为const必须先声明再调用,所以不考虑先后问题。

源码

        // const+普通函数
        function fn() {
            console.log(this);
            return function () {
                console.log(this)
            }
        }
        const obj = { name: '张三' };
        const resFn = fn.call(obj);		// 1
        resFn();	// 2
        
// 输出结果:
// {name: '张三'}
//Window {window: Window, self: Window, document: #document, name: '', location: Location, …}

分析如下

  • 1:call()方法使 fn()下的 this 指向obj
  • 2:fn.call(obj)() 调用匿名函数,所以 this 指向window

总结

普通函数中的this指向

先弄明白普通函数中的this指向

源码

        function fn() {
            console.log('我是外面的' + this);
            return function () {
                console.log('我是里面的' + this)
            }
        }
        fn.call()(); // 这一步其实相当于先调用了fn(),再调用里面匿名函数

// 输出结果
// 我是外面的[object Window]
// 我是里面的[object Window]

结论:
普通函数(两种声明方式:自定义函数,函数表达式)中的this均指向window
函数中的方法调用,那么this就指向调用者

const/let声明

因为const只能先声明再调用,所以无需考虑先后问题

fn()return普通函数

内容详情请见“第四种情况”

结论

  1. fn()下的this指向call()中指向的对象
  2. return 的匿名函数中的this指向window

fn()return箭头函数

内容详情请见“第一种情况”

结论

  1. fn()下的this指向call()中指向的对象
  2. return 的箭头函数不绑定this,其this指向上下文中的this,即与fn()下的一致

var声明

因为具有变量提升和函数提升,所以有多重情况可考虑

fn()return普通函数

先声明变量再调用

内容详情请见“第三种情况”

结论

  1. fn()下的this指向call()中指向的对象
  2. return 的匿名函数中的this指向window
先调用再声明变量

内容详情请见“第三种情况”

结论

  • 两个this都指向window

fn()return箭头函数

先声明变量再调用

内容详情请见“第二种情况”

结论

  • 两个this都指向call()中指向的对象
先调用再声明变量

内容详情请见“第二种情况”

结论

  • 两个this都指向window
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在React中,箭头函数组件是一种用于定义无状态组件的简洁语法。它们通常用于只有一个render方法的组件,没有自己的状态或生命周期方法。箭头函数组件的定义方式类似于函数表达式,使用箭头函数语法来定义组件。由于箭头函数没有自己的this,它的函数体中使用的this实际上是继承自定义它时所在的普通函数的this。这意味着箭头函数组件中的this将指向父级组件的this,或者如果定义在全局范围内,则指向全局对象window/undefined。\[1\] 在使用箭头函数组件时,需要注意一些性能问题。如果将箭头函数作为prop传递给子组件,子组件可能会进行额外的重新渲染。为了避免这种性能问题,通常建议使用class组件的语法来定义组件。\[2\] 另外,需要注意的是,箭头函数无法直接通过显示绑定修改this指向。但可以通过修改外层函数的this指向来间接修改箭头函数的this。\[3\] 总结来说,箭头函数组件是一种简洁的定义无状态组件的语法,它继承自父级组件的this,并且需要注意性能问题和无法直接修改this指向的限制。 #### 引用[.reference_title] - *1* *3* [react组件中箭头函数使用](https://blog.csdn.net/weixin_39289876/article/details/122534211)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [在React的render方法中使用箭头函数](https://blog.csdn.net/wu_xianqiang/article/details/109187963)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值