找不到箭头函数的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是在写完代码就已经确定了,而不是运行的时候确定的,希望我的文章能给大家带来一点帮助

欢迎点赞、收藏、转发~

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄3 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端