QA@IT

for in とhasOwnProperty

4886 PV

for in と
hasOwnProperty

http://tomcky.hatenadiary.jp/entry/2014/06/16/224904

こちらのURLのものを理解したいのですが、何故hasOwnPropertyが必要なのかわかりません。
なぜ全プロパティを列挙することがいけないのですか?
key in myObjでmyObjからキーを取り出しているのですから、hasOwnPropertyを使ってもkeyは必ず含まれているのではないのですか?
これを使うと使わない場合と何が違うのでしょうか。

回答

参考にされている記事のコードを実際に動かしてみたでしょうか? そうすれば分かるはずなのですが。

key in myObjでmyObjからキーを取り出しているのですから、hasOwnPropertyを使ってもkeyは必ず含まれているのではないのですか?

それはそうなのですが、for ... in ではプロトタイプチェーンをたどって意図しない余計なもの(参考にされている記事では myFunction)まで取得してくるということが記事の 2 つ目のコードを試すと分かるはずです。コンソール出力は以下のようになるはずです。

hoge:HOGE
fuga:FUGA
myFunction:function () { console.log('This is myFunction'); }

記事の 3 つ目のコードでは、myObj 直下のプロパティ(参考にされている記事では hoge と fuga)か否かを hasOwnProperty で調べて、myObj 直下のプロパティのみコンソールに出力しています。結果は hoge:HOGE と fuga:FUGA だけになるはずです。

【追記】

2017/05/29 11:45 の私のコメントに「参考にされていた記事では実際にどういうケースがあるかが分からないということと理解して、回答欄に例(あくまで例です)を書いておきます」と書きましたが、それを以下に書いておきます。あくまで私が思いついた一例です。他にもっと適切で分かりやすい例があるかもしれませんが・・・

JavaScript でオブジェクト指向を実装するのに prototype を利用できます。例えば以下のように Person クラスを定義したとします。Person クラスの Own プロパティは Name, LastName, BirthDate のみですが、for ... in で hasOwnProperty を使わないと Name, LastName, BirthDate の他に initialize, getAge も取得されます。コードを実行してみてください。

// Person クラスの疑似コンストラクター
var Person = function (name, lastname, birthdate) {
    this.initialize(name, lastname, birthdate);
}

// メンバー
Person.prototype.initialize = function (name, lastname, birthdate) {
    this.Name = name;
    this.LastName = lastname;
    this.BirthDate = birthdate;
}

// メンバー
Person.prototype.getAge = function () {
    return 18;
}

var p = new Person("web", "surfer", "2017/5/59");

for (var key in p) {
    console.log(key + ':' + p[key]);
}

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + ':' + p[key]);
    }
}
編集 履歴 (3)
  • ありがとうございます。余計なものを取得してしまうと言うのが、どういった場合に取得してしまうのかわからないのです。
    いつもとりあえずhasOwnPropertyを入れたり、おかしくなったら入れてみたりしているのですが、その際にわかると良いなと思いまして。
    -
  • > どういった場合に取得してしまうのかわからないのです。

    参考にされていた記事に書いてあった通りなのですが・・・ 多分、参考にされていた記事では実際にどういうケースがあるかが分からないということと理解して、回答欄に例(あくまで例です)を書いておきます。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。