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

モダン for (var x in obj) -> for (;;)

More than 5 years have passed since last update.

今までの for (var in )

JavaScript で オブジェクトをハッシュ、連想配列代わりに利用し、for 文で回す場合このように書いていました

var forEachHash = function (obj, callback) {
  var name;

  for (name in obj) {
    if (obj.hasOwnProperty(name)) { // prototype を除く
       callback(obj[name], name);
    }
  }
};

しかし、元々 for (var x in obj) パターンのでは、name にプロトタイプからのプロパティ名まで取得してしまいます。
なので、Object.prototype.hasOwnProperty() で条件付けする必要がありました。

Object.keys() を使おう

ES5 で Object.keys() が導入されたので、for (;;) 文で安全に目的のプロパティのみを参照してループできるようになります。

var forEachHash = function(obj, callback) {
  var keys = Object.keys(obj),
        index, length, key, value;

  for(index = 0, length = keys.length; index < length; index++) {
    key = keys[index];
    value = obj[key];
    callback(value, key);
  }
};

Object.keys(obj) は引数のオブジェクトから enumable なプロパティ名のみの配列を返します。

オブジェクトのクローンを作りたい時などは Object.getOwnPropertyNames()

目的がハッシュの各 key, value をループで取得したい場合でなく、インスタンスのクローンを作りたい場合などは Object.keys() でなく、 Object.getOwnPropertyNames() を使います。

// 任意のオブジェクトを複製する
var clone = function (obj) {
  var copied = Object.create(obj),
        names = Object.getOwnPropertyNames(obj),
        index, length, name, desc;

  for (index = 0, length = names.length; index < length; index++){
    name = names[index];
    desc = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(copied, name, desc);
  }
  return copied;
};

上記の例では Object.create() でまず prorotype のプロパティを引き継いだ新しいオブジェクトを作り、Object.getOwnPropertyNames() でインスタンスメソッドやプロパティ名を取得します。
その後、 Object.getOwnPropertyDescriptor() で元のプロパティの読み書き制限や列挙可能か、再定義可能かなどの指定をそのまま Object.defineProperty() で引き継ぎさせています。

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
ユーザーは見つかりませんでした