あなたのミックスインは本当に ECMAScript 5 と互換性がありますか?_基本

WBOY
リリース: 2016-05-16 17:37:42
オリジナル
1104 人が閲覧しました

私は最近、ECMAScript 5 を最大限に活用する必要があるクライアントとのプロジェクトに取り組んでいたのですが、非常に興味深い問題に遭遇しました。 この問題は、非常に一般的なパターン、つまり JavaScript で 1 つのオブジェクトのプロパティまたはメソッドを別のオブジェクトに混合するミックスインに起因します。

ほとんどのミックスインの機能は次のようになります:

コードをコピー コードは次のとおりです。

function mixin(receiver, Supply) {
for(サプライヤーのvarプロパティ){
>

この mixin() 関数では、for ループがサプライヤー オブジェクトのプロパティを反復処理し、それらをレシーバー オブジェクトに割り当てます。 ほとんどすべての JavaScript ライブラリには、次のようなコードを作成できる何らかの形式の同様の機能があります。


コードをコピー

コードは次のとおりです。mixin(object, { name : 「ニコラス」、 SayName: function() {
console.log(this.name);
}
});
object.sayName(); // 「ニコラス」を出力します




この例では、オブジェクト object はプロパティ名とメソッドsayName()を受け取ります。 これは ECMAScript 3 では正常に機能しますが、ECMAScript 5 ではあまり機能しません。

これが私が抱えている問題です:

コードをコピー

コードは次のとおりです。(function() { // 後で入力します var name;
mixin(object, {
get name() { return name;

}
});

// これは後で言っておきます
name = "Nicholas";

}());

console.log(object.name); // 未定義


この例は少し不自然に見えますが、問題を正確に説明しています。 混合されるプロパティでは、ECMAScript 5 の新機能であるゲッター プロパティ アクセサーが使用されます。ゲッターは初期化されていないローカル変数名を参照しているため、プロパティは未定義です。

その後、アクセサーゲッターが有効な値を返せるように、name に値が割り当てられます。 残念ながら、object.name (mixined プロパティ) は常に未定義を返します。

何が起こっているのですか?

mixin() 関数を注意深く分析してみましょう。 実際、ループ ステートメントでは、プロパティはあるオブジェクトから別のオブジェクトに再割り当てされません。 実際には、同じ名前のプロパティを作成し、それにサプライヤー オブジェクトのアクセサー メソッド getter の戻り値を割り当てます。 (注釈: ターゲット オブジェクトはゲッター メソッドを取得するのではなく、ゲッター メソッドの戻り値を取得します。@justjavac)

この例では、mixin() プロセスは実際には次のようになります:

コードをコピー

コードは次のとおりです。receiver.name =supplier.name;
属性receiver.nameが作成され、supplier.nameの値が割り当てられます。 もちろん、supplier.name にはローカル変数名の値を返す getter メソッドがあります。 このとき、name の値は未定義のため、receiver.name に値が格納されます。 receiver.name に対して作成された getter メソッドがないため、その値は決して変更されません。

この問題を解決するには、プロパティ記述子 (アノテーション: 記述子) を使用して、あるオブジェクトから別のオブジェクトにプロパティを混合する必要があります。 mixin() の純粋な ECMAScript 5 バージョンは次のようになります:

コードをコピーします

コードは次のとおりです。function mixin(receiver, Supply) { Object.keys(supplier).forEach(function(value, property) { Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
});
}

この新しいバージョンの関数では、Object.keys() を使用して、サプライヤー オブジェクトのすべての列挙プロパティを含む配列を取得します。 次に、foreach() メソッドを使用して、これらのプロパティを反復処理します。 Object.getOwnPropertyDescriptor() メソッドを呼び出して、サプライヤー オブジェクトの各プロパティ記述子 (記述子) を取得します。

記述子にはゲッター メソッドやセッター メソッドを含むすべてのプロパティ情報が含まれているため、記述子を Object.defineProperty() に直接渡して、受信側オブジェクトに同じプロパティを作成できます。 この新しいバージョンの mixin() を使用すると、以前に発生した問題を解決し、期待どおりの結果を得ることができます。 getter メソッドはサプライヤーからレシーバーに正しく渡されます。

もちろん、古いブラウザをサポートする必要がある場合は、ECMAScript 3 にフォールバックする関数が必要になります。

コードをコピーします コードは次のとおりです。

function mixin(receiver, Supply) {
if (Object.keys) {
Object.keys(supplier).forEach(function(value, property) {
Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
} );
} else {
for (サプライヤーの var プロパティ) {
if (supplier.hasOwnProperty(プロパティ)) {
レシーバー[プロパティ] = サプライヤー[プロパティ];
}
}
}
}

mixin() 関数を使用する必要がある場合は、ECMAScript 5、特にゲッター メソッドとセッター メソッドで正しく動作することを必ず再確認してください。 そうしないと、私と同じような間違いを犯すことになります。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート