乐趣区

关于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 牛逼。

退出移动版