JavaScript

Class.prototype = { ... } が駄目な理由

More than 3 years have passed since last update.

javascriptでクラスを定義(厳密にクラスではない)する時、下記のような書き方をする方は少なくないのではないでしょうか。

var Hoaa = function() { ... };

Hoaa.prototype = { ... };

この方法には少し問題があるようです。


Function.prototypeは空ではない

functionを宣言をすると、内部的にFunctionオブジェクトがnewされていますが、Function.prototypeの中身は空ではありません。試しにChromeのconsoleなどを使い確かめてみてください。

Hoaa.prototype

> Hoaa {}

Hoaaを開くと、内部的にconstructorを持ち、その中に関数名などの情報を持っていることがわかります。これを、冒頭のような書き方をすると当然prototypeの中身は新しいObjectで上書きされてしまいます。

Hoaa.prototype = {};

Hoaa.prototype
> Object {}


それで、なんか困るの?

個人的にはエラー検知などの用途を除けば、constructorの中身に影響される実装を行うことはまずありませんが、少なくともprototypeを上書きすると通常のFunctionオブジェクトと構造が変わってしまうことになります。予期しないバグを避ける為にも、ブラウザの実装に準拠したFunctionとして扱う方が良さそうです。


じゃあどうしたらいいの?

タイピングの手間を惜しまず、以下のように書きます。

Hoaa.prototype.method = function() { ... };

または、何かしらのライブラリのextendを使う方法でもよいかと思います。

Hoaa.prototype = _.extend(Hoaa.prototype, { ... });