Titanium Mobile でRPG開発進捗48日目
先日id:dataichxさんにご指摘頂いたcloneについて
ようやく手をつけることが出来ました。
まず、教えて頂いたurlを参考に、よさそうな感じのソースをコピー。
参考
http://blogs.msdn.com/b/ie/archive/2010/10/27/ecmascript-5-part-1-reusable-code.aspx
問題発生。以下の2点。
- ECMAScript5に対応した環境じゃないと使えないメソッドがあった
- Object.prototypeにcloneを追加すると怒られる
仕方が無いので、原始的にコピーを行うclone関数を作成することに。
階層や配列の扱いにも対応してみた。
以下がソースです。
※ 2011/11/04 @rlldiさんのアドバイスを元に変更しています。
var clone = function (o) { if (typeof o != 'object') return o; // if (o.hasOwnProperty('length')) { // if(Object.prototype.toString.call(o) === "[object Array]") { /* if (o instanceof Array) { var n = []; } else { var n = {}; } */ var n = (o instanceof Array)?[]:{}; for (var p in o) { n[p] = clone(o[p]); } return n; };
typeofでobject以外の場合は値として戻す。
lengthメソッドがあるか確認して、あれば配列として宣言
なければオブジェクトとして宣言することにした。
こうしないと配列もオブジェクトになってしまって
lengthが取得できなくなるのだ。
これがはたして正しいのかはわからんけれども
正常に動いているので今のところよしとしています。
問題点や、その問題点に関する解決方法があったらご指摘ください。
まぁ、自分が利用する範囲では問題ないので
利用範囲を限定すれば問題ないとは思います。
追記 2011/11/4
insetanceof演算子しらなかったのでありがたかったです。
そこでこんなソースになりました。
// if (o.hasOwnProperty('length')) { if (o instanceof Array) {
動きました!ばんじゃーい!
でも、instanceof演算子をぐぐったところ次の記事に行き当たりました。
Array かどうかを判定するいくつかの方法について - latest log
http://d.hatena.ne.jp/uupaa/20090116/1232051707
記事は結構古いものなのですが、jQueryのinArrayがどういう実装なのか
というところが速度を含めた形で書いてあります。
遅くなるけど、せっかくなので動作検証してみました。
// if (o.hasOwnProperty('length')) { // if (o instanceof Array) { if (Object.prototype.toString.call(o) === "[object Array]") {
動きました!ばんじゃーい!
でも、まぁ文字列操作なんで遅いんでしょうね。
で、判定は結局 if (o instanceof Array) { で行けそうです。
ただ、typeofみたいに型名は取れませんので、型名取ろうかっていう話。
JavaScript メモ by kanegon
http://www2.wbs.ne.jp/~kanegon/doc/jsmemo.txt
2003年の記事でした。
でも気になって実行してみました。
var typename = function (o) { if (typeof(o) == "object") { if ((""+o.constructor).match(/^\s*function +(\w+)/)) return RegExp.$1; } return typeof(o); };
オブジェクト名取れた!ばんじゃーい!
ということで、cloneの中身を少しだけ変えました。