找不到箭头函数的this?试试用Babel

大家都知道普通函数里的this指向最后一个调用他的对象上,箭头函数里的this指向当前作用域的上一个,但是在比较复杂的代码结构中,很多同学在日常工作或面试中总是无法很快判断箭头函数的this指向。

其实我们可以将ES6中的箭头函数通过Babel转为ES5的普通函数来看,就可以发现转义后的箭头函数的this就已经确定,如:

javascript 复制代码
var b=11;
var obj={
 b:22,
 say:()=>{
   console.log(this.b);
 }
}
obj.say(); //输出的值为11

转ES5后:

javascript 复制代码
"use strict";

var _this = void 0;
var b = 11;
var obj = {
  b: 22,
  say: function say() {
    console.log(_this.b);
  }
};
obj.say(); //输出的值为11

若当前在浏览器环境,则_this指向window,那么当下次碰到箭头函数时,我们是否可以往箭头函数的上层作用域找到第一个地方可以写下var _this = this的语句,那么这里的this就是这个箭头函数的this指向。

例子

再看一个复杂一点的例子:

javascript 复制代码
var str = '111';
const obj = {
    str:'obj',
    fn: ()=>{
    	console.log(this.str);    
    },
    fn2: function(){ // fn的上一层是fn2
    	console.log(this.str)
          return {
            str: 'newObj',
            fn3: ()=>{
            console.log(this.str);    
          }    
      }
    }
}
obj.fn() // 输出 111
obj.fn2().fn3(); //输出obj,obj

笔者在obj定义了一个箭头函数fn,在最外层可以定义他的this,所以fn的this指向window

我们在一个返回的对象中定义了一个箭头函数fn3,在fn3的上面的fn2可以定义他的this,而fn2是被obj调用的,所以fn的this指向obj,我们来看一下转为ES5是怎样:

javascript 复制代码
"use strict";

var _this = void 0;
var str = '111';
var obj = {
  str: 'obj',
  fn: function fn() {
    console.log(_this.str);
  },
  fn2: function fn2() {
    var _this2 = this;
    // fn的上一层是fn2
    console.log(this.str);
    return {
      str: 'newObj',
      fn3: function fn3() {
        console.log(_this2.str);
      }
    };
  }
};
obj.fn(); // 输出 111
obj.fn2().fn3(); //输出obj,obj

再来看一个例子:

javascript 复制代码
let object = {
  name: "小强",
  x: 50,
  put() {
    setTimeout(
      () => {
        console.log(this.x);
        console.log(this.name);
      }, 500);
  },
};
object.put(); //输出结果:50  小强

我们直接找到setTimeout外面的put函数,在里面写下var _this = this,把_this带入箭头函数的this,就有答案了:

javascript 复制代码
"use strict";

var object = {
  name: "小强",
  x: 50,
  put: function put() {
    var _this = this;
    setTimeout(function () {
      console.log(_this.x);
      console.log(_this.name);
    }, 500);
  }
};
object.put(); //输出结果:50  小强

箭头函数嵌套箭头函数

当箭头函数里面还有箭头函数时,想象一下把第二个箭头函数的this定义在fn2中,那fn2还是箭头函数,是不是还得往上走,最后把三个箭头函数的this都定义在fn中,fn被obj调用,所以this都指向obj

javascript 复制代码
const obj = {
  a: '222',
  fn: function () {
    return {
      fn2: () => {
        console.log(this.a)  // 222

        return () => {
          console.log(this.a)  // 222

          return () => {
            console.log(this.a) // 222
          }
        }
      }
    }
  }
}
obj.fn().fn2()()()  // 222  222  222

看看转为ES5以后:

javascript 复制代码
"use strict";

var obj = {
  a: '222',
  fn: function fn() {
    var _this = this;
    return {
      fn2: function fn2() {
        console.log(_this.a); // 222

        return function () {
          console.log(_this.a); // 222

          return function () {
            console.log(_this.a); // 222
          };
        };
      }
    };
  }
};
obj.fn().fn2()()(); // 222  222  222

感兴趣的同学可以用在线工具babeljs.io/repl将ES6转ES5

总结

通过这些例子,大家也能看出来箭头函数的this是在写完代码就已经确定了,而不是运行的时候确定的,希望我的文章能给大家带来一点帮助

欢迎点赞、收藏、转发~

相关推荐
Autumn_ing4 小时前
Design.md生成UI怎么验收?举例运营后台的颜色、状态和数据核对
前端·ui·ai·设计系统·paico·ai生成ui·design.md
远离UE44 小时前
UE5 Substrate Thin Film 源码拆析
开发语言·javascript·ue5
keyipatience5 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
朱涛的自习室5 小时前
我给 Gemini 4 和 DeepSeek 搞了套「末位淘汰」,AI 干活会更猛吗?(Day 3)
android·前端·后端
java1234_小锋7 小时前
【技术专题】HTML5 网页技术 - HTML5简介 & HTML5 文档结构
前端·html·html5
鶴哥只手遮天8 小时前
Vue 3 核心源码深度剖析系列(v3.5.44)-第 1 章 项目全景:monorepo 架构与工程化体系
前端·vue.js·开源
流星。。方8 小时前
小团队官网SEO落地:前端语义化与静态生成的工程实践
前端·状态模式
用户530429765798 小时前
盘点危化品搬运诊断的6类工具与自处理边界判断
前端
curtain8 小时前
从古法编程到 Agent:我入行这两年,AI 改变了什么
前端·openai
zyfts8 小时前
10分钟自制Codex钉钉通知Skill:AI干完活自动钉钉提醒你
前端