Babelトランスコード「super」に関する注意事項


事の起因は問答の上で1人の友达の質問を見て、チェンの1峰の先生のECMAScript 6の入門の上でsuperのキーワードの1段のコードの問題について聞いて、以下はこのコードのスクリーンショットです:
このスレ主はthis.xの値が3ではないと思っていると言っています.下のネットユーザーはコードをchromeコンソールに貼り付けてみると、この結果は間違いないと言っています.その後、スレ主は彼の考えが間違っていると言っていました.私もついでにコードをchomeの下に貼り付けて実行した後、答えも確かに3です.
もともとこの件は何もなく終わって、ちょうど私はWebStormを開いてコードを書く準備をして、ついでにコードファイルの中に貼り付けて、保存>webpackパッケージ>ブラウザをリフレッシュして、Consoleを見ました:
!これは神馬事情で、出力はなんと2!

もんだいぶんせき


なぜchromeの直接実行の結果と一致しないのですか?問題はBabelトランスコードにあるはずだと考えた.すぐにトランスコードされたファイルを開き、このコードの場所にナビゲートします.
var B = function (_A) {
    _inherits(B, _A);

    function B() {
        _classCallCheck(this, B);

        var _this = _possibleConstructorReturn(this, (B.__proto__ || Object.getPrototypeOf(B)).call(this));

        _this.x = 2;
        _set(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), 'x', 3, _this);
        console.log(_get(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), 'x', _this)); // undefined
        console.log(_this.x); // 3
        return _this;
    }

    return B;
}(A);
super.x = 3;_set(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), 'x', 3, _this);に対応しています.ここには_set()の関数があります.この_set()は何ですか.
var _set = function set(object, property, value, receiver) {
    var desc = Object.getOwnPropertyDescriptor(object, property);
    if (desc === undefined) {
        var parent = Object.getPrototypeOf(object);
        if (parent !== null) {
            set(parent, property, value, receiver);
        }
    } else if ('value' in desc && desc.writable) {
        desc.value = value;
    } else {
        var setter = desc.set;
        if (setter !== undefined) {
            setter.call(receiver, value);
        }
    }
    return value;
};

この関数をよく見て、何が起こっているのか分かりました.チェン一峰先生のコードと上のトランスコードを組み合わせると、_set()から伝わってきた最初のパラメータはB.prototype.__proto__--つまりAのプロトタイプオブジェクト--A.prototypeで、最初の文のコードはまずx の記述子を探して、もし見つからないならばプロトタイプチェーンに沿って探し続けます...もちろん見つからないので、何も実行していないに相当し、this.xの値は依然として2です.
この_set()関数の論理に従えば、this.xの値はどのような場合に3になるのでしょうか.2つの条件を満たすには、次の手順に従います.
  • A.prototypeにはx属性定義
  • が必要である.
  • このx属性定義には、setアクセサ
  • も定義する必要がある.
    たとえば、次のようにします.
    Object.defineProperty(A.prototype, 'x', {
        get: function () {
            return this._x;
        },
        set: function (value) {
            this._x = value;
        }
    });

    そしてもう1本走ってみると、やはりthis.xの値は3!ちょっと待って...どうしてconsole.log(super.x); // undefinedという文の結果はundefinedでも3でもないのですか.トランスコードを見ると_get()関数があります.
    var _get = function get(object, property, receiver) {
        if (object === null) object = Function.prototype;
        var desc = Object.getOwnPropertyDescriptor(object, property);
        if (desc === undefined) {
            var parent = Object.getPrototypeOf(object);
            if (parent === null) {
                return undefined;
            } else {
                return get(parent, property, receiver);
            }
        } else if ("value" in desc) {
            return desc.value;
        } else {
            var getter = desc.get;
            if (getter === undefined) {
                return undefined;
            }
            return getter.call(receiver);
        }
    };

    はい、コードは最後のelseのgetterに行きました.自然super.xの読み取り結果は3です.
    今のところ、なぜBabelがこのようにトランスコード処理するのかを見る時間がありません.もし答えがあれば、伝言討論を歓迎します.