Babelトランスコード「super」に関する注意事項
3594 ワード
事の起因は問答の上で1人の友达の質問を見て、チェンの1峰の先生のECMAScript 6の入門の上でsuperのキーワードの1段のコードの問題について聞いて、以下はこのコードのスクリーンショットです:
このスレ主は
もともとこの件は何もなく終わって、ちょうど私はWebStormを開いてコードを書く準備をして、ついでにコードファイルの中に貼り付けて、保存>webpackパッケージ>ブラウザをリフレッシュして、Consoleを見ました:
!これは神馬事情で、出力はなんと2!
なぜchromeの直接実行の結果と一致しないのですか?問題はBabelトランスコードにあるはずだと考えた.すぐにトランスコードされたファイルを開き、このコードの場所にナビゲートします.
この関数をよく見て、何が起こっているのか分かりました.チェン一峰先生のコードと上のトランスコードを組み合わせると、
この が必要である.この も定義する必要がある.
たとえば、次のようにします.
そしてもう1本走ってみると、やはり
はい、コードは最後のelseの
今のところ、なぜBabelがこのようにトランスコード処理するのかを見る時間がありません.もし答えがあれば、伝言討論を歓迎します.
このスレ主は
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がこのようにトランスコード処理するのかを見る時間がありません.もし答えがあれば、伝言討論を歓迎します.