javascriptでは関数の返り値にvoidはなく、undefinedが返る

javascriptで、配列がこういう形の場合


ar = ["col1", "col2", "col3", "col4"];
中身を全部見たい場合はこういう風に見る(のが普通だよね?)

// Printという関数はどこかで定義されているとする
for(var i in ar){
Print(ar[i]);
}
//あるいは、
for(var j=0; j
で、こういうのをたまたま見つけて、新しい書き方を知った。
自分流にブレークダウンするとこういう感じか、

/** イテレータを内包するオブジェクト */
function cols()
{
this.ar = ["col1", "col2", "col3", "col4"];
this.idx = 0;
this.len = this.ar.length;
this.each = eachImpl;
this.get = getImpl;
this.hasNext = hasNextImpl;
}

/**
* eachの実装
* 要素ごとに指定した関数を実行する
*/
function eachImpl(func)
{
for(var i=0;i this.idx;
}

/** WSHで外部に出力するための関数 */
function Print(str)
{
WScript.Echo(str);
}

こんなのを用意しておいて、次のようにして使う

var a = new cols();
a.each(Print); // col1,col2,col3,col4を出力する
あるいは、次のようにして使う

var a = new cols();
while(a.hasNext()){
a.get(Print);
}
と、ここで、引数に無名関数を入れてみる。

var a = new cols();
while(a.hasNext()){
a.get(function(val){WScript.Echo(val);});
}
同じようになる。が、

var a = new cols();
var b = "";
while(a.hasNext()){
b += a.get(function(val){ return val;});
}
Print(b);
と、やると、undefinedの嵐になる。???どういうことだ?

と、仕事で悩んで、家でもちょっと悩んで、今ようやく気づいた。
getImplを次のように変えないと!

/**
* getの実装
* 要素を一つ取り出して、指定した関数を実行した結果を返す
* ついでに内部の要素の番号を進める
*/
function getImpl(func)
{
var ret = this.ar[this.idx];
this.idx++;
return func(ret);
}
で、ここで、関数が明示的に何も返さない場合は、undefinedが帰っていたことに驚いた。
(nullか、長さ0の文字列が返るものと思い込んでいた)
確かに関数の戻り値は定義してないからundefinedなんだろうけど。