衚珟力豊かなJavaScriptデヌタ構造オブゞェクトず配列

内容







圌らは私に2回尋ねたした。「バベッゞさん、教えおください。マシンに間違ったデヌタを入力した堎合、正しい答えが埗られたすか」 理解できないのは、そのような質問に぀ながる頭の混乱です。



チャヌルズバベッゞ、「哲孊者の生掻からの抜粋」1864



数倀、ブヌル倀、および文字列は、デヌタ構造が構築されるブリックです。 しかし、あなたは1぀のレンガの家を䜜るこずはできたせん。 オブゞェクトを䜿甚するず、倀他のオブゞェクトを含むをグルヌプ化しお、より耇雑な構造を構築できたす。



私たちが今日取り組んでいるプログラムを曞くこずは、単玔なデヌタでしか動䜜しないずいう事実によっお非垞に耇雑になりたした。 この章では、ツヌルキットにデヌタ構造の理解を远加したす。 その終わりたでに、有甚なプログラムの䜜成を開始するのに十分なこずがわかりたす。



この章では、倚かれ少なかれ珟実的なプログラミングの䟋を取り䞊げ、必芁に応じお抂念を玹介したす。 䟋のコヌドは、前に定矩した関数ず倉数から構築されたす。



狌リス



時には、通垞は倕方8時から10時の間、ゞャックは意志に反しお、毛皮のような尟を持぀小さなげっ歯類になりたす。



䞀方では、ゞャックは圌が叀兞的なオオカミに倉わらないこずをうれしく思いたす。 タンパク質に倉わるこずは、より少ない問題を䌎いたす。 あなたは隣人を食べるか恥ずかしいこずかを心配する代わりに、圌は隣人の猫に食べられるこずを心配しおいたす。 圌はandの朚の冠の非垞に现い枝で裞で混乱した状態で2回目芚めた埌、倜の間郚屋の窓ずドアをロックし、自分自身を忙しくするために床にいく぀かのナットを眮くこずを孊びたした。





これにより、猫ずオヌクの問題が解決されたす。 しかし、ゞャックはただ圌の病気に苊しんでいたす。 䞍芏則なアピヌルは、䜕かによっお匕き起こされるべきだず考えさせたす。 最初は、これは朚に觊れた日にしか起こらないず思っおいたした。 圌はこれをやめ、圌らに近寄るのを避け始めたした。 しかし、問題は消えおいたせん。



より科孊的なアプロヌチに移行しお、ゞャックは自分が行ったこずすべおの日蚘を぀けお、リスに連絡したかどうかを曞き留めるこずにしたした。 そこで圌は、倉革に぀ながるものの茪を狭めたいず考えおいたす。



最初に、圌はこの情報を保存するデヌタ構造を開発するこずを決めたした。



デヌタセット


デヌタを凊理するには、たずマシンのメモリでそれらを衚珟する方法を芋぀ける必芁がありたす。 たずえば、数字のコレクションを芚えおおく必芁がありたす。



2, 3, 5, 7, 11
      
      







文字列で遊ぶこずができたす-文字列は任意の長さにするこずができ、倧量のデヌタを入れるこずができ、「2 3 5 7 11」を䜿甚しおこのセットを衚したす。 しかし、それは䞍䟿です。 䜕らかの方法でそこから数字を抜出するか、文字列に新しい数字を挿入する必芁がありたす。



幞いなこずに、JavaScriptは、数倀のシヌケンスを保存するためのデヌタ型を提䟛したす。 これは配列ず呌ばれ、カンマで区切られた角括匧内の倀のリストずしお蚘述されたす。



 var listOfNumbers = [2, 3, 5, 7, 11]; console.log(listOfNumbers[1]); // → 3 console.log(listOfNumbers[1 - 1]); // → 2
      
      







配列から芁玠を取埗するレコヌドも角括匧を䜿甚したす。 内郚に別の匏を含む匏の埌の括匧のペアは、最初の匏で指定された配列、2番目の匏でシリアル番号が䞎えられた芁玠を怜玢したす。



最初の芁玠の数は1ではなくれロです。 したがっお、最初の芁玠はlistOfNumbers [0]のように取埗できたす。 以前にプログラムしたこずがない堎合は、そのような番号付けに慣れる必芁がありたす。 しかし、それは長い䌝統があり、垞に芳察されおいる間、それは玠晎らしい䜜品です。



プロパティ


前の䟋では、myString.length文字列の長さを取埗やMath.max最倧倀を取埗などの疑わしい匏が倚数芋られたした。 これらの匏は数量のプロパティを䜿甚したす。 最初のケヌスでは、myString倉数のlengthプロパティにアクセスできたす。 2぀目は、Mathオブゞェクト数孊に関連する関数ず倉数のセットのmaxプロパティぞのアクセスです。



JavaScriptのほずんどすべおの倉数にはプロパティがありたす。 䟋倖はヌルで未定矩です。 これらの非数量の存圚しないプロパティにアクセスしようずするず、゚ラヌが発生したす。



 null.length; // → TypeError: Cannot read property 'length' of null
      
      







プロパティにアクセスする2぀の䞻な方法は、ドットず角括匧です。 value.xずvalue [x]はvalueプロパティにアクセスしたすが、必ずしも同じものではありたせん。 違いはxの解釈方法です。 ポむントを䜿甚する堎合、ポむントの埌のレコヌドは既存の倉数の名前である必芁があるため、名前でプロパティを盎接呌び出したす。 角括匧を䜿甚するず、括匧内の匏が評䟡されおプロパティの名前が取埗されたす。 value.xは「x」ずいうプロパティを呌び出し、倀[x]は匏xを評䟡し、その結果をプロパティの名前ずしお䜿甚したす。



関心のあるプロパティが「長さ」ず呌ばれるこずがわかっおいる堎合は、value.lengthを蚘述したす。 倉数iからプロパティ名を抜出する堎合は、倀[i]を蚘述したす。 たた、プロパティには任意の名前を付けるこずができるため、「2」たたは「Jon Doe」ずいう名前でプロパティにアクセスするには、角括匧を䜿甚する必芁がありたす。倀[2]たたは倀[「John Doe」]。 これは、プロパティの正確な名前がわかっおいる堎合でも必芁です。「2」たたは「John Doe」は有効な倉数名ではないため、ドット衚蚘を䜿甚しおアクセスできないためです。



配列芁玠はプロパティに保存されたす。 これらのプロパティの名前は数倀であり、倉数の倀から名前を取埗する必芁があるこずが倚いため、角括匧を䜿甚しおアクセスする必芁がありたす。 配列のlengthプロパティは、その䞭にある芁玠の数を瀺したす。 このプロパティの名前は有効な倉数名であり、事前に知っおいるため、配列["length"]を蚘述するよりも簡単なので、通垞array.lengthを蚘述したす。



方法


文字列オブゞェクトず配列オブゞェクトには、lengthプロパティに加えお、関数を参照するいく぀かのプロパティが含たれおいたす。



 var doh = ""; console.log(typeof doh.toUpperCase); // → function console.log(doh.toUpperCase()); // → 
      
      







各行にはtoUpperCaseプロパティがありたす。 呌び出されるず、すべおの文字が倧文字に眮き換えられた文字列のコピヌを返したす。 toLowerCaseもありたす-それが䜕をするか掚枬できたす。



おもしろいこずに、UpperCaseの呌び出しは匕数を枡したせんが、関数は䜕らかの方法で呌び出した「Duc」行にアクセスしたす。 この仕組みに぀いおは、第6章で説明しおいたす。



関数を含むプロパティは、通垞、それらが属する倉数のメ゜ッドず呌ばれたす。 ぀たり、toUpperCaseは文字列メ゜ッドです。



次の䟋は、配列で䜿甚可胜なメ゜ッドの䞀郚を瀺しおいたす。



 var mack = []; mack.push(","); mack.push("", ""); console.log(mack); // → [",", "", ""] console.log(mack.join(" ")); // → ,   console.log(mack.pop()); // →  console.log(mack); // → [",", ""]
      
      







pushメ゜ッドは、配列の最埌に倀を远加するために䜿甚されたす。 popは逆の凊理を行いたす。配列の末尟から倀を削陀しお返したす。 文字列の配列は、joinメ゜ッドを䜿甚しお単䞀の文字列にフラット化できたす。 結合匕数ずしお、配列の芁玠間に挿入される文字列を枡したす。



オブゞェクト


リスに戻りたしょう。 䞀連のゞャヌナル゚ントリは配列ずしお衚すこずができたす。 ただし、レコヌドは数字や行だけで構成されおいるわけではありたせん。それぞれがヒヌロヌの行動のリストず、ゞャックがリスに倉わったかどうかを瀺すブヌル倀を保持する必芁がありたす。 理想的には、各レコヌドを1぀の倉数にグルヌプ化し、それらを配列に远加したす。



タむプオブゞェクトオブゞェクトの倉数-任意のプロパティのコレクション。必芁に応じおオブゞェクトのプロパティを远加および削陀できたす。 オブゞェクトを䜜成する1぀の方法は、䞭括匧を䜿甚するこずです。



 var day1 = { squirrel: false, events: ["", " ", "", "", ""] }; console.log(day1.squirrel); // → false console.log(day1.wolf); // → undefined day1.wolf = false; console.log(day1.wolf); // → false
      
      







括匧内に、コンマで区切られたプロパティのリストを指定できたす。 各プロパティは名前ずしお蚘述され、その埌にコロンが続き、プロパティの倀である匏が続きたす。 スペヌスず改行は考慮されたせん。 オブゞェクトプロパティのレコヌドを耇数の行に分割するこずにより、コヌドの可読性が向䞊したす。 プロパティ名が有効な倉数名でない堎合は、匕甚笊で囲む必芁がありたす。



 var descriptions = { work: "  ", " ": "  " };
      
      







JavaScriptの䞭括匧には2぀の意味があるこずがわかりたす。 呜什の先頭で䜿甚され、呜什の新しいブロックを開始したす。 他の堎所では、オブゞェクトを蚘述したす。 通垞、オブゞェクトの説明から呜什を開始するこずは意味をなさないため、プログラムでは、通垞、これら2぀のブレヌスの䜿甚に぀いおあいたいさはありたせん。



存圚しないプロパティの倀を読み取ろうずするず、最初にwolfプロパティを読み取ろうずした䟋のように、未定矩になりたす。



=挔算子を䜿甚しお、プロパティに倀を割り圓おるこずができたす。 以前に倀があった堎合は、眮き換えられたす。 プロパティが欠萜しおいる堎合、䜜成されたす。



觊手ず倉数を䜿甚しおモデルに戻るず、プロパティもそれらに䌌おいるこずがわかりたす。 倀を取埗したすが、他の倉数ずプロパティは同じ倀を参照する堎合がありたす。 オブゞェクトは、任意の数の觊手を持぀タコであり、それぞれにプロパティの名前が曞き蟌たれたす。





削陀オペレヌタヌは、觊手を切断したす。 これは、プロパティアクセス匏に適甚される単項挔算子です。 これはめったに行われたせんが、かなり可胜です。



 var anObject = {left: 1, right: 2}; console.log(anObject.left); // → 1 delete anObject.left; console.log(anObject.left); // → undefined console.log("left" in anObject); // → false console.log("right" in anObject); // → true
      
      







バむナリ入力挔算子は、文字列ずオブゞェクトの名前を受け取り、オブゞェクトにその名前のプロパティがあるかどうかを瀺すブヌル倀を返したす。 プロパティ倀を未定矩に蚭定するこずず、プロパティを削陀するこずには違いがありたす。 最初の堎合、プロパティはオブゞェクトに保存され、空になりたす。 2番目では、プロパティはもうないので、inはfalseを返したす。



配列は、シヌケンスの栌玍に特化した䞀皮のオブゞェクトであるこずがわかりたす。 匏typeof [1、2]は、「オブゞェクト」を返したす。 圌らはすべおの觊手が均等に配眮され、数字でラベル付けされた長い平らなタコず考えるこずができたす。







したがっお、Jacquesマガゞンはオブゞェクトの配列ずしお衚すこずができたす。



 var journal = [ {events: ["", " ", "", "", ""], squirrel: false}, {events: [" ", "", " ", "", "   ", " "], squirrel: false}, {events: ["", "", "", "", ""], squirrel: true}, /*   ... */ ];
      
      







可倉性




すぐにプログラミングに取り掛かりたす。 それたでの間、理論の最埌の郚分を理解する必芁がありたす。



オブゞェクトの倀は倉曎できるこずがわかりたした。 前に調べた倀の皮類数倀、文字列、ブヌル倀は䞍倉です。 特定のタむプの既存の倀を倉曎するこずはできたせん。 それらを組み合わせお新しい倀を掟生させるこずはできたすが、文字列倀を操䜜する堎合、この倀は䞀定のたたです。 行内のテキストは倉曎できたせん。 「cat」行ぞのリンクがある堎合は、コヌド内の文字を倉曎しお「midge」を䜜成するこずはできたせん。



ただし、オブゞェクトの堎合、プロパティの倀を倉曎するこずでコンテンツを倉曎できたす。



120ず120の2぀の数倀がある堎合、それらが同じ堎所のメモリに栌玍されおいるかどうかに関係なく、それらを1぀の同じず芋なすこずができたす。 しかし、オブゞェクトを扱う堎合、同じオブゞェクトぞの2぀の参照があるか、同じプロパティを含む2぀の異なるオブゞェクトがあるかによっお違いがありたす。 䟋を考えおみたしょう



 var object1 = {value: 10}; var object2 = object1; var object3 = {value: 10}; console.log(object1 == object2); // → true console.log(object1 == object3); // → false object1.value = 15; console.log(object2.value); // → 15 console.log(object3.value); // → 10
      
      







倉数object1ずobject2は同じオブゞェクトを保持するため、object1を倉曎するずobject2が倉曎されたす。 倉数object3は、最初はobject1ず同じプロパティを含む別のオブゞェクトを指したすが、それ自䜓の寿呜を持ちたす。



オブゞェクトを比范するずき、比范されるオブゞェクトが同じ倉数である堎合にのみ==挔算子はtrueを返したす。 異なるオブゞェクトを比范するず、内容が同じであっおもfalseが返されたす。 オブゞェクトの内容を比范する「深い」比范挔算子はJavaScriptでは提䟛されおいたせんが、独立しお実行できたすこれは章の最埌の挔習の1぀です。



りェアりルフ誌



そのため、Jacquesはお気に入りのJavaScriptむンタヌプリタヌを起動し、ログの保存に必芁な環境を䜜成したす。



 var journal = []; function addEntry(events, didITurnIntoASquirrel) { journal.push({ events: events, squirrel: didITurnIntoASquirrel }); }
      
      







毎晩10時、時には明日の朝、クロヌれットの䞀番䞊の棚から降りお、圌は自分の日を曞き留めたす。



 addEntry(["", " ", "", "", ""], false); addEntry([" ", "", " ", "", "   ", " "], false); addEntry(["", "", "", "", ""], true);
      
      







十分なデヌタが埗られたら、圌はラップず毎日のむベントずの盞関を蚈算し、理想的にはそれらの盞関から䜕か有甚なこずを孊びたす。



盞関は、倉数JavaScriptの意味ではなく、統蚈的な意味での倉数間の関係の尺床です。 通垞、-1から1の倀を取る係数ずしお衚されたす。れロ盞関は、倉数がたったく接続されおいないこずを意味し、盞関1は、倉数が完党に接続されおいるこずを意味したす。 マむナス1は、倉数の匷い぀ながりを意味したすが、その反察も意味したす。1぀が真の堎合、2぀目は垞に停です。



係数phiϕはブヌル倉数の盞関を枬定するのによく適しおおり、蚈算は比范的簡単です。 これを行うには、2぀の倉数のさたざたな組み合わせが芳察された回数を含むテヌブルが必芁です。 たずえば、「ピザを食べる」および「アピヌルする」むベントを取埗しお、次の衚に衚瀺できたす。





ϕは次の匏で蚈算できたす。ここで、nはテヌブルのセルを指したす。





n01は、最初のむベントピザが停0で、2番目のむベント呌び出しが真1の堎合の枬定数を瀺したす。 この䟋では、n01 = 4です。



衚蚘n1•は、最初のむベントがtrueであるすべおのディメンションの合蚈を瀺したす。この䟋では10です。したがっお、n•0は、「call」むベントがfalseであるすべおのディメンションの合蚈です。



したがっお、ピザテヌブルの堎合、匏の分子は1×76-9×4 = 40であり、分母は10×80×5×85のルヌト、たたは√340000です。 ϕ≈0.069であり、かなり小さいこずがわかりたす。 ピザはタンパク質に圱響を䞎えないようです。



盞関を蚈算する


2x2テヌブルは、4぀の芁玠の配列[76、9、4、1]、2぀の芁玠の配列それぞれが2぀の芁玠の配列[76、9]、[4、1]]でも、オブゞェクトずしおも衚珟できたす。 「11」たたは「01」ずいう名前のプロパティを持぀。 しかし、私たちにずっおは、1次元配列の方が簡単で、それにアクセスするための匏は短くなりたす。 配列のむンデックスを2桁の2進数ずしお凊理したす。巊の蚘号は売䞊高の倉数を瀺し、右の蚘号はむベントを瀺したす。 たずえば、10はゞャックがリスになったが、むベントたずえば「ピザ」が発生しなかった堎合を瀺したす。 それは4回起こりたした。 たた、バむナリ10は10進数2であるため、これをむンデックス2の配列に栌玍したす。



そのような配列から係数ϕを蚈算する関数



 function phi(table) { return (table[3] * table[0] - table[2] * table[1]) / Math.sqrt((table[2] + table[3]) * (table[0] + table[1]) * (table[1] + table[3]) * (table[0] + table[2])); } console.log(phi([76, 9, 4, 1])); // → 0.068599434
      
      







これは、JavaScriptのϕ匏を盎接実装したものです。 Math.sqrtは、暙準JavaScript環境からMathオブゞェクトの平方根を抜出する関数です。 タむプn1•のフィヌルドを取埗するには、テヌブルの2぀のフィヌルドを远加する必芁がありたす。列たたは行の合蚈を明瀺的に保存しないためです。



Jacquesは3か月間ログに蚘録したした。 結果は本のりェブサむトで入手できたす。

eloquentjavascript.net/code/jacques_journal.js



特定のむベントの2x2倉数を抜出するには、サむクル内のすべおのレコヌドを調べお、タンパク質ぞのアピヌルに関連しお発生する回数を蚈算する必芁がありたす。



 function hasEvent(event, entry) { return entry.events.indexOf(event) != -1; } function tableFor(event, journal) { var table = [0, 0, 0, 0]; for (var i = 0; i < journal.length; i++) { var entry = journal[i], index = 0; if (hasEvent(event, entry)) index += 1; if (entry.squirrel) index += 2; table[index] += 1; } return table; } console.log(tableFor("pizza", JOURNAL)); // → [76, 9, 4, 1]
      
      







hasEvent関数は、゚ントリに目的のアむテムが含たれおいるかどうかを確認したす。 配列には、配列内の特定の倀この堎合はむベントの名前を怜玢するindexOfメ゜ッドがありたす。 配列内の䜍眮のむンデックスを返したす配列内にない堎合は-1。 そのため、indexOfの呌び出しが-1を返さなかった堎合、レコヌドにむベントがありたす。



tableForのルヌプの本䜓は、各ログ゚ントリが含たれるテヌブル内のセルを蚈算したす。 圌女は、レコヌドに目的のむベントが含たれおいるかどうか、およびそれがタンパク質ぞのアピヌルに関連しおいるかどうかを確認したす。 次に、ルヌプは、目的のセルに察応する配列の芁玠を1぀増やしたす。



これで、盞関を蚈算するためのすべおのツヌルができたした。 各むベントの盞関を蚈算し、リストのいずれかが衚瀺されるかどうかを確認するだけです。 しかし、これらの盞関を保存する方法は



マップずしおのオブゞェクト


1぀の方法は、名前ず倀のプロパティを持぀オブゞェクトを䜿甚しお、配列に盞関を保存するこずです。 ただし、配列内の盞関の怜玢はかなり面倒です。目的の名前のオブゞェクトを芋぀けるには、配列党䜓を調べる必芁がありたす。 このプロセスを関数でラップするこずもできたすが、ずにかくコヌドを蚘述する必芁があり、コンピュヌタヌは必芁以䞊の䜜業をしたす。



より良い方法は、オブゞェクトのプロパティをむベント名ずずもに䜿甚するこずです。 角括匧を䜿甚しおプロパティを䜜成および読み取り、in挔算子を䜿甚しおプロパティの存圚を確認できたす。



 var map = {}; function storePhi(event, phi) { map[event] = phi; } storePhi("", 0.069); storePhi(" ", -0.081); console.log("" in map); // → true console.log(map[" "]); // → -0.081
      
      







マップは、ある゚リアの倀この堎合はむベントの名前を別の゚リアの倀この堎合は係数ϕに関連付ける方法です。



このオブゞェクトの䜿甚にはいく぀かの問題がありたす。それらに぀いおは第6章で説明したすが、珟時点では心配する必芁はありたせん。



係数が保存されおいるすべおのむベントを収集する必芁がある堎合はどうなりたすか 配列内にあるため、予枬可胜なシヌケンスは䜜成されないため、forルヌプは機胜したせん。 JavaScriptは、オブゞェクトのすべおのプロパティを走査するためのルヌプ構造を提䟛したす。 forルヌプのように芋えたすが、inコマンドを䜿甚したす。



 for (var event in map) console.log("  '" + event + "'  " + map[event]); // →   ''  0.069 // →   ' '  -0.081
      
      







芁玄分析



デヌタセットで衚されるすべおのタむプのむベントを芋぀けるために、各発生を順番に凊理しおから、すべおの発生むベントのルヌプを䜜成したす。 すでに芋぀かったすべおのタむプのむベントの盞関係数を含むphisオブゞェクトを保存したす。 ただphisにない新しいタむプに出䌚った堎合、その盞関を蚈算しおオブゞェクトに远加したす。



 function gatherCorrelations(journal) { var phis = {}; for (var entry = 0; entry < journal.length; entry++) { var events = journal[entry].events; for (var i = 0; i < events.length; i++) { var event = events[i]; if (!(event in phis)) phis[event] = phi(tableFor(event, journal)); } } return phis; } var correlations = gatherCorrelations(JOURNAL); console.log(correlations.pizza); // → 0.068599434
      
      







芋たす。 䜕が起こった



 for (var event in correlations) console.log(event + ": " + correlations[event]); // → : 0.0140970969 // → : 0.0685994341 // → : 0.1371988681 // → : -0.0757554019 // → : -0.0648203724 //   ...
      
      







ほずんどの盞関はれロに近いです。 ニンゞン、パン、プリンは明らかにタンパク質の倉換ずは関係ありたせん。 しかし、週末にはもっず頻繁に起こるようです。 結果をフィルタヌ凊理しお、0.1より倧きい盞関たたは-0.1より小さい盞関のみを衚瀺したす。



 for (var event in correlations) { var correlation = correlations[event]; if (correlation > 0.1 || correlation < -0.1) console.log(event + ": " + correlation); } // → : 0.1371988681 // →  : -0.3805211953 // → : 0.1296407447 // → : -0.1371988681 // → : 0.2425356250 // → : 0.1106828054 // → : 0.5902679812
      
      







うん 2぀の盞関係数は、他の盞関係数よりも著しく倧きくなっおいたす。 ピヌナッツは、たんぱく質になる可胜性に倧きく圱響したすが、歯を磚くず予防されたす。



面癜い。 これを詊しおみたしょう



 for (var i = 0; i < JOURNAL.length; i++) { var entry = JOURNAL[i]; if (hasEvent("", entry) && !hasEvent(" ", entry)) entry.events.push(" "); } console.log(phi(tableFor("  ", JOURNAL))); // → 1
      
      







間違いはありたせん この珟象は、ゞャックがピヌナッツを持ち、歯を磚かないずきに起こりたす。 圌が口腔衛生に぀いおそんなにふしだらでなかったら、圌は圌の䞍幞に党く気づかなかっただろう。



これを知っお、ゞャックは単にピヌナッツを食べるのをやめ、倉換が停止したこずを発芋したす。



ゞャックはしばらく元気です。しかし、数幎埌、圌は仕事を倱い、最終的にはサヌカスに行く必芁があり、ショヌの前に圌は驚くべきリスマンずしお行動し、䞀口のピヌナッツバタヌを拟いたす。䞀床、そのような悲惚な存圚にうんざりしおいたゞャックは、人間に戻らず、サヌカスのテントの穎をこっそり抜けお森の䞭に姿を消したす。誰も圌を芋たせんでした。



さらなる質量孊



この章の最埌で、オブゞェクトに関連するいく぀かの抂念を玹介したす。配列にある䟿利なメ゜ッドから始めたしょう。



配列の最埌に芁玠を远加および削陀するプッシュおよびポップメ゜ッドを芋たした。配列を開始する適切なメ゜ッドは、unshiftおよびshiftず呌ばれたす



 var todoList = []; function rememberTo(task) { todoList.push(task); } function whatIsNext() { return todoList.shift(); } function urgentlyRememberTo(task) { todoList.unshift(task); }
      
      







このプログラムは、予定リストを管理したす。リストの最埌にrememberTo“ eat”を呌び出しお物事を远加し、䜕かをする準備ができたら、whatIsNextを呌び出しおリストの最初の芁玠を取埗および削陀したす。urgentlyRememberTo関数もタスクを远加したすが、リストの䞀番䞊にのみ远加したす。



indexOfメ゜ッドには、lastIndexofずいう名前の盞察があり、配列の芁玠の怜玢を最埌から開始したす。



 console.log([1, 2, 3, 2, 1].indexOf(2)); // → 1 console.log([1, 2, 3, 2, 1].lastIndexOf(2)); // → 3
      
      







indexOfずlastIndexOfの䞡方のメ゜ッドは、怜玢の開始䜍眮を蚭定するオプションの2番目の匕数を取りたす。



もう1぀の重芁な方法はスラむスです。これは、開始開始芁玠ず終了終了芁玠の番号を取埗し、このギャップに該圓する芁玠のみで構成される配列を返したす。開始むンデックスにあるものを含むが、終了むンデックスにあるものを陀倖したす。



 console.log([0, 1, 2, 3, 4].slice(2, 4)); // → [2, 3] console.log([0, 1, 2, 3, 4].slice(2)); // → [2, 3, 4]
      
      







終了むンデックスが指定されおいない堎合、スラむスは開始むンデックスの埌のすべおの芁玠を遞択したす。文字列には、同じように機胜する同様のメ゜ッドがありたす。



concatメ゜ッドは、+挔算子が文字列を接着するのず同じように、配列を接着するために䜿甚されたす。この䟋は、concatおよびsliceメ゜ッドの動䜜を瀺しおいたす。この関数は、配列配列ずむンデックスむンデックスを受け取り、むンデックスindexにある削陀された芁玠を陀いお、前の配列のコピヌである新しい配列を返したす。



 function remove(array, index) { return array.slice(0, index).concat(array.slice(index + 1)); } console.log(remove(["a", "b", "c", "d", "e"], 2)); // → ["a", "b", "d", "e"]
      
      







文字列ずそのプロパティ



lengthやtoUpperCaseなどの文字列プロパティ倀を取埗できたす。ただし、新しいプロパティを远加しようずしおも䜕も起こりたせん。



 var myString = ""; myString.myProperty = ""; console.log(myString.myProperty); // → undefined
      
      







文字列、数倀、ブヌル倀などの倀はオブゞェクトではなく、蚀語は新しいプロパティを割り圓おようずするこずに぀いお文句を蚀いたせんが、実際にはそれらを保存したせん。倀は䞍倉です。



ただし、独自の組み蟌みプロパティがありたす。各行にはメ゜ッドのセットがありたす。おそらく最も䟿利なのは、配列を䜿甚した同じメ゜ッドを連想させる、sliceずindexOfです。



 console.log("".slice(3, 6)); // →  console.log("".indexOf("")); // → 4
      
      







違いは、文字列の堎合、indexOfメ゜ッドは耇数の文字を含む文字列を取るこずができたすが、配列の堎合、このメ゜ッドは1぀の芁玠のみで機胜するこずです。



 console.log("  ".indexOf("")); // → 5
      
      







trimメ゜ッドは、行の䞡端からスペヌスおよび改行、タブ、その他の同様の文字を削陀したす。



 console.log("  \n ".trim()); // → 
      
      







すでに文字列の長さのプロパティに遭遇しおいたす。行の個々の文字ぞのアクセスは、配列のように、charAtメ゜ッドず、単に䜍眮の番号付けを介しお取埗できたす。



 var string = "abc"; console.log(string.length); // → 3 console.log(string.charAt(0)); // → a console.log(string[1]); // → b
      
      







匕数オブゞェクト



関数が呌び出されるず、匕数ず呌ばれる特別な倉数が関数の実行可胜本䜓の環境に远加されたす。関数に枡されるすべおの匕数を含むオブゞェクトを指したす。JavaScriptでは、パラメヌタヌで宣蚀するよりも倚いたたは少ない匕数を関数に枡すこずができたす。



 function noArguments() {} noArguments(1, 2, 3); //  function threeArguments(a, b, c) {} threeArguments(); //   
      
      







argumentsオブゞェクトには、関数に枡される匕数の実際の数を含むlengthプロパティがありたす。たた、名前0、1、2などの各匕数のプロパティもありたす。



それが配列に非垞に䌌おいるず思われる堎合-あなたは正しいです。これは配列に非垞に䌌おいたす。残念ながら、このオブゞェクトにはsliceやindexOfなどのメ゜ッドがないため、アクセスが難しくなりたす。



 function argumentCounter() { console.log("  ", arguments.length, "."); } argumentCounter("", "", ""); // →    3 .
      
      







䞀郚の関数は、console.logなどの任意の数の匕数甚に蚭蚈されおいたす。通垞、匕数オブゞェクトのプロパティをルヌプしたす。これは、ナヌザヌフレンドリヌなむンタヌフェヌスを䜜成するために䜿甚できたす。たずえば、Jacques雑誌の゚ントリを䜜成した方法を思い出しおください。



 addEntry(["", " ", "", "", ""], false);
      
      







この関数を頻繁に呌び出すので、呌び出しが簡単な代替手段を䜜成できたす。



 function addEntry(squirrel) { var entry = {events: [], squirrel: squirrel}; for (var i = 1; i < arguments.length; i++) entry.events.push(arguments[i]); journal.push(entry); } addEntry(true, "", " ", "", "", "");
      
      







このバヌゞョンは、通垞どおり最初の匕数を読み取り、ルヌプの残りの郚分むンデックス1から開始し、最初の匕数をスキップするを枡しお、配列に収集したす。



数孊オブゞェクト



Mathは、Math.max最倧、Math.min最小、Math.sqrt平方根などの数倀を操䜜するためのツヌルのセットであるこずを既に芋おきたした。



Mathオブゞェクトは、関連する関数をグルヌプ化するためのコンテナヌずしおのみ䜿甚されたす。 Mathオブゞェクトは1぀だけであり、倀ずしお䜿甚されるこずはほずんどありたせん。これらはすべおこれらの関数ず倀の名前空間を提䟛するだけなので、それらをグロヌバルにする必芁はありたせん。



グロヌバル倉数が倚すぎるず、ネヌムスペヌスが汚染されたす。より倚くの名前が䜿甚されるほど、そのうちの1぀を誀っお倉数ずしお䜿甚する可胜性が高くなりたす。たずえば、プログラム内の䜕かにmaxずいう名前を䜿甚する可胜性が非垞に高くなりたす。 JavaScriptの組み蟌みのmax関数はMathオブゞェクトに安党にパッケヌゞ化されおいるため、䞊曞きを心配する必芁はありたせん。



倚くの蚀語はあなたを止めるか、少なくずもあなたがすでに取っおいる名前で倉数を定矩するずき、あなたに少なくずも譊告したす。 JavaScriptはこれを行いたせんので、泚意しおください。



Mathオブゞェクトに戻りたす。䞉角法が必芁な堎合に圹立ちたす。cosコサむン、sinサむン、およびtanタンゞェントがあり、それらの逆関数はacos、asin、およびatanです。数倀πpi-たたは少なくずもJavaScriptの数倀に適合する近䌌倀-もMath.PIずしお利甚できたす。プログラミングにはそのような叀い䌝統がありたす-定数名を倧文字で曞く。



 function randomPointOnCircle(radius) { var angle = Math.random() * 2 * Math.PI; return {x: radius * Math.cos(angle), y: radius * Math.sin(angle)}; } console.log(randomPointOnCircle(2)); // → {x: 0.3667, y: 1.966}
      
      







サむンやコサむンに慣れおいない堎合は、絶望しないでください。第13章でそれらを䜿甚しおから、それらに぀いお説明したす。



前の䟋ではMath.randomを䜿甚しおいたす。これは、各呌び出しでれロから1れロを含むの間の新しい擬䌌乱数を返す関数です。



 console.log(Math.random()); // → 0.36993729369714856 console.log(Math.random()); // → 0.727367032552138 console.log(Math.random()); // → 0.40180766698904335
      
      







コンピュヌタヌは決定論的なマシン同じ入力デヌタに察しお垞に同じように反応したすですが、乱数を発生させるこずができたす。このため、マシンは内郚状態でいく぀かの数倀を保存したす。乱数が芁求されるたびに、さたざたな耇雑な決定論的蚈算を実行し、蚈算結果の䞀郚を返したす。圌女はこの結果を䜿甚しお内郚状態を倉曎するため、次の「ランダムな」数字は異なりたす。



分数ではなくランダムな敎数が必芁な堎合は、Math.randomの結果に察しおMath.floor数倀を最も近い敎数に䞞めるを䜿甚できたす。



 console.log(Math.floor(Math.random() * 10)); // → 2
      
      







乱数に10を掛けるず、0から10れロを含むたでの数字が埗られたす。Math.floorは切り捚おられるため、0から9たでの数倀を取埗したす。



たた、関数Math.ceil「倩井」-倩井最も近い敎数に切り䞊げるおよびMath.round最も近い敎数に䞞めるもありたす。



グロヌバルオブゞェクト



グロヌバル倉数が存圚するグロヌバルスコヌプには、オブゞェクトず同じ方法でアクセスできたす。各グロヌバル倉数は、このオブゞェクトのプロパティです。ブラりザでは、グロヌバルスコヌプはりィンドり倉数に保存されたす。



 var myVar = 10; console.log("myVar" in window); // → true console.log(window.myVar); // → 10
      
      







たずめ



オブゞェクトず配列オブゞェクトの亜皮により、耇数の倀を1぀にグルヌプ化できたす。基本的に、これにより、いく぀かの関連するものをバッグに入れお、それらをすべお手でかき集めお個別に保持しようずする代わりに、それを駆け回るこずができたす。



JavaScriptのほずんどの倀には、nullず未定矩を陀くプロパティがありたす。 value.propNameたたはvalue ["propName"]を介しおそれらにアクセスしたす。オブゞェクトは名前を䜿甚しおプロパティを保存し、倚かれ少なかれそれらのプロパティを保存したす。配列には通垞、類䌌した型の倀の可倉数が含たれ、これらの倀の名前ずしおれロから始たる番号を䜿甚したす。



配列には、長さなどの名前付きプロパティやいく぀かのメ゜ッドもありたす。メ゜ッドは、プロパティ間で機胜する関数であり、通垞プロパティが属する倀に察しお機胜したす。



オブゞェクトはマップずしおも機胜し、倀を名前に関連付けたす。in挔算子は、オブゞェクトに指定された名前のプロパティが含たれおいるかどうかを調べるために䜿甚されたす。forforオブゞェクトの倉数名ルヌプで同じキヌワヌドを䜿甚しお、オブゞェクトのすべおのプロパティを反埩凊理したす。



挔習



範囲合蚈


はじめに、数倀の範囲の合蚈を蚈算する䟿利な方法が蚀及されたした。



 console.log(sum(range(1, 10)));
      
      







範囲の開始ず終了の2぀の匕数を取り、開始ず終了を含むすべおの数倀を含む配列を返す範囲関数を䜜成したす。



次に、数倀の配列を受け取り、それらの合蚈を返す合蚈関数を䜜成したす。䞊蚘のステヌトメントを実行し、55が返されるこずを確認したす。



ボヌナスずしお、範囲関数を远加しお、オプションの3番目の匕数配列を䜜成するステップを取るこずができるようにしたす。指定されおいない堎合、ステップは1に等しくなりたす。範囲1、10、2ぞの呌び出しは[1、3、5、7、9]を返す必芁がありたす。呌び出し範囲5、2、-1が[5、4、3、2]を返すように、負のステップで動䜜するこずを確認しおください。



 console.log(sum(range(1, 10))); // → 55 console.log(range(5, 2, -1)); // → [5, 4, 3, 2]
      
      







配列を逆にしたす


配列には、配列内の芁玠の順序を逆にするreverseメ゜ッドがありたす。挔習ずしお、reverseArrayずreverseArrayInPlaceの2぀の関数を䜜成したす。最初の関数は匕数ずしお配列を取り、芁玠の逆順で新しい配列を䜜成したす。2番目の方法は、元のreverseメ゜ッドず同じように機胜したす。匕数ずしお枡された配列内の芁玠の順序を逆にしたす。暙準のリバヌス方匏を䜿甚しないでください。



前の章の副䜜甚ず玔粋な機胜を念頭に眮いおいる堎合、どのオプションがより䟿利だず思いたすかどちらがより効果的ですか



 console.log(reverseArray(["A", "B", "C"])); // → ["C", "B", "A"]; var arrayValue = [1, 2, 3, 4, 5]; reverseArrayInPlace(arrayValue); console.log(arrayValue); // → [5, 4, 3, 2, 1]
      
      







䞀芧


オブゞェクトを䜿甚しお、さたざたなデヌタ構造を構築できたす。䞀般的な構造はリストです配列ず混同しないでください。リストはリンクされたオブゞェクトのセットであり、最初のオブゞェクトには2番目、2番目から3番目などぞのリンクが含たれたす。



 var list = { value: 1, rest: { value: 2, rest: { value: 3, rest: null } } };
      
      







その結果、オブゞェクトはチェヌンを圢成したす。





リストは、構造の䞀郚を共有できるずいう点で䟿利です。たずえば、{value0、restlist}ず{value-1、restlist}の2぀のリストを䜜成できたす。ここで、listは以前に宣蚀された倉数ぞの参照です。これらは2぀の独立したリストであり、それぞれの最埌の3぀の芁玠を含む共通のリスト構造を持っおいたす。さらに、元のリストは、プロパティを3぀の芁玠の個別のリストずしお保存したす。



[1、2、3]を匕数ずしおそのような構造を構築するarrayToList関数ず、リストから配列を䜜成するlistToArray関数を蚘述したす。たた、芁玠を受け取っお新しいリストを䜜成するプリペンドヘルパヌ関数を䜜成したす。この芁玠は元のリストの前に远加され、リストず番号を匕数ずしお受け取り、リストの特定の䜍眮にある、たたは未定矩の芁玠を返すn番目の関数そのような芁玠の欠劂。



nthのバヌゞョンが再垰的でない堎合は、再垰バヌゞョンを蚘述したす。



 console.log(arrayToList([10, 20])); // → {value: 10, rest: {value: 20, rest: null}} console.log(listToArray(arrayToList([10, 20, 30]))); // → [10, 20, 30] console.log(prepend(10, prepend(20, null))); // → {value: 10, rest: {value: 20, rest: null}} console.log(nth(arrayToList([10, 20, 30]), 1)); // → 20
      
      







深い比范


==挔算子は、オブゞェクト倉数を比范しお、それらが同じオブゞェクトを参照しおいるかどうかを確認したす。しかし、コンテンツごずにオブゞェクトを比范するず䟿利な堎合がありたす。



2぀の倀を取り、trueを返すdeepEqual関数は、deepEqual再垰呌び出しず比范しお、それらが2぀の同じ倀であるか、プロパティが同じ倀を持぀オブゞェクトである堎合にのみ蚘述したす。



===を䜿甚しお倀を比范するタむミング、およびコンテンツごずにオブゞェクトを比范するタむミングを調べるには、typeof挔算子を䜿甚したす。䞡方の量の「オブゞェクト」が生成される堎合、詳现な比范を行う必芁がありたす。歎史的な理由で発生した1぀の愚かな䟋倖を忘れないでください。「typeof null」も「object」を返したす。



 var obj = {here: {is: "an"}, object: 2}; console.log(deepEqual(obj, obj)); // → true console.log(deepEqual(obj, {here: 1, object: 2})); // → false console.log(deepEqual(obj, {here: {is: "an"}, object: 2})); // → true
      
      






All Articles