/** * @fileoverview オブジェクトにクラスインスタンスのmethodおよびconstructorを * セットする。プロパティを再帰的にチェックしてmethodを探す。 * Firefox4.0, Google Chrome11, Internet Explorer8でテスト済。 * @author mimami24im@gmail.com */ /** * @namespace */ var miqtutl = {}; /** * chkobjのmethodおよびconstructorをtargetobjに設定する。(コピーではない) * targetobjにmethodと同名のプロパティが存在した場合は、 * 上書きせずエラーメッセージ出力。 * @param {Object} chkobj チェック対象object * @param {Object} targetobj method設定先object * @return {Array.} エラーメッセージ配列 */ miqtutl.setmethod = function(chkobj, targetobj) { // argumentチェック if (typeof chkobj != 'object') { return ['chkobj is not object.']; } if (typeof targetobj != 'object') { return ['targetobj is not object.']; } // objectにmethodが存在するか再帰的にチェック var rtnmsg = miqtutl.smethod_(chkobj, targetobj, 'targetobj', 0); return rtnmsg; }; /** * objectにmethodが存在するか再帰的にチェックする。 * @param {Object} chkobj チェック対象object * @param {Object} targetobj method付与対象object * @param {string} targetobjname targetobj名 * @param {numer} depth 再帰の深さ * @return {Array.} エラーメッセージ配列 * @private */ miqtutl.smethod_ = function(chkobj, targetobj, targetobjname, depth) { var maxDepth = 10; // 再起する深さの最大値 var rtnmsg = []; // returnするエラーメッセージ if (depth >= maxDepth) { // 再帰の深さが最大値になった場合、処理を打ち切る throw 'depth over ' + maxDepth; } if (typeof chkobj != 'object' || chkobj === null) { return rtnmsg; } var tobjname; if (chkobj instanceof Array) { for (var i = 0; i < chkobj.length; i++) { if (typeof chkobj[i] == 'object') { tobjname = targetobjname + '[' + i + ']'; if (typeof targetobj[i] == 'object') { rtnmsg = rtnmsg.concat(miqtutl.smethod_(chkobj[i], targetobj[i], tobjname, depth + 1)); } else { rtnmsg.push(tobjname + ' is not object, or not exist.'); } } } } else { for (var prop in chkobj) { tobjname = targetobjname + '.' + prop; if (typeof chkobj[prop] == 'function') { if (targetobj[prop] != undefined) { rtnmsg.push(tobjname + ' already exists, so cannot set method.'); } else { targetobj[prop] = chkobj[prop]; } } else if (typeof chkobj[prop] == 'object') { if (typeof targetobj[prop] == 'object') { rtnmsg = rtnmsg.concat(miqtutl.smethod_(chkobj[prop], targetobj[prop], tobjname, depth + 1)); } else { rtnmsg.push(tobjname + ' is not object, or not exist.'); } } } // constructorを設定 if (typeof chkobj.constructor == 'function' && chkobj.constructor != Object) { targetobj.constructor = chkobj.constructor; // deepEqualにpassするため、chkobj.constructorを // ユーザー定義プロパティにする chkobj.constructor = chkobj.constructor; } } return rtnmsg; };