jsdo.itユーザのtsmallfieldさんから以下のお題が出た。
(本物の)配列かどうかを判断するのに
var isArray = function(arg){
return [].concat(arg)[0] !== arg;
};ではどうだろう?とふと思ついたのでテスト。
http://jsdo.it/tsmallfield/isArray
10分ほど考えて、これが失敗するコードを作成
var a = []; a[0] = a; isArray(a); // => false
Array#concatで、配列でないものは配列の0番目に、そうでないものは頭からマージされるので、それの0番目を取り出して元々のオブジェクトと比較すれば、同じオブジェクトが返ってくるということは配列でない、という論理。ただしJavaScriptのオブジェクトの場合、この手の比較は実質アドレス値の比較になるので、循環参照して0番目に同じアドレスが入るようにしておくと、同じアドレス値同士での比較になってしまい、偽値が返却されてしまう。