关于javascript:vuebabel箭头函数下调试时诡异的this

试验开始

场景:

  1. webpack: mode=development
  2. babel: babel/preset-env
  3. 箭头函数
  4. 其实和vue关系不大,只不过我是在vue里遇到了这个恶心的问题

问题:

  1. debugger过程中,实时监控的this,和console.log(this)的不统一。

简化代码:

const test1 = () => {
  console.log('test1 called this------>', this);
};
const test2 = () => {
  console.log('test2 called this------>', this);
  test1();
};

test2();

运行后果:

输入了两个Window对象,貌似没问题

但这时给两个console打上断点,再运行一次,按f10后退到test1()的执行

喜剧,监督了个 undefined 进去了。

再来一遍,这次把console里的this删掉

果不其然,监督里还是个 undefined ,在控制台里输出this,这下控制台里也 undefined

试验完结

难道不应用this,就undefined;而应用他,就有指向?
其实这里运行起来的js其实是被webpack打包过的,而且应用了babel兼容,让咱们批改下代码,如下:

class TClass {
  a = 1;
  b = 2;
  c = 3;
  constructor() {}
  test1() {
    console.log('test1 called this.a----->', this.a);
    this.test2().then(() => {
      debugger;
      console.log('test1 called this.c----->', this.c);
    });
  }
  test2() {
    return new Promise((resolve, reject) => {
      console.log('test2 called this.b----->', this.b);
      resolve();
    });
  }
}

const tObject = new TClass();
tObject.test1();

运行一下,在debugger处监督this

this指向Window?,再看控制台输入

我类的属性怎么跑Window下来了???不行,间接在控制台打印看看

无语。。。。既然运行的是babel后的代码,不如去babel官网翻译下

如果我手动加一个 _this 监督

居然逮到你了

实际上正在运行的是解决后的js,这造成了调试中的艰难,还好曾经找到解决办法:
应用babel-plugin-transform-es2015-arrow-functions依赖

npm i babel-plugin-transform-es2015-arrow-functions -D

装置胜利后在webpack.config.js或babel.config.json里加上这个插件

module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: [['transform-es2015-arrow-functions', { spec: true }]],
          },
        },
      },
    ],
  },

让我康康这次有什么变动

这下监视器,输入,控制台,以及鼠标指向this(截不进去图)都能正确辨认了。

问题解决了,但又没齐全解决。

这里有一篇阐明了V8的优化也会导致这样的状况产生,不过这是另一种状况了
Why does Chrome debugger think closed local variable is undefined?
真是百度两小时不如谷歌两分钟。(一开始我也认为本人的问题出在这里,但发现看错了方向)

结语

JS牛逼。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理