Babel 6-异步箭头函数中的“this”指向函数

4
使用以下设置的Babel 6:
require("babel-register")({
  extensions: [".es6", ".es", ".jsx", ".js"],
  plugins: ['transform-runtime'],
  presets: ["es2015", "stage-0"]
});

出乎意料的是,在普通箭头函数和异步箭头函数之间,this引用存在差异。因此,我的问题实际上是,是否有其他人可以确认这是最新babel中的一个错误,并且我应该在哪里报告这个问题。

class TestClass
{   
    name = "John Doe";

    testMethodSuccess()
    {
        return new Promise((resolve) => {
            console.log(this);
            setTimeout(resolve, 1000);
        });
    }

    testMethodFailure()
    {
        return new Promise(async (resolve) => {
            console.log(this);
            setTimeout(resolve, 1000);
        });
    }
}

(async () => {
    try{
        var testObject = new TestClass();
        await testObject.testMethodSuccess();
        await testObject.testMethodFailure();
    }catch(e){
        console.error(e);
    }
})();

以下是上述代码的结果:
"use strict";

var _regenerator = require("babel-runtime/regenerator");

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _promise = require("babel-runtime/core-js/promise");

var _promise2 = _interopRequireDefault(_promise);

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require("babel-runtime/helpers/createClass");

var _createClass3 = _interopRequireDefault(_createClass2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var TestClass = function () {
    function TestClass() {
        (0, _classCallCheck3.default)(this, TestClass);
        this.name = "John Doe";
    }

    (0, _createClass3.default)(TestClass, [{
        key: "testMethodSuccess",
        value: function testMethodSuccess() {
            var _this = this;

            return new _promise2.default(function (resolve) {
                console.log(_this);
                setTimeout(resolve, 1000);
            });
        }
    }, {
        key: "testMethodFailure",
        value: function testMethodFailure() {
            return new _promise2.default(function () {
                var _this2 = this;

                var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(resolve) {
                    return _regenerator2.default.wrap(function _callee$(_context) {
                        while (1) {
                            switch (_context.prev = _context.next) {
                                case 0:
                                    console.log(_this2);
                                    setTimeout(resolve, 1000);

                                case 2:
                                case "end":
                                    return _context.stop();
                            }
                        }
                    }, _callee, _this2);
                }));
                return function (_x) {
                    return ref.apply(this, arguments);
                };
            }());
        }
    }]);
    return TestClass;
}();

(0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2() {
    var testObject;
    return _regenerator2.default.wrap(function _callee2$(_context2) {
        while (1) {
            switch (_context2.prev = _context2.next) {
                case 0:
                    _context2.prev = 0;
                    testObject = new TestClass();
                    _context2.next = 4;
                    return testObject.testMethodSuccess();

                case 4:
                    _context2.next = 6;
                    return testObject.testMethodFailure();

                case 6:
                    _context2.next = 11;
                    break;

                case 8:
                    _context2.prev = 8;
                    _context2.t0 = _context2["catch"](0);

                    console.error(_context2.t0);

                case 11:
                case "end":
                    return _context2.stop();
            }
        }
    }, _callee2, undefined, [[0, 8]]);

你能否发布转译后的 ES5 代码? - zerkms
如果您查看添加的转译代码,您会发现在testMethodFailure中有一个“var _this2 = this”,它指向该函数。我没有预料到在其前面添加async时,this的引用会发生变化。而且在以前的版本中,它运行得非常好。 - Olle Tiinus
看起来这是 Babel 6 的一个 bug。网站上的“尝试一下”仍然是 Babel 5,并且该行 var _this2 = this; 是立即在那里生成的 testMethodFailure 内而不是在 promise 回调内部生成的。 - James Thorpe
5
已经有一个错误报告了。 - James Thorpe
1个回答

3

2
箭头函数中这有严重问题。 - SuperUberDuper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接