Help us understand the problem. What is going on with this article?

function リテラルでのコンストラクタは Object.create() するとクラス名が消える?

More than 5 years have passed since last update.

JavaScript を書いてる人はおそらく普段このようなコードでクラスとインスタンスを記述するかと思います。

var Hoge = function (foo, bar) {
  this.foo = foo;
  this.bar = bar;
};
var hoge = new Hoge('hello', 'world');

しかし、ES5 で導入された Object.create() でこのオブジェクトを複製すると、Firefox や WebKitのコンソールで Object と出力されてしまいます。

実際には プロトタイプチェーンを引き継いでいますし、以下のような実行結果になります。

var hogeClone = Object.create(hoge);
console.log(hogeClone.constructor === Hoge); // true
console.log(hogeClone instanceof Hoge); // true

これは、var による変数に無名の function リテラルでコンストラクタを宣言している場合に起きる現象です。デバッガがオブジェクトのコンストラクタを認識する時に、hoge.constructor.name を参照するので、無名関数リテラルではその値が空と判断され、「それじゃあ出力で表示するクラス名は タダのObjectでいいね」と判断するためです。

console.log(hoge.constructor.name); // ""

ちゃんとデバッガがクラス名を出力するパターン

var Hoge = function Hoge(foo, bar){
  this.foo = foo;
  this.bar = bar;
};

// Firefox の Firebug だと、これでもダメ。
// function Hoge () {} と完全に function 文にする必要あり。

var hoge = new Hoge('hey!', 'you!');

console.log(hoge.constructor.name); // "Hoge"

このようにリテラルでなく、文としてコンストラクタを宣言すると、デバッガは function.name を参照してインスタンスをクラス名で表示してくれるようになります。

「実行に影響ないよね?」← やり方によってはあるよ

function 文で書いてしまうと、スコープの一番先頭に移動されるので、リテラルでの宣言と挙動が変わるケースは存在します。

しかし、大抵の場合、クラスのコンストラクタ宣言でそうした影響の可能性はほぼ無いかと思われます。(別にコンストラクタがグローバルリークするわけでもないし、宣言した箇所のスコープは保持するので)
特に var Hoge = function Hoge() {} のように名前つき function リテラル で宣言する場合はほとんど影響ないです。

じゃあ、してもしなくてもあんまり変わらないのかというと、デバッグしやすさにおいてかなり影響があります。

すべて var でコンストラクタを定義してあると、せっかくクラスを定義して、メソッドやプロトタイプを当て、役割を決めているのにデバッガですべて Object として出力されてしまってはもったいないですよね。

VoQn
デジタルプロダクトデザイナー
http://voqn.github.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした