(2017-11-04 8:50頃 追記)
旧タイトル「プロトタイプをよく分かっていなかったようです・・」を変更しました。
当初、「自分が上手くコードを書き替えられないのはプロトタイプの仕組みを理解していないからだ」と考え旧タイトルにしていたのですが、問題は別のところにあったようなので、ベストアンサーを済ませた後ではありますが、タイトルを修正させて頂くことにしました。
何卒、ご了承ください。
以下はカードゲームのシャッフル部分を抜粋したコードで、一応は意図した通りに動いたのですが
javascript
1Array.prototype.shuffle = function() { 2 let i = this.length; 3 while (i > 0) { 4 const j = parseInt(Math.random() * i, 10); 5 i--; 6 [this[i], this[j]] = [this[j], this[i]]; 7 } 8 return this; 9}; 10 11const cards = []; 12for (let i = 1; i <= 8; i++) { 13 cards.push(i); 14 cards.push(i); 15} 16cards.shuffle(); 17 18console.log(cards); // [5, 3, 1, 8, 4, 6, 6, 7, 2, 1, 3, 4, 2, 5, 7, 8] 19
これですとESLintに
Array prototype is read only, properties should not be added. (no-extend-native)
(配列プロトタイプは読み取り専用であり、プロパティを追加しないでください。)
と怒られてしまいました。
で、初心者の私としてはここらへんの標準は分かりませんが、取りあえず
「なるほど、これは好ましい手法ではないのかもしれない」
と思いまして、
怒られない書き方に修正しようとしました。
しかし上手くいかず、ハマってしまいました。
javascript
1const MyArray = []; 2MyArray.prototype.shuffle = function() { 3
とすると
Uncaught TypeError: Cannot set property 'shuffle' of undefined
と言われ、
そりゃそうだと思いながらいろいろ試すのですが上手く動いてくれず、
結局
こんな書き方↓に落ち着いたわけですが
javascript
1const cards = []; 2 3cards.shuffle = function() { 4 let i = this.length; 5 while (i > 0) { 6 const j = parseInt(Math.random() * i, 10); 7 i--; 8 [this[i], this[j]] = [this[j], this[i]]; 9 } 10 return this; 11}; 12 13for (let i = 1; i <= 8; i++) { 14 cards.push(i); 15 cards.push(i); 16} 17cards.shuffle(); 18 19console.log(cards); 20// [4, 8, 6, 7, 1, 5, 1, 7, 6, 4, 2, 8, 3, 5, 2, 3, shuffle: ƒ] 21
確かにこれなら思惑通りに動くのですけど、
これでは、将来的にコードの再利用も考慮したつもりであった、当初の思想から思いっきり外れてしまい、不本意な書き方になってしまいました。
(まぁ、理解不足・知識不足が判明したため、再利用も何もあったものではないのですが。)
何か大きな勘違いがあるかもしれませんし。
ESLintの「no-extend-native」をoffにしても良いのですけど、何だかモヤモヤします。
そこで質問です。
今回の場合ですと、「配列名.shuffle();」と書けば配列の中身がシャッフルされる汎用コードを残しておきたいです。
勉強不足で理解が追い付かないかもしれませんが、当面の模範解答をご教授願えますでしょうか。
よろしくお願いします。
回答5件
あなたの回答
tips
プレビュー