[{"data":1,"prerenderedAt":9279},["ShallowReactive",2],{"article:\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime":3,"related-articles:\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime":534,"search:articles":5028,"search:books":8621},{"id":4,"title":5,"body":6,"description":523,"extension":524,"meta":525,"navigation":103,"path":526,"publishDate":527,"published":103,"seo":528,"stem":529,"tags":530,"thumbnail":532,"updated":527,"__hash__":533},"articles\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime.md","JavaScriptのランタイム構成からイベントループを学ぶ",{"type":7,"value":8,"toc":513},"minimark",[9,13,24,27,32,35,38,41,60,62,65,68,155,158,193,196,199,202,205,219,222,266,269,271,274,277,291,296,299,301,304,329,332,335,337,340,343,360,363,366,443,446,454,465,474,477,497,500,509],[10,11,12],"p",{},"こんにちは、Yuriです。",[10,14,15,16,23],{},"今回は、JavaScriptのイベントループについて、動画「",[17,18,22],"a",{"href":19,"rel":20},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=eiC58R16hb8",[21],"nofollow","JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue","」で学んだ内容を整理します。",[10,25,26],{},"ブラウザでJavaScriptがどのように同期処理と非同期処理を扱っているのか、ランタイムを構成する要素から確認していきます。",[28,29,31],"h2",{"id":30},"javascriptエンジンとホスト環境","JavaScriptエンジンとホスト環境",[10,33,34],{},"ブラウザでJavaScriptを実行するためには、JavaScriptエンジンとブラウザというホスト環境が連携します。",[10,36,37],{},"JavaScriptエンジンはコードを解析・実行し、ブラウザはタイマー、ネットワーク通信、DOMイベントなどの環境固有の機能を提供します。",[10,39,40],{},"イベントループを理解するうえでは、次の要素を押さえておくと全体像が見えやすくなります。",[42,43,44,48,51,54,57],"ul",{},[45,46,47],"li",{},"コールスタック",[45,49,50],{},"Web APIs",[45,52,53],{},"タスクキュー",[45,55,56],{},"マイクロタスクキュー",[45,58,59],{},"イベントループ",[28,61,47],{"id":47},[10,63,64],{},"コールスタックは、実行中の関数や実行コンテキストを管理するスタックです。",[10,66,67],{},"後から追加されたものが先に取り出される、後入れ先出し（LIFO）の構造になっています。",[69,70,75],"pre",{"className":71,"code":72,"language":73,"meta":74,"style":74},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","function a() {\n  console.log('a')\n}\n\nfunction b() {\n  a()\n}\n\nfunction c() {\n  b()\n}\n\nc()\n","javascript","",[76,77,78,86,92,98,105,111,117,122,127,133,139,144,149],"code",{"__ignoreMap":74},[79,80,83],"span",{"class":81,"line":82},"line",1,[79,84,85],{},"function a() {\n",[79,87,89],{"class":81,"line":88},2,[79,90,91],{},"  console.log('a')\n",[79,93,95],{"class":81,"line":94},3,[79,96,97],{},"}\n",[79,99,101],{"class":81,"line":100},4,[79,102,104],{"emptyLinePlaceholder":103},true,"\n",[79,106,108],{"class":81,"line":107},5,[79,109,110],{},"function b() {\n",[79,112,114],{"class":81,"line":113},6,[79,115,116],{},"  a()\n",[79,118,120],{"class":81,"line":119},7,[79,121,97],{},[79,123,125],{"class":81,"line":124},8,[79,126,104],{"emptyLinePlaceholder":103},[79,128,130],{"class":81,"line":129},9,[79,131,132],{},"function c() {\n",[79,134,136],{"class":81,"line":135},10,[79,137,138],{},"  b()\n",[79,140,142],{"class":81,"line":141},11,[79,143,97],{},[79,145,147],{"class":81,"line":146},12,[79,148,104],{"emptyLinePlaceholder":103},[79,150,152],{"class":81,"line":151},13,[79,153,154],{},"c()\n",[10,156,157],{},"このコードは、次の流れで実行されます。",[159,160,161,167,176,183],"ol",{},[45,162,163,166],{},[76,164,165],{},"c()"," がスタックへ追加される",[45,168,169,171,172,175],{},[76,170,165],{}," から呼ばれた ",[76,173,174],{},"b()"," が追加される",[45,177,178,171,180,175],{},[76,179,174],{},[76,181,182],{},"a()",[45,184,185,187,188,187,190,192],{},[76,186,182],{},"、",[76,189,174],{},[76,191,165],{}," の順に処理を終えてスタックから取り除かれる",[10,194,195],{},"1つの長い同期処理がコールスタックを占有すると、その処理が終わるまでクリックや描画など、同じスレッド上のほかの処理を進められません。",[28,197,50],{"id":198},"web-apis",[10,200,201],{},"Web APIsは、ブラウザというホスト環境が提供する機能です。",[10,203,204],{},"代表的なものには、次があります。",[42,206,207,210,213,216],{},[45,208,209],{},"Fetch API",[45,211,212],{},"タイマー",[45,214,215],{},"Geolocation API",[45,217,218],{},"DOMイベント",[10,220,221],{},"JavaScriptからこれらの非同期APIを呼び出すと、ブラウザ側でタイマーの計測やネットワーク通信などが進みます。JavaScriptはその完了を待ってコールスタックを占有し続ける必要がないため、別のコードを実行できます。",[69,223,225],{"className":71,"code":224,"language":73,"meta":74,"style":74},"navigator.geolocation.getCurrentPosition(\n  position => console.log(position),\n  error => console.error(error),\n)\n\nfetch('https:\u002F\u002Fexample.com\u002Fapi\u002Fdata')\n  .then(response => response.json())\n  .then(data => console.log(data))\n",[76,226,227,232,237,242,247,251,256,261],{"__ignoreMap":74},[79,228,229],{"class":81,"line":82},[79,230,231],{},"navigator.geolocation.getCurrentPosition(\n",[79,233,234],{"class":81,"line":88},[79,235,236],{},"  position => console.log(position),\n",[79,238,239],{"class":81,"line":94},[79,240,241],{},"  error => console.error(error),\n",[79,243,244],{"class":81,"line":100},[79,245,246],{},")\n",[79,248,249],{"class":81,"line":107},[79,250,104],{"emptyLinePlaceholder":103},[79,252,253],{"class":81,"line":113},[79,254,255],{},"fetch('https:\u002F\u002Fexample.com\u002Fapi\u002Fdata')\n",[79,257,258],{"class":81,"line":119},[79,259,260],{},"  .then(response => response.json())\n",[79,262,263],{"class":81,"line":124},[79,264,265],{},"  .then(data => console.log(data))\n",[10,267,268],{},"APIの処理が完了しても、コールバックがその場ですぐに実行されるとは限りません。実行可能になった処理は、タスクやマイクロタスクとしてキューへ登録されます。",[28,270,53],{"id":53},[10,272,273],{},"タスクキューには、タイマーやイベントなどをきっかけに実行可能になったタスクが並びます。",[10,275,276],{},"代表的な例は次のとおりです。",[42,278,279,285,288],{},[45,280,281,284],{},[76,282,283],{},"setTimeout()"," のコールバック",[45,286,287],{},"ユーザー操作のイベントハンドラー",[45,289,290],{},"メッセージイベント",[10,292,293,295],{},[76,294,283],{}," に指定する時間は、コールバックが必ずその時間後に実行されるという意味ではありません。指定時間を経過したあとにタスクとして実行可能になるまでの最低待機時間です。",[10,297,298],{},"コールスタックや先に処理されるタスクが残っていれば、実際の実行はさらに遅くなります。",[28,300,56],{"id":56},[10,302,303],{},"マイクロタスクキューには、主に次の処理が登録されます。",[42,305,306,318,324],{},[45,307,308,309,187,312,187,315],{},"Promiseの ",[76,310,311],{},"then()",[76,313,314],{},"catch()",[76,316,317],{},"finally()",[45,319,320,323],{},[76,321,322],{},"queueMicrotask()"," に渡したコールバック",[45,325,326,284],{},[76,327,328],{},"MutationObserver",[10,330,331],{},"現在のタスクと同期処理が終わってコールスタックが空になると、次のタスクへ進む前にマイクロタスクキューが空になるまで処理されます。",[10,333,334],{},"マイクロタスクの実行中に新しいマイクロタスクが追加された場合も、同じタイミングで続けて処理されます。そのため、マイクロタスクを追加し続ける処理は、次のタスクや画面描画を遅らせる可能性があります。",[28,336,59],{"id":59},[10,338,339],{},"イベントループは、コールスタックと各キューの状態を見ながら、実行する処理を選び続けます。",[10,341,342],{},"ブラウザ上の流れを単純化すると、次のようになります。",[159,344,345,348,351,354,357],{},[45,346,347],{},"1つのタスクを実行する",[45,349,350],{},"コールスタック上の同期処理を最後まで実行する",[45,352,353],{},"マイクロタスクキューを空になるまで処理する",[45,355,356],{},"必要に応じて画面を描画する",[45,358,359],{},"次のタスクへ進む",[28,361,362],{"id":362},"コードで実行順を確認する",[10,364,365],{},"タスクとマイクロタスクの実行順を、コードで確認してみましょう。",[69,367,369],{"className":71,"code":368,"language":73,"meta":74,"style":74},"console.log('start')\n\nsetTimeout(() => {\n  console.log('timeout')\n}, 0)\n\nPromise.resolve().then(() => {\n  console.log('promise')\n})\n\nqueueMicrotask(() => {\n  console.log('microtask')\n})\n\nconsole.log('end')\n",[76,370,371,376,380,385,390,395,399,404,409,414,418,423,428,432,437],{"__ignoreMap":74},[79,372,373],{"class":81,"line":82},[79,374,375],{},"console.log('start')\n",[79,377,378],{"class":81,"line":88},[79,379,104],{"emptyLinePlaceholder":103},[79,381,382],{"class":81,"line":94},[79,383,384],{},"setTimeout(() => {\n",[79,386,387],{"class":81,"line":100},[79,388,389],{},"  console.log('timeout')\n",[79,391,392],{"class":81,"line":107},[79,393,394],{},"}, 0)\n",[79,396,397],{"class":81,"line":113},[79,398,104],{"emptyLinePlaceholder":103},[79,400,401],{"class":81,"line":119},[79,402,403],{},"Promise.resolve().then(() => {\n",[79,405,406],{"class":81,"line":124},[79,407,408],{},"  console.log('promise')\n",[79,410,411],{"class":81,"line":129},[79,412,413],{},"})\n",[79,415,416],{"class":81,"line":135},[79,417,104],{"emptyLinePlaceholder":103},[79,419,420],{"class":81,"line":141},[79,421,422],{},"queueMicrotask(() => {\n",[79,424,425],{"class":81,"line":146},[79,426,427],{},"  console.log('microtask')\n",[79,429,430],{"class":81,"line":151},[79,431,413],{},[79,433,435],{"class":81,"line":434},14,[79,436,104],{"emptyLinePlaceholder":103},[79,438,440],{"class":81,"line":439},15,[79,441,442],{},"console.log('end')\n",[10,444,445],{},"出力順は次のようになります。",[69,447,452],{"className":448,"code":450,"language":451,"meta":74},[449],"language-text","start\nend\npromise\nmicrotask\ntimeout\n","text",[76,453,450],{"__ignoreMap":74},[10,455,456,457,460,461,464],{},"まず同期処理の ",[76,458,459],{},"start"," と ",[76,462,463],{},"end"," が出力されます。",[10,466,467,468,470,471,473],{},"続いて、登録された順にPromiseのコールバックと ",[76,469,322],{}," のコールバックがマイクロタスクとして実行されます。マイクロタスクキューが空になったあと、",[76,472,283],{}," のコールバックが次のタスクとして実行されます。",[28,475,476],{"id":476},"まとめ",[42,478,479,482,485,488,491,494],{},[45,480,481],{},"コールスタックは、実行中の関数をLIFOで管理する",[45,483,484],{},"ブラウザは、タイマーやネットワーク通信などのWeb APIsを提供する",[45,486,487],{},"タイマーやイベントのコールバックなどは、タスクとしてキューへ登録される",[45,489,490],{},"Promiseのコールバックなどは、マイクロタスクとして登録される",[45,492,493],{},"現在のタスクが完了すると、次のタスクより先にマイクロタスクが処理される",[45,495,496],{},"長い同期処理や増え続けるマイクロタスクは、画面の応答を遅らせる可能性がある",[10,498,499],{},"非同期処理の実行順で迷ったときは、「現在の同期処理」「マイクロタスク」「次のタスク」の順に分けて考えると整理しやすくなります。",[10,501,502,503,508],{},"より詳しい実行モデルは、",[17,504,507],{"href":505,"rel":506},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FExecution_model",[21],"MDNのJavaScript実行モデル","も参考になります。",[510,511,512],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":74,"searchDepth":88,"depth":88,"links":514},[515,516,517,518,519,520,521,522],{"id":30,"depth":88,"text":31},{"id":47,"depth":88,"text":47},{"id":198,"depth":88,"text":50},{"id":53,"depth":88,"text":53},{"id":56,"depth":88,"text":56},{"id":59,"depth":88,"text":59},{"id":362,"depth":88,"text":362},{"id":476,"depth":88,"text":476},"ブラウザのJavaScriptランタイムを構成するコールスタック、Web APIs、タスクキュー、マイクロタスクキューとイベントループの関係を整理します。","md",{},"\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime","2024-11-25",{"title":5,"description":523},"articles\u002F2024\u002Flearn-javascript-eventloop-from-runtime",[531],"JavaScript","\u002Fimages\u002Farticles\u002Flearn-javascript-eventloop-from-runtime.png","BcnDDE_gLqK4tjYoVA9O89QF7-dNwS-6lyORZ07cH5g",[535,1243,2920,3410,3781,4209,4601],{"id":536,"title":537,"body":538,"description":1234,"extension":524,"meta":1235,"navigation":103,"path":1236,"publishDate":1237,"published":103,"seo":1238,"stem":1239,"tags":1240,"thumbnail":1241,"updated":1237,"__hash__":1242},"articles\u002Farticles\u002F2024\u002Flately-learned-js-tip.md","最近学んだJavaScriptのTipsをアウトプット",{"type":7,"value":539,"toc":1217},[540,542,545,548,551,598,602,605,673,691,706,722,737,740,743,779,789,797,811,837,853,856,871,874,881,938,941,948,981,991,995,1004,1023,1026,1034,1072,1075,1099,1106,1112,1123,1151,1172,1175,1181,1184,1201,1203,1206,1215],[10,541,12],{},[10,543,544],{},"今回は、最近学んだJavaScriptの小さなTipsとして、オブジェクトの分割代入とオプショナルチェーンを整理します。",[28,546,547],{"id":547},"オブジェクトの分割代入",[10,549,550],{},"オブジェクトの分割代入を使うと、プロパティの値を取り出して変数へ代入できます。",[69,552,554],{"className":71,"code":553,"language":73,"meta":74,"style":74},"const user = {\n  greeting: 'Hello',\n  farewell: 'Bye',\n}\n\nconst { greeting, farewell } = user\n\nconsole.log(greeting) \u002F\u002F 'Hello'\nconsole.log(farewell) \u002F\u002F 'Bye'\n",[76,555,556,561,566,571,575,579,584,588,593],{"__ignoreMap":74},[79,557,558],{"class":81,"line":82},[79,559,560],{},"const user = {\n",[79,562,563],{"class":81,"line":88},[79,564,565],{},"  greeting: 'Hello',\n",[79,567,568],{"class":81,"line":94},[79,569,570],{},"  farewell: 'Bye',\n",[79,572,573],{"class":81,"line":100},[79,574,97],{},[79,576,577],{"class":81,"line":107},[79,578,104],{"emptyLinePlaceholder":103},[79,580,581],{"class":81,"line":113},[79,582,583],{},"const { greeting, farewell } = user\n",[79,585,586],{"class":81,"line":119},[79,587,104],{"emptyLinePlaceholder":103},[79,589,590],{"class":81,"line":124},[79,591,592],{},"console.log(greeting) \u002F\u002F 'Hello'\n",[79,594,595],{"class":81,"line":129},[79,596,597],{},"console.log(farewell) \u002F\u002F 'Bye'\n",[599,600,601],"h3",{"id":601},"ネストしたプロパティを取り出す",[10,603,604],{},"オブジェクトの中にオブジェクトがある場合は、データの構造に合わせて分割代入のパターンもネストできます。",[69,606,608],{"className":71,"code":607,"language":73,"meta":74,"style":74},"const user = {\n  greeting: 'Hello',\n  message: {\n    farewell: 'Bye',\n  },\n}\n\nconst {\n  greeting,\n  message: { farewell },\n} = user\n\nconsole.log(greeting) \u002F\u002F 'Hello'\nconsole.log(farewell) \u002F\u002F 'Bye'\n",[76,609,610,614,618,623,628,633,637,641,646,651,656,661,665,669],{"__ignoreMap":74},[79,611,612],{"class":81,"line":82},[79,613,560],{},[79,615,616],{"class":81,"line":88},[79,617,565],{},[79,619,620],{"class":81,"line":94},[79,621,622],{},"  message: {\n",[79,624,625],{"class":81,"line":100},[79,626,627],{},"    farewell: 'Bye',\n",[79,629,630],{"class":81,"line":107},[79,631,632],{},"  },\n",[79,634,635],{"class":81,"line":113},[79,636,97],{},[79,638,639],{"class":81,"line":119},[79,640,104],{"emptyLinePlaceholder":103},[79,642,643],{"class":81,"line":124},[79,644,645],{},"const {\n",[79,647,648],{"class":81,"line":129},[79,649,650],{},"  greeting,\n",[79,652,653],{"class":81,"line":135},[79,654,655],{},"  message: { farewell },\n",[79,657,658],{"class":81,"line":141},[79,659,660],{},"} = user\n",[79,662,663],{"class":81,"line":146},[79,664,104],{"emptyLinePlaceholder":103},[79,666,667],{"class":81,"line":151},[79,668,592],{},[79,670,671],{"class":81,"line":434},[79,672,597],{},[10,674,675,676,679,680,683,684,687,688,690],{},"この例で作られる変数は",[76,677,678],{},"greeting","と",[76,681,682],{},"farewell","です。",[76,685,686],{},"message","は、内側の",[76,689,682],{},"へたどるためのパターンとして使われているだけなので、変数として宣言されません。",[69,692,694],{"className":71,"code":693,"language":73,"meta":74,"style":74},"console.log(message)\n\u002F\u002F ReferenceError: message is not defined\n",[76,695,696,701],{"__ignoreMap":74},[79,697,698],{"class":81,"line":82},[79,699,700],{},"console.log(message)\n",[79,702,703],{"class":81,"line":88},[79,704,705],{},"\u002F\u002F ReferenceError: message is not defined\n",[707,708,711],"article-callout",{"title":709,"type":710},"親オブジェクトも使いたい場合","note",[10,712,713,715,716,718,719,721],{},[76,714,686],{},"自体と、その中の",[76,717,682],{},"を両方使いたい場合は、分割代入を分けるか、先に",[76,720,686],{},"を取り出してから再度分割代入します。",[69,723,725],{"className":71,"code":724,"language":73,"meta":74,"style":74},"const { message } = user\nconst { farewell } = message\n",[76,726,727,732],{"__ignoreMap":74},[79,728,729],{"class":81,"line":82},[79,730,731],{},"const { message } = user\n",[79,733,734],{"class":81,"line":88},[79,735,736],{},"const { farewell } = message\n",[599,738,739],{"id":739},"プロパティ名とは異なる変数名で受け取る",[10,741,742],{},"コロンの右側へ名前を書くと、プロパティ名とは異なる変数名で値を受け取れます。",[69,744,746],{"className":71,"code":745,"language":73,"meta":74,"style":74},"const user = {\n  name: 'Yuri',\n}\n\nconst { name: userName } = user\n\nconsole.log(userName) \u002F\u002F 'Yuri'\n",[76,747,748,752,757,761,765,770,774],{"__ignoreMap":74},[79,749,750],{"class":81,"line":82},[79,751,560],{},[79,753,754],{"class":81,"line":88},[79,755,756],{},"  name: 'Yuri',\n",[79,758,759],{"class":81,"line":94},[79,760,97],{},[79,762,763],{"class":81,"line":100},[79,764,104],{"emptyLinePlaceholder":103},[79,766,767],{"class":81,"line":107},[79,768,769],{},"const { name: userName } = user\n",[79,771,772],{"class":81,"line":113},[79,773,104],{"emptyLinePlaceholder":103},[79,775,776],{"class":81,"line":119},[79,777,778],{},"console.log(userName) \u002F\u002F 'Yuri'\n",[10,780,781,782,785,786,683],{},"この場合も",[76,783,784],{},"name","という変数は作られず、作られるのは",[76,787,788],{},"userName",[28,790,792,793,796],{"id":791},"オプショナルチェーン","オプショナルチェーン（",[76,794,795],{},"?.","）",[10,798,799,800,803,804,807,808,810],{},"オプショナルチェーンは、参照の途中にある値が",[76,801,802],{},"null","または",[76,805,806],{},"undefined","だった場合、エラーを発生させずに",[76,809,806],{},"を返す演算子です。",[69,812,814],{"className":71,"code":813,"language":73,"meta":74,"style":74},"const user = {\n  name: 'Yuri',\n}\n\nconsole.log(user.profile?.hobby) \u002F\u002F undefined\n",[76,815,816,820,824,828,832],{"__ignoreMap":74},[79,817,818],{"class":81,"line":82},[79,819,560],{},[79,821,822],{"class":81,"line":88},[79,823,756],{},[79,825,826],{"class":81,"line":94},[79,827,97],{},[79,829,830],{"class":81,"line":100},[79,831,104],{"emptyLinePlaceholder":103},[79,833,834],{"class":81,"line":107},[79,835,836],{},"console.log(user.profile?.hobby) \u002F\u002F undefined\n",[10,838,839,842,843,845,846,848,849,852],{},[76,840,841],{},"user.profile","は",[76,844,806],{},"ですが、",[76,847,795],{},"を使っているため、その先の",[76,850,851],{},"hobby","へアクセスせず評価を終了します。",[10,854,855],{},"通常のプロパティアクセスではエラーになります。",[69,857,859],{"className":71,"code":858,"language":73,"meta":74,"style":74},"console.log(user.profile.hobby)\n\u002F\u002F TypeError: Cannot read properties of undefined\n",[76,860,861,866],{"__ignoreMap":74},[79,862,863],{"class":81,"line":82},[79,864,865],{},"console.log(user.profile.hobby)\n",[79,867,868],{"class":81,"line":88},[79,869,870],{},"\u002F\u002F TypeError: Cannot read properties of undefined\n",[599,872,873],{"id":873},"配列の要素へアクセスする",[10,875,876,877,880],{},"角括弧によるアクセスでは、",[76,878,879],{},"?.[]","の形で使用します。",[69,882,884],{"className":71,"code":883,"language":73,"meta":74,"style":74},"const items = [\n  { name: 'Item 1' },\n  { name: 'Item 2' },\n]\n\nconsole.log(items[1]?.name) \u002F\u002F 'Item 2'\nconsole.log(items[3]?.name) \u002F\u002F undefined\n\nconst emptyItems = undefined\n\nconsole.log(emptyItems?.[0]) \u002F\u002F undefined\n",[76,885,886,891,896,901,906,910,915,920,924,929,933],{"__ignoreMap":74},[79,887,888],{"class":81,"line":82},[79,889,890],{},"const items = [\n",[79,892,893],{"class":81,"line":88},[79,894,895],{},"  { name: 'Item 1' },\n",[79,897,898],{"class":81,"line":94},[79,899,900],{},"  { name: 'Item 2' },\n",[79,902,903],{"class":81,"line":100},[79,904,905],{},"]\n",[79,907,908],{"class":81,"line":107},[79,909,104],{"emptyLinePlaceholder":103},[79,911,912],{"class":81,"line":113},[79,913,914],{},"console.log(items[1]?.name) \u002F\u002F 'Item 2'\n",[79,916,917],{"class":81,"line":119},[79,918,919],{},"console.log(items[3]?.name) \u002F\u002F undefined\n",[79,921,922],{"class":81,"line":124},[79,923,104],{"emptyLinePlaceholder":103},[79,925,926],{"class":81,"line":129},[79,927,928],{},"const emptyItems = undefined\n",[79,930,931],{"class":81,"line":135},[79,932,104],{"emptyLinePlaceholder":103},[79,934,935],{"class":81,"line":141},[79,936,937],{},"console.log(emptyItems?.[0]) \u002F\u002F undefined\n",[599,939,940],{"id":940},"関数やメソッドを呼び出す",[10,942,943,944,947],{},"関数が存在するときだけ呼び出したい場合は、",[76,945,946],{},"?.()","を使用します。",[69,949,951],{"className":71,"code":950,"language":73,"meta":74,"style":74},"const actions = {\n  greet: () => 'Hello',\n}\n\nconsole.log(actions.greet?.()) \u002F\u002F 'Hello'\nconsole.log(actions.sayGoodbye?.()) \u002F\u002F undefined\n",[76,952,953,958,963,967,971,976],{"__ignoreMap":74},[79,954,955],{"class":81,"line":82},[79,956,957],{},"const actions = {\n",[79,959,960],{"class":81,"line":88},[79,961,962],{},"  greet: () => 'Hello',\n",[79,964,965],{"class":81,"line":94},[79,966,97],{},[79,968,969],{"class":81,"line":100},[79,970,104],{"emptyLinePlaceholder":103},[79,972,973],{"class":81,"line":107},[79,974,975],{},"console.log(actions.greet?.()) \u002F\u002F 'Hello'\n",[79,977,978],{"class":81,"line":113},[79,979,980],{},"console.log(actions.sayGoodbye?.()) \u002F\u002F undefined\n",[10,982,983,984,987,988,990],{},"プロパティが存在していても、その値が関数でなければ",[76,985,986],{},"TypeError","になります。",[76,989,946],{},"は「呼び出し可能かどうか」まで確認するものではありません。",[599,992,994],{"id":993},"dom要素へアクセスする","DOM要素へアクセスする",[10,996,997,1000,1001,1003],{},[76,998,999],{},"querySelector","は対象が見つからなかった場合に",[76,1002,802],{},"を返します。要素が存在するときだけプロパティを参照したい場合にも利用できます。",[69,1005,1007],{"className":71,"code":1006,"language":73,"meta":74,"style":74},"const button = document.querySelector('.sample-button')\n\nconsole.log(button?.textContent) \u002F\u002F 要素がなければundefined\n",[76,1008,1009,1014,1018],{"__ignoreMap":74},[79,1010,1011],{"class":81,"line":82},[79,1012,1013],{},"const button = document.querySelector('.sample-button')\n",[79,1015,1016],{"class":81,"line":88},[79,1017,104],{"emptyLinePlaceholder":103},[79,1019,1020],{"class":81,"line":94},[79,1021,1022],{},"console.log(button?.textContent) \u002F\u002F 要素がなければundefined\n",[599,1024,1025],{"id":1025},"短絡評価される範囲",[10,1027,1028,1029,803,1031,1033],{},"オプショナルチェーンでは、左側が",[76,1030,802],{},[76,1032,806],{},"の場合、そのチェーンの残りは評価されません。",[69,1035,1037],{"className":71,"code":1036,"language":73,"meta":74,"style":74},"let index = 0\nconst items = null\n\nconst item = items?.[index++]\n\nconsole.log(item) \u002F\u002F undefined\nconsole.log(index) \u002F\u002F 0\n",[76,1038,1039,1044,1049,1053,1058,1062,1067],{"__ignoreMap":74},[79,1040,1041],{"class":81,"line":82},[79,1042,1043],{},"let index = 0\n",[79,1045,1046],{"class":81,"line":88},[79,1047,1048],{},"const items = null\n",[79,1050,1051],{"class":81,"line":94},[79,1052,104],{"emptyLinePlaceholder":103},[79,1054,1055],{"class":81,"line":100},[79,1056,1057],{},"const item = items?.[index++]\n",[79,1059,1060],{"class":81,"line":107},[79,1061,104],{"emptyLinePlaceholder":103},[79,1063,1064],{"class":81,"line":113},[79,1065,1066],{},"console.log(item) \u002F\u002F undefined\n",[79,1068,1069],{"class":81,"line":119},[79,1070,1071],{},"console.log(index) \u002F\u002F 0\n",[10,1073,1074],{},"ただし、オプショナルチェーンが途切れた後のアクセスは保護されません。",[69,1076,1078],{"className":71,"code":1077,"language":73,"meta":74,"style":74},"const user = null\n\nuser?.profile.name \u002F\u002F undefined\n(user?.profile).name \u002F\u002F TypeError\n",[76,1079,1080,1085,1089,1094],{"__ignoreMap":74},[79,1081,1082],{"class":81,"line":82},[79,1083,1084],{},"const user = null\n",[79,1086,1087],{"class":81,"line":88},[79,1088,104],{"emptyLinePlaceholder":103},[79,1090,1091],{"class":81,"line":94},[79,1092,1093],{},"user?.profile.name \u002F\u002F undefined\n",[79,1095,1096],{"class":81,"line":100},[79,1097,1098],{},"(user?.profile).name \u002F\u002F TypeError\n",[10,1100,1101,1102,1105],{},"括弧で区切ると、その後の",[76,1103,1104],{},".name","は別のプロパティアクセスとして評価されます。",[28,1107,1109,1108],{"id":1108},"と組み合わせて既定値を設定する",[76,1110,1111],{},"??",[10,1113,1114,1115,803,1117,1119,1120,1122],{},"オプショナルチェーンで取得した結果が",[76,1116,802],{},[76,1118,806],{},"だった場合、ヌル値合体演算子（",[76,1121,1111],{},"）で既定値を設定できます。",[69,1124,1126],{"className":71,"code":1125,"language":73,"meta":74,"style":74},"const user = {}\n\nconst hobby = user.profile?.hobby ?? '未設定'\n\nconsole.log(hobby) \u002F\u002F '未設定'\n",[76,1127,1128,1133,1137,1142,1146],{"__ignoreMap":74},[79,1129,1130],{"class":81,"line":82},[79,1131,1132],{},"const user = {}\n",[79,1134,1135],{"class":81,"line":88},[79,1136,104],{"emptyLinePlaceholder":103},[79,1138,1139],{"class":81,"line":94},[79,1140,1141],{},"const hobby = user.profile?.hobby ?? '未設定'\n",[79,1143,1144],{"class":81,"line":100},[79,1145,104],{"emptyLinePlaceholder":103},[79,1147,1148],{"class":81,"line":107},[79,1149,1150],{},"console.log(hobby) \u002F\u002F '未設定'\n",[10,1152,1153,842,1156,1159,1160,1163,1164,1166,1167,803,1169,1171],{},[76,1154,1155],{},"||",[76,1157,1158],{},"0","、空文字列、",[76,1161,1162],{},"false","も右側の値へ置き換えますが、",[76,1165,1111],{},"が右側を返すのは",[76,1168,802],{},[76,1170,806],{},"の場合だけです。",[28,1173,1174],{"id":1174},"オプショナルチェーンを使うときの注意点",[10,1176,1177,1178,1180],{},"オプショナルチェーンは条件分岐を簡潔にできますが、必須であるはずの値にまで使用すると、不具合を",[76,1179,806],{},"として見逃す可能性があります。",[10,1182,1183],{},"次のように使い分けることが大切です。",[42,1185,1186,1192,1195],{},[45,1187,1188,1189,1191],{},"値が存在しないことを仕様として許容する場合は",[76,1190,795],{},"を使う",[45,1193,1194],{},"値が必須の場合は明示的に確認し、存在しなければエラーとして扱う",[45,1196,1197,1198,1200],{},"取得結果に既定値が必要な場合は",[76,1199,1111],{},"を組み合わせる",[28,1202,476],{"id":476},[10,1204,1205],{},"ネストした分割代入を使うと、深い階層の値を簡潔に変数へ取り出せます。ただし、途中のプロパティ名がそのまま変数になるわけではありません。",[10,1207,1208,1209,1211,1212,1214],{},"オプショナルチェーンを使うと、",[76,1210,802],{},"や",[76,1213,806],{},"の可能性があるプロパティ、配列、関数へ安全にアクセスできます。便利さだけで多用せず、その値が本当に省略可能なのかを考えて使っていきたいです。",[510,1216,512],{},{"title":74,"searchDepth":88,"depth":88,"links":1218},[1219,1223,1230,1232,1233],{"id":547,"depth":88,"text":547,"children":1220},[1221,1222],{"id":601,"depth":94,"text":601},{"id":739,"depth":94,"text":739},{"id":791,"depth":88,"text":1224,"children":1225},"オプショナルチェーン（?.）",[1226,1227,1228,1229],{"id":873,"depth":94,"text":873},{"id":940,"depth":94,"text":940},{"id":993,"depth":94,"text":994},{"id":1025,"depth":94,"text":1025},{"id":1108,"depth":88,"text":1231},"??と組み合わせて既定値を設定する",{"id":1174,"depth":88,"text":1174},{"id":476,"depth":88,"text":476},"JavaScriptのネストしたオブジェクトの分割代入とオプショナルチェーンについて、コード例と注意点を交えて整理します。",{},"\u002Farticles\u002F2024\u002Flately-learned-js-tip","2024-12-28",{"title":537,"description":1234},"articles\u002F2024\u002Flately-learned-js-tip",[531],"\u002Fimages\u002Farticles\u002Flately-learned-js-tip.png","Xi5F4LrgdP-cQxce9jEEPhpLiC086mIJfek4NR0cS3g",{"id":1244,"title":1245,"body":1246,"description":2911,"extension":524,"meta":2912,"navigation":103,"path":2913,"publishDate":2914,"published":103,"seo":2915,"stem":2916,"tags":2917,"thumbnail":2918,"updated":2914,"__hash__":2919},"articles\u002Farticles\u002F2024\u002Forganize-learned-from-todo.md","Todoアプリのハンズオンで学んだことを整理する",{"type":7,"value":1247,"toc":2882},[1248,1250,1259,1272,1275,1282,1291,1328,1331,1338,1340,1343,1346,1388,1391,1395,1398,1408,1411,1414,1420,1429,1637,1648,1651,1654,1756,1759,1762,1855,1858,1861,1891,1894,1897,1908,2057,2060,2063,2066,2069,2072,2080,2092,2160,2166,2171,2177,2220,2225,2228,2231,2297,2304,2307,2314,2427,2436,2443,2448,2508,2511,2514,2517,2611,2614,2620,2639,2649,2652,2655,2734,2741,2744,2747,2868,2871,2873,2876,2879],[10,1249,12],{},[10,1251,1252,1253,1258],{},"今回は「",[17,1254,1257],{"href":1255,"rel":1256},"https:\u002F\u002Fzenn.dev\u002Fsprout2000\u002Fbooks\u002F76a279bb90c3f3",[21],"React Hooks と TypeScript でつくる Todo PWA ～入門 React ハンズオン～","」を進める中で学んだことを、次の4つに分けて整理します。",[42,1260,1261,1264,1266,1269],{},[45,1262,1263],{},"HTML",[45,1265,531],{},[45,1267,1268],{},"React",[45,1270,1271],{},"TypeScript",[28,1273,1263],{"id":1274},"html",[599,1276,1278,1281],{"id":1277},"autofocus属性",[76,1279,1280],{},"autofocus","属性",[10,1283,1284,1286,1287,1290],{},[76,1285,1280],{},"は、ページの読み込み時や",[76,1288,1289],{},"dialog","要素の表示時に、指定した要素へ自動的にフォーカスするための属性です。",[69,1292,1295],{"className":1293,"code":1294,"language":1274,"meta":74,"style":74},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cinput type=\"text\" autofocus>\n",[76,1296,1297],{"__ignoreMap":74},[79,1298,1299,1303,1307,1311,1314,1317,1320,1322,1325],{"class":81,"line":82},[79,1300,1302],{"class":1301},"sMK4o","\u003C",[79,1304,1306],{"class":1305},"swJcz","input",[79,1308,1310],{"class":1309},"spNyl"," type",[79,1312,1313],{"class":1301},"=",[79,1315,1316],{"class":1301},"\"",[79,1318,451],{"class":1319},"sfazB",[79,1321,1316],{"class":1301},[79,1323,1324],{"class":1309}," autofocus",[79,1326,1327],{"class":1301},">\n",[10,1329,1330],{},"1つの文書やダイアログ内では、複数の要素へ指定しないようにします。複数指定した場合、最初に見つかった要素がフォーカスされます。",[707,1332,1335],{"title":1333,"type":1334},"アクセシビリティへの配慮","caution",[10,1336,1337],{},"ページを開いた直後にフォーカスが移動すると、スクリーンリーダー利用者やモバイル利用者を混乱させる場合があります。本当に自動フォーカスが必要かを検討して使用しましょう。",[28,1339,531],{"id":73},[599,1341,1342],{"id":1342},"オブジェクトのプロパティ名を動的にする",[10,1344,1345],{},"オブジェクトリテラルのプロパティ名を角括弧で囲むと、式の評価結果をプロパティ名として使用できます。これは計算プロパティ名と呼ばれます。",[69,1347,1349],{"className":71,"code":1348,"language":73,"meta":74,"style":74},"const key = 'sampleKey'\n\nconst sample = {\n  [key]: 'sampleValue',\n}\n\nconsole.log(sample) \u002F\u002F { sampleKey: 'sampleValue' }\nconsole.log(sample[key]) \u002F\u002F 'sampleValue'\n",[76,1350,1351,1356,1360,1365,1370,1374,1378,1383],{"__ignoreMap":74},[79,1352,1353],{"class":81,"line":82},[79,1354,1355],{},"const key = 'sampleKey'\n",[79,1357,1358],{"class":81,"line":88},[79,1359,104],{"emptyLinePlaceholder":103},[79,1361,1362],{"class":81,"line":94},[79,1363,1364],{},"const sample = {\n",[79,1366,1367],{"class":81,"line":100},[79,1368,1369],{},"  [key]: 'sampleValue',\n",[79,1371,1372],{"class":81,"line":107},[79,1373,97],{},[79,1375,1376],{"class":81,"line":113},[79,1377,104],{"emptyLinePlaceholder":103},[79,1379,1380],{"class":81,"line":119},[79,1381,1382],{},"console.log(sample) \u002F\u002F { sampleKey: 'sampleValue' }\n",[79,1384,1385],{"class":81,"line":124},[79,1386,1387],{},"console.log(sample[key]) \u002F\u002F 'sampleValue'\n",[10,1389,1390],{},"入力項目の名前をキーとしてオブジェクトを更新する場合などに利用できます。",[599,1392,1394],{"id":1393},"tree-shaking","Tree Shaking",[10,1396,1397],{},"Tree Shakingは、利用されていないコードをビルド結果から取り除く最適化です。",[10,1399,1400,1401,679,1404,1407],{},"主にバンドラーがES Modulesの",[76,1402,1403],{},"import",[76,1405,1406],{},"export","を静的に解析し、参照されていないエクスポートを出力対象から除外します。",[10,1409,1410],{},"実際に削除できる範囲は、バンドラーの設定やコードに副作用があるかどうかによって変わります。",[28,1412,1268],{"id":1413},"react",[599,1415,1417],{"id":1416},"createroot",[76,1418,1419],{},"createRoot",[10,1421,1422,1424,1425,1428],{},[76,1423,1419],{},"は、Reactが管理するルートをブラウザのDOM要素へ作成するAPIです。作成したルートの",[76,1426,1427],{},"render","メソッドへReact要素を渡して表示します。",[69,1430,1434],{"className":1431,"code":1432,"language":1433,"meta":74,"style":74},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { StrictMode } from 'react'\nimport { createRoot } from 'react-dom\u002Fclient'\nimport App from '.\u002FApp'\n\nconst container = document.getElementById('root')\n\nif (!container) {\n  throw new Error('root要素が見つかりません')\n}\n\ncreateRoot(container).render(\n  \u003CStrictMode>\n    \u003CApp \u002F>\n  \u003C\u002FStrictMode>,\n)\n","tsx",[76,1435,1436,1462,1482,1499,1503,1536,1540,1557,1579,1583,1587,1601,1612,1623,1633],{"__ignoreMap":74},[79,1437,1438,1441,1444,1448,1451,1454,1457,1459],{"class":81,"line":82},[79,1439,1403],{"class":1440},"s7zQu",[79,1442,1443],{"class":1301}," {",[79,1445,1447],{"class":1446},"sTEyZ"," StrictMode",[79,1449,1450],{"class":1301}," }",[79,1452,1453],{"class":1440}," from",[79,1455,1456],{"class":1301}," '",[79,1458,1413],{"class":1319},[79,1460,1461],{"class":1301},"'\n",[79,1463,1464,1466,1468,1471,1473,1475,1477,1480],{"class":81,"line":88},[79,1465,1403],{"class":1440},[79,1467,1443],{"class":1301},[79,1469,1470],{"class":1446}," createRoot",[79,1472,1450],{"class":1301},[79,1474,1453],{"class":1440},[79,1476,1456],{"class":1301},[79,1478,1479],{"class":1319},"react-dom\u002Fclient",[79,1481,1461],{"class":1301},[79,1483,1484,1486,1489,1492,1494,1497],{"class":81,"line":94},[79,1485,1403],{"class":1440},[79,1487,1488],{"class":1446}," App ",[79,1490,1491],{"class":1440},"from",[79,1493,1456],{"class":1301},[79,1495,1496],{"class":1319},".\u002FApp",[79,1498,1461],{"class":1301},[79,1500,1501],{"class":81,"line":100},[79,1502,104],{"emptyLinePlaceholder":103},[79,1504,1505,1508,1511,1513,1516,1519,1523,1526,1529,1532,1534],{"class":81,"line":107},[79,1506,1507],{"class":1309},"const",[79,1509,1510],{"class":1446}," container ",[79,1512,1313],{"class":1301},[79,1514,1515],{"class":1446}," document",[79,1517,1518],{"class":1301},".",[79,1520,1522],{"class":1521},"s2Zo4","getElementById",[79,1524,1525],{"class":1446},"(",[79,1527,1528],{"class":1301},"'",[79,1530,1531],{"class":1319},"root",[79,1533,1528],{"class":1301},[79,1535,246],{"class":1446},[79,1537,1538],{"class":81,"line":113},[79,1539,104],{"emptyLinePlaceholder":103},[79,1541,1542,1545,1548,1551,1554],{"class":81,"line":119},[79,1543,1544],{"class":1440},"if",[79,1546,1547],{"class":1446}," (",[79,1549,1550],{"class":1301},"!",[79,1552,1553],{"class":1446},"container) ",[79,1555,1556],{"class":1301},"{\n",[79,1558,1559,1562,1565,1568,1570,1572,1575,1577],{"class":81,"line":124},[79,1560,1561],{"class":1440},"  throw",[79,1563,1564],{"class":1301}," new",[79,1566,1567],{"class":1521}," Error",[79,1569,1525],{"class":1305},[79,1571,1528],{"class":1301},[79,1573,1574],{"class":1319},"root要素が見つかりません",[79,1576,1528],{"class":1301},[79,1578,246],{"class":1305},[79,1580,1581],{"class":81,"line":129},[79,1582,97],{"class":1301},[79,1584,1585],{"class":81,"line":135},[79,1586,104],{"emptyLinePlaceholder":103},[79,1588,1589,1591,1594,1596,1598],{"class":81,"line":141},[79,1590,1419],{"class":1521},[79,1592,1593],{"class":1446},"(container)",[79,1595,1518],{"class":1301},[79,1597,1427],{"class":1521},[79,1599,1600],{"class":1446},"(\n",[79,1602,1603,1606,1610],{"class":81,"line":146},[79,1604,1605],{"class":1301},"  \u003C",[79,1607,1609],{"class":1608},"sBMFI","StrictMode",[79,1611,1327],{"class":1301},[79,1613,1614,1617,1620],{"class":81,"line":151},[79,1615,1616],{"class":1301},"    \u003C",[79,1618,1619],{"class":1608},"App",[79,1621,1622],{"class":1301}," \u002F>\n",[79,1624,1625,1628,1630],{"class":81,"line":434},[79,1626,1627],{"class":1301},"  \u003C\u002F",[79,1629,1609],{"class":1608},[79,1631,1632],{"class":1301},">,\n",[79,1634,1635],{"class":81,"line":439},[79,1636,246],{"class":1446},[10,1638,1639,1641,1642,1644,1645,947],{},[76,1640,1419],{},"へ渡したDOM要素の内側はReactが管理します。サーバー側でReactが生成したHTMLを再利用する場合は、",[76,1643,1419],{},"ではなく",[76,1646,1647],{},"hydrateRoot",[599,1649,1650],{"id":1650},"stateを直接変更しない",[10,1652,1653],{},"Reactのstateに保存したオブジェクトや配列は、読み取り専用として扱います。値を直接変更せず、新しい値を作ってset関数へ渡します。",[69,1655,1657],{"className":1431,"code":1656,"language":1433,"meta":74,"style":74},"setTodos(currentTodos =>\n  currentTodos.map(todo =>\n    todo.id === id\n      ? { ...todo, completed: true }\n      : todo,\n  ),\n)\n",[76,1658,1659,1673,1690,1706,1734,1745,1752],{"__ignoreMap":74},[79,1660,1661,1664,1666,1670],{"class":81,"line":82},[79,1662,1663],{"class":1521},"setTodos",[79,1665,1525],{"class":1446},[79,1667,1669],{"class":1668},"sHdIc","currentTodos",[79,1671,1672],{"class":1309}," =>\n",[79,1674,1675,1678,1680,1683,1685,1688],{"class":81,"line":88},[79,1676,1677],{"class":1446},"  currentTodos",[79,1679,1518],{"class":1301},[79,1681,1682],{"class":1521},"map",[79,1684,1525],{"class":1446},[79,1686,1687],{"class":1668},"todo",[79,1689,1672],{"class":1309},[79,1691,1692,1695,1697,1700,1703],{"class":81,"line":94},[79,1693,1694],{"class":1446},"    todo",[79,1696,1518],{"class":1301},[79,1698,1699],{"class":1446},"id ",[79,1701,1702],{"class":1301},"===",[79,1704,1705],{"class":1446}," id\n",[79,1707,1708,1711,1713,1716,1718,1721,1724,1727,1731],{"class":81,"line":100},[79,1709,1710],{"class":1301},"      ?",[79,1712,1443],{"class":1301},[79,1714,1715],{"class":1301}," ...",[79,1717,1687],{"class":1446},[79,1719,1720],{"class":1301},",",[79,1722,1723],{"class":1305}," completed",[79,1725,1726],{"class":1301},":",[79,1728,1730],{"class":1729},"sfNiH"," true",[79,1732,1733],{"class":1301}," }\n",[79,1735,1736,1739,1742],{"class":81,"line":107},[79,1737,1738],{"class":1301},"      :",[79,1740,1741],{"class":1446}," todo",[79,1743,1744],{"class":1301},",\n",[79,1746,1747,1750],{"class":81,"line":113},[79,1748,1749],{"class":1446},"  )",[79,1751,1744],{"class":1301},[79,1753,1754],{"class":81,"line":119},[79,1755,246],{"class":1446},[10,1757,1758],{},"配列を新しく作っても、その中にあるオブジェクトまでは自動的に複製されません。更新対象のオブジェクトもスプレッド構文などで新しく作る必要があります。",[10,1760,1761],{},"配列を更新する際は、次のように破壊的な操作を避けます。",[1763,1764,1765,1781],"table",{},[1766,1767,1768],"thead",{},[1769,1770,1771,1775,1778],"tr",{},[1772,1773,1774],"th",{},"操作",[1772,1776,1777],{},"避けたい方法",[1772,1779,1780],{},"利用する方法",[1782,1783,1784,1804,1825,1839],"tbody",{},[1769,1785,1786,1790,1798],{},[1787,1788,1789],"td",{},"追加",[1787,1791,1792,187,1795],{},[76,1793,1794],{},"push",[76,1796,1797],{},"unshift",[1787,1799,1800,1801],{},"スプレッド構文、",[76,1802,1803],{},"concat",[1769,1805,1806,1809,1817],{},[1787,1807,1808],{},"削除",[1787,1810,1811,187,1814],{},[76,1812,1813],{},"pop",[76,1815,1816],{},"splice",[1787,1818,1819,187,1822],{},[76,1820,1821],{},"filter",[76,1823,1824],{},"slice",[1769,1826,1827,1830,1835],{},[1787,1828,1829],{},"置換",[1787,1831,1832,1833],{},"添字への代入、",[76,1834,1816],{},[1787,1836,1837],{},[76,1838,1682],{},[1769,1840,1841,1844,1850],{},[1787,1842,1843],{},"並び替え",[1787,1845,1846,1847],{},"元配列への",[76,1848,1849],{},"sort",[1787,1851,1852,1853],{},"コピー後に",[76,1854,1849],{},[599,1856,1857],{"id":1857},"直前のstateを基に更新する",[10,1859,1860],{},"更新後のstateが更新前の値に依存する場合は、set関数へ値ではなく更新用の関数を渡します。",[69,1862,1864],{"className":1431,"code":1863,"language":1433,"meta":74,"style":74},"setCount(currentCount => currentCount + 1)\n",[76,1865,1866],{"__ignoreMap":74},[79,1867,1868,1871,1873,1876,1879,1882,1885,1889],{"class":81,"line":82},[79,1869,1870],{"class":1521},"setCount",[79,1872,1525],{"class":1446},[79,1874,1875],{"class":1668},"currentCount",[79,1877,1878],{"class":1309}," =>",[79,1880,1881],{"class":1446}," currentCount ",[79,1883,1884],{"class":1301},"+",[79,1886,1888],{"class":1887},"sbssI"," 1",[79,1890,246],{"class":1446},[10,1892,1893],{},"Reactはイベントハンドラーの処理をまとめてからstateを更新することがあります。更新用関数を使うことで、その時点の最新のstateを基に次の値を計算できます。",[599,1895,1896],{"id":1896},"イベントハンドラーの命名",[10,1898,1899,1900,1903,1904,1907],{},"イベントを処理する関数には",[76,1901,1902],{},"handle","、propsとして受け渡すイベントには",[76,1905,1906],{},"on","を付けると役割が伝わりやすくなります。",[69,1909,1911],{"className":1431,"code":1910,"language":1433,"meta":74,"style":74},"type TodoItemProps = {\n  onChange: (id: number) => void\n}\n\nfunction TodoItem({ onChange }: TodoItemProps) {\n  const handleChange = () => {\n    onChange(1)\n  }\n\n  return \u003Cinput type=\"checkbox\" onChange={handleChange} \u002F>\n}\n",[76,1912,1913,1927,1952,1956,1960,1983,2000,2012,2017,2021,2053],{"__ignoreMap":74},[79,1914,1915,1918,1921,1924],{"class":81,"line":82},[79,1916,1917],{"class":1309},"type",[79,1919,1920],{"class":1608}," TodoItemProps",[79,1922,1923],{"class":1301}," =",[79,1925,1926],{"class":1301}," {\n",[79,1928,1929,1932,1934,1936,1939,1941,1944,1947,1949],{"class":81,"line":88},[79,1930,1931],{"class":1305},"  onChange",[79,1933,1726],{"class":1301},[79,1935,1547],{"class":1301},[79,1937,1938],{"class":1668},"id",[79,1940,1726],{"class":1301},[79,1942,1943],{"class":1608}," number",[79,1945,1946],{"class":1301},")",[79,1948,1878],{"class":1309},[79,1950,1951],{"class":1608}," void\n",[79,1953,1954],{"class":81,"line":94},[79,1955,97],{"class":1301},[79,1957,1958],{"class":81,"line":100},[79,1959,104],{"emptyLinePlaceholder":103},[79,1961,1962,1965,1968,1971,1974,1977,1979,1981],{"class":81,"line":107},[79,1963,1964],{"class":1309},"function",[79,1966,1967],{"class":1521}," TodoItem",[79,1969,1970],{"class":1301},"({",[79,1972,1973],{"class":1668}," onChange",[79,1975,1976],{"class":1301}," }:",[79,1978,1920],{"class":1608},[79,1980,1946],{"class":1301},[79,1982,1926],{"class":1301},[79,1984,1985,1988,1991,1993,1996,1998],{"class":81,"line":113},[79,1986,1987],{"class":1309},"  const",[79,1989,1990],{"class":1446}," handleChange",[79,1992,1923],{"class":1301},[79,1994,1995],{"class":1301}," ()",[79,1997,1878],{"class":1309},[79,1999,1926],{"class":1301},[79,2001,2002,2005,2007,2010],{"class":81,"line":119},[79,2003,2004],{"class":1521},"    onChange",[79,2006,1525],{"class":1305},[79,2008,2009],{"class":1887},"1",[79,2011,246],{"class":1305},[79,2013,2014],{"class":81,"line":124},[79,2015,2016],{"class":1301},"  }\n",[79,2018,2019],{"class":81,"line":129},[79,2020,104],{"emptyLinePlaceholder":103},[79,2022,2023,2026,2029,2031,2033,2035,2037,2040,2042,2044,2047,2050],{"class":81,"line":135},[79,2024,2025],{"class":1440},"  return",[79,2027,2028],{"class":1301}," \u003C",[79,2030,1306],{"class":1305},[79,2032,1310],{"class":1309},[79,2034,1313],{"class":1301},[79,2036,1316],{"class":1301},[79,2038,2039],{"class":1319},"checkbox",[79,2041,1316],{"class":1301},[79,2043,1973],{"class":1309},[79,2045,2046],{"class":1301},"={",[79,2048,2049],{"class":1446},"handleChange",[79,2051,2052],{"class":1301},"} \u002F>\n",[79,2054,2055],{"class":81,"line":141},[79,2056,97],{"class":1301},[10,2058,2059],{},"これはReactが強制する規則ではありませんが、一貫した命名はコードを読みやすくします。",[599,2061,2062],{"id":2062},"propsの分割代入",[10,2064,2065],{},"propsを分割代入すると記述は短くなりますが、変数がprops由来なのかコンポーネント内で定義されたものなのか分かりにくくなる場合があります。",[10,2067,2068],{},"コンポーネントが大きくなった場合は、変数名やコンポーネントの責務を見直し、値の出所を追いやすくすることが大切です。",[28,2070,1271],{"id":2071},"typescript",[599,2073,2075,679,2078],{"id":2074},"documentgetelementbyidとnull",[76,2076,2077],{},"document.getElementById",[76,2079,802],{},[10,2081,2082,2084,2085,2088,2089,2091],{},[76,2083,2077],{},"の戻り値は",[76,2086,2087],{},"HTMLElement | null","です。対象の要素が存在しない可能性があるため、利用前に",[76,2090,802],{},"を確認します。",[69,2093,2096],{"className":2094,"code":2095,"language":2071,"meta":74,"style":74},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const container = document.getElementById('root')\n\nif (!container) {\n  throw new Error('root要素が見つかりません')\n}\n",[76,2097,2098,2122,2126,2138,2156],{"__ignoreMap":74},[79,2099,2100,2102,2104,2106,2108,2110,2112,2114,2116,2118,2120],{"class":81,"line":82},[79,2101,1507],{"class":1309},[79,2103,1510],{"class":1446},[79,2105,1313],{"class":1301},[79,2107,1515],{"class":1446},[79,2109,1518],{"class":1301},[79,2111,1522],{"class":1521},[79,2113,1525],{"class":1446},[79,2115,1528],{"class":1301},[79,2117,1531],{"class":1319},[79,2119,1528],{"class":1301},[79,2121,246],{"class":1446},[79,2123,2124],{"class":81,"line":88},[79,2125,104],{"emptyLinePlaceholder":103},[79,2127,2128,2130,2132,2134,2136],{"class":81,"line":94},[79,2129,1544],{"class":1440},[79,2131,1547],{"class":1446},[79,2133,1550],{"class":1301},[79,2135,1553],{"class":1446},[79,2137,1556],{"class":1301},[79,2139,2140,2142,2144,2146,2148,2150,2152,2154],{"class":81,"line":100},[79,2141,1561],{"class":1440},[79,2143,1564],{"class":1301},[79,2145,1567],{"class":1521},[79,2147,1525],{"class":1305},[79,2149,1528],{"class":1301},[79,2151,1574],{"class":1319},[79,2153,1528],{"class":1301},[79,2155,246],{"class":1305},[79,2157,2158],{"class":81,"line":107},[79,2159,97],{"class":1301},[10,2161,2162,2163,2165],{},"Non-nullアサーション演算子（",[76,2164,1550],{},"）で確認を省略することもできますが、実行時に要素が必ず存在することをTypeScriptが保証するわけではありません。",[599,2167,2169],{"id":2168},"readonly",[76,2170,2168],{},[10,2172,2173,2174,2176],{},"プロパティへ",[76,2175,2168],{},"を指定すると、そのプロパティへの再代入を型チェックで防げます。",[69,2178,2180],{"className":2094,"code":2179,"language":2071,"meta":74,"style":74},"type Todo = {\n  readonly id: number\n  title: string\n}\n",[76,2181,2182,2193,2206,2216],{"__ignoreMap":74},[79,2183,2184,2186,2189,2191],{"class":81,"line":82},[79,2185,1917],{"class":1309},[79,2187,2188],{"class":1608}," Todo",[79,2190,1923],{"class":1301},[79,2192,1926],{"class":1301},[79,2194,2195,2198,2201,2203],{"class":81,"line":88},[79,2196,2197],{"class":1309},"  readonly",[79,2199,2200],{"class":1305}," id",[79,2202,1726],{"class":1301},[79,2204,2205],{"class":1608}," number\n",[79,2207,2208,2211,2213],{"class":81,"line":94},[79,2209,2210],{"class":1305},"  title",[79,2212,1726],{"class":1301},[79,2214,2215],{"class":1608}," string\n",[79,2217,2218],{"class":81,"line":100},[79,2219,97],{"class":1301},[10,2221,2222,2224],{},[76,2223,2168],{},"はコンパイル時の制約です。また、入れ子になったオブジェクトまで自動的に読み取り専用にするものではありません。",[599,2226,2227],{"id":2227},"イベントごとの型",[10,2229,2230],{},"Reactのイベントハンドラーでは、対象に応じたイベント型を利用できます。",[69,2232,2234],{"className":1431,"code":2233,"language":1433,"meta":74,"style":74},"function handleChange(event: React.ChangeEvent\u003CHTMLInputElement>) {\n  console.log(event.target.checked)\n}\n",[76,2235,2236,2267,2293],{"__ignoreMap":74},[79,2237,2238,2240,2242,2244,2247,2249,2252,2254,2257,2259,2262,2265],{"class":81,"line":82},[79,2239,1964],{"class":1309},[79,2241,1990],{"class":1521},[79,2243,1525],{"class":1301},[79,2245,2246],{"class":1668},"event",[79,2248,1726],{"class":1301},[79,2250,2251],{"class":1608}," React",[79,2253,1518],{"class":1301},[79,2255,2256],{"class":1608},"ChangeEvent",[79,2258,1302],{"class":1301},[79,2260,2261],{"class":1608},"HTMLInputElement",[79,2263,2264],{"class":1301},">)",[79,2266,1926],{"class":1301},[79,2268,2269,2272,2274,2277,2279,2281,2283,2286,2288,2291],{"class":81,"line":88},[79,2270,2271],{"class":1446},"  console",[79,2273,1518],{"class":1301},[79,2275,2276],{"class":1521},"log",[79,2278,1525],{"class":1305},[79,2280,2246],{"class":1446},[79,2282,1518],{"class":1301},[79,2284,2285],{"class":1446},"target",[79,2287,1518],{"class":1301},[79,2289,2290],{"class":1446},"checked",[79,2292,246],{"class":1305},[79,2294,2295],{"class":81,"line":94},[79,2296,97],{"class":1301},[10,2298,2299,2300,2303],{},"イベント型だけでなく、",[76,2301,2302],{},"ChangeEventHandler\u003CHTMLInputElement>","のようなハンドラー全体の型を付ける方法もあります。",[599,2305,2306],{"id":2306},"ジェネリクスの型引数へ制約を付ける",[10,2308,2309,2310,2313],{},"型引数に",[76,2311,2312],{},"extends","を指定すると、ジェネリクスで受け取れる型に必要なプロパティを保証できます。",[69,2315,2317],{"className":2094,"code":2316,"language":2071,"meta":74,"style":74},"type Identifiable = {\n  id: number\n}\n\nfunction findById\u003CT extends Identifiable>(items: T[], id: number) {\n  return items.find(item => item.id === id)\n}\n",[76,2318,2319,2330,2339,2343,2347,2390,2423],{"__ignoreMap":74},[79,2320,2321,2323,2326,2328],{"class":81,"line":82},[79,2322,1917],{"class":1309},[79,2324,2325],{"class":1608}," Identifiable",[79,2327,1923],{"class":1301},[79,2329,1926],{"class":1301},[79,2331,2332,2335,2337],{"class":81,"line":88},[79,2333,2334],{"class":1305},"  id",[79,2336,1726],{"class":1301},[79,2338,2205],{"class":1608},[79,2340,2341],{"class":81,"line":94},[79,2342,97],{"class":1301},[79,2344,2345],{"class":81,"line":100},[79,2346,104],{"emptyLinePlaceholder":103},[79,2348,2349,2351,2354,2356,2359,2362,2364,2367,2370,2372,2375,2378,2380,2382,2384,2386,2388],{"class":81,"line":107},[79,2350,1964],{"class":1309},[79,2352,2353],{"class":1521}," findById",[79,2355,1302],{"class":1301},[79,2357,2358],{"class":1608},"T",[79,2360,2361],{"class":1309}," extends",[79,2363,2325],{"class":1608},[79,2365,2366],{"class":1301},">(",[79,2368,2369],{"class":1668},"items",[79,2371,1726],{"class":1301},[79,2373,2374],{"class":1608}," T",[79,2376,2377],{"class":1446},"[]",[79,2379,1720],{"class":1301},[79,2381,2200],{"class":1668},[79,2383,1726],{"class":1301},[79,2385,1943],{"class":1608},[79,2387,1946],{"class":1301},[79,2389,1926],{"class":1301},[79,2391,2392,2394,2397,2399,2402,2404,2407,2409,2412,2414,2416,2419,2421],{"class":81,"line":113},[79,2393,2025],{"class":1440},[79,2395,2396],{"class":1446}," items",[79,2398,1518],{"class":1301},[79,2400,2401],{"class":1521},"find",[79,2403,1525],{"class":1305},[79,2405,2406],{"class":1668},"item",[79,2408,1878],{"class":1309},[79,2410,2411],{"class":1446}," item",[79,2413,1518],{"class":1301},[79,2415,1938],{"class":1446},[79,2417,2418],{"class":1301}," ===",[79,2420,2200],{"class":1446},[79,2422,246],{"class":1305},[79,2424,2425],{"class":81,"line":119},[79,2426,97],{"class":1301},[10,2428,2429,2430,2432,2433,2435],{},"制約がなければ",[76,2431,2358],{},"にどのような型が渡されるか分からないため、関数内で",[76,2434,1938],{},"へ安全にアクセスできません。",[599,2437,2439,2442],{"id":2438},"keyof型演算子",[76,2440,2441],{},"keyof","型演算子",[10,2444,2445,2447],{},[76,2446,2441],{},"は、オブジェクト型のプロパティ名からユニオン型を作る型演算子です。",[69,2449,2451],{"className":2094,"code":2450,"language":2071,"meta":74,"style":74},"type Todo = {\n  id: number\n  title: string\n}\n\ntype TodoKey = keyof Todo\n\u002F\u002F 'id' | 'title'\n",[76,2452,2453,2463,2471,2479,2483,2487,2502],{"__ignoreMap":74},[79,2454,2455,2457,2459,2461],{"class":81,"line":82},[79,2456,1917],{"class":1309},[79,2458,2188],{"class":1608},[79,2460,1923],{"class":1301},[79,2462,1926],{"class":1301},[79,2464,2465,2467,2469],{"class":81,"line":88},[79,2466,2334],{"class":1305},[79,2468,1726],{"class":1301},[79,2470,2205],{"class":1608},[79,2472,2473,2475,2477],{"class":81,"line":94},[79,2474,2210],{"class":1305},[79,2476,1726],{"class":1301},[79,2478,2215],{"class":1608},[79,2480,2481],{"class":81,"line":100},[79,2482,97],{"class":1301},[79,2484,2485],{"class":81,"line":107},[79,2486,104],{"emptyLinePlaceholder":103},[79,2488,2489,2491,2494,2496,2499],{"class":81,"line":113},[79,2490,1917],{"class":1309},[79,2492,2493],{"class":1608}," TodoKey",[79,2495,1923],{"class":1301},[79,2497,2498],{"class":1301}," keyof",[79,2500,2501],{"class":1608}," Todo\n",[79,2503,2504],{"class":81,"line":119},[79,2505,2507],{"class":2506},"sHwdD","\u002F\u002F 'id' | 'title'\n",[10,2509,2510],{},"プロパティを追加・削除したときにユニオン型を手作業で更新する必要がなくなり、型定義との不整合を防ぎやすくなります。",[599,2512,2513],{"id":2513},"インデックスアクセス型",[10,2515,2516],{},"インデックスアクセス型を使うと、オブジェクト型から特定のプロパティの型を取り出せます。",[69,2518,2520],{"className":2094,"code":2519,"language":2071,"meta":74,"style":74},"type Todo = {\n  id: number\n  title: string\n}\n\ntype TodoId = Todo['id']\n\u002F\u002F number\n\ntype TodoValue = Todo[keyof Todo]\n\u002F\u002F number | string\n",[76,2521,2522,2532,2540,2548,2552,2556,2578,2583,2587,2606],{"__ignoreMap":74},[79,2523,2524,2526,2528,2530],{"class":81,"line":82},[79,2525,1917],{"class":1309},[79,2527,2188],{"class":1608},[79,2529,1923],{"class":1301},[79,2531,1926],{"class":1301},[79,2533,2534,2536,2538],{"class":81,"line":88},[79,2535,2334],{"class":1305},[79,2537,1726],{"class":1301},[79,2539,2205],{"class":1608},[79,2541,2542,2544,2546],{"class":81,"line":94},[79,2543,2210],{"class":1305},[79,2545,1726],{"class":1301},[79,2547,2215],{"class":1608},[79,2549,2550],{"class":81,"line":100},[79,2551,97],{"class":1301},[79,2553,2554],{"class":81,"line":107},[79,2555,104],{"emptyLinePlaceholder":103},[79,2557,2558,2560,2563,2565,2567,2570,2572,2574,2576],{"class":81,"line":113},[79,2559,1917],{"class":1309},[79,2561,2562],{"class":1608}," TodoId",[79,2564,1923],{"class":1301},[79,2566,2188],{"class":1608},[79,2568,2569],{"class":1446},"[",[79,2571,1528],{"class":1301},[79,2573,1938],{"class":1319},[79,2575,1528],{"class":1301},[79,2577,905],{"class":1446},[79,2579,2580],{"class":81,"line":119},[79,2581,2582],{"class":2506},"\u002F\u002F number\n",[79,2584,2585],{"class":81,"line":124},[79,2586,104],{"emptyLinePlaceholder":103},[79,2588,2589,2591,2594,2596,2598,2600,2602,2604],{"class":81,"line":129},[79,2590,1917],{"class":1309},[79,2592,2593],{"class":1608}," TodoValue",[79,2595,1923],{"class":1301},[79,2597,2188],{"class":1608},[79,2599,2569],{"class":1446},[79,2601,2441],{"class":1301},[79,2603,2188],{"class":1608},[79,2605,905],{"class":1446},[79,2607,2608],{"class":81,"line":135},[79,2609,2610],{"class":2506},"\u002F\u002F number | string\n",[599,2612,2613],{"id":2613},"アンビエント宣言",[10,2615,2616,2619],{},[76,2617,2618],{},"declare","を使うと、実装が別の場所に存在する値や型をTypeScriptへ伝えられます。JavaScriptライブラリや実行環境が提供するグローバル変数の型を補う場合などに使用します。",[69,2621,2623],{"className":2094,"code":2622,"language":2071,"meta":74,"style":74},"declare const appVersion: string\n",[76,2624,2625],{"__ignoreMap":74},[79,2626,2627,2629,2632,2635,2637],{"class":81,"line":82},[79,2628,2618],{"class":1309},[79,2630,2631],{"class":1309}," const",[79,2633,2634],{"class":1446}," appVersion",[79,2636,1726],{"class":1301},[79,2638,2215],{"class":1608},[10,2640,2641,2642,2645,2646,2648],{},"一般的には",[76,2643,2644],{},".d.ts","形式の型定義ファイルへ記述します。",[76,2647,2618],{},"は実行時の値を作成しないため、実体が存在しなければ実行時エラーになります。",[599,2650,2651],{"id":2651},"メソッドの型注釈",[10,2653,2654],{},"オブジェクト型のメソッドは、メソッド構文と関数プロパティ構文のどちらでも表現できます。",[69,2656,2658],{"className":2094,"code":2657,"language":2071,"meta":74,"style":74},"type Formatter = {\n  format(value: string): string\n}\n\ntype FormatterProperty = {\n  format: (value: string) => string\n}\n",[76,2659,2660,2671,2691,2695,2699,2710,2730],{"__ignoreMap":74},[79,2661,2662,2664,2667,2669],{"class":81,"line":82},[79,2663,1917],{"class":1309},[79,2665,2666],{"class":1608}," Formatter",[79,2668,1923],{"class":1301},[79,2670,1926],{"class":1301},[79,2672,2673,2676,2678,2681,2683,2686,2689],{"class":81,"line":88},[79,2674,2675],{"class":1305},"  format",[79,2677,1525],{"class":1301},[79,2679,2680],{"class":1668},"value",[79,2682,1726],{"class":1301},[79,2684,2685],{"class":1608}," string",[79,2687,2688],{"class":1301},"):",[79,2690,2215],{"class":1608},[79,2692,2693],{"class":81,"line":94},[79,2694,97],{"class":1301},[79,2696,2697],{"class":81,"line":100},[79,2698,104],{"emptyLinePlaceholder":103},[79,2700,2701,2703,2706,2708],{"class":81,"line":107},[79,2702,1917],{"class":1309},[79,2704,2705],{"class":1608}," FormatterProperty",[79,2707,1923],{"class":1301},[79,2709,1926],{"class":1301},[79,2711,2712,2714,2716,2718,2720,2722,2724,2726,2728],{"class":81,"line":113},[79,2713,2675],{"class":1305},[79,2715,1726],{"class":1301},[79,2717,1547],{"class":1301},[79,2719,2680],{"class":1668},[79,2721,1726],{"class":1301},[79,2723,2685],{"class":1608},[79,2725,1946],{"class":1301},[79,2727,1878],{"class":1309},[79,2729,2215],{"class":1608},[79,2731,2732],{"class":81,"line":119},[79,2733,97],{"class":1301},[10,2735,2736,2737,2740],{},"両者には、継承や",[76,2738,2739],{},"strictFunctionTypes","における引数型の扱いなどで違いがあります。プロジェクト内で意図に合った書き方へ揃えることが大切です。",[599,2742,2743],{"id":2743},"型ガード",[10,2745,2746],{},"型ガードは、実行時の確認を通して変数の型を絞り込む仕組みです。ユーザー定義型ガードでは、戻り値の型に型述語を指定します。",[69,2748,2750],{"className":2094,"code":2749,"language":2071,"meta":74,"style":74},"function isNumber(value: unknown): value is number {\n  return typeof value === 'number'\n}\n\nconst value: unknown = 10\n\nif (isNumber(value)) {\n  console.log(value.toFixed(2))\n}\n",[76,2751,2752,2780,2798,2802,2806,2821,2825,2839,2864],{"__ignoreMap":74},[79,2753,2754,2756,2759,2761,2763,2765,2768,2770,2773,2776,2778],{"class":81,"line":82},[79,2755,1964],{"class":1309},[79,2757,2758],{"class":1521}," isNumber",[79,2760,1525],{"class":1301},[79,2762,2680],{"class":1668},[79,2764,1726],{"class":1301},[79,2766,2767],{"class":1608}," unknown",[79,2769,2688],{"class":1301},[79,2771,2772],{"class":1668}," value",[79,2774,2775],{"class":1301}," is",[79,2777,1943],{"class":1608},[79,2779,1926],{"class":1301},[79,2781,2782,2784,2787,2789,2791,2793,2796],{"class":81,"line":88},[79,2783,2025],{"class":1440},[79,2785,2786],{"class":1301}," typeof",[79,2788,2772],{"class":1446},[79,2790,2418],{"class":1301},[79,2792,1456],{"class":1301},[79,2794,2795],{"class":1319},"number",[79,2797,1461],{"class":1301},[79,2799,2800],{"class":81,"line":94},[79,2801,97],{"class":1301},[79,2803,2804],{"class":81,"line":100},[79,2805,104],{"emptyLinePlaceholder":103},[79,2807,2808,2810,2812,2814,2816,2818],{"class":81,"line":107},[79,2809,1507],{"class":1309},[79,2811,2772],{"class":1446},[79,2813,1726],{"class":1301},[79,2815,2767],{"class":1608},[79,2817,1923],{"class":1301},[79,2819,2820],{"class":1887}," 10\n",[79,2822,2823],{"class":81,"line":113},[79,2824,104],{"emptyLinePlaceholder":103},[79,2826,2827,2829,2831,2834,2837],{"class":81,"line":119},[79,2828,1544],{"class":1440},[79,2830,1547],{"class":1446},[79,2832,2833],{"class":1521},"isNumber",[79,2835,2836],{"class":1446},"(value)) ",[79,2838,1556],{"class":1301},[79,2840,2841,2843,2845,2847,2849,2851,2853,2856,2858,2861],{"class":81,"line":124},[79,2842,2271],{"class":1446},[79,2844,1518],{"class":1301},[79,2846,2276],{"class":1521},[79,2848,1525],{"class":1305},[79,2850,2680],{"class":1446},[79,2852,1518],{"class":1301},[79,2854,2855],{"class":1521},"toFixed",[79,2857,1525],{"class":1305},[79,2859,2860],{"class":1887},"2",[79,2862,2863],{"class":1305},"))\n",[79,2865,2866],{"class":81,"line":129},[79,2867,97],{"class":1301},[10,2869,2870],{},"APIレスポンスなど外部から受け取った値は、型アサーションで決めつけるのではなく、実行時に検証してから利用すると安全です。",[28,2872,476],{"id":476},[10,2874,2875],{},"Todoアプリの実装を通して、HTML属性の使い方からReactのstate更新、TypeScriptの型操作まで、幅広い内容を学べました。",[10,2877,2878],{},"個々の構文を覚えるだけでなく、「なぜその書き方が必要なのか」を実際のアプリ開発と結び付けて理解することが大切だと感じました。",[510,2880,2881],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":74,"searchDepth":88,"depth":88,"links":2883},[2884,2887,2891,2898,2910],{"id":1274,"depth":88,"text":1263,"children":2885},[2886],{"id":1277,"depth":94,"text":1277},{"id":73,"depth":88,"text":531,"children":2888},[2889,2890],{"id":1342,"depth":94,"text":1342},{"id":1393,"depth":94,"text":1394},{"id":1413,"depth":88,"text":1268,"children":2892},[2893,2894,2895,2896,2897],{"id":1416,"depth":94,"text":1419},{"id":1650,"depth":94,"text":1650},{"id":1857,"depth":94,"text":1857},{"id":1896,"depth":94,"text":1896},{"id":2062,"depth":94,"text":2062},{"id":2071,"depth":88,"text":1271,"children":2899},[2900,2902,2903,2904,2905,2906,2907,2908,2909],{"id":2074,"depth":94,"text":2901},"document.getElementByIdとnull",{"id":2168,"depth":94,"text":2168},{"id":2227,"depth":94,"text":2227},{"id":2306,"depth":94,"text":2306},{"id":2438,"depth":94,"text":2438},{"id":2513,"depth":94,"text":2513},{"id":2613,"depth":94,"text":2613},{"id":2651,"depth":94,"text":2651},{"id":2743,"depth":94,"text":2743},{"id":476,"depth":88,"text":476},"React HooksとTypeScriptでTodoアプリを作るハンズオンを通して学んだ、HTML、JavaScript、React、TypeScriptのポイントを整理します。",{},"\u002Farticles\u002F2024\u002Forganize-learned-from-todo","2024-12-23",{"title":1245,"description":2911},"articles\u002F2024\u002Forganize-learned-from-todo",[1268,1271],"\u002Fimages\u002Farticles\u002Forganize-learned-from-todo.png","ic1Do2Gie9Gb4WmAmZ2IL55ETNgmySMOwEHT_s3q0bk",{"id":2921,"title":2922,"body":2923,"description":3400,"extension":524,"meta":3401,"navigation":103,"path":3402,"publishDate":3403,"published":103,"seo":3404,"stem":3405,"tags":3406,"thumbnail":3408,"updated":3403,"__hash__":3409},"articles\u002Farticles\u002F2024\u002Fdescribe-webstorage-indexeddb.md","Web StorageとIndexedDBについて整理する",{"type":7,"value":2924,"toc":3390},[2925,2927,2930,2940,2943,2946,2949,2952,3036,3039,3044,3047,3075,3086,3137,3140,3143,3151,3170,3173,3176,3179,3182,3185,3287,3290,3304,3307,3310,3313,3337,3343,3346,3349,3356,3359,3362,3377,3380,3382,3385,3388],[10,2926,12],{},[10,2928,2929],{},"Todoアプリを作った際にIndexedDBを利用したのですが、ブラウザにデータを保存する方法としてはWeb Storageもあります。",[10,2931,2932,2933,187,2936,2939],{},"今回は、",[76,2934,2935],{},"localStorage",[76,2937,2938],{},"sessionStorage","、IndexedDBの特徴と使い分けを整理します。",[28,2941,2942],{"id":2942},"ブラウザにデータを保存する仕組み",[10,2944,2945],{},"Web StorageとIndexedDBは、どちらもブラウザ側にデータを保存するためのWeb APIです。",[10,2947,2948],{},"保存したデータが自動的にサーバーへ送信されることはなく、同一オリジンの制約を受けます。ただし、保存容量やデータが削除される条件はブラウザや利用状況によって異なるため、永続性を前提にしすぎないことが大切です。",[10,2950,2951],{},"主な違いは次のとおりです。",[1763,2953,2954,2968],{},[1766,2955,2956],{},[1769,2957,2958,2961,2963,2965],{},[1772,2959,2960],{},"項目",[1772,2962,2935],{},[1772,2964,2938],{},[1772,2966,2967],{},"IndexedDB",[1782,2969,2970,2983,2996,3009,3022],{},[1769,2971,2972,2975,2978,2980],{},[1787,2973,2974],{},"保存形式",[1787,2976,2977],{},"文字列のキーバリュー",[1787,2979,2977],{},[1787,2981,2982],{},"オブジェクトやBlobなど",[1769,2984,2985,2988,2991,2993],{},[1787,2986,2987],{},"API",[1787,2989,2990],{},"同期",[1787,2992,2990],{},[1787,2994,2995],{},"非同期",[1769,2997,2998,3001,3004,3007],{},[1787,2999,3000],{},"データの範囲",[1787,3002,3003],{},"同一オリジン",[1787,3005,3006],{},"同一オリジンかつタブ単位",[1787,3008,3003],{},[1769,3010,3011,3014,3017,3020],{},[1787,3012,3013],{},"データの寿命",[1787,3015,3016],{},"明示的に削除されるまで",[1787,3018,3019],{},"タブを閉じるまで",[1787,3021,3016],{},[1769,3023,3024,3027,3030,3033],{},[1787,3025,3026],{},"得意な用途",[1787,3028,3029],{},"小さな設定値",[1787,3031,3032],{},"一時的な入力状態",[1787,3034,3035],{},"大量・構造化データ",[28,3037,2935],{"id":3038},"localstorage",[10,3040,3041,3043],{},[76,3042,2935],{},"は、文字列をキーバリュー形式で保存する同期APIです。",[10,3045,3046],{},"ブラウザやタブを閉じてもデータが残るため、テーマや表示設定など、小さく単純なデータの保存に向いています。",[69,3048,3050],{"className":71,"code":3049,"language":73,"meta":74,"style":74},"localStorage.setItem('theme', 'dark')\n\nconst theme = localStorage.getItem('theme')\n\nlocalStorage.removeItem('theme')\n",[76,3051,3052,3057,3061,3066,3070],{"__ignoreMap":74},[79,3053,3054],{"class":81,"line":82},[79,3055,3056],{},"localStorage.setItem('theme', 'dark')\n",[79,3058,3059],{"class":81,"line":88},[79,3060,104],{"emptyLinePlaceholder":103},[79,3062,3063],{"class":81,"line":94},[79,3064,3065],{},"const theme = localStorage.getItem('theme')\n",[79,3067,3068],{"class":81,"line":100},[79,3069,104],{"emptyLinePlaceholder":103},[79,3071,3072],{"class":81,"line":107},[79,3073,3074],{},"localStorage.removeItem('theme')\n",[10,3076,3077,3078,3081,3082,3085],{},"値は文字列として保存されます。オブジェクトを扱う場合は、保存時に",[76,3079,3080],{},"JSON.stringify()","、取得時に",[76,3083,3084],{},"JSON.parse()","が必要です。",[69,3087,3089],{"className":71,"code":3088,"language":73,"meta":74,"style":74},"const settings = {\n  theme: 'dark',\n  fontSize: 16,\n}\n\nlocalStorage.setItem('settings', JSON.stringify(settings))\n\nconst storedSettings = JSON.parse(\n  localStorage.getItem('settings') ?? '{}',\n)\n",[76,3090,3091,3096,3101,3106,3110,3114,3119,3123,3128,3133],{"__ignoreMap":74},[79,3092,3093],{"class":81,"line":82},[79,3094,3095],{},"const settings = {\n",[79,3097,3098],{"class":81,"line":88},[79,3099,3100],{},"  theme: 'dark',\n",[79,3102,3103],{"class":81,"line":94},[79,3104,3105],{},"  fontSize: 16,\n",[79,3107,3108],{"class":81,"line":100},[79,3109,97],{},[79,3111,3112],{"class":81,"line":107},[79,3113,104],{"emptyLinePlaceholder":103},[79,3115,3116],{"class":81,"line":113},[79,3117,3118],{},"localStorage.setItem('settings', JSON.stringify(settings))\n",[79,3120,3121],{"class":81,"line":119},[79,3122,104],{"emptyLinePlaceholder":103},[79,3124,3125],{"class":81,"line":124},[79,3126,3127],{},"const storedSettings = JSON.parse(\n",[79,3129,3130],{"class":81,"line":129},[79,3131,3132],{},"  localStorage.getItem('settings') ?? '{}',\n",[79,3134,3135],{"class":81,"line":135},[79,3136,246],{},[10,3138,3139],{},"同期APIのため、大きなデータを頻繁に読み書きするとメインスレッドを塞ぐ可能性があります。",[28,3141,2938],{"id":3142},"sessionstorage",[10,3144,3145,3147,3148,3150],{},[76,3146,2938],{},"も、文字列をキーバリュー形式で保存する同期APIです。基本的な操作方法は",[76,3149,2935],{},"と同じです。",[69,3152,3154],{"className":71,"code":3153,"language":73,"meta":74,"style":74},"sessionStorage.setItem('draft', '入力途中の内容')\n\nconst draft = sessionStorage.getItem('draft')\n",[76,3155,3156,3161,3165],{"__ignoreMap":74},[79,3157,3158],{"class":81,"line":82},[79,3159,3160],{},"sessionStorage.setItem('draft', '入力途中の内容')\n",[79,3162,3163],{"class":81,"line":88},[79,3164,104],{"emptyLinePlaceholder":103},[79,3166,3167],{"class":81,"line":94},[79,3168,3169],{},"const draft = sessionStorage.getItem('draft')\n",[10,3171,3172],{},"ページを再読み込みしてもデータは残りますが、保存領域はタブごとのページセッションに分かれ、タブを閉じるとデータも削除されます。",[10,3174,3175],{},"そのため、フォームの入力途中の状態や、画面遷移中だけ保持したい一時的な情報に向いています。",[28,3177,2967],{"id":3178},"indexeddb",[10,3180,3181],{},"IndexedDBは、大量の構造化データをブラウザへ保存するための非同期APIです。",[10,3183,3184],{},"JavaScriptのオブジェクトだけでなく、ファイルやBlobなども保存できます。また、オブジェクトストア、インデックス、トランザクションを利用できるため、検索や更新を伴うデータ管理に向いています。",[69,3186,3188],{"className":71,"code":3187,"language":73,"meta":74,"style":74},"const request = indexedDB.open('todo-app', 1)\n\nrequest.onupgradeneeded = () => {\n  const database = request.result\n\n  if (!database.objectStoreNames.contains('todos')) {\n    database.createObjectStore('todos', {\n      keyPath: 'id',\n      autoIncrement: true,\n    })\n  }\n}\n\nrequest.onsuccess = () => {\n  const database = request.result\n  const transaction = database.transaction('todos', 'readwrite')\n  const todos = transaction.objectStore('todos')\n\n  todos.add({ title: '記事を書く', completed: false })\n}\n",[76,3189,3190,3195,3199,3204,3209,3213,3218,3223,3228,3233,3238,3242,3246,3250,3255,3259,3265,3271,3276,3282],{"__ignoreMap":74},[79,3191,3192],{"class":81,"line":82},[79,3193,3194],{},"const request = indexedDB.open('todo-app', 1)\n",[79,3196,3197],{"class":81,"line":88},[79,3198,104],{"emptyLinePlaceholder":103},[79,3200,3201],{"class":81,"line":94},[79,3202,3203],{},"request.onupgradeneeded = () => {\n",[79,3205,3206],{"class":81,"line":100},[79,3207,3208],{},"  const database = request.result\n",[79,3210,3211],{"class":81,"line":107},[79,3212,104],{"emptyLinePlaceholder":103},[79,3214,3215],{"class":81,"line":113},[79,3216,3217],{},"  if (!database.objectStoreNames.contains('todos')) {\n",[79,3219,3220],{"class":81,"line":119},[79,3221,3222],{},"    database.createObjectStore('todos', {\n",[79,3224,3225],{"class":81,"line":124},[79,3226,3227],{},"      keyPath: 'id',\n",[79,3229,3230],{"class":81,"line":129},[79,3231,3232],{},"      autoIncrement: true,\n",[79,3234,3235],{"class":81,"line":135},[79,3236,3237],{},"    })\n",[79,3239,3240],{"class":81,"line":141},[79,3241,2016],{},[79,3243,3244],{"class":81,"line":146},[79,3245,97],{},[79,3247,3248],{"class":81,"line":151},[79,3249,104],{"emptyLinePlaceholder":103},[79,3251,3252],{"class":81,"line":434},[79,3253,3254],{},"request.onsuccess = () => {\n",[79,3256,3257],{"class":81,"line":439},[79,3258,3208],{},[79,3260,3262],{"class":81,"line":3261},16,[79,3263,3264],{},"  const transaction = database.transaction('todos', 'readwrite')\n",[79,3266,3268],{"class":81,"line":3267},17,[79,3269,3270],{},"  const todos = transaction.objectStore('todos')\n",[79,3272,3274],{"class":81,"line":3273},18,[79,3275,104],{"emptyLinePlaceholder":103},[79,3277,3279],{"class":81,"line":3278},19,[79,3280,3281],{},"  todos.add({ title: '記事を書く', completed: false })\n",[79,3283,3285],{"class":81,"line":3284},20,[79,3286,97],{},[10,3288,3289],{},"Web Storageよりも扱う概念は多いものの、次のような用途で力を発揮します。",[42,3291,3292,3295,3298,3301],{},[45,3293,3294],{},"オフラインでも利用するアプリ",[45,3296,3297],{},"Todoやメモなど、件数が増えるデータ",[45,3299,3300],{},"検索や並び替えにインデックスを使いたいデータ",[45,3302,3303],{},"画像やファイルを含むデータ",[28,3305,3306],{"id":3306},"保存容量とデータの削除",[10,3308,3309],{},"ブラウザストレージの容量は、特定の数値をどの環境でも保証できるものではありません。ブラウザ、端末の空き容量、ユーザー設定などによって変わります。",[10,3311,3312],{},"利用状況はStorage APIから概算できます。",[69,3314,3316],{"className":71,"code":3315,"language":73,"meta":74,"style":74},"const estimate = await navigator.storage.estimate()\n\nconsole.log(estimate.usage)\nconsole.log(estimate.quota)\n",[76,3317,3318,3323,3327,3332],{"__ignoreMap":74},[79,3319,3320],{"class":81,"line":82},[79,3321,3322],{},"const estimate = await navigator.storage.estimate()\n",[79,3324,3325],{"class":81,"line":88},[79,3326,104],{"emptyLinePlaceholder":103},[79,3328,3329],{"class":81,"line":94},[79,3330,3331],{},"console.log(estimate.usage)\n",[79,3333,3334],{"class":81,"line":100},[79,3335,3336],{},"console.log(estimate.quota)\n",[707,3338,3340],{"title":3339,"type":1334},"ブラウザストレージを唯一の保存先にしない",[10,3341,3342],{},"保存したデータは、ユーザーによるサイトデータの削除や、ブラウザのストレージ管理によって失われる場合があります。失われると困るデータはサーバーにも保存しましょう。",[28,3344,3345],{"id":3345},"セキュリティ上の注意",[10,3347,3348],{},"Web StorageとIndexedDBは、認証された同一オリジンのJavaScriptからアクセスできます。",[707,3350,3353],{"title":3351,"type":3352},"機密情報の保存に注意する","warning",[10,3354,3355],{},"クロスサイトスクリプティング（XSS）が発生すると、保存内容を読み取られる可能性があります。アクセストークンや個人情報などの機密情報を、安易に保存しないようにしましょう。",[28,3357,3358],{"id":3358},"どれを選ぶか",[10,3360,3361],{},"選び方を簡単にまとめると、次のようになります。",[42,3363,3364,3369,3374],{},[45,3365,3366,3367],{},"小さな設定をブラウザを閉じた後も残したい場合は",[76,3368,2935],{},[45,3370,3371,3372],{},"タブを開いている間だけ一時的に残したい場合は",[76,3373,2938],{},[45,3375,3376],{},"大量のデータや構造化データを非同期で扱いたい場合はIndexedDB",[10,3378,3379],{},"Web Storageは手軽ですが、同期APIであり文字列しか保存できません。データ量が増えるアプリや、検索・更新を伴うデータにはIndexedDBを検討するとよいでしょう。",[28,3381,476],{"id":476},[10,3383,3384],{},"Web StorageとIndexedDBは、どちらもブラウザ側へデータを保存できますが、得意な用途が異なります。",[10,3386,3387],{},"保存するデータの量や形式だけでなく、同期処理による影響、データを保持する期間、失われた場合の影響まで考えて選ぶことが大切です。",[510,3389,512],{},{"title":74,"searchDepth":88,"depth":88,"links":3391},[3392,3393,3394,3395,3396,3397,3398,3399],{"id":2942,"depth":88,"text":2942},{"id":3038,"depth":88,"text":2935},{"id":3142,"depth":88,"text":2938},{"id":3178,"depth":88,"text":2967},{"id":3306,"depth":88,"text":3306},{"id":3345,"depth":88,"text":3345},{"id":3358,"depth":88,"text":3358},{"id":476,"depth":88,"text":476},"localStorage、sessionStorage、IndexedDBの違いを、保存形式、同期・非同期、データの寿命、用途から整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-webstorage-indexeddb","2024-12-22",{"title":2922,"description":3400},"articles\u002F2024\u002Fdescribe-webstorage-indexeddb",[3407,2967],"Web Storage","\u002Fimages\u002Farticles\u002Fdescribe-webstorage-indexeddb.png","3W_8UP01CjjLWIG3qOQhJB7e1YiLPuYONYyx_372v98",{"id":4,"title":5,"body":3411,"description":523,"extension":524,"meta":3778,"navigation":103,"path":526,"publishDate":527,"published":103,"seo":3779,"stem":529,"tags":3780,"thumbnail":532,"updated":527,"__hash__":533},{"type":7,"value":3412,"toc":3768},[3413,3415,3420,3422,3424,3426,3428,3430,3442,3444,3446,3448,3504,3506,3532,3534,3536,3538,3540,3550,3552,3588,3590,3592,3594,3596,3606,3610,3612,3614,3616,3634,3636,3638,3640,3642,3644,3656,3658,3660,3724,3726,3731,3737,3743,3745,3759,3761,3766],[10,3414,12],{},[10,3416,15,3417,23],{},[17,3418,22],{"href":19,"rel":3419},[21],[10,3421,26],{},[28,3423,31],{"id":30},[10,3425,34],{},[10,3427,37],{},[10,3429,40],{},[42,3431,3432,3434,3436,3438,3440],{},[45,3433,47],{},[45,3435,50],{},[45,3437,53],{},[45,3439,56],{},[45,3441,59],{},[28,3443,47],{"id":47},[10,3445,64],{},[10,3447,67],{},[69,3449,3450],{"className":71,"code":72,"language":73,"meta":74,"style":74},[76,3451,3452,3456,3460,3464,3468,3472,3476,3480,3484,3488,3492,3496,3500],{"__ignoreMap":74},[79,3453,3454],{"class":81,"line":82},[79,3455,85],{},[79,3457,3458],{"class":81,"line":88},[79,3459,91],{},[79,3461,3462],{"class":81,"line":94},[79,3463,97],{},[79,3465,3466],{"class":81,"line":100},[79,3467,104],{"emptyLinePlaceholder":103},[79,3469,3470],{"class":81,"line":107},[79,3471,110],{},[79,3473,3474],{"class":81,"line":113},[79,3475,116],{},[79,3477,3478],{"class":81,"line":119},[79,3479,97],{},[79,3481,3482],{"class":81,"line":124},[79,3483,104],{"emptyLinePlaceholder":103},[79,3485,3486],{"class":81,"line":129},[79,3487,132],{},[79,3489,3490],{"class":81,"line":135},[79,3491,138],{},[79,3493,3494],{"class":81,"line":141},[79,3495,97],{},[79,3497,3498],{"class":81,"line":146},[79,3499,104],{"emptyLinePlaceholder":103},[79,3501,3502],{"class":81,"line":151},[79,3503,154],{},[10,3505,157],{},[159,3507,3508,3512,3518,3524],{},[45,3509,3510,166],{},[76,3511,165],{},[45,3513,3514,171,3516,175],{},[76,3515,165],{},[76,3517,174],{},[45,3519,3520,171,3522,175],{},[76,3521,174],{},[76,3523,182],{},[45,3525,3526,187,3528,187,3530,192],{},[76,3527,182],{},[76,3529,174],{},[76,3531,165],{},[10,3533,195],{},[28,3535,50],{"id":198},[10,3537,201],{},[10,3539,204],{},[42,3541,3542,3544,3546,3548],{},[45,3543,209],{},[45,3545,212],{},[45,3547,215],{},[45,3549,218],{},[10,3551,221],{},[69,3553,3554],{"className":71,"code":224,"language":73,"meta":74,"style":74},[76,3555,3556,3560,3564,3568,3572,3576,3580,3584],{"__ignoreMap":74},[79,3557,3558],{"class":81,"line":82},[79,3559,231],{},[79,3561,3562],{"class":81,"line":88},[79,3563,236],{},[79,3565,3566],{"class":81,"line":94},[79,3567,241],{},[79,3569,3570],{"class":81,"line":100},[79,3571,246],{},[79,3573,3574],{"class":81,"line":107},[79,3575,104],{"emptyLinePlaceholder":103},[79,3577,3578],{"class":81,"line":113},[79,3579,255],{},[79,3581,3582],{"class":81,"line":119},[79,3583,260],{},[79,3585,3586],{"class":81,"line":124},[79,3587,265],{},[10,3589,268],{},[28,3591,53],{"id":53},[10,3593,273],{},[10,3595,276],{},[42,3597,3598,3602,3604],{},[45,3599,3600,284],{},[76,3601,283],{},[45,3603,287],{},[45,3605,290],{},[10,3607,3608,295],{},[76,3609,283],{},[10,3611,298],{},[28,3613,56],{"id":56},[10,3615,303],{},[42,3617,3618,3626,3630],{},[45,3619,308,3620,187,3622,187,3624],{},[76,3621,311],{},[76,3623,314],{},[76,3625,317],{},[45,3627,3628,323],{},[76,3629,322],{},[45,3631,3632,284],{},[76,3633,328],{},[10,3635,331],{},[10,3637,334],{},[28,3639,59],{"id":59},[10,3641,339],{},[10,3643,342],{},[159,3645,3646,3648,3650,3652,3654],{},[45,3647,347],{},[45,3649,350],{},[45,3651,353],{},[45,3653,356],{},[45,3655,359],{},[28,3657,362],{"id":362},[10,3659,365],{},[69,3661,3662],{"className":71,"code":368,"language":73,"meta":74,"style":74},[76,3663,3664,3668,3672,3676,3680,3684,3688,3692,3696,3700,3704,3708,3712,3716,3720],{"__ignoreMap":74},[79,3665,3666],{"class":81,"line":82},[79,3667,375],{},[79,3669,3670],{"class":81,"line":88},[79,3671,104],{"emptyLinePlaceholder":103},[79,3673,3674],{"class":81,"line":94},[79,3675,384],{},[79,3677,3678],{"class":81,"line":100},[79,3679,389],{},[79,3681,3682],{"class":81,"line":107},[79,3683,394],{},[79,3685,3686],{"class":81,"line":113},[79,3687,104],{"emptyLinePlaceholder":103},[79,3689,3690],{"class":81,"line":119},[79,3691,403],{},[79,3693,3694],{"class":81,"line":124},[79,3695,408],{},[79,3697,3698],{"class":81,"line":129},[79,3699,413],{},[79,3701,3702],{"class":81,"line":135},[79,3703,104],{"emptyLinePlaceholder":103},[79,3705,3706],{"class":81,"line":141},[79,3707,422],{},[79,3709,3710],{"class":81,"line":146},[79,3711,427],{},[79,3713,3714],{"class":81,"line":151},[79,3715,413],{},[79,3717,3718],{"class":81,"line":434},[79,3719,104],{"emptyLinePlaceholder":103},[79,3721,3722],{"class":81,"line":439},[79,3723,442],{},[10,3725,445],{},[69,3727,3729],{"className":3728,"code":450,"language":451,"meta":74},[449],[76,3730,450],{"__ignoreMap":74},[10,3732,456,3733,460,3735,464],{},[76,3734,459],{},[76,3736,463],{},[10,3738,467,3739,470,3741,473],{},[76,3740,322],{},[76,3742,283],{},[28,3744,476],{"id":476},[42,3746,3747,3749,3751,3753,3755,3757],{},[45,3748,481],{},[45,3750,484],{},[45,3752,487],{},[45,3754,490],{},[45,3756,493],{},[45,3758,496],{},[10,3760,499],{},[10,3762,502,3763,508],{},[17,3764,507],{"href":505,"rel":3765},[21],[510,3767,512],{},{"title":74,"searchDepth":88,"depth":88,"links":3769},[3770,3771,3772,3773,3774,3775,3776,3777],{"id":30,"depth":88,"text":31},{"id":47,"depth":88,"text":47},{"id":198,"depth":88,"text":50},{"id":53,"depth":88,"text":53},{"id":56,"depth":88,"text":56},{"id":59,"depth":88,"text":59},{"id":362,"depth":88,"text":362},{"id":476,"depth":88,"text":476},{},{"title":5,"description":523},[531],{"id":3782,"title":3783,"body":3784,"description":4200,"extension":524,"meta":4201,"navigation":103,"path":4202,"publishDate":4203,"published":103,"seo":4204,"stem":4205,"tags":4206,"thumbnail":4207,"updated":4203,"__hash__":4208},"articles\u002Farticles\u002F2024\u002Fhow-to-use-javascript-built-in-objects.md","JavaScriptのビルトインオブジェクトのメソッドをどう使うか",{"type":7,"value":3785,"toc":4192},[3786,3788,3791,3794,3798,3801,3813,3822,3826,3836,3863,3880,3888,3891,3898,3938,3949,3957,3970,3994,3998,4005,4043,4049,4054,4075,4078,4087,4125,4135,4153,4155,4187,4190],[10,3787,12],{},[10,3789,3790],{},"今回は、プロジェクトで「なるほど」と思った、JavaScriptのビルトインオブジェクトのメソッドの使い方を紹介します。",[10,3792,3793],{},"具体的には、オブジェクトが自身のプロパティを持っているか、安全に確認する方法です。仕組みを知っておくと、オブジェクトに同名のメソッドが定義されている場合も意図した判定ができます。",[28,3795,3797],{"id":3796},"ビルトインオブジェクトってなに","「ビルトインオブジェクト」ってなに？",[10,3799,3800],{},"ビルトインオブジェクトは「組み込みオブジェクト」とも呼ばれ、JavaScriptの実行環境にあらかじめ用意されているオブジェクトです。",[10,3802,3803,187,3806,187,3809,3812],{},[76,3804,3805],{},"Object",[76,3807,3808],{},"Array",[76,3810,3811],{},"String"," など、さまざまな種類があります。",[10,3814,3815,3816,3821],{},"詳しくは、",[17,3817,3820],{"href":3818,"rel":3819},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects",[21],"MDNの標準組み込みオブジェクト","を参照してください。",[28,3823,3825],{"id":3824},"hasownpropertyをインスタンスから呼び出す","hasOwnPropertyをインスタンスから呼び出す",[10,3827,3828,3829,3831,3832,3835],{},"まずは、オブジェクト自身が ",[76,3830,784],{}," プロパティを持っているか、",[76,3833,3834],{},"hasOwnProperty()"," で確認してみます。",[69,3837,3839],{"className":71,"code":3838,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n}\n\nobj.hasOwnProperty('name') \u002F\u002F true\n",[76,3840,3841,3846,3850,3854,3858],{"__ignoreMap":74},[79,3842,3843],{"class":81,"line":82},[79,3844,3845],{},"const obj = {\n",[79,3847,3848],{"class":81,"line":88},[79,3849,756],{},[79,3851,3852],{"class":81,"line":94},[79,3853,97],{},[79,3855,3856],{"class":81,"line":100},[79,3857,104],{"emptyLinePlaceholder":103},[79,3859,3860],{"class":81,"line":107},[79,3861,3862],{},"obj.hasOwnProperty('name') \u002F\u002F true\n",[10,3864,3865,3866,3869,3870,3873,3874,3876,3877,3879],{},"オブジェクトリテラルで作成した ",[76,3867,3868],{},"obj"," は、通常 ",[76,3871,3872],{},"Object.prototype"," を継承しています。そのため、",[76,3875,3872],{}," に定義されている ",[76,3878,3834],{}," を呼び出せます。",[10,3881,3882,3883,508],{},"プロトタイプ継承については、",[17,3884,3887],{"href":3885,"rel":3886},"https:\u002F\u002Fja.javascript.info\u002Fprototype-inheritance",[21],"JavaScript.infoのプロトタイプ継承",[28,3889,3890],{"id":3890},"インスタンスから呼び出す場合の問題",[10,3892,3893,3894,3897],{},"では、オブジェクト自身が ",[76,3895,3896],{},"hasOwnProperty"," という同名のメソッドを持っていたらどうなるでしょうか。",[69,3899,3901],{"className":71,"code":3900,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nobj.hasOwnProperty('name') \u002F\u002F 「Hello」と出力される\n",[76,3902,3903,3907,3911,3916,3921,3925,3929,3933],{"__ignoreMap":74},[79,3904,3905],{"class":81,"line":82},[79,3906,3845],{},[79,3908,3909],{"class":81,"line":88},[79,3910,756],{},[79,3912,3913],{"class":81,"line":94},[79,3914,3915],{},"  hasOwnProperty() {\n",[79,3917,3918],{"class":81,"line":100},[79,3919,3920],{},"    console.log('Hello')\n",[79,3922,3923],{"class":81,"line":107},[79,3924,632],{},[79,3926,3927],{"class":81,"line":113},[79,3928,97],{},[79,3930,3931],{"class":81,"line":119},[79,3932,104],{"emptyLinePlaceholder":103},[79,3934,3935],{"class":81,"line":124},[79,3936,3937],{},"obj.hasOwnProperty('name') \u002F\u002F 「Hello」と出力される\n",[10,3939,3940,3941,3944,3945,3948],{},"先ほどは ",[76,3942,3943],{},"true"," を返していた呼び出しが、今度は ",[76,3946,3947],{},"Hello"," を出力しました。",[10,3950,3951,3953,3954,3956],{},[76,3952,3868],{}," 自身の ",[76,3955,3896],{}," が、プロトタイプから継承した同名メソッドよりも優先されたためです。外部から受け取ったオブジェクトなど、自分で構造を完全に管理できない値では、インスタンスから直接呼び出す方法は意図しない結果につながる可能性があります。",[10,3958,3959,3960,3963,3964,3966,3967,3969],{},"また、",[76,3961,3962],{},"Object.create(null)"," で作ったオブジェクトは ",[76,3965,3872],{}," を継承しないため、そもそも ",[76,3968,3834],{}," を持っていません。",[69,3971,3973],{"className":71,"code":3972,"language":73,"meta":74,"style":74},"const obj = Object.create(null)\nobj.name = 'Yuri'\n\nobj.hasOwnProperty('name') \u002F\u002F TypeError\n",[76,3974,3975,3980,3985,3989],{"__ignoreMap":74},[79,3976,3977],{"class":81,"line":82},[79,3978,3979],{},"const obj = Object.create(null)\n",[79,3981,3982],{"class":81,"line":88},[79,3983,3984],{},"obj.name = 'Yuri'\n",[79,3986,3987],{"class":81,"line":94},[79,3988,104],{"emptyLinePlaceholder":103},[79,3990,3991],{"class":81,"line":100},[79,3992,3993],{},"obj.hasOwnProperty('name') \u002F\u002F TypeError\n",[28,3995,3997],{"id":3996},"objecthasownを使う","Object.hasOwnを使う",[10,3999,4000,4001,4004],{},"現在は、オブジェクト自身のプロパティを調べる場合、静的メソッドの ",[76,4002,4003],{},"Object.hasOwn()"," を使うと簡潔です。",[69,4006,4008],{"className":71,"code":4007,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nObject.hasOwn(obj, 'name') \u002F\u002F true\n",[76,4009,4010,4014,4018,4022,4026,4030,4034,4038],{"__ignoreMap":74},[79,4011,4012],{"class":81,"line":82},[79,4013,3845],{},[79,4015,4016],{"class":81,"line":88},[79,4017,756],{},[79,4019,4020],{"class":81,"line":94},[79,4021,3915],{},[79,4023,4024],{"class":81,"line":100},[79,4025,3920],{},[79,4027,4028],{"class":81,"line":107},[79,4029,632],{},[79,4031,4032],{"class":81,"line":113},[79,4033,97],{},[79,4035,4036],{"class":81,"line":119},[79,4037,104],{"emptyLinePlaceholder":103},[79,4039,4040],{"class":81,"line":124},[79,4041,4042],{},"Object.hasOwn(obj, 'name') \u002F\u002F true\n",[10,4044,4045,4046,4048],{},"第1引数に調べたいオブジェクト、第2引数にプロパティ名を渡します。対象のオブジェクトに同名の ",[76,4047,3896],{}," が定義されていても影響を受けません。",[10,4050,4051,4053],{},[76,4052,3962],{}," で作ったオブジェクトにも使用できます。",[69,4055,4057],{"className":71,"code":4056,"language":73,"meta":74,"style":74},"const obj = Object.create(null)\nobj.name = 'Yuri'\n\nObject.hasOwn(obj, 'name') \u002F\u002F true\n",[76,4058,4059,4063,4067,4071],{"__ignoreMap":74},[79,4060,4061],{"class":81,"line":82},[79,4062,3979],{},[79,4064,4065],{"class":81,"line":88},[79,4066,3984],{},[79,4068,4069],{"class":81,"line":94},[79,4070,104],{"emptyLinePlaceholder":103},[79,4072,4073],{"class":81,"line":100},[79,4074,4042],{},[28,4076,4077],{"id":4077},"古い実行環境も考慮する場合",[10,4079,4080,4082,4083,4086],{},[76,4081,4003],{}," を利用できない古い実行環境まで考慮する場合は、",[76,4084,4085],{},"Object.prototype.hasOwnProperty.call()"," という書き方もできます。",[69,4088,4090],{"className":71,"code":4089,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nObject.prototype.hasOwnProperty.call(obj, 'name') \u002F\u002F true\n",[76,4091,4092,4096,4100,4104,4108,4112,4116,4120],{"__ignoreMap":74},[79,4093,4094],{"class":81,"line":82},[79,4095,3845],{},[79,4097,4098],{"class":81,"line":88},[79,4099,756],{},[79,4101,4102],{"class":81,"line":94},[79,4103,3915],{},[79,4105,4106],{"class":81,"line":100},[79,4107,3920],{},[79,4109,4110],{"class":81,"line":107},[79,4111,632],{},[79,4113,4114],{"class":81,"line":113},[79,4115,97],{},[79,4117,4118],{"class":81,"line":119},[79,4119,104],{"emptyLinePlaceholder":103},[79,4121,4122],{"class":81,"line":124},[79,4123,4124],{},"Object.prototype.hasOwnProperty.call(obj, 'name') \u002F\u002F true\n",[10,4126,4127,4130,4131,4134],{},[76,4128,4129],{},"call()"," の第1引数に ",[76,4132,4133],{},"this"," として扱うオブジェクトを指定し、それ以降の引数を元のメソッドへ渡しています。",[10,4136,4137,4138,4140,4141,4143,4144,4146,4147,4149,4150,4152],{},"この例では ",[76,4139,3872],{}," が持つ本来の ",[76,4142,3834],{}," を直接取得し、",[76,4145,3868],{}," を ",[76,4148,4133],{}," として呼び出しています。そのため、",[76,4151,3868],{}," 自身に定義された同名メソッドの影響を受けません。",[28,4154,476],{"id":476},[42,4156,4157,4163,4166,4173,4180],{},[45,4158,4159,4160,4162],{},"オブジェクトリテラルは通常、",[76,4161,3872],{}," のメソッドを継承する",[45,4164,4165],{},"オブジェクト自身が同名メソッドを持つと、継承したメソッドは隠される",[45,4167,4168,3963,4170,4172],{},[76,4169,3962],{},[76,4171,3834],{}," を継承しない",[45,4174,4175,4176,4179],{},"自身のプロパティを確認する場合は、基本的に ",[76,4177,4178],{},"Object.hasOwn(obj, property)"," を使う",[45,4181,4182,4183,4186],{},"古い実行環境も考慮する場合は、",[76,4184,4185],{},"Object.prototype.hasOwnProperty.call(obj, property)"," を使える",[10,4188,4189],{},"オブジェクトの出所や構造を完全には把握できない場合も、インスタンスの同名メソッドに依存しない呼び出し方を選ぶと安全です。",[510,4191,512],{},{"title":74,"searchDepth":88,"depth":88,"links":4193},[4194,4195,4196,4197,4198,4199],{"id":3796,"depth":88,"text":3797},{"id":3824,"depth":88,"text":3825},{"id":3890,"depth":88,"text":3890},{"id":3996,"depth":88,"text":3997},{"id":4077,"depth":88,"text":4077},{"id":476,"depth":88,"text":476},"JavaScriptでオブジェクト自身のプロパティを安全に確認する方法を、hasOwnPropertyとObject.hasOwnの違いから整理します。",{},"\u002Farticles\u002F2024\u002Fhow-to-use-javascript-built-in-objects","2024-11-24",{"title":3783,"description":4200},"articles\u002F2024\u002Fhow-to-use-javascript-built-in-objects",[531],"\u002Fimages\u002Farticles\u002Fhow-to-use-javascript-built-in-objects.png","nujvvO9Kj5xXhtbuHUxO1l6JeNtgWjuj3S4rljZKkdU",{"id":4210,"title":4211,"body":4212,"description":4592,"extension":524,"meta":4593,"navigation":103,"path":4594,"publishDate":4595,"published":103,"seo":4596,"stem":4597,"tags":4598,"thumbnail":4599,"updated":4595,"__hash__":4600},"articles\u002Farticles\u002F2024\u002Fdescribe-javascript-deepcopy.md","JavaScriptのディープコピーとは？",{"type":7,"value":4213,"toc":4585},[4214,4216,4219,4222,4226,4229,4232,4241,4244,4251,4302,4316,4331,4334,4358,4361,4370,4374,4381,4427,4432,4447,4450,4474,4489,4496,4505,4509,4512,4521,4524,4549,4555,4557,4580,4583],[10,4215,12],{},[10,4217,4218],{},"今回は、JavaScriptにおけるオブジェクトのディープコピーについて紹介します。",[10,4220,4221],{},"シャローコピーとの違いや実装方法を理解しておくと、コピー先の変更が意図せずコピー元へ影響する問題を避けられます。",[28,4223,4225],{"id":4224},"ディープコピーとは","ディープコピーとは？",[10,4227,4228],{},"ディープコピーとは、コピー元とコピー先が、内部にあるオブジェクトの参照を共有しないコピーのことです。",[10,4230,4231],{},"たとえば、入れ子になったオブジェクトをコピーしたあと、コピー先の内側にある値を変更しても、コピー元の値には影響しません。",[10,4233,4234,4235,4240],{},"詳しい定義は、",[17,4236,4239],{"href":4237,"rel":4238},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FGlossary\u002FDeep_copy",[21],"MDNのディープコピー","も参照してください。",[28,4242,4243],{"id":4243},"シャローコピーでは参照が共有される",[10,4245,4246,4247,4250],{},"まずは、",[76,4248,4249],{},"Object.assign()"," を使ったシャローコピーを確認します。",[69,4252,4254],{"className":71,"code":4253,"language":73,"meta":74,"style":74},"const original = {\n  user: {\n    name: 'Yuri',\n  },\n  settings: {\n    theme: 'light',\n  },\n}\n\nconst shallowCopy = Object.assign({}, original)\n",[76,4255,4256,4261,4266,4271,4275,4280,4285,4289,4293,4297],{"__ignoreMap":74},[79,4257,4258],{"class":81,"line":82},[79,4259,4260],{},"const original = {\n",[79,4262,4263],{"class":81,"line":88},[79,4264,4265],{},"  user: {\n",[79,4267,4268],{"class":81,"line":94},[79,4269,4270],{},"    name: 'Yuri',\n",[79,4272,4273],{"class":81,"line":100},[79,4274,632],{},[79,4276,4277],{"class":81,"line":107},[79,4278,4279],{},"  settings: {\n",[79,4281,4282],{"class":81,"line":113},[79,4283,4284],{},"    theme: 'light',\n",[79,4286,4287],{"class":81,"line":119},[79,4288,632],{},[79,4290,4291],{"class":81,"line":124},[79,4292,97],{},[79,4294,4295],{"class":81,"line":129},[79,4296,104],{"emptyLinePlaceholder":103},[79,4298,4299],{"class":81,"line":135},[79,4300,4301],{},"const shallowCopy = Object.assign({}, original)\n",[10,4303,4304,4307,4308,4311,4312,4315],{},[76,4305,4306],{},"Object.assign({}, original)"," で新しい外側のオブジェクトは作られますが、",[76,4309,4310],{},"user"," や ",[76,4313,4314],{},"settings"," はコピー元と同じオブジェクトを参照しています。",[69,4317,4319],{"className":71,"code":4318,"language":73,"meta":74,"style":74},"console.log(original === shallowCopy) \u002F\u002F false\nconsole.log(original.user === shallowCopy.user) \u002F\u002F true\n",[76,4320,4321,4326],{"__ignoreMap":74},[79,4322,4323],{"class":81,"line":82},[79,4324,4325],{},"console.log(original === shallowCopy) \u002F\u002F false\n",[79,4327,4328],{"class":81,"line":88},[79,4329,4330],{},"console.log(original.user === shallowCopy.user) \u002F\u002F true\n",[10,4332,4333],{},"そのため、コピー先にある入れ子の値を変更すると、コピー元にも影響します。",[69,4335,4337],{"className":71,"code":4336,"language":73,"meta":74,"style":74},"shallowCopy.user.name = 'Kohei'\n\nconsole.log(original.user.name) \u002F\u002F 「Kohei」\nconsole.log(shallowCopy.user.name) \u002F\u002F 「Kohei」\n",[76,4338,4339,4344,4348,4353],{"__ignoreMap":74},[79,4340,4341],{"class":81,"line":82},[79,4342,4343],{},"shallowCopy.user.name = 'Kohei'\n",[79,4345,4346],{"class":81,"line":88},[79,4347,104],{"emptyLinePlaceholder":103},[79,4349,4350],{"class":81,"line":94},[79,4351,4352],{},"console.log(original.user.name) \u002F\u002F 「Kohei」\n",[79,4354,4355],{"class":81,"line":100},[79,4356,4357],{},"console.log(shallowCopy.user.name) \u002F\u002F 「Kohei」\n",[10,4359,4360],{},"オブジェクトスプレッド構文も、同様にシャローコピーです。",[69,4362,4364],{"className":71,"code":4363,"language":73,"meta":74,"style":74},"const shallowCopy = { ...original }\n",[76,4365,4366],{"__ignoreMap":74},[79,4367,4368],{"class":81,"line":82},[79,4369,4363],{},[28,4371,4373],{"id":4372},"structuredcloneでディープコピーする","structuredCloneでディープコピーする",[10,4375,4376,4377,4380],{},"ディープコピーには、",[76,4378,4379],{},"structuredClone()"," を利用できます。",[69,4382,4384],{"className":71,"code":4383,"language":73,"meta":74,"style":74},"const original = {\n  user: {\n    name: 'Yuri',\n  },\n  settings: {\n    theme: 'light',\n  },\n}\n\nconst deepCopy = structuredClone(original)\n",[76,4385,4386,4390,4394,4398,4402,4406,4410,4414,4418,4422],{"__ignoreMap":74},[79,4387,4388],{"class":81,"line":82},[79,4389,4260],{},[79,4391,4392],{"class":81,"line":88},[79,4393,4265],{},[79,4395,4396],{"class":81,"line":94},[79,4397,4270],{},[79,4399,4400],{"class":81,"line":100},[79,4401,632],{},[79,4403,4404],{"class":81,"line":107},[79,4405,4279],{},[79,4407,4408],{"class":81,"line":113},[79,4409,4284],{},[79,4411,4412],{"class":81,"line":119},[79,4413,632],{},[79,4415,4416],{"class":81,"line":124},[79,4417,97],{},[79,4419,4420],{"class":81,"line":129},[79,4421,104],{"emptyLinePlaceholder":103},[79,4423,4424],{"class":81,"line":135},[79,4425,4426],{},"const deepCopy = structuredClone(original)\n",[10,4428,4429,4431],{},[76,4430,4379],{}," で作ったコピーは、入れ子のオブジェクトもコピー元とは異なる参照になります。",[69,4433,4435],{"className":71,"code":4434,"language":73,"meta":74,"style":74},"console.log(original === deepCopy) \u002F\u002F false\nconsole.log(original.user === deepCopy.user) \u002F\u002F false\n",[76,4436,4437,4442],{"__ignoreMap":74},[79,4438,4439],{"class":81,"line":82},[79,4440,4441],{},"console.log(original === deepCopy) \u002F\u002F false\n",[79,4443,4444],{"class":81,"line":88},[79,4445,4446],{},"console.log(original.user === deepCopy.user) \u002F\u002F false\n",[10,4448,4449],{},"コピー先を変更しても、コピー元には影響しません。",[69,4451,4453],{"className":71,"code":4452,"language":73,"meta":74,"style":74},"deepCopy.user.name = 'Kohei'\n\nconsole.log(original.user.name) \u002F\u002F 「Yuri」\nconsole.log(deepCopy.user.name) \u002F\u002F 「Kohei」\n",[76,4454,4455,4460,4464,4469],{"__ignoreMap":74},[79,4456,4457],{"class":81,"line":82},[79,4458,4459],{},"deepCopy.user.name = 'Kohei'\n",[79,4461,4462],{"class":81,"line":88},[79,4463,104],{"emptyLinePlaceholder":103},[79,4465,4466],{"class":81,"line":94},[79,4467,4468],{},"console.log(original.user.name) \u002F\u002F 「Yuri」\n",[79,4470,4471],{"class":81,"line":100},[79,4472,4473],{},"console.log(deepCopy.user.name) \u002F\u002F 「Kohei」\n",[10,4475,4476,4478,4479,187,4482,187,4485,4488],{},[76,4477,4379],{}," は通常のオブジェクトや配列だけでなく、",[76,4480,4481],{},"Date",[76,4483,4484],{},"Map",[76,4486,4487],{},"Set"," など、構造化複製アルゴリズムが対応している型をコピーできます。また、循環参照を持つオブジェクトにも対応しています。",[10,4490,4491,4492,4495],{},"ただし、関数など構造化複製できない値が含まれている場合は ",[76,4493,4494],{},"DataCloneError"," が発生します。すべてのJavaScriptの値を無条件にコピーできるわけではありません。",[10,4497,4498,4499,4504],{},"詳しい対応範囲は、",[17,4500,4503],{"href":4501,"rel":4502},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002FstructuredClone",[21],"MDNのstructuredClone()","を確認してください。",[28,4506,4508],{"id":4507},"jsonを使ったディープコピーの注意点","JSONを使ったディープコピーの注意点",[10,4510,4511],{},"単純なデータだけを扱う場合、JSONへ変換して戻す方法もあります。",[69,4513,4515],{"className":71,"code":4514,"language":73,"meta":74,"style":74},"const deepCopy = JSON.parse(JSON.stringify(original))\n",[76,4516,4517],{"__ignoreMap":74},[79,4518,4519],{"class":81,"line":82},[79,4520,4514],{},[10,4522,4523],{},"ただし、この方法はJSONとして表現できる値に限られます。",[42,4525,4526,4531,4540,4546],{},[45,4527,4528,4530],{},[76,4529,4481],{}," は文字列へ変換される",[45,4532,4533,4535,4536,4539],{},[76,4534,806],{},"、関数、",[76,4537,4538],{},"Symbol"," などは正しく保持できない",[45,4541,4542,4545],{},[76,4543,4544],{},"BigInt"," を含むと例外が発生する",[45,4547,4548],{},"循環参照を持つオブジェクトは変換できない",[10,4550,4551,4552,4554],{},"対象がJSON互換のデータだと分かっている場合には使えますが、一般的なディープコピーとしては ",[76,4553,4379],{}," の方が意図を表しやすく、扱える型も多くなります。",[28,4556,476],{"id":476},[42,4558,4559,4564,4567,4572,4577],{},[45,4560,4561,4563],{},[76,4562,4249],{}," とオブジェクトスプレッド構文はシャローコピーになる",[45,4565,4566],{},"シャローコピーでは、入れ子のオブジェクトの参照がコピー元と共有される",[45,4568,4569,4571],{},[76,4570,4379],{}," を使うと、対応している値をディープコピーできる",[45,4573,4574,4576],{},[76,4575,4379],{}," でも、関数などコピーできない値がある",[45,4578,4579],{},"JSONによるコピーは、JSON互換データだけに限定して使う",[10,4581,4582],{},"コピー方法を選ぶときは、対象のデータ構造と、コピー後にどの階層まで独立して変更したいかを確認することが大切です。",[510,4584,512],{},{"title":74,"searchDepth":88,"depth":88,"links":4586},[4587,4588,4589,4590,4591],{"id":4224,"depth":88,"text":4225},{"id":4243,"depth":88,"text":4243},{"id":4372,"depth":88,"text":4373},{"id":4507,"depth":88,"text":4508},{"id":476,"depth":88,"text":476},"JavaScriptのシャローコピーとディープコピーの違いを確認し、structuredCloneを使った実装方法と注意点を整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-javascript-deepcopy","2024-11-23",{"title":4211,"description":4592},"articles\u002F2024\u002Fdescribe-javascript-deepcopy",[531],"\u002Fimages\u002Farticles\u002Fdescribe-javascript-deepcopy.png","dtSQ5LrS1Kfo1hFYE2MzMKOvrhU_5JGE1X1eQ9eHhIY",{"id":4602,"title":4603,"body":4604,"description":5018,"extension":524,"meta":5019,"navigation":103,"path":5020,"publishDate":5021,"published":103,"seo":5022,"stem":5023,"tags":5024,"thumbnail":5025,"updated":5026,"__hash__":5027},"articles\u002Farticles\u002F2024\u002Fdescribe-behavior-javascript-this.md","JavaScriptのthisの挙動について呼び出し元で整理する",{"type":7,"value":4605,"toc":5010},[4606,4608,4614,4618,4623,4629,4632,4635,4641,4649,4651,4657,4663,4672,4675,4715,4722,4741,4743,4749,4769,4772,4809,4821,4842,4848,4851,4854,4896,4914,4924,4938,4948,4963,4965,4970,5003,5008],[10,4607,12],{},[10,4609,4610,4611,4613],{},"今回は、プロジェクトや個人開発で振り回されることが多かったJavaScriptの ",[76,4612,4133],{}," の挙動について、あらためて振り返ります。自分をはじめ、初学者の方も知っておくと開発が楽になるかと思います。",[28,4615,4617],{"id":4616},"そもそもthisってなんだ","そもそも「this」ってなんだ？",[10,4619,4620,4622],{},[76,4621,4133],{}," は、関数が実行されたときのコンテキストを参照するためのキーワードです。",[10,4624,4625,4626,4628],{},"同じ関数であっても、どのように呼び出されたかによって ",[76,4627,4133],{}," が参照する値は変わります。この特徴が便利なところでもあり、難しいところでもあります。",[10,4630,4631],{},"それでは、呼び出し方によって参照先がどう変わるのか見てみましょう。",[28,4633,4634],{"id":4634},"使用する場所ごとのthis",[10,4636,4637,4638,4640],{},"この記事では、",[76,4639,4133],{}," を使用するケースを次の2つに分けて確認します。",[42,4642,4643,4646],{},[45,4644,4645],{},"オブジェクトのメソッドとして呼び出す場合",[45,4647,4648],{},"通常の関数として呼び出す場合",[28,4650,4645],{"id":4645},[10,4652,4653,4654,4656],{},"オブジェクトのメソッドとして呼び出した場合、",[76,4655,4133],{}," は基本的に呼び出し元のオブジェクトを参照します。",[10,4658,4659,4660,4662],{},"ここでいう呼び出し元のオブジェクトとは、次の例では ",[76,4661,3868],{}," のことです。",[69,4664,4666],{"className":71,"code":4665,"language":73,"meta":74,"style":74},"const obj = {}\n",[76,4667,4668],{"__ignoreMap":74},[79,4669,4670],{"class":81,"line":82},[79,4671,4665],{},[10,4673,4674],{},"実際に挙動を見てみましょう。",[69,4676,4678],{"className":71,"code":4677,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n  message: function () {\n    console.log('Hello ' + this.name)\n  },\n}\n\nobj.message()\n",[76,4679,4680,4684,4688,4693,4698,4702,4706,4710],{"__ignoreMap":74},[79,4681,4682],{"class":81,"line":82},[79,4683,3845],{},[79,4685,4686],{"class":81,"line":88},[79,4687,756],{},[79,4689,4690],{"class":81,"line":94},[79,4691,4692],{},"  message: function () {\n",[79,4694,4695],{"class":81,"line":100},[79,4696,4697],{},"    console.log('Hello ' + this.name)\n",[79,4699,4700],{"class":81,"line":107},[79,4701,632],{},[79,4703,4704],{"class":81,"line":113},[79,4705,97],{},[79,4707,4708],{"class":81,"line":119},[79,4709,104],{"emptyLinePlaceholder":103},[79,4711,4712],{"class":81,"line":124},[79,4713,4714],{},"obj.message()\n",[10,4716,4717,4718,4721],{},"この例では、",[76,4719,4720],{},"Hello Yuri"," と出力されます。",[10,4723,4724,4727,4728,4730,4731,4733,4734,4730,4737,4740],{},[76,4725,4726],{},"obj.message()"," という形で呼び出しているため、メソッド内の ",[76,4729,4133],{}," は ",[76,4732,3868],{}," を参照します。したがって、",[76,4735,4736],{},"this.name",[76,4738,4739],{},"obj.name"," として評価されます。",[28,4742,4648],{"id":4648},[10,4744,4745,4746,4748],{},"通常の関数として呼び出した場合、",[76,4747,4133],{}," の値は実行モードによって異なります。",[42,4750,4751,4761],{},[45,4752,4753,4754,4756,4757,4760],{},"非厳格モードのブラウザでは、",[76,4755,4133],{}," はグローバルオブジェクトの ",[76,4758,4759],{},"window"," を参照する",[45,4762,4763,4764,4730,4766,4768],{},"厳格モードやES Modulesでは、",[76,4765,4133],{},[76,4767,806],{}," になる",[10,4770,4771],{},"次のコードは、ブラウザの非厳格モードで実行する例です。",[69,4773,4775],{"className":71,"code":4774,"language":73,"meta":74,"style":74},"window.name = 'Yuri'\n\nfunction message() {\n  console.log('Hello ' + this.name)\n}\n\nmessage()\n",[76,4776,4777,4782,4786,4791,4796,4800,4804],{"__ignoreMap":74},[79,4778,4779],{"class":81,"line":82},[79,4780,4781],{},"window.name = 'Yuri'\n",[79,4783,4784],{"class":81,"line":88},[79,4785,104],{"emptyLinePlaceholder":103},[79,4787,4788],{"class":81,"line":94},[79,4789,4790],{},"function message() {\n",[79,4792,4793],{"class":81,"line":100},[79,4794,4795],{},"  console.log('Hello ' + this.name)\n",[79,4797,4798],{"class":81,"line":107},[79,4799,97],{},[79,4801,4802],{"class":81,"line":113},[79,4803,104],{"emptyLinePlaceholder":103},[79,4805,4806],{"class":81,"line":119},[79,4807,4808],{},"message()\n",[10,4810,4811,4812,4814,4815,4818,4819,4721],{},"非厳格モードでは ",[76,4813,4736],{}," が ",[76,4816,4817],{},"window.name"," として評価されるため、",[76,4820,4720],{},[4822,4823,4824],"blockquote",{},[10,4825,4826,4311,4829,4831,4832,4834,4835,4838,4839,4841],{},[76,4827,4828],{},"let",[76,4830,1507],{}," で宣言した変数は、",[76,4833,4759],{}," オブジェクトのプロパティとして追加されません。一方、ブラウザでトップレベルに ",[76,4836,4837],{},"var"," を使って宣言した変数は、",[76,4840,4759],{}," のプロパティになります。",[10,4843,4844,4845,4847],{},"現在のフロントエンド開発ではES Modulesが広く使われています。ES Modulesは自動的に厳格モードとして扱われるため、通常の関数呼び出しで ",[76,4846,4133],{}," に依存する実装は避けた方が安全です。",[28,4849,4850],{"id":4850},"オブジェクトのメソッドを変数へ代入した場合",[10,4852,4853],{},"ここまでを踏まえて、オブジェクトのメソッドを変数へ代入した場合の挙動を見てみましょう。",[69,4855,4857],{"className":71,"code":4856,"language":73,"meta":74,"style":74},"const obj = {\n  name: 'Yuri',\n  message: function () {\n    console.log('Hello ' + this.name)\n  },\n}\n\nconst message = obj.message\nmessage()\n",[76,4858,4859,4863,4867,4871,4875,4879,4883,4887,4892],{"__ignoreMap":74},[79,4860,4861],{"class":81,"line":82},[79,4862,3845],{},[79,4864,4865],{"class":81,"line":88},[79,4866,756],{},[79,4868,4869],{"class":81,"line":94},[79,4870,4692],{},[79,4872,4873],{"class":81,"line":100},[79,4874,4697],{},[79,4876,4877],{"class":81,"line":107},[79,4878,632],{},[79,4880,4881],{"class":81,"line":113},[79,4882,97],{},[79,4884,4885],{"class":81,"line":119},[79,4886,104],{"emptyLinePlaceholder":103},[79,4888,4889],{"class":81,"line":124},[79,4890,4891],{},"const message = obj.message\n",[79,4893,4894],{"class":81,"line":129},[79,4895,4808],{},[10,4897,4898,4901,4902,4904,4905,4908,4909,460,4911,4913],{},[76,4899,4900],{},"const message = obj.message"," では、関数そのものを変数へ代入しています。その後は ",[76,4903,4726],{}," ではなく ",[76,4906,4907],{},"message()"," として呼び出しているため、",[76,4910,4133],{},[76,4912,3868],{}," の結び付きは失われます。",[10,4915,4811,4916,4814,4918,4920,4921,4923],{},[76,4917,4133],{},[76,4919,4759],{}," を参照します。",[76,4922,4817],{}," が設定されていなければ、実行環境に応じて空文字などが返ります。",[10,4925,4926,4927,4814,4929,4931,4932,4934,4935,4937],{},"厳格モードやES Modulesでは ",[76,4928,4133],{},[76,4930,806],{}," になるため、",[76,4933,4736],{}," を読み取ろうとすると ",[76,4936,986],{}," が発生します。",[10,4939,4940,4941,4944,4945,4947],{},"このような場合は、",[76,4942,4943],{},"bind()"," を使って ",[76,4946,4133],{}," の参照先を固定できます。",[69,4949,4951],{"className":71,"code":4950,"language":73,"meta":74,"style":74},"const message = obj.message.bind(obj)\nmessage() \u002F\u002F 「Hello Yuri」と出力される\n",[76,4952,4953,4958],{"__ignoreMap":74},[79,4954,4955],{"class":81,"line":82},[79,4956,4957],{},"const message = obj.message.bind(obj)\n",[79,4959,4960],{"class":81,"line":88},[79,4961,4962],{},"message() \u002F\u002F 「Hello Yuri」と出力される\n",[28,4964,476],{"id":476},[10,4966,4967,4969],{},[76,4968,4133],{}," の参照先は、関数を定義した場所だけではなく、主に関数の呼び出し方によって決まります。",[42,4971,4972,4981,4991,4994],{},[45,4973,4974,4976,4977,4730,4979,4760],{},[76,4975,4726],{}," のようなメソッド呼び出しでは、",[76,4978,4133],{},[76,4980,3868],{},[45,4982,4983,4985,4986,4988,4989,4768],{},[76,4984,4907],{}," のような通常の関数呼び出しでは、非厳格モードのブラウザなら ",[76,4987,4759],{},"、厳格モードやES Modulesなら ",[76,4990,806],{},[45,4992,4993],{},"メソッドを変数へ代入すると、元のオブジェクトとの結び付きは失われる",[45,4995,4996,4997,4999,5000,5002],{},"元のオブジェクトを参照させたい場合は、",[76,4998,4943],{}," で ",[76,5001,4133],{}," を固定できる",[10,5004,5005,5007],{},[76,5006,4133],{}," で迷ったときは「この関数はどのような形で呼び出されているか」を確認すると、参照先を判断しやすくなります。",[510,5009,512],{},{"title":74,"searchDepth":88,"depth":88,"links":5011},[5012,5013,5014,5015,5016,5017],{"id":4616,"depth":88,"text":4617},{"id":4634,"depth":88,"text":4634},{"id":4645,"depth":88,"text":4645},{"id":4648,"depth":88,"text":4648},{"id":4850,"depth":88,"text":4850},{"id":476,"depth":88,"text":476},"JavaScriptのthisが何を参照するのか、メソッド呼び出しと関数呼び出しの違いから整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-behavior-javascript-this","2024-11-20",{"title":4603,"description":5018},"articles\u002F2024\u002Fdescribe-behavior-javascript-this",[531],"\u002Fimages\u002Farticles\u002Fdescribe-behavior-javascript-this.png","2025-03-21","Kay_1TeIK8YsouKEwYLRPzbQMnabHxZ_GWvHciKSZBs",[5029,5574,6921,7299,7670,7996,8295],{"id":536,"title":537,"body":5030,"description":1234,"extension":524,"meta":5571,"navigation":103,"path":1236,"publishDate":1237,"published":103,"seo":5572,"stem":1239,"tags":5573,"thumbnail":1241,"updated":1237,"__hash__":1242},{"type":7,"value":5031,"toc":5556},[5032,5034,5036,5038,5040,5080,5082,5084,5144,5154,5166,5176,5188,5190,5192,5224,5230,5234,5242,5266,5276,5278,5290,5292,5296,5344,5346,5350,5378,5384,5386,5392,5408,5410,5416,5448,5450,5470,5474,5478,5486,5510,5524,5526,5530,5532,5544,5546,5548,5554],[10,5033,12],{},[10,5035,544],{},[28,5037,547],{"id":547},[10,5039,550],{},[69,5041,5042],{"className":71,"code":553,"language":73,"meta":74,"style":74},[76,5043,5044,5048,5052,5056,5060,5064,5068,5072,5076],{"__ignoreMap":74},[79,5045,5046],{"class":81,"line":82},[79,5047,560],{},[79,5049,5050],{"class":81,"line":88},[79,5051,565],{},[79,5053,5054],{"class":81,"line":94},[79,5055,570],{},[79,5057,5058],{"class":81,"line":100},[79,5059,97],{},[79,5061,5062],{"class":81,"line":107},[79,5063,104],{"emptyLinePlaceholder":103},[79,5065,5066],{"class":81,"line":113},[79,5067,583],{},[79,5069,5070],{"class":81,"line":119},[79,5071,104],{"emptyLinePlaceholder":103},[79,5073,5074],{"class":81,"line":124},[79,5075,592],{},[79,5077,5078],{"class":81,"line":129},[79,5079,597],{},[599,5081,601],{"id":601},[10,5083,604],{},[69,5085,5086],{"className":71,"code":607,"language":73,"meta":74,"style":74},[76,5087,5088,5092,5096,5100,5104,5108,5112,5116,5120,5124,5128,5132,5136,5140],{"__ignoreMap":74},[79,5089,5090],{"class":81,"line":82},[79,5091,560],{},[79,5093,5094],{"class":81,"line":88},[79,5095,565],{},[79,5097,5098],{"class":81,"line":94},[79,5099,622],{},[79,5101,5102],{"class":81,"line":100},[79,5103,627],{},[79,5105,5106],{"class":81,"line":107},[79,5107,632],{},[79,5109,5110],{"class":81,"line":113},[79,5111,97],{},[79,5113,5114],{"class":81,"line":119},[79,5115,104],{"emptyLinePlaceholder":103},[79,5117,5118],{"class":81,"line":124},[79,5119,645],{},[79,5121,5122],{"class":81,"line":129},[79,5123,650],{},[79,5125,5126],{"class":81,"line":135},[79,5127,655],{},[79,5129,5130],{"class":81,"line":141},[79,5131,660],{},[79,5133,5134],{"class":81,"line":146},[79,5135,104],{"emptyLinePlaceholder":103},[79,5137,5138],{"class":81,"line":151},[79,5139,592],{},[79,5141,5142],{"class":81,"line":434},[79,5143,597],{},[10,5145,675,5146,679,5148,683,5150,687,5152,690],{},[76,5147,678],{},[76,5149,682],{},[76,5151,686],{},[76,5153,682],{},[69,5155,5156],{"className":71,"code":693,"language":73,"meta":74,"style":74},[76,5157,5158,5162],{"__ignoreMap":74},[79,5159,5160],{"class":81,"line":82},[79,5161,700],{},[79,5163,5164],{"class":81,"line":88},[79,5165,705],{},[707,5167,5168],{"title":709,"type":710},[10,5169,5170,715,5172,718,5174,721],{},[76,5171,686],{},[76,5173,682],{},[76,5175,686],{},[69,5177,5178],{"className":71,"code":724,"language":73,"meta":74,"style":74},[76,5179,5180,5184],{"__ignoreMap":74},[79,5181,5182],{"class":81,"line":82},[79,5183,731],{},[79,5185,5186],{"class":81,"line":88},[79,5187,736],{},[599,5189,739],{"id":739},[10,5191,742],{},[69,5193,5194],{"className":71,"code":745,"language":73,"meta":74,"style":74},[76,5195,5196,5200,5204,5208,5212,5216,5220],{"__ignoreMap":74},[79,5197,5198],{"class":81,"line":82},[79,5199,560],{},[79,5201,5202],{"class":81,"line":88},[79,5203,756],{},[79,5205,5206],{"class":81,"line":94},[79,5207,97],{},[79,5209,5210],{"class":81,"line":100},[79,5211,104],{"emptyLinePlaceholder":103},[79,5213,5214],{"class":81,"line":107},[79,5215,769],{},[79,5217,5218],{"class":81,"line":113},[79,5219,104],{"emptyLinePlaceholder":103},[79,5221,5222],{"class":81,"line":119},[79,5223,778],{},[10,5225,781,5226,785,5228,683],{},[76,5227,784],{},[76,5229,788],{},[28,5231,792,5232,796],{"id":791},[76,5233,795],{},[10,5235,799,5236,803,5238,807,5240,810],{},[76,5237,802],{},[76,5239,806],{},[76,5241,806],{},[69,5243,5244],{"className":71,"code":813,"language":73,"meta":74,"style":74},[76,5245,5246,5250,5254,5258,5262],{"__ignoreMap":74},[79,5247,5248],{"class":81,"line":82},[79,5249,560],{},[79,5251,5252],{"class":81,"line":88},[79,5253,756],{},[79,5255,5256],{"class":81,"line":94},[79,5257,97],{},[79,5259,5260],{"class":81,"line":100},[79,5261,104],{"emptyLinePlaceholder":103},[79,5263,5264],{"class":81,"line":107},[79,5265,836],{},[10,5267,5268,842,5270,845,5272,848,5274,852],{},[76,5269,841],{},[76,5271,806],{},[76,5273,795],{},[76,5275,851],{},[10,5277,855],{},[69,5279,5280],{"className":71,"code":858,"language":73,"meta":74,"style":74},[76,5281,5282,5286],{"__ignoreMap":74},[79,5283,5284],{"class":81,"line":82},[79,5285,865],{},[79,5287,5288],{"class":81,"line":88},[79,5289,870],{},[599,5291,873],{"id":873},[10,5293,876,5294,880],{},[76,5295,879],{},[69,5297,5298],{"className":71,"code":883,"language":73,"meta":74,"style":74},[76,5299,5300,5304,5308,5312,5316,5320,5324,5328,5332,5336,5340],{"__ignoreMap":74},[79,5301,5302],{"class":81,"line":82},[79,5303,890],{},[79,5305,5306],{"class":81,"line":88},[79,5307,895],{},[79,5309,5310],{"class":81,"line":94},[79,5311,900],{},[79,5313,5314],{"class":81,"line":100},[79,5315,905],{},[79,5317,5318],{"class":81,"line":107},[79,5319,104],{"emptyLinePlaceholder":103},[79,5321,5322],{"class":81,"line":113},[79,5323,914],{},[79,5325,5326],{"class":81,"line":119},[79,5327,919],{},[79,5329,5330],{"class":81,"line":124},[79,5331,104],{"emptyLinePlaceholder":103},[79,5333,5334],{"class":81,"line":129},[79,5335,928],{},[79,5337,5338],{"class":81,"line":135},[79,5339,104],{"emptyLinePlaceholder":103},[79,5341,5342],{"class":81,"line":141},[79,5343,937],{},[599,5345,940],{"id":940},[10,5347,943,5348,947],{},[76,5349,946],{},[69,5351,5352],{"className":71,"code":950,"language":73,"meta":74,"style":74},[76,5353,5354,5358,5362,5366,5370,5374],{"__ignoreMap":74},[79,5355,5356],{"class":81,"line":82},[79,5357,957],{},[79,5359,5360],{"class":81,"line":88},[79,5361,962],{},[79,5363,5364],{"class":81,"line":94},[79,5365,97],{},[79,5367,5368],{"class":81,"line":100},[79,5369,104],{"emptyLinePlaceholder":103},[79,5371,5372],{"class":81,"line":107},[79,5373,975],{},[79,5375,5376],{"class":81,"line":113},[79,5377,980],{},[10,5379,983,5380,987,5382,990],{},[76,5381,986],{},[76,5383,946],{},[599,5385,994],{"id":993},[10,5387,5388,1000,5390,1003],{},[76,5389,999],{},[76,5391,802],{},[69,5393,5394],{"className":71,"code":1006,"language":73,"meta":74,"style":74},[76,5395,5396,5400,5404],{"__ignoreMap":74},[79,5397,5398],{"class":81,"line":82},[79,5399,1013],{},[79,5401,5402],{"class":81,"line":88},[79,5403,104],{"emptyLinePlaceholder":103},[79,5405,5406],{"class":81,"line":94},[79,5407,1022],{},[599,5409,1025],{"id":1025},[10,5411,1028,5412,803,5414,1033],{},[76,5413,802],{},[76,5415,806],{},[69,5417,5418],{"className":71,"code":1036,"language":73,"meta":74,"style":74},[76,5419,5420,5424,5428,5432,5436,5440,5444],{"__ignoreMap":74},[79,5421,5422],{"class":81,"line":82},[79,5423,1043],{},[79,5425,5426],{"class":81,"line":88},[79,5427,1048],{},[79,5429,5430],{"class":81,"line":94},[79,5431,104],{"emptyLinePlaceholder":103},[79,5433,5434],{"class":81,"line":100},[79,5435,1057],{},[79,5437,5438],{"class":81,"line":107},[79,5439,104],{"emptyLinePlaceholder":103},[79,5441,5442],{"class":81,"line":113},[79,5443,1066],{},[79,5445,5446],{"class":81,"line":119},[79,5447,1071],{},[10,5449,1074],{},[69,5451,5452],{"className":71,"code":1077,"language":73,"meta":74,"style":74},[76,5453,5454,5458,5462,5466],{"__ignoreMap":74},[79,5455,5456],{"class":81,"line":82},[79,5457,1084],{},[79,5459,5460],{"class":81,"line":88},[79,5461,104],{"emptyLinePlaceholder":103},[79,5463,5464],{"class":81,"line":94},[79,5465,1093],{},[79,5467,5468],{"class":81,"line":100},[79,5469,1098],{},[10,5471,1101,5472,1105],{},[76,5473,1104],{},[28,5475,5476,1108],{"id":1108},[76,5477,1111],{},[10,5479,1114,5480,803,5482,1119,5484,1122],{},[76,5481,802],{},[76,5483,806],{},[76,5485,1111],{},[69,5487,5488],{"className":71,"code":1125,"language":73,"meta":74,"style":74},[76,5489,5490,5494,5498,5502,5506],{"__ignoreMap":74},[79,5491,5492],{"class":81,"line":82},[79,5493,1132],{},[79,5495,5496],{"class":81,"line":88},[79,5497,104],{"emptyLinePlaceholder":103},[79,5499,5500],{"class":81,"line":94},[79,5501,1141],{},[79,5503,5504],{"class":81,"line":100},[79,5505,104],{"emptyLinePlaceholder":103},[79,5507,5508],{"class":81,"line":107},[79,5509,1150],{},[10,5511,5512,842,5514,1159,5516,1163,5518,1166,5520,803,5522,1171],{},[76,5513,1155],{},[76,5515,1158],{},[76,5517,1162],{},[76,5519,1111],{},[76,5521,802],{},[76,5523,806],{},[28,5525,1174],{"id":1174},[10,5527,1177,5528,1180],{},[76,5529,806],{},[10,5531,1183],{},[42,5533,5534,5538,5540],{},[45,5535,1188,5536,1191],{},[76,5537,795],{},[45,5539,1194],{},[45,5541,1197,5542,1200],{},[76,5543,1111],{},[28,5545,476],{"id":476},[10,5547,1205],{},[10,5549,1208,5550,1211,5552,1214],{},[76,5551,802],{},[76,5553,806],{},[510,5555,512],{},{"title":74,"searchDepth":88,"depth":88,"links":5557},[5558,5562,5568,5569,5570],{"id":547,"depth":88,"text":547,"children":5559},[5560,5561],{"id":601,"depth":94,"text":601},{"id":739,"depth":94,"text":739},{"id":791,"depth":88,"text":1224,"children":5563},[5564,5565,5566,5567],{"id":873,"depth":94,"text":873},{"id":940,"depth":94,"text":940},{"id":993,"depth":94,"text":994},{"id":1025,"depth":94,"text":1025},{"id":1108,"depth":88,"text":1231},{"id":1174,"depth":88,"text":1174},{"id":476,"depth":88,"text":476},{},{"title":537,"description":1234},[531],{"id":1244,"title":1245,"body":5575,"description":2911,"extension":524,"meta":6918,"navigation":103,"path":2913,"publishDate":2914,"published":103,"seo":6919,"stem":2916,"tags":6920,"thumbnail":2918,"updated":2914,"__hash__":2919},{"type":7,"value":5576,"toc":6890},[5577,5579,5584,5594,5596,5600,5606,5630,5632,5636,5638,5640,5642,5678,5680,5682,5684,5690,5692,5694,5698,5704,5868,5876,5878,5880,5958,5960,5962,6030,6032,6034,6056,6058,6060,6066,6188,6190,6192,6194,6196,6198,6204,6212,6278,6282,6286,6290,6326,6330,6332,6334,6390,6394,6396,6400,6498,6504,6508,6512,6566,6568,6570,6572,6660,6662,6666,6682,6688,6690,6692,6764,6768,6770,6772,6880,6882,6884,6886,6888],[10,5578,12],{},[10,5580,1252,5581,1258],{},[17,5582,1257],{"href":1255,"rel":5583},[21],[42,5585,5586,5588,5590,5592],{},[45,5587,1263],{},[45,5589,531],{},[45,5591,1268],{},[45,5593,1271],{},[28,5595,1263],{"id":1274},[599,5597,5598,1281],{"id":1277},[76,5599,1280],{},[10,5601,5602,1286,5604,1290],{},[76,5603,1280],{},[76,5605,1289],{},[69,5607,5608],{"className":1293,"code":1294,"language":1274,"meta":74,"style":74},[76,5609,5610],{"__ignoreMap":74},[79,5611,5612,5614,5616,5618,5620,5622,5624,5626,5628],{"class":81,"line":82},[79,5613,1302],{"class":1301},[79,5615,1306],{"class":1305},[79,5617,1310],{"class":1309},[79,5619,1313],{"class":1301},[79,5621,1316],{"class":1301},[79,5623,451],{"class":1319},[79,5625,1316],{"class":1301},[79,5627,1324],{"class":1309},[79,5629,1327],{"class":1301},[10,5631,1330],{},[707,5633,5634],{"title":1333,"type":1334},[10,5635,1337],{},[28,5637,531],{"id":73},[599,5639,1342],{"id":1342},[10,5641,1345],{},[69,5643,5644],{"className":71,"code":1348,"language":73,"meta":74,"style":74},[76,5645,5646,5650,5654,5658,5662,5666,5670,5674],{"__ignoreMap":74},[79,5647,5648],{"class":81,"line":82},[79,5649,1355],{},[79,5651,5652],{"class":81,"line":88},[79,5653,104],{"emptyLinePlaceholder":103},[79,5655,5656],{"class":81,"line":94},[79,5657,1364],{},[79,5659,5660],{"class":81,"line":100},[79,5661,1369],{},[79,5663,5664],{"class":81,"line":107},[79,5665,97],{},[79,5667,5668],{"class":81,"line":113},[79,5669,104],{"emptyLinePlaceholder":103},[79,5671,5672],{"class":81,"line":119},[79,5673,1382],{},[79,5675,5676],{"class":81,"line":124},[79,5677,1387],{},[10,5679,1390],{},[599,5681,1394],{"id":1393},[10,5683,1397],{},[10,5685,1400,5686,679,5688,1407],{},[76,5687,1403],{},[76,5689,1406],{},[10,5691,1410],{},[28,5693,1268],{"id":1413},[599,5695,5696],{"id":1416},[76,5697,1419],{},[10,5699,5700,1424,5702,1428],{},[76,5701,1419],{},[76,5703,1427],{},[69,5705,5706],{"className":1431,"code":1432,"language":1433,"meta":74,"style":74},[76,5707,5708,5726,5744,5758,5762,5786,5790,5802,5820,5824,5828,5840,5848,5856,5864],{"__ignoreMap":74},[79,5709,5710,5712,5714,5716,5718,5720,5722,5724],{"class":81,"line":82},[79,5711,1403],{"class":1440},[79,5713,1443],{"class":1301},[79,5715,1447],{"class":1446},[79,5717,1450],{"class":1301},[79,5719,1453],{"class":1440},[79,5721,1456],{"class":1301},[79,5723,1413],{"class":1319},[79,5725,1461],{"class":1301},[79,5727,5728,5730,5732,5734,5736,5738,5740,5742],{"class":81,"line":88},[79,5729,1403],{"class":1440},[79,5731,1443],{"class":1301},[79,5733,1470],{"class":1446},[79,5735,1450],{"class":1301},[79,5737,1453],{"class":1440},[79,5739,1456],{"class":1301},[79,5741,1479],{"class":1319},[79,5743,1461],{"class":1301},[79,5745,5746,5748,5750,5752,5754,5756],{"class":81,"line":94},[79,5747,1403],{"class":1440},[79,5749,1488],{"class":1446},[79,5751,1491],{"class":1440},[79,5753,1456],{"class":1301},[79,5755,1496],{"class":1319},[79,5757,1461],{"class":1301},[79,5759,5760],{"class":81,"line":100},[79,5761,104],{"emptyLinePlaceholder":103},[79,5763,5764,5766,5768,5770,5772,5774,5776,5778,5780,5782,5784],{"class":81,"line":107},[79,5765,1507],{"class":1309},[79,5767,1510],{"class":1446},[79,5769,1313],{"class":1301},[79,5771,1515],{"class":1446},[79,5773,1518],{"class":1301},[79,5775,1522],{"class":1521},[79,5777,1525],{"class":1446},[79,5779,1528],{"class":1301},[79,5781,1531],{"class":1319},[79,5783,1528],{"class":1301},[79,5785,246],{"class":1446},[79,5787,5788],{"class":81,"line":113},[79,5789,104],{"emptyLinePlaceholder":103},[79,5791,5792,5794,5796,5798,5800],{"class":81,"line":119},[79,5793,1544],{"class":1440},[79,5795,1547],{"class":1446},[79,5797,1550],{"class":1301},[79,5799,1553],{"class":1446},[79,5801,1556],{"class":1301},[79,5803,5804,5806,5808,5810,5812,5814,5816,5818],{"class":81,"line":124},[79,5805,1561],{"class":1440},[79,5807,1564],{"class":1301},[79,5809,1567],{"class":1521},[79,5811,1525],{"class":1305},[79,5813,1528],{"class":1301},[79,5815,1574],{"class":1319},[79,5817,1528],{"class":1301},[79,5819,246],{"class":1305},[79,5821,5822],{"class":81,"line":129},[79,5823,97],{"class":1301},[79,5825,5826],{"class":81,"line":135},[79,5827,104],{"emptyLinePlaceholder":103},[79,5829,5830,5832,5834,5836,5838],{"class":81,"line":141},[79,5831,1419],{"class":1521},[79,5833,1593],{"class":1446},[79,5835,1518],{"class":1301},[79,5837,1427],{"class":1521},[79,5839,1600],{"class":1446},[79,5841,5842,5844,5846],{"class":81,"line":146},[79,5843,1605],{"class":1301},[79,5845,1609],{"class":1608},[79,5847,1327],{"class":1301},[79,5849,5850,5852,5854],{"class":81,"line":151},[79,5851,1616],{"class":1301},[79,5853,1619],{"class":1608},[79,5855,1622],{"class":1301},[79,5857,5858,5860,5862],{"class":81,"line":434},[79,5859,1627],{"class":1301},[79,5861,1609],{"class":1608},[79,5863,1632],{"class":1301},[79,5865,5866],{"class":81,"line":439},[79,5867,246],{"class":1446},[10,5869,5870,1641,5872,1644,5874,947],{},[76,5871,1419],{},[76,5873,1419],{},[76,5875,1647],{},[599,5877,1650],{"id":1650},[10,5879,1653],{},[69,5881,5882],{"className":1431,"code":1656,"language":1433,"meta":74,"style":74},[76,5883,5884,5894,5908,5920,5940,5948,5954],{"__ignoreMap":74},[79,5885,5886,5888,5890,5892],{"class":81,"line":82},[79,5887,1663],{"class":1521},[79,5889,1525],{"class":1446},[79,5891,1669],{"class":1668},[79,5893,1672],{"class":1309},[79,5895,5896,5898,5900,5902,5904,5906],{"class":81,"line":88},[79,5897,1677],{"class":1446},[79,5899,1518],{"class":1301},[79,5901,1682],{"class":1521},[79,5903,1525],{"class":1446},[79,5905,1687],{"class":1668},[79,5907,1672],{"class":1309},[79,5909,5910,5912,5914,5916,5918],{"class":81,"line":94},[79,5911,1694],{"class":1446},[79,5913,1518],{"class":1301},[79,5915,1699],{"class":1446},[79,5917,1702],{"class":1301},[79,5919,1705],{"class":1446},[79,5921,5922,5924,5926,5928,5930,5932,5934,5936,5938],{"class":81,"line":100},[79,5923,1710],{"class":1301},[79,5925,1443],{"class":1301},[79,5927,1715],{"class":1301},[79,5929,1687],{"class":1446},[79,5931,1720],{"class":1301},[79,5933,1723],{"class":1305},[79,5935,1726],{"class":1301},[79,5937,1730],{"class":1729},[79,5939,1733],{"class":1301},[79,5941,5942,5944,5946],{"class":81,"line":107},[79,5943,1738],{"class":1301},[79,5945,1741],{"class":1446},[79,5947,1744],{"class":1301},[79,5949,5950,5952],{"class":81,"line":113},[79,5951,1749],{"class":1446},[79,5953,1744],{"class":1301},[79,5955,5956],{"class":81,"line":119},[79,5957,246],{"class":1446},[10,5959,1758],{},[10,5961,1761],{},[1763,5963,5964,5974],{},[1766,5965,5966],{},[1769,5967,5968,5970,5972],{},[1772,5969,1774],{},[1772,5971,1777],{},[1772,5973,1780],{},[1782,5975,5976,5990,6006,6018],{},[1769,5977,5978,5980,5986],{},[1787,5979,1789],{},[1787,5981,5982,187,5984],{},[76,5983,1794],{},[76,5985,1797],{},[1787,5987,1800,5988],{},[76,5989,1803],{},[1769,5991,5992,5994,6000],{},[1787,5993,1808],{},[1787,5995,5996,187,5998],{},[76,5997,1813],{},[76,5999,1816],{},[1787,6001,6002,187,6004],{},[76,6003,1821],{},[76,6005,1824],{},[1769,6007,6008,6010,6014],{},[1787,6009,1829],{},[1787,6011,1832,6012],{},[76,6013,1816],{},[1787,6015,6016],{},[76,6017,1682],{},[1769,6019,6020,6022,6026],{},[1787,6021,1843],{},[1787,6023,1846,6024],{},[76,6025,1849],{},[1787,6027,1852,6028],{},[76,6029,1849],{},[599,6031,1857],{"id":1857},[10,6033,1860],{},[69,6035,6036],{"className":1431,"code":1863,"language":1433,"meta":74,"style":74},[76,6037,6038],{"__ignoreMap":74},[79,6039,6040,6042,6044,6046,6048,6050,6052,6054],{"class":81,"line":82},[79,6041,1870],{"class":1521},[79,6043,1525],{"class":1446},[79,6045,1875],{"class":1668},[79,6047,1878],{"class":1309},[79,6049,1881],{"class":1446},[79,6051,1884],{"class":1301},[79,6053,1888],{"class":1887},[79,6055,246],{"class":1446},[10,6057,1893],{},[599,6059,1896],{"id":1896},[10,6061,1899,6062,1903,6064,1907],{},[76,6063,1902],{},[76,6065,1906],{},[69,6067,6068],{"className":1431,"code":1910,"language":1433,"meta":74,"style":74},[76,6069,6070,6080,6100,6104,6108,6126,6140,6150,6154,6158,6184],{"__ignoreMap":74},[79,6071,6072,6074,6076,6078],{"class":81,"line":82},[79,6073,1917],{"class":1309},[79,6075,1920],{"class":1608},[79,6077,1923],{"class":1301},[79,6079,1926],{"class":1301},[79,6081,6082,6084,6086,6088,6090,6092,6094,6096,6098],{"class":81,"line":88},[79,6083,1931],{"class":1305},[79,6085,1726],{"class":1301},[79,6087,1547],{"class":1301},[79,6089,1938],{"class":1668},[79,6091,1726],{"class":1301},[79,6093,1943],{"class":1608},[79,6095,1946],{"class":1301},[79,6097,1878],{"class":1309},[79,6099,1951],{"class":1608},[79,6101,6102],{"class":81,"line":94},[79,6103,97],{"class":1301},[79,6105,6106],{"class":81,"line":100},[79,6107,104],{"emptyLinePlaceholder":103},[79,6109,6110,6112,6114,6116,6118,6120,6122,6124],{"class":81,"line":107},[79,6111,1964],{"class":1309},[79,6113,1967],{"class":1521},[79,6115,1970],{"class":1301},[79,6117,1973],{"class":1668},[79,6119,1976],{"class":1301},[79,6121,1920],{"class":1608},[79,6123,1946],{"class":1301},[79,6125,1926],{"class":1301},[79,6127,6128,6130,6132,6134,6136,6138],{"class":81,"line":113},[79,6129,1987],{"class":1309},[79,6131,1990],{"class":1446},[79,6133,1923],{"class":1301},[79,6135,1995],{"class":1301},[79,6137,1878],{"class":1309},[79,6139,1926],{"class":1301},[79,6141,6142,6144,6146,6148],{"class":81,"line":119},[79,6143,2004],{"class":1521},[79,6145,1525],{"class":1305},[79,6147,2009],{"class":1887},[79,6149,246],{"class":1305},[79,6151,6152],{"class":81,"line":124},[79,6153,2016],{"class":1301},[79,6155,6156],{"class":81,"line":129},[79,6157,104],{"emptyLinePlaceholder":103},[79,6159,6160,6162,6164,6166,6168,6170,6172,6174,6176,6178,6180,6182],{"class":81,"line":135},[79,6161,2025],{"class":1440},[79,6163,2028],{"class":1301},[79,6165,1306],{"class":1305},[79,6167,1310],{"class":1309},[79,6169,1313],{"class":1301},[79,6171,1316],{"class":1301},[79,6173,2039],{"class":1319},[79,6175,1316],{"class":1301},[79,6177,1973],{"class":1309},[79,6179,2046],{"class":1301},[79,6181,2049],{"class":1446},[79,6183,2052],{"class":1301},[79,6185,6186],{"class":81,"line":141},[79,6187,97],{"class":1301},[10,6189,2059],{},[599,6191,2062],{"id":2062},[10,6193,2065],{},[10,6195,2068],{},[28,6197,1271],{"id":2071},[599,6199,6200,679,6202],{"id":2074},[76,6201,2077],{},[76,6203,802],{},[10,6205,6206,2084,6208,2088,6210,2091],{},[76,6207,2077],{},[76,6209,2087],{},[76,6211,802],{},[69,6213,6214],{"className":2094,"code":2095,"language":2071,"meta":74,"style":74},[76,6215,6216,6240,6244,6256,6274],{"__ignoreMap":74},[79,6217,6218,6220,6222,6224,6226,6228,6230,6232,6234,6236,6238],{"class":81,"line":82},[79,6219,1507],{"class":1309},[79,6221,1510],{"class":1446},[79,6223,1313],{"class":1301},[79,6225,1515],{"class":1446},[79,6227,1518],{"class":1301},[79,6229,1522],{"class":1521},[79,6231,1525],{"class":1446},[79,6233,1528],{"class":1301},[79,6235,1531],{"class":1319},[79,6237,1528],{"class":1301},[79,6239,246],{"class":1446},[79,6241,6242],{"class":81,"line":88},[79,6243,104],{"emptyLinePlaceholder":103},[79,6245,6246,6248,6250,6252,6254],{"class":81,"line":94},[79,6247,1544],{"class":1440},[79,6249,1547],{"class":1446},[79,6251,1550],{"class":1301},[79,6253,1553],{"class":1446},[79,6255,1556],{"class":1301},[79,6257,6258,6260,6262,6264,6266,6268,6270,6272],{"class":81,"line":100},[79,6259,1561],{"class":1440},[79,6261,1564],{"class":1301},[79,6263,1567],{"class":1521},[79,6265,1525],{"class":1305},[79,6267,1528],{"class":1301},[79,6269,1574],{"class":1319},[79,6271,1528],{"class":1301},[79,6273,246],{"class":1305},[79,6275,6276],{"class":81,"line":107},[79,6277,97],{"class":1301},[10,6279,2162,6280,2165],{},[76,6281,1550],{},[599,6283,6284],{"id":2168},[76,6285,2168],{},[10,6287,2173,6288,2176],{},[76,6289,2168],{},[69,6291,6292],{"className":2094,"code":2179,"language":2071,"meta":74,"style":74},[76,6293,6294,6304,6314,6322],{"__ignoreMap":74},[79,6295,6296,6298,6300,6302],{"class":81,"line":82},[79,6297,1917],{"class":1309},[79,6299,2188],{"class":1608},[79,6301,1923],{"class":1301},[79,6303,1926],{"class":1301},[79,6305,6306,6308,6310,6312],{"class":81,"line":88},[79,6307,2197],{"class":1309},[79,6309,2200],{"class":1305},[79,6311,1726],{"class":1301},[79,6313,2205],{"class":1608},[79,6315,6316,6318,6320],{"class":81,"line":94},[79,6317,2210],{"class":1305},[79,6319,1726],{"class":1301},[79,6321,2215],{"class":1608},[79,6323,6324],{"class":81,"line":100},[79,6325,97],{"class":1301},[10,6327,6328,2224],{},[76,6329,2168],{},[599,6331,2227],{"id":2227},[10,6333,2230],{},[69,6335,6336],{"className":1431,"code":2233,"language":1433,"meta":74,"style":74},[76,6337,6338,6364,6386],{"__ignoreMap":74},[79,6339,6340,6342,6344,6346,6348,6350,6352,6354,6356,6358,6360,6362],{"class":81,"line":82},[79,6341,1964],{"class":1309},[79,6343,1990],{"class":1521},[79,6345,1525],{"class":1301},[79,6347,2246],{"class":1668},[79,6349,1726],{"class":1301},[79,6351,2251],{"class":1608},[79,6353,1518],{"class":1301},[79,6355,2256],{"class":1608},[79,6357,1302],{"class":1301},[79,6359,2261],{"class":1608},[79,6361,2264],{"class":1301},[79,6363,1926],{"class":1301},[79,6365,6366,6368,6370,6372,6374,6376,6378,6380,6382,6384],{"class":81,"line":88},[79,6367,2271],{"class":1446},[79,6369,1518],{"class":1301},[79,6371,2276],{"class":1521},[79,6373,1525],{"class":1305},[79,6375,2246],{"class":1446},[79,6377,1518],{"class":1301},[79,6379,2285],{"class":1446},[79,6381,1518],{"class":1301},[79,6383,2290],{"class":1446},[79,6385,246],{"class":1305},[79,6387,6388],{"class":81,"line":94},[79,6389,97],{"class":1301},[10,6391,2299,6392,2303],{},[76,6393,2302],{},[599,6395,2306],{"id":2306},[10,6397,2309,6398,2313],{},[76,6399,2312],{},[69,6401,6402],{"className":2094,"code":2316,"language":2071,"meta":74,"style":74},[76,6403,6404,6414,6422,6426,6430,6466,6494],{"__ignoreMap":74},[79,6405,6406,6408,6410,6412],{"class":81,"line":82},[79,6407,1917],{"class":1309},[79,6409,2325],{"class":1608},[79,6411,1923],{"class":1301},[79,6413,1926],{"class":1301},[79,6415,6416,6418,6420],{"class":81,"line":88},[79,6417,2334],{"class":1305},[79,6419,1726],{"class":1301},[79,6421,2205],{"class":1608},[79,6423,6424],{"class":81,"line":94},[79,6425,97],{"class":1301},[79,6427,6428],{"class":81,"line":100},[79,6429,104],{"emptyLinePlaceholder":103},[79,6431,6432,6434,6436,6438,6440,6442,6444,6446,6448,6450,6452,6454,6456,6458,6460,6462,6464],{"class":81,"line":107},[79,6433,1964],{"class":1309},[79,6435,2353],{"class":1521},[79,6437,1302],{"class":1301},[79,6439,2358],{"class":1608},[79,6441,2361],{"class":1309},[79,6443,2325],{"class":1608},[79,6445,2366],{"class":1301},[79,6447,2369],{"class":1668},[79,6449,1726],{"class":1301},[79,6451,2374],{"class":1608},[79,6453,2377],{"class":1446},[79,6455,1720],{"class":1301},[79,6457,2200],{"class":1668},[79,6459,1726],{"class":1301},[79,6461,1943],{"class":1608},[79,6463,1946],{"class":1301},[79,6465,1926],{"class":1301},[79,6467,6468,6470,6472,6474,6476,6478,6480,6482,6484,6486,6488,6490,6492],{"class":81,"line":113},[79,6469,2025],{"class":1440},[79,6471,2396],{"class":1446},[79,6473,1518],{"class":1301},[79,6475,2401],{"class":1521},[79,6477,1525],{"class":1305},[79,6479,2406],{"class":1668},[79,6481,1878],{"class":1309},[79,6483,2411],{"class":1446},[79,6485,1518],{"class":1301},[79,6487,1938],{"class":1446},[79,6489,2418],{"class":1301},[79,6491,2200],{"class":1446},[79,6493,246],{"class":1305},[79,6495,6496],{"class":81,"line":119},[79,6497,97],{"class":1301},[10,6499,2429,6500,2432,6502,2435],{},[76,6501,2358],{},[76,6503,1938],{},[599,6505,6506,2442],{"id":2438},[76,6507,2441],{},[10,6509,6510,2447],{},[76,6511,2441],{},[69,6513,6514],{"className":2094,"code":2450,"language":2071,"meta":74,"style":74},[76,6515,6516,6526,6534,6542,6546,6550,6562],{"__ignoreMap":74},[79,6517,6518,6520,6522,6524],{"class":81,"line":82},[79,6519,1917],{"class":1309},[79,6521,2188],{"class":1608},[79,6523,1923],{"class":1301},[79,6525,1926],{"class":1301},[79,6527,6528,6530,6532],{"class":81,"line":88},[79,6529,2334],{"class":1305},[79,6531,1726],{"class":1301},[79,6533,2205],{"class":1608},[79,6535,6536,6538,6540],{"class":81,"line":94},[79,6537,2210],{"class":1305},[79,6539,1726],{"class":1301},[79,6541,2215],{"class":1608},[79,6543,6544],{"class":81,"line":100},[79,6545,97],{"class":1301},[79,6547,6548],{"class":81,"line":107},[79,6549,104],{"emptyLinePlaceholder":103},[79,6551,6552,6554,6556,6558,6560],{"class":81,"line":113},[79,6553,1917],{"class":1309},[79,6555,2493],{"class":1608},[79,6557,1923],{"class":1301},[79,6559,2498],{"class":1301},[79,6561,2501],{"class":1608},[79,6563,6564],{"class":81,"line":119},[79,6565,2507],{"class":2506},[10,6567,2510],{},[599,6569,2513],{"id":2513},[10,6571,2516],{},[69,6573,6574],{"className":2094,"code":2519,"language":2071,"meta":74,"style":74},[76,6575,6576,6586,6594,6602,6606,6610,6630,6634,6638,6656],{"__ignoreMap":74},[79,6577,6578,6580,6582,6584],{"class":81,"line":82},[79,6579,1917],{"class":1309},[79,6581,2188],{"class":1608},[79,6583,1923],{"class":1301},[79,6585,1926],{"class":1301},[79,6587,6588,6590,6592],{"class":81,"line":88},[79,6589,2334],{"class":1305},[79,6591,1726],{"class":1301},[79,6593,2205],{"class":1608},[79,6595,6596,6598,6600],{"class":81,"line":94},[79,6597,2210],{"class":1305},[79,6599,1726],{"class":1301},[79,6601,2215],{"class":1608},[79,6603,6604],{"class":81,"line":100},[79,6605,97],{"class":1301},[79,6607,6608],{"class":81,"line":107},[79,6609,104],{"emptyLinePlaceholder":103},[79,6611,6612,6614,6616,6618,6620,6622,6624,6626,6628],{"class":81,"line":113},[79,6613,1917],{"class":1309},[79,6615,2562],{"class":1608},[79,6617,1923],{"class":1301},[79,6619,2188],{"class":1608},[79,6621,2569],{"class":1446},[79,6623,1528],{"class":1301},[79,6625,1938],{"class":1319},[79,6627,1528],{"class":1301},[79,6629,905],{"class":1446},[79,6631,6632],{"class":81,"line":119},[79,6633,2582],{"class":2506},[79,6635,6636],{"class":81,"line":124},[79,6637,104],{"emptyLinePlaceholder":103},[79,6639,6640,6642,6644,6646,6648,6650,6652,6654],{"class":81,"line":129},[79,6641,1917],{"class":1309},[79,6643,2593],{"class":1608},[79,6645,1923],{"class":1301},[79,6647,2188],{"class":1608},[79,6649,2569],{"class":1446},[79,6651,2441],{"class":1301},[79,6653,2188],{"class":1608},[79,6655,905],{"class":1446},[79,6657,6658],{"class":81,"line":135},[79,6659,2610],{"class":2506},[599,6661,2613],{"id":2613},[10,6663,6664,2619],{},[76,6665,2618],{},[69,6667,6668],{"className":2094,"code":2622,"language":2071,"meta":74,"style":74},[76,6669,6670],{"__ignoreMap":74},[79,6671,6672,6674,6676,6678,6680],{"class":81,"line":82},[79,6673,2618],{"class":1309},[79,6675,2631],{"class":1309},[79,6677,2634],{"class":1446},[79,6679,1726],{"class":1301},[79,6681,2215],{"class":1608},[10,6683,2641,6684,2645,6686,2648],{},[76,6685,2644],{},[76,6687,2618],{},[599,6689,2651],{"id":2651},[10,6691,2654],{},[69,6693,6694],{"className":2094,"code":2657,"language":2071,"meta":74,"style":74},[76,6695,6696,6706,6722,6726,6730,6740,6760],{"__ignoreMap":74},[79,6697,6698,6700,6702,6704],{"class":81,"line":82},[79,6699,1917],{"class":1309},[79,6701,2666],{"class":1608},[79,6703,1923],{"class":1301},[79,6705,1926],{"class":1301},[79,6707,6708,6710,6712,6714,6716,6718,6720],{"class":81,"line":88},[79,6709,2675],{"class":1305},[79,6711,1525],{"class":1301},[79,6713,2680],{"class":1668},[79,6715,1726],{"class":1301},[79,6717,2685],{"class":1608},[79,6719,2688],{"class":1301},[79,6721,2215],{"class":1608},[79,6723,6724],{"class":81,"line":94},[79,6725,97],{"class":1301},[79,6727,6728],{"class":81,"line":100},[79,6729,104],{"emptyLinePlaceholder":103},[79,6731,6732,6734,6736,6738],{"class":81,"line":107},[79,6733,1917],{"class":1309},[79,6735,2705],{"class":1608},[79,6737,1923],{"class":1301},[79,6739,1926],{"class":1301},[79,6741,6742,6744,6746,6748,6750,6752,6754,6756,6758],{"class":81,"line":113},[79,6743,2675],{"class":1305},[79,6745,1726],{"class":1301},[79,6747,1547],{"class":1301},[79,6749,2680],{"class":1668},[79,6751,1726],{"class":1301},[79,6753,2685],{"class":1608},[79,6755,1946],{"class":1301},[79,6757,1878],{"class":1309},[79,6759,2215],{"class":1608},[79,6761,6762],{"class":81,"line":119},[79,6763,97],{"class":1301},[10,6765,2736,6766,2740],{},[76,6767,2739],{},[599,6769,2743],{"id":2743},[10,6771,2746],{},[69,6773,6774],{"className":2094,"code":2749,"language":2071,"meta":74,"style":74},[76,6775,6776,6800,6816,6820,6824,6838,6842,6854,6876],{"__ignoreMap":74},[79,6777,6778,6780,6782,6784,6786,6788,6790,6792,6794,6796,6798],{"class":81,"line":82},[79,6779,1964],{"class":1309},[79,6781,2758],{"class":1521},[79,6783,1525],{"class":1301},[79,6785,2680],{"class":1668},[79,6787,1726],{"class":1301},[79,6789,2767],{"class":1608},[79,6791,2688],{"class":1301},[79,6793,2772],{"class":1668},[79,6795,2775],{"class":1301},[79,6797,1943],{"class":1608},[79,6799,1926],{"class":1301},[79,6801,6802,6804,6806,6808,6810,6812,6814],{"class":81,"line":88},[79,6803,2025],{"class":1440},[79,6805,2786],{"class":1301},[79,6807,2772],{"class":1446},[79,6809,2418],{"class":1301},[79,6811,1456],{"class":1301},[79,6813,2795],{"class":1319},[79,6815,1461],{"class":1301},[79,6817,6818],{"class":81,"line":94},[79,6819,97],{"class":1301},[79,6821,6822],{"class":81,"line":100},[79,6823,104],{"emptyLinePlaceholder":103},[79,6825,6826,6828,6830,6832,6834,6836],{"class":81,"line":107},[79,6827,1507],{"class":1309},[79,6829,2772],{"class":1446},[79,6831,1726],{"class":1301},[79,6833,2767],{"class":1608},[79,6835,1923],{"class":1301},[79,6837,2820],{"class":1887},[79,6839,6840],{"class":81,"line":113},[79,6841,104],{"emptyLinePlaceholder":103},[79,6843,6844,6846,6848,6850,6852],{"class":81,"line":119},[79,6845,1544],{"class":1440},[79,6847,1547],{"class":1446},[79,6849,2833],{"class":1521},[79,6851,2836],{"class":1446},[79,6853,1556],{"class":1301},[79,6855,6856,6858,6860,6862,6864,6866,6868,6870,6872,6874],{"class":81,"line":124},[79,6857,2271],{"class":1446},[79,6859,1518],{"class":1301},[79,6861,2276],{"class":1521},[79,6863,1525],{"class":1305},[79,6865,2680],{"class":1446},[79,6867,1518],{"class":1301},[79,6869,2855],{"class":1521},[79,6871,1525],{"class":1305},[79,6873,2860],{"class":1887},[79,6875,2863],{"class":1305},[79,6877,6878],{"class":81,"line":129},[79,6879,97],{"class":1301},[10,6881,2870],{},[28,6883,476],{"id":476},[10,6885,2875],{},[10,6887,2878],{},[510,6889,2881],{},{"title":74,"searchDepth":88,"depth":88,"links":6891},[6892,6895,6899,6906,6917],{"id":1274,"depth":88,"text":1263,"children":6893},[6894],{"id":1277,"depth":94,"text":1277},{"id":73,"depth":88,"text":531,"children":6896},[6897,6898],{"id":1342,"depth":94,"text":1342},{"id":1393,"depth":94,"text":1394},{"id":1413,"depth":88,"text":1268,"children":6900},[6901,6902,6903,6904,6905],{"id":1416,"depth":94,"text":1419},{"id":1650,"depth":94,"text":1650},{"id":1857,"depth":94,"text":1857},{"id":1896,"depth":94,"text":1896},{"id":2062,"depth":94,"text":2062},{"id":2071,"depth":88,"text":1271,"children":6907},[6908,6909,6910,6911,6912,6913,6914,6915,6916],{"id":2074,"depth":94,"text":2901},{"id":2168,"depth":94,"text":2168},{"id":2227,"depth":94,"text":2227},{"id":2306,"depth":94,"text":2306},{"id":2438,"depth":94,"text":2438},{"id":2513,"depth":94,"text":2513},{"id":2613,"depth":94,"text":2613},{"id":2651,"depth":94,"text":2651},{"id":2743,"depth":94,"text":2743},{"id":476,"depth":88,"text":476},{},{"title":1245,"description":2911},[1268,1271],{"id":2921,"title":2922,"body":6922,"description":3400,"extension":524,"meta":7296,"navigation":103,"path":3402,"publishDate":3403,"published":103,"seo":7297,"stem":3405,"tags":7298,"thumbnail":3408,"updated":3403,"__hash__":3409},{"type":7,"value":6923,"toc":7286},[6924,6926,6928,6934,6936,6938,6940,6942,7008,7010,7014,7016,7040,7046,7090,7092,7094,7100,7116,7118,7120,7122,7124,7126,7210,7212,7222,7224,7226,7228,7248,7252,7254,7256,7260,7262,7264,7276,7278,7280,7282,7284],[10,6925,12],{},[10,6927,2929],{},[10,6929,2932,6930,187,6932,2939],{},[76,6931,2935],{},[76,6933,2938],{},[28,6935,2942],{"id":2942},[10,6937,2945],{},[10,6939,2948],{},[10,6941,2951],{},[1763,6943,6944,6956],{},[1766,6945,6946],{},[1769,6947,6948,6950,6952,6954],{},[1772,6949,2960],{},[1772,6951,2935],{},[1772,6953,2938],{},[1772,6955,2967],{},[1782,6957,6958,6968,6978,6988,6998],{},[1769,6959,6960,6962,6964,6966],{},[1787,6961,2974],{},[1787,6963,2977],{},[1787,6965,2977],{},[1787,6967,2982],{},[1769,6969,6970,6972,6974,6976],{},[1787,6971,2987],{},[1787,6973,2990],{},[1787,6975,2990],{},[1787,6977,2995],{},[1769,6979,6980,6982,6984,6986],{},[1787,6981,3000],{},[1787,6983,3003],{},[1787,6985,3006],{},[1787,6987,3003],{},[1769,6989,6990,6992,6994,6996],{},[1787,6991,3013],{},[1787,6993,3016],{},[1787,6995,3019],{},[1787,6997,3016],{},[1769,6999,7000,7002,7004,7006],{},[1787,7001,3026],{},[1787,7003,3029],{},[1787,7005,3032],{},[1787,7007,3035],{},[28,7009,2935],{"id":3038},[10,7011,7012,3043],{},[76,7013,2935],{},[10,7015,3046],{},[69,7017,7018],{"className":71,"code":3049,"language":73,"meta":74,"style":74},[76,7019,7020,7024,7028,7032,7036],{"__ignoreMap":74},[79,7021,7022],{"class":81,"line":82},[79,7023,3056],{},[79,7025,7026],{"class":81,"line":88},[79,7027,104],{"emptyLinePlaceholder":103},[79,7029,7030],{"class":81,"line":94},[79,7031,3065],{},[79,7033,7034],{"class":81,"line":100},[79,7035,104],{"emptyLinePlaceholder":103},[79,7037,7038],{"class":81,"line":107},[79,7039,3074],{},[10,7041,3077,7042,3081,7044,3085],{},[76,7043,3080],{},[76,7045,3084],{},[69,7047,7048],{"className":71,"code":3088,"language":73,"meta":74,"style":74},[76,7049,7050,7054,7058,7062,7066,7070,7074,7078,7082,7086],{"__ignoreMap":74},[79,7051,7052],{"class":81,"line":82},[79,7053,3095],{},[79,7055,7056],{"class":81,"line":88},[79,7057,3100],{},[79,7059,7060],{"class":81,"line":94},[79,7061,3105],{},[79,7063,7064],{"class":81,"line":100},[79,7065,97],{},[79,7067,7068],{"class":81,"line":107},[79,7069,104],{"emptyLinePlaceholder":103},[79,7071,7072],{"class":81,"line":113},[79,7073,3118],{},[79,7075,7076],{"class":81,"line":119},[79,7077,104],{"emptyLinePlaceholder":103},[79,7079,7080],{"class":81,"line":124},[79,7081,3127],{},[79,7083,7084],{"class":81,"line":129},[79,7085,3132],{},[79,7087,7088],{"class":81,"line":135},[79,7089,246],{},[10,7091,3139],{},[28,7093,2938],{"id":3142},[10,7095,7096,3147,7098,3150],{},[76,7097,2938],{},[76,7099,2935],{},[69,7101,7102],{"className":71,"code":3153,"language":73,"meta":74,"style":74},[76,7103,7104,7108,7112],{"__ignoreMap":74},[79,7105,7106],{"class":81,"line":82},[79,7107,3160],{},[79,7109,7110],{"class":81,"line":88},[79,7111,104],{"emptyLinePlaceholder":103},[79,7113,7114],{"class":81,"line":94},[79,7115,3169],{},[10,7117,3172],{},[10,7119,3175],{},[28,7121,2967],{"id":3178},[10,7123,3181],{},[10,7125,3184],{},[69,7127,7128],{"className":71,"code":3187,"language":73,"meta":74,"style":74},[76,7129,7130,7134,7138,7142,7146,7150,7154,7158,7162,7166,7170,7174,7178,7182,7186,7190,7194,7198,7202,7206],{"__ignoreMap":74},[79,7131,7132],{"class":81,"line":82},[79,7133,3194],{},[79,7135,7136],{"class":81,"line":88},[79,7137,104],{"emptyLinePlaceholder":103},[79,7139,7140],{"class":81,"line":94},[79,7141,3203],{},[79,7143,7144],{"class":81,"line":100},[79,7145,3208],{},[79,7147,7148],{"class":81,"line":107},[79,7149,104],{"emptyLinePlaceholder":103},[79,7151,7152],{"class":81,"line":113},[79,7153,3217],{},[79,7155,7156],{"class":81,"line":119},[79,7157,3222],{},[79,7159,7160],{"class":81,"line":124},[79,7161,3227],{},[79,7163,7164],{"class":81,"line":129},[79,7165,3232],{},[79,7167,7168],{"class":81,"line":135},[79,7169,3237],{},[79,7171,7172],{"class":81,"line":141},[79,7173,2016],{},[79,7175,7176],{"class":81,"line":146},[79,7177,97],{},[79,7179,7180],{"class":81,"line":151},[79,7181,104],{"emptyLinePlaceholder":103},[79,7183,7184],{"class":81,"line":434},[79,7185,3254],{},[79,7187,7188],{"class":81,"line":439},[79,7189,3208],{},[79,7191,7192],{"class":81,"line":3261},[79,7193,3264],{},[79,7195,7196],{"class":81,"line":3267},[79,7197,3270],{},[79,7199,7200],{"class":81,"line":3273},[79,7201,104],{"emptyLinePlaceholder":103},[79,7203,7204],{"class":81,"line":3278},[79,7205,3281],{},[79,7207,7208],{"class":81,"line":3284},[79,7209,97],{},[10,7211,3289],{},[42,7213,7214,7216,7218,7220],{},[45,7215,3294],{},[45,7217,3297],{},[45,7219,3300],{},[45,7221,3303],{},[28,7223,3306],{"id":3306},[10,7225,3309],{},[10,7227,3312],{},[69,7229,7230],{"className":71,"code":3315,"language":73,"meta":74,"style":74},[76,7231,7232,7236,7240,7244],{"__ignoreMap":74},[79,7233,7234],{"class":81,"line":82},[79,7235,3322],{},[79,7237,7238],{"class":81,"line":88},[79,7239,104],{"emptyLinePlaceholder":103},[79,7241,7242],{"class":81,"line":94},[79,7243,3331],{},[79,7245,7246],{"class":81,"line":100},[79,7247,3336],{},[707,7249,7250],{"title":3339,"type":1334},[10,7251,3342],{},[28,7253,3345],{"id":3345},[10,7255,3348],{},[707,7257,7258],{"title":3351,"type":3352},[10,7259,3355],{},[28,7261,3358],{"id":3358},[10,7263,3361],{},[42,7265,7266,7270,7274],{},[45,7267,3366,7268],{},[76,7269,2935],{},[45,7271,3371,7272],{},[76,7273,2938],{},[45,7275,3376],{},[10,7277,3379],{},[28,7279,476],{"id":476},[10,7281,3384],{},[10,7283,3387],{},[510,7285,512],{},{"title":74,"searchDepth":88,"depth":88,"links":7287},[7288,7289,7290,7291,7292,7293,7294,7295],{"id":2942,"depth":88,"text":2942},{"id":3038,"depth":88,"text":2935},{"id":3142,"depth":88,"text":2938},{"id":3178,"depth":88,"text":2967},{"id":3306,"depth":88,"text":3306},{"id":3345,"depth":88,"text":3345},{"id":3358,"depth":88,"text":3358},{"id":476,"depth":88,"text":476},{},{"title":2922,"description":3400},[3407,2967],{"id":4,"title":5,"body":7300,"description":523,"extension":524,"meta":7667,"navigation":103,"path":526,"publishDate":527,"published":103,"seo":7668,"stem":529,"tags":7669,"thumbnail":532,"updated":527,"__hash__":533},{"type":7,"value":7301,"toc":7657},[7302,7304,7309,7311,7313,7315,7317,7319,7331,7333,7335,7337,7393,7395,7421,7423,7425,7427,7429,7439,7441,7477,7479,7481,7483,7485,7495,7499,7501,7503,7505,7523,7525,7527,7529,7531,7533,7545,7547,7549,7613,7615,7620,7626,7632,7634,7648,7650,7655],[10,7303,12],{},[10,7305,15,7306,23],{},[17,7307,22],{"href":19,"rel":7308},[21],[10,7310,26],{},[28,7312,31],{"id":30},[10,7314,34],{},[10,7316,37],{},[10,7318,40],{},[42,7320,7321,7323,7325,7327,7329],{},[45,7322,47],{},[45,7324,50],{},[45,7326,53],{},[45,7328,56],{},[45,7330,59],{},[28,7332,47],{"id":47},[10,7334,64],{},[10,7336,67],{},[69,7338,7339],{"className":71,"code":72,"language":73,"meta":74,"style":74},[76,7340,7341,7345,7349,7353,7357,7361,7365,7369,7373,7377,7381,7385,7389],{"__ignoreMap":74},[79,7342,7343],{"class":81,"line":82},[79,7344,85],{},[79,7346,7347],{"class":81,"line":88},[79,7348,91],{},[79,7350,7351],{"class":81,"line":94},[79,7352,97],{},[79,7354,7355],{"class":81,"line":100},[79,7356,104],{"emptyLinePlaceholder":103},[79,7358,7359],{"class":81,"line":107},[79,7360,110],{},[79,7362,7363],{"class":81,"line":113},[79,7364,116],{},[79,7366,7367],{"class":81,"line":119},[79,7368,97],{},[79,7370,7371],{"class":81,"line":124},[79,7372,104],{"emptyLinePlaceholder":103},[79,7374,7375],{"class":81,"line":129},[79,7376,132],{},[79,7378,7379],{"class":81,"line":135},[79,7380,138],{},[79,7382,7383],{"class":81,"line":141},[79,7384,97],{},[79,7386,7387],{"class":81,"line":146},[79,7388,104],{"emptyLinePlaceholder":103},[79,7390,7391],{"class":81,"line":151},[79,7392,154],{},[10,7394,157],{},[159,7396,7397,7401,7407,7413],{},[45,7398,7399,166],{},[76,7400,165],{},[45,7402,7403,171,7405,175],{},[76,7404,165],{},[76,7406,174],{},[45,7408,7409,171,7411,175],{},[76,7410,174],{},[76,7412,182],{},[45,7414,7415,187,7417,187,7419,192],{},[76,7416,182],{},[76,7418,174],{},[76,7420,165],{},[10,7422,195],{},[28,7424,50],{"id":198},[10,7426,201],{},[10,7428,204],{},[42,7430,7431,7433,7435,7437],{},[45,7432,209],{},[45,7434,212],{},[45,7436,215],{},[45,7438,218],{},[10,7440,221],{},[69,7442,7443],{"className":71,"code":224,"language":73,"meta":74,"style":74},[76,7444,7445,7449,7453,7457,7461,7465,7469,7473],{"__ignoreMap":74},[79,7446,7447],{"class":81,"line":82},[79,7448,231],{},[79,7450,7451],{"class":81,"line":88},[79,7452,236],{},[79,7454,7455],{"class":81,"line":94},[79,7456,241],{},[79,7458,7459],{"class":81,"line":100},[79,7460,246],{},[79,7462,7463],{"class":81,"line":107},[79,7464,104],{"emptyLinePlaceholder":103},[79,7466,7467],{"class":81,"line":113},[79,7468,255],{},[79,7470,7471],{"class":81,"line":119},[79,7472,260],{},[79,7474,7475],{"class":81,"line":124},[79,7476,265],{},[10,7478,268],{},[28,7480,53],{"id":53},[10,7482,273],{},[10,7484,276],{},[42,7486,7487,7491,7493],{},[45,7488,7489,284],{},[76,7490,283],{},[45,7492,287],{},[45,7494,290],{},[10,7496,7497,295],{},[76,7498,283],{},[10,7500,298],{},[28,7502,56],{"id":56},[10,7504,303],{},[42,7506,7507,7515,7519],{},[45,7508,308,7509,187,7511,187,7513],{},[76,7510,311],{},[76,7512,314],{},[76,7514,317],{},[45,7516,7517,323],{},[76,7518,322],{},[45,7520,7521,284],{},[76,7522,328],{},[10,7524,331],{},[10,7526,334],{},[28,7528,59],{"id":59},[10,7530,339],{},[10,7532,342],{},[159,7534,7535,7537,7539,7541,7543],{},[45,7536,347],{},[45,7538,350],{},[45,7540,353],{},[45,7542,356],{},[45,7544,359],{},[28,7546,362],{"id":362},[10,7548,365],{},[69,7550,7551],{"className":71,"code":368,"language":73,"meta":74,"style":74},[76,7552,7553,7557,7561,7565,7569,7573,7577,7581,7585,7589,7593,7597,7601,7605,7609],{"__ignoreMap":74},[79,7554,7555],{"class":81,"line":82},[79,7556,375],{},[79,7558,7559],{"class":81,"line":88},[79,7560,104],{"emptyLinePlaceholder":103},[79,7562,7563],{"class":81,"line":94},[79,7564,384],{},[79,7566,7567],{"class":81,"line":100},[79,7568,389],{},[79,7570,7571],{"class":81,"line":107},[79,7572,394],{},[79,7574,7575],{"class":81,"line":113},[79,7576,104],{"emptyLinePlaceholder":103},[79,7578,7579],{"class":81,"line":119},[79,7580,403],{},[79,7582,7583],{"class":81,"line":124},[79,7584,408],{},[79,7586,7587],{"class":81,"line":129},[79,7588,413],{},[79,7590,7591],{"class":81,"line":135},[79,7592,104],{"emptyLinePlaceholder":103},[79,7594,7595],{"class":81,"line":141},[79,7596,422],{},[79,7598,7599],{"class":81,"line":146},[79,7600,427],{},[79,7602,7603],{"class":81,"line":151},[79,7604,413],{},[79,7606,7607],{"class":81,"line":434},[79,7608,104],{"emptyLinePlaceholder":103},[79,7610,7611],{"class":81,"line":439},[79,7612,442],{},[10,7614,445],{},[69,7616,7618],{"className":7617,"code":450,"language":451,"meta":74},[449],[76,7619,450],{"__ignoreMap":74},[10,7621,456,7622,460,7624,464],{},[76,7623,459],{},[76,7625,463],{},[10,7627,467,7628,470,7630,473],{},[76,7629,322],{},[76,7631,283],{},[28,7633,476],{"id":476},[42,7635,7636,7638,7640,7642,7644,7646],{},[45,7637,481],{},[45,7639,484],{},[45,7641,487],{},[45,7643,490],{},[45,7645,493],{},[45,7647,496],{},[10,7649,499],{},[10,7651,502,7652,508],{},[17,7653,507],{"href":505,"rel":7654},[21],[510,7656,512],{},{"title":74,"searchDepth":88,"depth":88,"links":7658},[7659,7660,7661,7662,7663,7664,7665,7666],{"id":30,"depth":88,"text":31},{"id":47,"depth":88,"text":47},{"id":198,"depth":88,"text":50},{"id":53,"depth":88,"text":53},{"id":56,"depth":88,"text":56},{"id":59,"depth":88,"text":59},{"id":362,"depth":88,"text":362},{"id":476,"depth":88,"text":476},{},{"title":5,"description":523},[531],{"id":3782,"title":3783,"body":7671,"description":4200,"extension":524,"meta":7993,"navigation":103,"path":4202,"publishDate":4203,"published":103,"seo":7994,"stem":4205,"tags":7995,"thumbnail":4207,"updated":4203,"__hash__":4208},{"type":7,"value":7672,"toc":7985},[7673,7675,7677,7679,7681,7683,7691,7696,7698,7704,7728,7738,7743,7745,7749,7785,7791,7797,7805,7825,7827,7831,7867,7871,7875,7895,7897,7903,7939,7945,7957,7959,7981,7983],[10,7674,12],{},[10,7676,3790],{},[10,7678,3793],{},[28,7680,3797],{"id":3796},[10,7682,3800],{},[10,7684,7685,187,7687,187,7689,3812],{},[76,7686,3805],{},[76,7688,3808],{},[76,7690,3811],{},[10,7692,3815,7693,3821],{},[17,7694,3820],{"href":3818,"rel":7695},[21],[28,7697,3825],{"id":3824},[10,7699,3828,7700,3831,7702,3835],{},[76,7701,784],{},[76,7703,3834],{},[69,7705,7706],{"className":71,"code":3838,"language":73,"meta":74,"style":74},[76,7707,7708,7712,7716,7720,7724],{"__ignoreMap":74},[79,7709,7710],{"class":81,"line":82},[79,7711,3845],{},[79,7713,7714],{"class":81,"line":88},[79,7715,756],{},[79,7717,7718],{"class":81,"line":94},[79,7719,97],{},[79,7721,7722],{"class":81,"line":100},[79,7723,104],{"emptyLinePlaceholder":103},[79,7725,7726],{"class":81,"line":107},[79,7727,3862],{},[10,7729,3865,7730,3869,7732,3873,7734,3876,7736,3879],{},[76,7731,3868],{},[76,7733,3872],{},[76,7735,3872],{},[76,7737,3834],{},[10,7739,3882,7740,508],{},[17,7741,3887],{"href":3885,"rel":7742},[21],[28,7744,3890],{"id":3890},[10,7746,3893,7747,3897],{},[76,7748,3896],{},[69,7750,7751],{"className":71,"code":3900,"language":73,"meta":74,"style":74},[76,7752,7753,7757,7761,7765,7769,7773,7777,7781],{"__ignoreMap":74},[79,7754,7755],{"class":81,"line":82},[79,7756,3845],{},[79,7758,7759],{"class":81,"line":88},[79,7760,756],{},[79,7762,7763],{"class":81,"line":94},[79,7764,3915],{},[79,7766,7767],{"class":81,"line":100},[79,7768,3920],{},[79,7770,7771],{"class":81,"line":107},[79,7772,632],{},[79,7774,7775],{"class":81,"line":113},[79,7776,97],{},[79,7778,7779],{"class":81,"line":119},[79,7780,104],{"emptyLinePlaceholder":103},[79,7782,7783],{"class":81,"line":124},[79,7784,3937],{},[10,7786,3940,7787,3944,7789,3948],{},[76,7788,3943],{},[76,7790,3947],{},[10,7792,7793,3953,7795,3956],{},[76,7794,3868],{},[76,7796,3896],{},[10,7798,3959,7799,3963,7801,3966,7803,3969],{},[76,7800,3962],{},[76,7802,3872],{},[76,7804,3834],{},[69,7806,7807],{"className":71,"code":3972,"language":73,"meta":74,"style":74},[76,7808,7809,7813,7817,7821],{"__ignoreMap":74},[79,7810,7811],{"class":81,"line":82},[79,7812,3979],{},[79,7814,7815],{"class":81,"line":88},[79,7816,3984],{},[79,7818,7819],{"class":81,"line":94},[79,7820,104],{"emptyLinePlaceholder":103},[79,7822,7823],{"class":81,"line":100},[79,7824,3993],{},[28,7826,3997],{"id":3996},[10,7828,4000,7829,4004],{},[76,7830,4003],{},[69,7832,7833],{"className":71,"code":4007,"language":73,"meta":74,"style":74},[76,7834,7835,7839,7843,7847,7851,7855,7859,7863],{"__ignoreMap":74},[79,7836,7837],{"class":81,"line":82},[79,7838,3845],{},[79,7840,7841],{"class":81,"line":88},[79,7842,756],{},[79,7844,7845],{"class":81,"line":94},[79,7846,3915],{},[79,7848,7849],{"class":81,"line":100},[79,7850,3920],{},[79,7852,7853],{"class":81,"line":107},[79,7854,632],{},[79,7856,7857],{"class":81,"line":113},[79,7858,97],{},[79,7860,7861],{"class":81,"line":119},[79,7862,104],{"emptyLinePlaceholder":103},[79,7864,7865],{"class":81,"line":124},[79,7866,4042],{},[10,7868,4045,7869,4048],{},[76,7870,3896],{},[10,7872,7873,4053],{},[76,7874,3962],{},[69,7876,7877],{"className":71,"code":4056,"language":73,"meta":74,"style":74},[76,7878,7879,7883,7887,7891],{"__ignoreMap":74},[79,7880,7881],{"class":81,"line":82},[79,7882,3979],{},[79,7884,7885],{"class":81,"line":88},[79,7886,3984],{},[79,7888,7889],{"class":81,"line":94},[79,7890,104],{"emptyLinePlaceholder":103},[79,7892,7893],{"class":81,"line":100},[79,7894,4042],{},[28,7896,4077],{"id":4077},[10,7898,7899,4082,7901,4086],{},[76,7900,4003],{},[76,7902,4085],{},[69,7904,7905],{"className":71,"code":4089,"language":73,"meta":74,"style":74},[76,7906,7907,7911,7915,7919,7923,7927,7931,7935],{"__ignoreMap":74},[79,7908,7909],{"class":81,"line":82},[79,7910,3845],{},[79,7912,7913],{"class":81,"line":88},[79,7914,756],{},[79,7916,7917],{"class":81,"line":94},[79,7918,3915],{},[79,7920,7921],{"class":81,"line":100},[79,7922,3920],{},[79,7924,7925],{"class":81,"line":107},[79,7926,632],{},[79,7928,7929],{"class":81,"line":113},[79,7930,97],{},[79,7932,7933],{"class":81,"line":119},[79,7934,104],{"emptyLinePlaceholder":103},[79,7936,7937],{"class":81,"line":124},[79,7938,4124],{},[10,7940,7941,4130,7943,4134],{},[76,7942,4129],{},[76,7944,4133],{},[10,7946,4137,7947,4140,7949,4143,7951,4146,7953,4149,7955,4152],{},[76,7948,3872],{},[76,7950,3834],{},[76,7952,3868],{},[76,7954,4133],{},[76,7956,3868],{},[28,7958,476],{"id":476},[42,7960,7961,7965,7967,7973,7977],{},[45,7962,4159,7963,4162],{},[76,7964,3872],{},[45,7966,4165],{},[45,7968,7969,3963,7971,4172],{},[76,7970,3962],{},[76,7972,3834],{},[45,7974,4175,7975,4179],{},[76,7976,4178],{},[45,7978,4182,7979,4186],{},[76,7980,4185],{},[10,7982,4189],{},[510,7984,512],{},{"title":74,"searchDepth":88,"depth":88,"links":7986},[7987,7988,7989,7990,7991,7992],{"id":3796,"depth":88,"text":3797},{"id":3824,"depth":88,"text":3825},{"id":3890,"depth":88,"text":3890},{"id":3996,"depth":88,"text":3997},{"id":4077,"depth":88,"text":4077},{"id":476,"depth":88,"text":476},{},{"title":3783,"description":4200},[531],{"id":4210,"title":4211,"body":7997,"description":4592,"extension":524,"meta":8292,"navigation":103,"path":4594,"publishDate":4595,"published":103,"seo":8293,"stem":4597,"tags":8294,"thumbnail":4599,"updated":4595,"__hash__":4600},{"type":7,"value":7998,"toc":8285},[7999,8001,8003,8005,8007,8009,8011,8016,8018,8022,8066,8074,8086,8088,8108,8110,8118,8120,8124,8168,8172,8184,8186,8206,8216,8220,8225,8227,8229,8237,8239,8257,8261,8263,8281,8283],[10,8000,12],{},[10,8002,4218],{},[10,8004,4221],{},[28,8006,4225],{"id":4224},[10,8008,4228],{},[10,8010,4231],{},[10,8012,4234,8013,4240],{},[17,8014,4239],{"href":4237,"rel":8015},[21],[28,8017,4243],{"id":4243},[10,8019,4246,8020,4250],{},[76,8021,4249],{},[69,8023,8024],{"className":71,"code":4253,"language":73,"meta":74,"style":74},[76,8025,8026,8030,8034,8038,8042,8046,8050,8054,8058,8062],{"__ignoreMap":74},[79,8027,8028],{"class":81,"line":82},[79,8029,4260],{},[79,8031,8032],{"class":81,"line":88},[79,8033,4265],{},[79,8035,8036],{"class":81,"line":94},[79,8037,4270],{},[79,8039,8040],{"class":81,"line":100},[79,8041,632],{},[79,8043,8044],{"class":81,"line":107},[79,8045,4279],{},[79,8047,8048],{"class":81,"line":113},[79,8049,4284],{},[79,8051,8052],{"class":81,"line":119},[79,8053,632],{},[79,8055,8056],{"class":81,"line":124},[79,8057,97],{},[79,8059,8060],{"class":81,"line":129},[79,8061,104],{"emptyLinePlaceholder":103},[79,8063,8064],{"class":81,"line":135},[79,8065,4301],{},[10,8067,8068,4307,8070,4311,8072,4315],{},[76,8069,4306],{},[76,8071,4310],{},[76,8073,4314],{},[69,8075,8076],{"className":71,"code":4318,"language":73,"meta":74,"style":74},[76,8077,8078,8082],{"__ignoreMap":74},[79,8079,8080],{"class":81,"line":82},[79,8081,4325],{},[79,8083,8084],{"class":81,"line":88},[79,8085,4330],{},[10,8087,4333],{},[69,8089,8090],{"className":71,"code":4336,"language":73,"meta":74,"style":74},[76,8091,8092,8096,8100,8104],{"__ignoreMap":74},[79,8093,8094],{"class":81,"line":82},[79,8095,4343],{},[79,8097,8098],{"class":81,"line":88},[79,8099,104],{"emptyLinePlaceholder":103},[79,8101,8102],{"class":81,"line":94},[79,8103,4352],{},[79,8105,8106],{"class":81,"line":100},[79,8107,4357],{},[10,8109,4360],{},[69,8111,8112],{"className":71,"code":4363,"language":73,"meta":74,"style":74},[76,8113,8114],{"__ignoreMap":74},[79,8115,8116],{"class":81,"line":82},[79,8117,4363],{},[28,8119,4373],{"id":4372},[10,8121,4376,8122,4380],{},[76,8123,4379],{},[69,8125,8126],{"className":71,"code":4383,"language":73,"meta":74,"style":74},[76,8127,8128,8132,8136,8140,8144,8148,8152,8156,8160,8164],{"__ignoreMap":74},[79,8129,8130],{"class":81,"line":82},[79,8131,4260],{},[79,8133,8134],{"class":81,"line":88},[79,8135,4265],{},[79,8137,8138],{"class":81,"line":94},[79,8139,4270],{},[79,8141,8142],{"class":81,"line":100},[79,8143,632],{},[79,8145,8146],{"class":81,"line":107},[79,8147,4279],{},[79,8149,8150],{"class":81,"line":113},[79,8151,4284],{},[79,8153,8154],{"class":81,"line":119},[79,8155,632],{},[79,8157,8158],{"class":81,"line":124},[79,8159,97],{},[79,8161,8162],{"class":81,"line":129},[79,8163,104],{"emptyLinePlaceholder":103},[79,8165,8166],{"class":81,"line":135},[79,8167,4426],{},[10,8169,8170,4431],{},[76,8171,4379],{},[69,8173,8174],{"className":71,"code":4434,"language":73,"meta":74,"style":74},[76,8175,8176,8180],{"__ignoreMap":74},[79,8177,8178],{"class":81,"line":82},[79,8179,4441],{},[79,8181,8182],{"class":81,"line":88},[79,8183,4446],{},[10,8185,4449],{},[69,8187,8188],{"className":71,"code":4452,"language":73,"meta":74,"style":74},[76,8189,8190,8194,8198,8202],{"__ignoreMap":74},[79,8191,8192],{"class":81,"line":82},[79,8193,4459],{},[79,8195,8196],{"class":81,"line":88},[79,8197,104],{"emptyLinePlaceholder":103},[79,8199,8200],{"class":81,"line":94},[79,8201,4468],{},[79,8203,8204],{"class":81,"line":100},[79,8205,4473],{},[10,8207,8208,4478,8210,187,8212,187,8214,4488],{},[76,8209,4379],{},[76,8211,4481],{},[76,8213,4484],{},[76,8215,4487],{},[10,8217,4491,8218,4495],{},[76,8219,4494],{},[10,8221,4498,8222,4504],{},[17,8223,4503],{"href":4501,"rel":8224},[21],[28,8226,4508],{"id":4507},[10,8228,4511],{},[69,8230,8231],{"className":71,"code":4514,"language":73,"meta":74,"style":74},[76,8232,8233],{"__ignoreMap":74},[79,8234,8235],{"class":81,"line":82},[79,8236,4514],{},[10,8238,4523],{},[42,8240,8241,8245,8251,8255],{},[45,8242,8243,4530],{},[76,8244,4481],{},[45,8246,8247,4535,8249,4539],{},[76,8248,806],{},[76,8250,4538],{},[45,8252,8253,4545],{},[76,8254,4544],{},[45,8256,4548],{},[10,8258,4551,8259,4554],{},[76,8260,4379],{},[28,8262,476],{"id":476},[42,8264,8265,8269,8271,8275,8279],{},[45,8266,8267,4563],{},[76,8268,4249],{},[45,8270,4566],{},[45,8272,8273,4571],{},[76,8274,4379],{},[45,8276,8277,4576],{},[76,8278,4379],{},[45,8280,4579],{},[10,8282,4582],{},[510,8284,512],{},{"title":74,"searchDepth":88,"depth":88,"links":8286},[8287,8288,8289,8290,8291],{"id":4224,"depth":88,"text":4225},{"id":4243,"depth":88,"text":4243},{"id":4372,"depth":88,"text":4373},{"id":4507,"depth":88,"text":4508},{"id":476,"depth":88,"text":476},{},{"title":4211,"description":4592},[531],{"id":4602,"title":4603,"body":8296,"description":5018,"extension":524,"meta":8618,"navigation":103,"path":5020,"publishDate":5021,"published":103,"seo":8619,"stem":5023,"tags":8620,"thumbnail":5025,"updated":5026,"__hash__":5027},{"type":7,"value":8297,"toc":8610},[8298,8300,8304,8306,8310,8314,8316,8318,8322,8328,8330,8334,8338,8346,8348,8384,8388,8400,8402,8406,8420,8422,8454,8462,8476,8480,8482,8484,8524,8536,8544,8554,8560,8572,8574,8578,8604,8608],[10,8299,12],{},[10,8301,4610,8302,4613],{},[76,8303,4133],{},[28,8305,4617],{"id":4616},[10,8307,8308,4622],{},[76,8309,4133],{},[10,8311,4625,8312,4628],{},[76,8313,4133],{},[10,8315,4631],{},[28,8317,4634],{"id":4634},[10,8319,4637,8320,4640],{},[76,8321,4133],{},[42,8323,8324,8326],{},[45,8325,4645],{},[45,8327,4648],{},[28,8329,4645],{"id":4645},[10,8331,4653,8332,4656],{},[76,8333,4133],{},[10,8335,4659,8336,4662],{},[76,8337,3868],{},[69,8339,8340],{"className":71,"code":4665,"language":73,"meta":74,"style":74},[76,8341,8342],{"__ignoreMap":74},[79,8343,8344],{"class":81,"line":82},[79,8345,4665],{},[10,8347,4674],{},[69,8349,8350],{"className":71,"code":4677,"language":73,"meta":74,"style":74},[76,8351,8352,8356,8360,8364,8368,8372,8376,8380],{"__ignoreMap":74},[79,8353,8354],{"class":81,"line":82},[79,8355,3845],{},[79,8357,8358],{"class":81,"line":88},[79,8359,756],{},[79,8361,8362],{"class":81,"line":94},[79,8363,4692],{},[79,8365,8366],{"class":81,"line":100},[79,8367,4697],{},[79,8369,8370],{"class":81,"line":107},[79,8371,632],{},[79,8373,8374],{"class":81,"line":113},[79,8375,97],{},[79,8377,8378],{"class":81,"line":119},[79,8379,104],{"emptyLinePlaceholder":103},[79,8381,8382],{"class":81,"line":124},[79,8383,4714],{},[10,8385,4717,8386,4721],{},[76,8387,4720],{},[10,8389,8390,4727,8392,4730,8394,4733,8396,4730,8398,4740],{},[76,8391,4726],{},[76,8393,4133],{},[76,8395,3868],{},[76,8397,4736],{},[76,8399,4739],{},[28,8401,4648],{"id":4648},[10,8403,4745,8404,4748],{},[76,8405,4133],{},[42,8407,8408,8414],{},[45,8409,4753,8410,4756,8412,4760],{},[76,8411,4133],{},[76,8413,4759],{},[45,8415,4763,8416,4730,8418,4768],{},[76,8417,4133],{},[76,8419,806],{},[10,8421,4771],{},[69,8423,8424],{"className":71,"code":4774,"language":73,"meta":74,"style":74},[76,8425,8426,8430,8434,8438,8442,8446,8450],{"__ignoreMap":74},[79,8427,8428],{"class":81,"line":82},[79,8429,4781],{},[79,8431,8432],{"class":81,"line":88},[79,8433,104],{"emptyLinePlaceholder":103},[79,8435,8436],{"class":81,"line":94},[79,8437,4790],{},[79,8439,8440],{"class":81,"line":100},[79,8441,4795],{},[79,8443,8444],{"class":81,"line":107},[79,8445,97],{},[79,8447,8448],{"class":81,"line":113},[79,8449,104],{"emptyLinePlaceholder":103},[79,8451,8452],{"class":81,"line":119},[79,8453,4808],{},[10,8455,4811,8456,4814,8458,4818,8460,4721],{},[76,8457,4736],{},[76,8459,4817],{},[76,8461,4720],{},[4822,8463,8464],{},[10,8465,8466,4311,8468,4831,8470,4834,8472,4838,8474,4841],{},[76,8467,4828],{},[76,8469,1507],{},[76,8471,4759],{},[76,8473,4837],{},[76,8475,4759],{},[10,8477,4844,8478,4847],{},[76,8479,4133],{},[28,8481,4850],{"id":4850},[10,8483,4853],{},[69,8485,8486],{"className":71,"code":4856,"language":73,"meta":74,"style":74},[76,8487,8488,8492,8496,8500,8504,8508,8512,8516,8520],{"__ignoreMap":74},[79,8489,8490],{"class":81,"line":82},[79,8491,3845],{},[79,8493,8494],{"class":81,"line":88},[79,8495,756],{},[79,8497,8498],{"class":81,"line":94},[79,8499,4692],{},[79,8501,8502],{"class":81,"line":100},[79,8503,4697],{},[79,8505,8506],{"class":81,"line":107},[79,8507,632],{},[79,8509,8510],{"class":81,"line":113},[79,8511,97],{},[79,8513,8514],{"class":81,"line":119},[79,8515,104],{"emptyLinePlaceholder":103},[79,8517,8518],{"class":81,"line":124},[79,8519,4891],{},[79,8521,8522],{"class":81,"line":129},[79,8523,4808],{},[10,8525,8526,4901,8528,4904,8530,4908,8532,460,8534,4913],{},[76,8527,4900],{},[76,8529,4726],{},[76,8531,4907],{},[76,8533,4133],{},[76,8535,3868],{},[10,8537,4811,8538,4814,8540,4920,8542,4923],{},[76,8539,4133],{},[76,8541,4759],{},[76,8543,4817],{},[10,8545,4926,8546,4814,8548,4931,8550,4934,8552,4937],{},[76,8547,4133],{},[76,8549,806],{},[76,8551,4736],{},[76,8553,986],{},[10,8555,4940,8556,4944,8558,4947],{},[76,8557,4943],{},[76,8559,4133],{},[69,8561,8562],{"className":71,"code":4950,"language":73,"meta":74,"style":74},[76,8563,8564,8568],{"__ignoreMap":74},[79,8565,8566],{"class":81,"line":82},[79,8567,4957],{},[79,8569,8570],{"class":81,"line":88},[79,8571,4962],{},[28,8573,476],{"id":476},[10,8575,8576,4969],{},[76,8577,4133],{},[42,8579,8580,8588,8596,8598],{},[45,8581,8582,4976,8584,4730,8586,4760],{},[76,8583,4726],{},[76,8585,4133],{},[76,8587,3868],{},[45,8589,8590,4985,8592,4988,8594,4768],{},[76,8591,4907],{},[76,8593,4759],{},[76,8595,806],{},[45,8597,4993],{},[45,8599,4996,8600,4999,8602,5002],{},[76,8601,4943],{},[76,8603,4133],{},[10,8605,8606,5007],{},[76,8607,4133],{},[510,8609,512],{},{"title":74,"searchDepth":88,"depth":88,"links":8611},[8612,8613,8614,8615,8616,8617],{"id":4616,"depth":88,"text":4617},{"id":4634,"depth":88,"text":4634},{"id":4645,"depth":88,"text":4645},{"id":4648,"depth":88,"text":4648},{"id":4850,"depth":88,"text":4850},{"id":476,"depth":88,"text":476},{},{"title":4603,"description":5018},[531],[8622],{"id":8623,"title":8624,"author":8625,"body":8626,"description":9269,"extension":524,"meta":9270,"navigation":103,"path":9271,"publishDate":9272,"published":103,"publisher":9273,"seo":9274,"stem":9275,"tags":9276,"__hash__":9278},"books\u002Fbooks\u002F2025\u002Forganize-learned-from-docker.md","Docker&仮想サーバー完全入門","リブロワークス",{"type":7,"value":8627,"toc":9256},[8628,8636,8639,8643,8646,8649,8655,8659,8662,8714,8729,8732,8753,8756,8760,8766,8790,8800,8807,8812,8818,8831,8837,8845,8851,8899,8905,8930,8934,8941,8976,8982,8985,8988,9041,9044,9051,9065,9068,9085,9095,9119,9122,9129,9143,9154,9174,9186,9190,9193,9200,9206,9209,9212,9214,9217,9220,9250,9253],[10,8629,8630,8631,8635],{},"『",[17,8632,8624],{"href":8633,"rel":8634},"https:\u002F\u002Fbook.impress.co.jp\u002Fbooks\u002F1121101138",[21],"』を読了したため、本書を通して学んだことをまとめます。",[10,8637,8638],{},"まだ1周目で理解が浅い部分もあるため、Dockerを実際に使いながら必要に応じて追記していきます。",[28,8640,8642],{"id":8641},"dockerでホスト環境への影響を抑える","Dockerでホスト環境への影響を抑える",[10,8644,8645],{},"Dockerを利用すると、アプリケーションに必要なランタイムやライブラリをコンテナ内にまとめられます。",[10,8647,8648],{},"ホストOSへ依存関係を直接インストールする場面を減らせるため、開発環境を整理しやすくなります。また、DockerfileやComposeファイルを共有することで、チーム内で環境を再現しやすくなります。",[707,8650,8652],{"title":8651,"type":710},"ホストOSから完全に独立するわけではない",[10,8653,8654],{},"コンテナはホストのカーネルやDocker Engineを利用します。ボリューム、ポート、CPUアーキテクチャなど、ホスト環境との接点がなくなるわけではありません。",[28,8656,8658],{"id":8657},"dockerコマンドで操作対象を明示する","Dockerコマンドで操作対象を明示する",[10,8660,8661],{},"Docker CLIには、操作対象を含めて記述するコマンドがあります。",[69,8663,8667],{"className":8664,"code":8665,"language":8666,"meta":74,"style":74},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker container run nginx\ndocker image pull nginx\ndocker volume ls\ndocker network ls\n","bash",[76,8668,8669,8683,8695,8705],{"__ignoreMap":74},[79,8670,8671,8674,8677,8680],{"class":81,"line":82},[79,8672,8673],{"class":1608},"docker",[79,8675,8676],{"class":1319}," container",[79,8678,8679],{"class":1319}," run",[79,8681,8682],{"class":1319}," nginx\n",[79,8684,8685,8687,8690,8693],{"class":81,"line":88},[79,8686,8673],{"class":1608},[79,8688,8689],{"class":1319}," image",[79,8691,8692],{"class":1319}," pull",[79,8694,8682],{"class":1319},[79,8696,8697,8699,8702],{"class":81,"line":94},[79,8698,8673],{"class":1608},[79,8700,8701],{"class":1319}," volume",[79,8703,8704],{"class":1319}," ls\n",[79,8706,8707,8709,8712],{"class":81,"line":100},[79,8708,8673],{"class":1608},[79,8710,8711],{"class":1319}," network",[79,8713,8704],{"class":1319},[10,8715,8716,187,8719,187,8722,187,8725,8728],{},[76,8717,8718],{},"container",[76,8720,8721],{},"image",[76,8723,8724],{},"volume",[76,8726,8727],{},"network","のように対象が明示されるため、何を操作するコマンドなのか把握しやすくなります。",[10,8730,8731],{},"一方で、次の短い形式も現在利用できます。",[69,8733,8735],{"className":8664,"code":8734,"language":8666,"meta":74,"style":74},"docker run nginx\ndocker pull nginx\n",[76,8736,8737,8745],{"__ignoreMap":74},[79,8738,8739,8741,8743],{"class":81,"line":82},[79,8740,8673],{"class":1608},[79,8742,8679],{"class":1319},[79,8744,8682],{"class":1319},[79,8746,8747,8749,8751],{"class":81,"line":88},[79,8748,8673],{"class":1608},[79,8750,8692],{"class":1319},[79,8752,8682],{"class":1319},[10,8754,8755],{},"短い形式を古いという理由だけで避ける必要はありません。学習時には対象を含む形式も知っておくと、CLIの構造を理解しやすいと感じました。",[28,8757,8759],{"id":8758},"docker-compose-v2を利用する","Docker Compose V2を利用する",[10,8761,8762,8763,947],{},"現在のCompose CLIでは、ハイフンのない",[76,8764,8765],{},"docker compose",[69,8767,8769],{"className":8664,"code":8768,"language":8666,"meta":74,"style":74},"docker compose up\ndocker compose down\n",[76,8770,8771,8781],{"__ignoreMap":74},[79,8772,8773,8775,8778],{"class":81,"line":82},[79,8774,8673],{"class":1608},[79,8776,8777],{"class":1319}," compose",[79,8779,8780],{"class":1319}," up\n",[79,8782,8783,8785,8787],{"class":81,"line":88},[79,8784,8673],{"class":1608},[79,8786,8777],{"class":1319},[79,8788,8789],{"class":1319}," down\n",[10,8791,8792,8793,8796,8797,8799],{},"旧Compose V1で使われていた",[76,8794,8795],{},"docker-compose","とはコマンド形式が異なります。Docker DesktopにはCompose CLIが含まれているため、基本的には",[76,8798,8765],{},"を利用します。",[28,8801,8803,8804,1191],{"id":8802},"composeファイルはcomposeyamlを使う","Composeファイルは",[76,8805,8806],{},"compose.yaml",[10,8808,8809,8810,683],{},"Composeファイルの推奨ファイル名は",[76,8811,8806],{},[69,8813,8816],{"className":8814,"code":8815,"language":451,"meta":74},[449],"compose.yaml\n",[76,8817,8815],{"__ignoreMap":74},[10,8819,8820,8823,8824,679,8827,8830],{},[76,8821,8822],{},"compose.yml","も利用できます。また、",[76,8825,8826],{},"docker-compose.yaml",[76,8828,8829],{},"docker-compose.yml","も後方互換性のためサポートされています。",[10,8832,8833,8834,8836],{},"複数の候補が同じ場所にある場合は",[76,8835,8806],{},"が優先されるため、新しく作る場合はこの名前へ揃えると分かりやすくなります。",[28,8838,8840,8841,8844],{"id":8839},"トップレベルのversionは不要","トップレベルの",[76,8842,8843],{},"version","は不要",[10,8846,8847,8848,8850],{},"以前のComposeファイルでは、先頭に次のような",[76,8849,8843],{},"を書く例がありました。",[69,8852,8856],{"className":8853,"code":8854,"language":8855,"meta":74,"style":74},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","version: '3'\n\nservices:\n  web:\n    image: nginx\n","yaml",[76,8857,8858,8871,8875,8883,8890],{"__ignoreMap":74},[79,8859,8860,8862,8864,8866,8869],{"class":81,"line":82},[79,8861,8843],{"class":1305},[79,8863,1726],{"class":1301},[79,8865,1456],{"class":1301},[79,8867,8868],{"class":1319},"3",[79,8870,1461],{"class":1301},[79,8872,8873],{"class":81,"line":88},[79,8874,104],{"emptyLinePlaceholder":103},[79,8876,8877,8880],{"class":81,"line":94},[79,8878,8879],{"class":1305},"services",[79,8881,8882],{"class":1301},":\n",[79,8884,8885,8888],{"class":81,"line":100},[79,8886,8887],{"class":1305},"  web",[79,8889,8882],{"class":1301},[79,8891,8892,8895,8897],{"class":81,"line":107},[79,8893,8894],{"class":1305},"    image",[79,8896,1726],{"class":1301},[79,8898,8682],{"class":1319},[10,8900,8901,8902,8904],{},"現在、トップレベルの",[76,8903,8843],{},"は後方互換性のために残されたobsoleteな項目です。指定してもComposeは最新のスキーマでファイルを検証するため、新しいComposeファイルでは省略します。",[69,8906,8908],{"className":8853,"code":8907,"language":8855,"meta":74,"style":74},"services:\n  web:\n    image: nginx\n",[76,8909,8910,8916,8922],{"__ignoreMap":74},[79,8911,8912,8914],{"class":81,"line":82},[79,8913,8879],{"class":1305},[79,8915,8882],{"class":1301},[79,8917,8918,8920],{"class":81,"line":88},[79,8919,8887],{"class":1305},[79,8921,8882],{"class":1301},[79,8923,8924,8926,8928],{"class":81,"line":94},[79,8925,8894],{"class":1305},[79,8927,1726],{"class":1301},[79,8929,8682],{"class":1319},[28,8931,8933],{"id":8932},"restart-policyは用途に合わせて設定する","restart policyは用途に合わせて設定する",[10,8935,8936,8937,8940],{},"Composeのサービスには、コンテナを再起動する条件を",[76,8938,8939],{},"restart","で設定できます。",[69,8942,8944],{"className":8853,"code":8943,"language":8855,"meta":74,"style":74},"services:\n  web:\n    image: nginx\n    restart: always\n",[76,8945,8946,8952,8958,8966],{"__ignoreMap":74},[79,8947,8948,8950],{"class":81,"line":82},[79,8949,8879],{"class":1305},[79,8951,8882],{"class":1301},[79,8953,8954,8956],{"class":81,"line":88},[79,8955,8887],{"class":1305},[79,8957,8882],{"class":1301},[79,8959,8960,8962,8964],{"class":81,"line":94},[79,8961,8894],{"class":1305},[79,8963,1726],{"class":1301},[79,8965,8682],{"class":1319},[79,8967,8968,8971,8973],{"class":81,"line":100},[79,8969,8970],{"class":1305},"    restart",[79,8972,1726],{"class":1301},[79,8974,8975],{"class":1319}," always\n",[10,8977,8978,8981],{},[76,8979,8980],{},"always","を指定したコンテナは、停止した場合やDockerデーモンが再起動した場合に再起動されます。",[10,8983,8984],{},"常時稼働が必要なサービスでは便利ですが、学習用コンテナへ一律に指定すると、Docker起動時に意図しないコンテナまで立ち上がることがあります。必要性を考えて設定することが大切です。",[10,8986,8987],{},"主なrestart policyには次があります。",[1763,8989,8990,9000],{},[1766,8991,8992],{},[1769,8993,8994,8997],{},[1772,8995,8996],{},"値",[1772,8998,8999],{},"動作",[1782,9001,9002,9012,9022,9031],{},[1769,9003,9004,9009],{},[1787,9005,9006],{},[76,9007,9008],{},"no",[1787,9010,9011],{},"自動的に再起動しない",[1769,9013,9014,9019],{},[1787,9015,9016],{},[76,9017,9018],{},"on-failure",[1787,9020,9021],{},"エラー終了した場合に再起動する",[1769,9023,9024,9028],{},[1787,9025,9026],{},[76,9027,8980],{},[1787,9029,9030],{},"停止した場合に常に再起動する",[1769,9032,9033,9038],{},[1787,9034,9035],{},[76,9036,9037],{},"unless-stopped",[1787,9039,9040],{},"明示的に停止されていない限り再起動する",[28,9042,9043],{"id":9043},"コンテナのログを確認する",[10,9045,9046,9047,9050],{},"Composeで起動したサービスのログは",[76,9048,9049],{},"docker compose logs","で確認できます。",[69,9052,9054],{"className":8664,"code":9053,"language":8666,"meta":74,"style":74},"docker compose logs\n",[76,9055,9056],{"__ignoreMap":74},[79,9057,9058,9060,9062],{"class":81,"line":82},[79,9059,8673],{"class":1608},[79,9061,8777],{"class":1319},[79,9063,9064],{"class":1319}," logs\n",[10,9066,9067],{},"サービスを指定すると、対象のログだけを表示できます。",[69,9069,9071],{"className":8664,"code":9070,"language":8666,"meta":74,"style":74},"docker compose logs web\n",[76,9072,9073],{"__ignoreMap":74},[79,9074,9075,9077,9079,9082],{"class":81,"line":82},[79,9076,8673],{"class":1608},[79,9078,8777],{"class":1319},[79,9080,9081],{"class":1319}," logs",[79,9083,9084],{"class":1319}," web\n",[10,9086,9087,9088,9091,9092,947],{},"ログを継続して追いかける場合は",[76,9089,9090],{},"--follow","、末尾の行数を限定する場合は",[76,9093,9094],{},"--tail",[69,9096,9098],{"className":8664,"code":9097,"language":8666,"meta":74,"style":74},"docker compose logs --follow --tail 100 web\n",[76,9099,9100],{"__ignoreMap":74},[79,9101,9102,9104,9106,9108,9111,9114,9117],{"class":81,"line":82},[79,9103,8673],{"class":1608},[79,9105,8777],{"class":1319},[79,9107,9081],{"class":1319},[79,9109,9110],{"class":1319}," --follow",[79,9112,9113],{"class":1319}," --tail",[79,9115,9116],{"class":1887}," 100",[79,9118,9084],{"class":1319},[28,9120,9121],{"id":9121},"イメージを再ビルドする",[10,9123,9124,9125,9128],{},"Composeでイメージをビルドするには",[76,9126,9127],{},"docker compose build","を使います。",[69,9130,9132],{"className":8664,"code":9131,"language":8666,"meta":74,"style":74},"docker compose build\n",[76,9133,9134],{"__ignoreMap":74},[79,9135,9136,9138,9140],{"class":81,"line":82},[79,9137,8673],{"class":1608},[79,9139,8777],{"class":1319},[79,9141,9142],{"class":1319}," build\n",[10,9144,9145,9146,9149,9150,9153],{},"コンテナの起動前にビルドも実行したい場合は、",[76,9147,9148],{},"docker compose up","へ",[76,9151,9152],{},"--build","を付けられます。",[69,9155,9157],{"className":8664,"code":9156,"language":8666,"meta":74,"style":74},"docker compose up --detach --build\n",[76,9158,9159],{"__ignoreMap":74},[79,9160,9161,9163,9165,9168,9171],{"class":81,"line":82},[79,9162,8673],{"class":1608},[79,9164,8777],{"class":1319},[79,9166,9167],{"class":1319}," up",[79,9169,9170],{"class":1319}," --detach",[79,9172,9173],{"class":1319}," --build\n",[10,9175,9176,9178,9179,803,9182,9185],{},[76,9177,9148],{},"は、サービスの設定やイメージが変更されている場合にコンテナを再作成します。ただし、Dockerfileやビルド対象を確実に再ビルドしてから起動したい場合は、",[76,9180,9181],{},"build",[76,9183,9184],{},"up --build","を明示すると意図が分かりやすくなります。",[28,9187,9189],{"id":9188},"dev-containerで開発環境をコンテナ化する","Dev Containerで開発環境をコンテナ化する",[10,9191,9192],{},"VS CodeのDev Containers拡張機能を使うと、コンテナを開発環境として利用できます。",[10,9194,9195,9196,9199],{},"プロジェクト内の",[76,9197,9198],{},".devcontainer\u002Fdevcontainer.json","へ設定を記述し、コンテナ内のランタイム、ツール、VS Code拡張機能などを揃えられます。",[69,9201,9204],{"className":9202,"code":9203,"language":451,"meta":74},[449],".devcontainer\u002F\n  devcontainer.json\n",[76,9205,9203],{"__ignoreMap":74},[10,9207,9208],{},"ソースコードをコンテナへマウントし、ターミナル、補完、コードナビゲーション、デバッグなどを普段のVS Codeと近い操作感で利用できます。",[10,9210,9211],{},"環境構築手順を文章だけで共有するよりも、実行環境そのものを設定として共有できる点が便利だと感じました。",[28,9213,476],{"id":476},[10,9215,9216],{},"本書を通して、Dockerの基本操作だけでなく、Composeによる複数コンテナの管理や、開発環境をコンテナ化する考え方を学べました。",[10,9218,9219],{},"特に、次の点を今後の開発でも意識したいです。",[42,9221,9222,9225,9230,9235,9241,9244,9247],{},[45,9223,9224],{},"Docker CLIで何を操作しているか理解する",[45,9226,9227,9228,1191],{},"Compose V2の",[76,9229,8765],{},[45,9231,8803,9232,9234],{},[76,9233,8806],{},"へ揃える",[45,9236,9237,9238,9240],{},"不要な",[76,9239,8843],{},"を記述しない",[45,9242,9243],{},"restart policyを用途に合わせて設定する",[45,9245,9246],{},"ログ確認と再ビルドのコマンドを使い分ける",[45,9248,9249],{},"Dev Containerで再現可能な開発環境を試す",[10,9251,9252],{},"Dockerはコマンドを覚えるだけでなく、イメージ、コンテナ、ボリューム、ネットワークの関係を実際に操作しながら理解していきたいです。",[510,9254,9255],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":74,"searchDepth":88,"depth":88,"links":9257},[9258,9259,9260,9261,9263,9264,9265,9266,9267,9268],{"id":8641,"depth":88,"text":8642},{"id":8657,"depth":88,"text":8658},{"id":8758,"depth":88,"text":8759},{"id":8802,"depth":88,"text":9262},"Composeファイルはcompose.yamlを使う",{"id":8839,"depth":88,"text":8839},{"id":8932,"depth":88,"text":8933},{"id":9043,"depth":88,"text":9043},{"id":9121,"depth":88,"text":9121},{"id":9188,"depth":88,"text":9189},{"id":476,"depth":88,"text":476},"『Docker&仮想サーバー完全入門』を読了したため、本書を通して学んだことをまとめます。",{},"\u002Fbooks\u002F2025\u002Forganize-learned-from-docker","2025-02-22","インプレス",{"title":8624,"description":9269},"books\u002F2025\u002Forganize-learned-from-docker",[9277],"Docker","tZTXcHlrKtyN5T4H4BpRH6Dc272-Srw05uyFSfG7w5Q",1786277110518]