forループせずに親のオブジェクトをゲトする

さすがに幼いこどもにナポリからブエノスアイレスまで旅をさせて,親をたずねさせるのはこんな世の中だし危険だしそのテの団体から「虐待だ」とかの声があがりかねないのでスッキリしたコードで親を探すことにします.

以前ちょこっとかいてた(function(o){return ...})(obj)てコードをつかって無名関数の再帰処理の具体的な例です.

あるPageItem(CS4まで?),またはTextFrame, Paragraph... なんでもいいんですけどforループをつかわずにparentプロパティのPage, Documentをゲトしてみるという話.

(動作はCS4 6.0.5で確認しています.CS5でのご使用は追記をお読みになってお試しください.)

//objはPage,Documentなんかを親にもってるオブジェクトです
var page = (function(o){
	return (o.parent instanceof Page)? o.parent : arguments.callee(o.parent)
})(obj);

var doc = (function(o){
	return (o.parent instanceof Document)? o.parent : arguments.callee(o.parent)
})(obj);

いまじぶんが把握してるなかでは,Applicationに対してparentプロパティを見にいってもApplicationが返ってくるようです.つまり探してるものが無ければ無限ループです.なので親がいない可能性を持つオブジェクトを再帰させる場合にはなにかしらの処置は準備しておくといいとおもいます.

上のコードをもすこし一般化させてみるとこんなかんじでしょうか.

var getParentObject = function(obj,fn){
	return (function(o){
		return (fn(o.parent))? o.parent : arguments.callee(o.parent)
	})(obj);
}

引数fnで検索する条件とか無かったらどうするかを仕込めばけっこう使えるのではとおもいます.

追記:
せうぞーさんのコメントでご指摘いただいているのですが,CS5だとPageItemの挙動がかわるそうで,上記のかきかたではPageItemをいれた場合にPageまでいくことができないようです.

>CS5以降でもいけるんじゃ…

CS5で試してみて、いろいろヤなことに気がつきました。

さっきなにげに「PageItemなのがわかっているならそのparentはPageですよね」なんて言っていましたが、
CS5ではPageItem.parentはSpreadです。Pageを通貨しましせん。だからPageにたどり着きたい時、この書き方はたいてい失敗します。
#だからparentPageなんてできたんですね。

Adobe Forumsでも丁寧に解説されていました。
http://forums.adobe.com/message/2728489#2728489

(CS5環境がいま手元にないので確認でき次第CS5でも検証してみます)