Locker と LWS でコピーされたオブジェクトのプロパティの違い

JSON.stringify(o) を使用してオブジェクトをコピーすると、Lightning Locker と LWS では動作が異なります。お使いのコードは、LWS では発生しない Lightning Locker の非標準動作に依存している可能性があります。

Lightning Locker では、プラットフォームオブジェクトはセキュアなラッパーに置き換えられます。この動作の例を Event オブジェクトで見てみましょう。Event オブジェクトは SecureEvent オブジェクトとして公開されます。SecureEvent は新しいオブジェクトであり、元の Event オブジェクトの継承されたプロパティと直接プロパティが、新しいオブジェクトではすべて直接プロパティになります。直接プロパティは「独自のプロパティ」と呼ばれます。独自のプロパティへの変換は、継承されたプロパティである Event.prototype.detailSecureEvent インスタンスの独自のプロパティになることを意味します。

JSON.stringify(o) は独自のプロパティに対してのみ動作しますが、Lightning Locker が有効になっている状態で Event オブジェクトに対して使用すると、SecureEvent によって独自のプロパティに変換されるため、すべてのプロパティが含められるようになります。Lightning Locker では、JSON.parse(JSON.stringify(o)) を使用することで、受信したオブジェクトを「コピー」することができます。

LWS はセキュアラッパーを使用しないため、オブジェクトは通常のブラウザープラットフォームと同じように動作します。LWS が有効化されている場合の Event オブジェクトでは、Event.prototype.detail は継承されたプロパティであって独自のプロパティではないため、JSON.stringify(o) でシリアライズされたプロパティには含まれません。したがって、すべてのプロパティがシリアライズされていることを前提とする手法は、LWS では同じようには動作しません。

JSON.parse(JSON.stringify(o)) を介した CustomEvent オブジェクトのコピーは、LWS への移行に際して問題が発生しやすい分野の 1 つです。CustomEvent.detail は独自のプロパティではないため、コピー時には除去されます。

たとえば、次のコードでは SecureEvent がラッピングによって detail プロパティを JSON.parse(JSON.stringify(event)) オブジェクトが解析できる独自のプロパティに変換しているため、このコードは Lightning Locker でのみ動作します。

Event オブジェクトの detail プロパティの値を渡すには、プロパティをオブジェクトから切り離して、新しいオブジェクトに割り当て直すことをお勧めします。