- ベストアンサー
JavaScriptのthisの挙動について
- JavaScriptでthisの挙動について調査しました。コードを実行した際に問題が発生し、thisが保持できていないことが原因でした。
- コード中でthisをobj.listに入れているにも関わらず、obj.listと同期してthisが消える現象が起きました。
- コード中で先頭に#を付けた部分を変更すると期待通りの動作になりましたが、もっと簡潔な書き方や迅速な解決方法があれば教えていただきたいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> obj.list.splice(tmp.index, 1); ここで 配列 this を破壊しています。 この時点で、obj.list == this (指してる先は同じ配列)なのですから、 obj.list.splice と this.splice は同じことです。 thisを破壊させない為には、参照だけコピーする シャローコピーではなく、 各要素をコピーするディープコピーをすれば良いでしょう。 > Code中で先頭に#を付けた部分を次のように変更すると期待通りに動作しましたが、腑に落ちません。 > #var obj = { > #num: this.join('') > #}; > #obj.list = obj.num.split(''); 2桁の要素が出てきたとたん破綻しそうな気がしますが…。 sliceメソッドは新しい配列を返してくれるので、これをつかえばいいでしょう。 var obj = { list: this.slice() }; あと、ソートアルゴリズムに(シャッフル後の確率分布が均等になるという意味で)問題はないですが、 spliceは配列が長くなると結構重いので、要素の入れ替えだけでシャッフルできる Fisher-Yates法がお勧めです。
その他の回答 (2)
- fujillin
- ベストアンサー率61% (1594/2576)
すでにきちんと回答が出ていますので、いわずもがなですが・・・ 元の配列を保存しておきたいのか直接シャッフルしたいのかが不明でしたので、両方可能な例。 flagをtureにすると元の配列は保存されます。(元はシャッフルされず新しい配列が返される) var randomize = function(flag){ var i, j, tmp, n = this.length; var a = flag?this.slice():this; for(i=0; i<n; i++){ j = Math.random()*n | 0; tmp = a[i], a[i] = a[j], a[j] = tmp; } return a; } Array.prototype.rs = randomize; var list = new Array(1,2,3,4,5,6,7,8,9); alert("result=" + list.rs(true).join(", ") + "\nlist =" + list.join(", ")); //保存 alert("result=" + list.rs().join(", ") + "\nlist =" + list.join(", ")); //シャッフル (インデントは全角空白になっています)
お礼
回答ありがとうございます。 これは…、Wernerさんの仰るFisher-Yates法というやつですね。 代入を,で区切れること、三項演算子の条件式の()がいらないことは初見です。 精進します。
- babu_baboo
- ベストアンサー率51% (268/525)
this のかいとうではありませんが・・・ var rs = function (a,b) {return Math.random () - .5}; alert ([0,1,2,3,4,5,6,7,8,9].sort (rs). sort (rs)); 1かいだとかたよるらしいので、2かいする?!(笑)
お礼
解答ありがとうございます。 sliceってそんなことができたんですね。 勉強になります。 spliceが重くなるということも知りませんでした。 Fisher-Yates法…。初耳です。調べておきます。 何も知らないな、僕は。 ありがとうございました。