New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

クラスモジュール(h5.cls)の、インスタンスをsealするオプション(isDynamic)を廃止 #597

Closed
simdy opened this Issue Dec 4, 2018 · 2 comments

Comments

Projects
None yet
1 participant
@simdy
Member

simdy commented Dec 4, 2018

ver.1.3.2まで、クラス定義のisDynamicの設定(デフォルト=false)でfalseを指定すると、インスタンスに対してObject.seal()を呼び出し、fieldで定義していないプロパティを(誤って)追加しようとした場合にエラーが発生するようにしていた。

しかし、この仕様を成立させるため、インスタンス生成ごとにfieldで定義されているプロパティをown-propertyとして追加する(instance.prop = value; のようなコードを呼び出す)ことをしており、このため、大量のインスタンスを生成した場合にインスタンス生成コストが高くパフォーマンス劣化が目立ってしまった。

そこで、ver.1.3.3で、isDynamicによる指定は廃止し、Object.seal()を行わないように仕様変更する。
また、これに伴い、インスタンス生成時にプロパティを初期化する処理も実行しないようにする。これによって、例えばフィールドを30個持つクラスのインスタンスを10万個生成した場合のパフォーマンスはIE11で10倍程度(1397ms⇒151ms)高速になる。

なお、クラス定義ではdefaultValueを指定することができるが、この値は、内部で保持しているクラスのプロトタイプオブジェクトに持たせるようにした。これにより、defaultValueについての仕様の互換性を保つ。インスタンス生成後(defaultValueが設定された)プロパティに対して読み取りだけを行っている間は、プロトタイプチェーンをたどって値が取得される。一度でも書き込みを行うと、そのプロパティはインスタンスのown-propertyとなり、以降はそのown-propertyが使われるようになる。

@simdy simdy self-assigned this Dec 4, 2018

@simdy simdy added this to the v1.3.3 milestone Dec 4, 2018

@simdy

This comment has been minimized.

Member

simdy commented Dec 4, 2018

なお、この変更により、一度も書き込みしていないフィールドは
instance.hasOwnProperty('fieldName')がfalseになる、という動作になる。
(ver.1.3.2までは、isDynamic=falseなクラスの場合、インスタンス生成時に
プロパティの初期化を行っていたのですべてのフィールドに対してhasOwnProperty()がtrueになっていた)

ただし、このような動作は、例えばTypeScriptで初期化式を記述せずにフィールドを定義した場合にも同様である。
(TypeScriptで、private number f1; のように定義しても、出力されたJSコードにはなにも出力されない。一方、private number f1 = 1; と書くと、コンストラクタ関数内に「this.f1 = 1;」というコードが追加される。(ただしObject.seal()は行わない。))

なお、クラスモジュールを使用した場合でも、コンストラクタの中で(ユーザーコードとして) Object.seal(this); というコードを呼び出せば、今まで通りそのインスタンスの動的なプロパティ追加を禁止することは可能なので、禁止させたい場合はそのように対応していただきたい。

今回の仕様変更は、JSの「型」についての言語的特性、TypeScript等型定義を可能にするJS向け言語の動作、共通的・汎用的に使用されるクラスモジュールの性格などから、パフォーマンスの問題がクラスモジュールの使用を妨げてしまうことの方が問題であると判断したものである。

@simdy simdy closed this Dec 4, 2018

@simdy

This comment has been minimized.

Member

simdy commented Dec 4, 2018

なお、クラス定義にisDynamicの指定がある場合、フレームワークはWARNログを出力する。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment