Object#hasOwnProperty() break? continue?
Objectの要素を列挙するときfor(i in Object);ループをつかったりするのですが、prototype.js*1などによるObject汚染(いい言葉ではないな)がありその回避手段としてObject#hasOwnPropertyを使ったりしますが今回は、そのループ内でhasOwnPropertyをつかったとき break と continueどちらを利用したらいいのかという実験。
breakをするとそれ以降のループが中断されるのでbreakした以降に自信のオブジェクトが出てきたら困る。安全策としてはcontinueで毎回チェックするというもの。ただprotoptypeチェーンに繋がっているメソッドやプロパティの分だけループするからお世辞にもいいとはいえない。
具体的には
●break
for(i in obj)
{
if(!obj.hasOwnProperty(i)) break;
// なにか処理をする
}
●continue
for(i in obj)
{
if(!obj.hasOwnProperty(i)) continue;
// なにか処理をする
}どちらがより適当かということ?
TRY1
Foo = function(){};
Foo.prototype =
{
one : 1, two : 2, three : 3
}
Bar = function(){};
Bar.prototype = new Foo();
Bar.prototype.prop1 = 1;
Bar.prototype.prop2 = 2;
Bar.prototype.prop3 = 3;
Obj = function(){};
Obj.prototype = new Bar();
Obj.prototype.method1 = function(){};
Obj.prototype.method2 = function(){};
Obj.prototype.method3 = function(){};
obj = new Obj();
for(i in obj)
document.write(i,', ');
TRY2
Foo = function(){};
Foo.prototype =
{
one : 1,
two : 2,
three : 3
}
Bar = function(){};
Bar.prototype = new Foo();
Bar.prototype.prop1 = 1;
Bar.prototype.prop2 = 2;
Bar.prototype.prop3 = 3;
Obj = function(){};
Obj.prototype = new Bar();
obj = new Obj();
obj.method1 = function(){};
obj.method2 = function(){};
obj.method3 = function(){};
for(i in obj)
document.write(i,', ');
Result2
IEでの結果
three, two, one, prop1, prop2, prop3, method1, method2, method3,
TRY3
Object.prototype.foo = '';
Object.prototype.bar = '';
obj = { one : 1, two : 2};
Result3
IEでの結果
bar, foo, one, two,
結果
実験結果より考察するとTRY1のようにprototypeチェーンでつなげていくとprototypeチェーンにつながっている新しいほうから列挙される。TRY2とTRY3ではIEの場合では(∀`?)という結果になり。静的メソッドは最後に列挙された。
まとめ
TRY1のパターンでは for(i in Object) で break文を利用してもよさげ。TRY2だとIEとそれ以外の挙動が異なる為breakではなくcontinueを利用したほうがいい。またTRY3においても同じ結果であった為に continueを推奨します。
*1:むかしの