找不到箭头函数的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,所以fnthis指向window

我们在一个返回的对象中定义了一个箭头函数fn3,在fn3的上面的fn2可以定义他的this,而fn2是被obj调用的,所以fnthis指向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中,fnobj调用,所以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/replES6ES5

总结

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

欢迎点赞、收藏、转发~

相关推荐
你挚爱的强哥39 分钟前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森1 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy1 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189111 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿2 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡3 小时前
commitlint校验git提交信息
前端
虾球xz4 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇4 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒4 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员4 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js