[{"data":1,"prerenderedAt":10450},["ShallowReactive",2],{"article:\u002Farticles\u002F2026\u002Fresolve-mac-system-data-storage-shortage-with-docker":3,"related-articles:\u002Farticles\u002F2026\u002Fresolve-mac-system-data-storage-shortage-with-docker":657,"search:articles":5741,"search:books":9798},{"id":4,"title":5,"body":6,"description":644,"extension":645,"meta":646,"navigation":647,"path":648,"publishDate":649,"published":647,"seo":650,"stem":651,"tags":652,"thumbnail":655,"updated":649,"__hash__":656},"articles\u002Farticles\u002F2026\u002Fresolve-mac-system-data-storage-shortage-with-docker.md","Macの「システムデータ」が267GBに増えた原因はDockerだった",{"type":7,"value":8,"toc":633},"minimark",[9,13,21,24,31,34,42,47,50,61,64,70,73,76,79,125,134,141,147,153,181,188,194,200,228,231,237,240,243,247,250,266,269,275,278,323,329,333,336,354,360,363,369,372,376,379,391,394,409,412,418,425,429,432,449,452,458,461,464,475,484,487,493,496,510,513,516,519,562,565,572,575,578,608,611,614,626,629],[10,11,12],"p",{},"こんにちは、Yuriです。",[10,14,15,16,20],{},"Xcodeをインストールしてアプリ開発するため、一応MacBookのストレージを確認したところ、「システムデータ」が ",[17,18,19],"strong",{},"267GB"," まで増えていました、、",[10,22,23],{},"システムデータはmacOSがまとめて表示している領域で、ストレージ設定を見ただけでは、何に容量を使っているのか全然分かりませんでした。",[10,25,26,27,30],{},"そこでターミナルから使用量を調べた結果、主な原因は ",[17,28,29],{},"Docker Desktopのデータ"," でした。",[10,32,33],{},"今回は、原因を特定した手順と、DockerのBuild Cache、Image、Volumeを整理して空き容量を増やした方法を紹介します。",[35,36,39],"article-callout",{"title":37,"type":38},"削除前に必要なデータを確認する","caution",[10,40,41],{},"この記事にはDockerのデータを削除するコマンドが登場します。必要なImageやVolumeまで削除しないよう、各コマンドの対象を確認し、DBなどの重要なデータは事前にバックアップしてください。",[43,44,46],"h2",{"id":45},"macのストレージ状況を確認する","Macのストレージ状況を確認する",[10,48,49],{},"macOSでは、次の順番でストレージの使用状況を確認できます。",[51,52,58],"pre",{"className":53,"code":55,"language":56,"meta":57},[54],"language-text","メニュー\n  ↓\nシステム設定\n  ↓\n一般\n  ↓\nストレージ\n","text","",[59,60,55],"code",{"__ignoreMap":57},[10,62,63],{},"今回確認したときは、システムデータだけで267GBを使用していました。",[51,65,68],{"className":66,"code":67,"language":56,"meta":57},[54],"システムデータ  267GB\n",[59,69,67],{"__ignoreMap":57},[10,71,72],{},"通常のファイル整理だけでは解消できそうになかったため、どのディレクトリが容量を使っているのか調べました。",[43,74,75],{"id":75},"容量を使っているディレクトリを調べる",[10,77,78],{},"まず、ホームディレクトリ直下の使用量を確認します。",[51,80,84],{"className":81,"code":82,"language":83,"meta":57,"style":57},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","du -h -d 1 ~ 2>\u002Fdev\u002Fnull | sort -h\n","bash",[59,85,86],{"__ignoreMap":57},[87,88,91,95,99,102,106,109,113,116,119,122],"span",{"class":89,"line":90},"line",1,[87,92,94],{"class":93},"sBMFI","du",[87,96,98],{"class":97},"sfazB"," -h",[87,100,101],{"class":97}," -d",[87,103,105],{"class":104},"sbssI"," 1",[87,107,108],{"class":97}," ~",[87,110,112],{"class":111},"sMK4o"," 2>",[87,114,115],{"class":97},"\u002Fdev\u002Fnull",[87,117,118],{"class":111}," |",[87,120,121],{"class":93}," sort",[87,123,124],{"class":97}," -h\n",[10,126,127,129,130,133],{},[59,128,94],{}," はディレクトリごとの使用量を表示するコマンドです。",[59,131,132],{},"-d 1"," を指定すると、1階層下までを集計できます。",[10,135,136,137,140],{},"結果を見ると、",[59,138,139],{},"~\u002FLibrary"," が約254GBを占めていました。",[51,142,145],{"className":143,"code":144,"language":56,"meta":57},[54],"254G  \u002FUsers\u002Fxxxxx\u002FLibrary\n",[59,146,144],{"__ignoreMap":57},[10,148,149,150,152],{},"次に、",[59,151,139],{}," の内訳を確認します。",[51,154,156],{"className":81,"code":155,"language":83,"meta":57,"style":57},"du -h -d 1 ~\u002FLibrary 2>\u002Fdev\u002Fnull | sort -h\n",[59,157,158],{"__ignoreMap":57},[87,159,160,162,164,166,168,171,173,175,177,179],{"class":89,"line":90},[87,161,94],{"class":93},[87,163,98],{"class":97},[87,165,101],{"class":97},[87,167,105],{"class":104},[87,169,170],{"class":97}," ~\u002FLibrary",[87,172,112],{"class":111},[87,174,115],{"class":97},[87,176,118],{"class":111},[87,178,121],{"class":93},[87,180,124],{"class":97},[10,182,183,184,187],{},"ここでは、",[59,185,186],{},"Containers"," が約210GBを使用していました。",[51,189,192],{"className":190,"code":191,"language":56,"meta":57},[54],"210G  \u002FUsers\u002Fxxxxx\u002FLibrary\u002FContainers\n",[59,193,191],{"__ignoreMap":57},[10,195,196,197,199],{},"さらに、",[59,198,186],{}," の中を調べます。",[51,201,203],{"className":81,"code":202,"language":83,"meta":57,"style":57},"du -h -d 1 ~\u002FLibrary\u002FContainers 2>\u002Fdev\u002Fnull | sort -h\n",[59,204,205],{"__ignoreMap":57},[87,206,207,209,211,213,215,218,220,222,224,226],{"class":89,"line":90},[87,208,94],{"class":93},[87,210,98],{"class":97},[87,212,101],{"class":97},[87,214,105],{"class":104},[87,216,217],{"class":97}," ~\u002FLibrary\u002FContainers",[87,219,112],{"class":111},[87,221,115],{"class":97},[87,223,118],{"class":111},[87,225,121],{"class":93},[87,227,124],{"class":97},[10,229,230],{},"すると、Docker Desktopのコンテナーディレクトリが約210GBを占めていることが分かりました。",[51,232,235],{"className":233,"code":234,"language":56,"meta":57},[54],"210G  \u002FUsers\u002Fxxxxx\u002FLibrary\u002FContainers\u002Fcom.docker.docker\n",[59,236,234],{"__ignoreMap":57},[10,238,239],{},"macOS版のDocker Desktopは、Linuxコンテナーを動かすための仮想ディスクをMac上に保存しています。",[10,241,242],{},"そのためDockerのImage、Volume、Build Cacheなどが増えると、macOSではシステムデータとして大きく表示されることがあります。",[43,244,246],{"id":245},"dockerの使用量を確認する","Dockerの使用量を確認する",[10,248,249],{},"Docker側の内訳は、次のコマンドで確認できます。",[51,251,253],{"className":81,"code":252,"language":83,"meta":57,"style":57},"docker system df\n",[59,254,255],{"__ignoreMap":57},[87,256,257,260,263],{"class":89,"line":90},[87,258,259],{"class":93},"docker",[87,261,262],{"class":97}," system",[87,264,265],{"class":97}," df\n",[10,267,268],{},"今回の主な結果は次のとおりでした。",[51,270,273],{"className":271,"code":272,"language":56,"meta":57},[54],"TYPE            TOTAL     SIZE\nImages          20        107.6GB\nContainers      12        526MB\nLocal Volumes   46        100.2GB\nBuild Cache     196       73GB\n",[59,274,272],{"__ignoreMap":57},[10,276,277],{},"特に容量が大きかったのは、次の3項目です。",[279,280,281,295],"table",{},[282,283,284],"thead",{},[285,286,287,291],"tr",{},[288,289,290],"th",{},"項目",[288,292,294],{"align":293},"right","容量",[296,297,298,307,315],"tbody",{},[285,299,300,304],{},[301,302,303],"td",{},"Images",[301,305,306],{"align":293},"107.6GB",[285,308,309,312],{},[301,310,311],{},"Local Volumes",[301,313,314],{"align":293},"100.2GB",[285,316,317,320],{},[301,318,319],{},"Build Cache",[301,321,322],{"align":293},"73GB",[10,324,325,328],{},[59,326,327],{},"docker system df"," の数値には共有レイヤーなども含まれるため、表示された値の合計が、そのままMac上で解放できる容量になるとは限りません。ただし、どの種類のデータから調べるべきかを判断する目安になります。",[43,330,332],{"id":331},"build-cacheを削除する","Build Cacheを削除する",[10,334,335],{},"まず、最も整理しやすいBuild Cacheを削除しました。",[51,337,339],{"className":81,"code":338,"language":83,"meta":57,"style":57},"docker builder prune -a\n",[59,340,341],{"__ignoreMap":57},[87,342,343,345,348,351],{"class":89,"line":90},[87,344,259],{"class":93},[87,346,347],{"class":97}," builder",[87,349,350],{"class":97}," prune",[87,352,353],{"class":97}," -a\n",[10,355,356,359],{},[59,357,358],{},"-a"," を付けると、現在使われていないBuild Cacheがまとめて削除されます。実行前には削除対象と確認メッセージが表示されます。",[10,361,362],{},"今回、Build Cacheは73GBから0Bになりました。",[51,364,367],{"className":365,"code":366,"language":56,"meta":57},[54],"73GB → 0B\n",[59,368,366],{"__ignoreMap":57},[10,370,371],{},"Build CacheはDocker Imageをビルドするときに再利用される中間データです。削除しても必要に応じて再生成されますが、次回のビルドには時間がかかる場合があります。",[43,373,375],{"id":374},"不要なimageを整理する","不要なImageを整理する",[10,377,378],{},"次に、保存されているImageを確認しました。",[51,380,382],{"className":81,"code":381,"language":83,"meta":57,"style":57},"docker images\n",[59,383,384],{"__ignoreMap":57},[87,385,386,388],{"class":89,"line":90},[87,387,259],{"class":93},[87,389,390],{"class":97}," images\n",[10,392,393],{},"まずは、タグがなく、コンテナーから参照されていないdangling imageを削除します。",[51,395,397],{"className":81,"code":396,"language":83,"meta":57,"style":57},"docker image prune\n",[59,398,399],{"__ignoreMap":57},[87,400,401,403,406],{"class":89,"line":90},[87,402,259],{"class":93},[87,404,405],{"class":97}," image",[87,407,408],{"class":97}," prune\n",[10,410,411],{},"今回の削除量は約2.4GBでした。",[51,413,416],{"className":414,"code":415,"language":56,"meta":57},[54],"Total reclaimed space: 2.355GB\n",[59,417,415],{"__ignoreMap":57},[10,419,420,421,424],{},"すべての未使用Imageを対象にする ",[59,422,423],{},"docker image prune -a"," もありますが、次回の起動時に再取得が必要になるImageまで削除されます。今回は一覧を確認しながら、必要なImageを残して整理しました。",[43,426,428],{"id":427},"大きなvolumeの中身を調べる","大きなVolumeの中身を調べる",[10,430,431],{},"Volumeごとの詳しい使用量は、次のコマンドで確認できます。",[51,433,435],{"className":81,"code":434,"language":83,"meta":57,"style":57},"docker system df -v\n",[59,436,437],{"__ignoreMap":57},[87,438,439,441,443,446],{"class":89,"line":90},[87,440,259],{"class":93},[87,442,262],{"class":97},[87,444,445],{"class":97}," df",[87,447,448],{"class":97}," -v\n",[10,450,451],{},"確認したところ、開発用DBのデータを保存しているVolumeが84.28GBを使用していました。",[51,453,456],{"className":454,"code":455,"language":56,"meta":57},[54],"xxxxxx_db-store  84.28GB\n",[59,457,455],{"__ignoreMap":57},[10,459,460],{},"このVolumeは現在利用しているプロジェクトのDBだったため、Volume自体は削除できません。そこで、DBの中に残っている不要な開発用スキーマを確認し、必要なデータではないことを確かめてから削除しました。",[10,462,463],{},"MySQLでは、次のSQLでスキーマを削除できます。",[51,465,469],{"className":466,"code":467,"language":468,"meta":57,"style":57},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","DROP SCHEMA schema_name;\n","sql",[59,470,471],{"__ignoreMap":57},[87,472,473],{"class":89,"line":90},[87,474,467],{},[35,476,478],{"title":477,"type":38},"DROP SCHEMAは元に戻せない",[10,479,480,483],{},[59,481,482],{},"DROP SCHEMA"," を実行すると、スキーマ内のテーブルやデータも削除されます。対象名をよく確認し、必要に応じてバックアップを取得してから実行してください。",[10,485,486],{},"不要なスキーマを整理した結果、Local Volumesの使用量は100.2GBから53.89GBまで減りました。",[51,488,491],{"className":489,"code":490,"language":56,"meta":57},[54],"100.2GB → 53.89GB\n",[59,492,490],{"__ignoreMap":57},[10,494,495],{},"なお、使われていないVolumeをまとめて削除する場合は、次のコマンドを利用できます。",[51,497,499],{"className":81,"code":498,"language":83,"meta":57,"style":57},"docker volume prune\n",[59,500,501],{"__ignoreMap":57},[87,502,503,505,508],{"class":89,"line":90},[87,504,259],{"class":93},[87,506,507],{"class":97}," volume",[87,509,408],{"class":97},[10,511,512],{},"VolumeにはDBなどの永続データが保存されていることがあります。名前や利用状況を確認せずに実行するのは避けたほうが安全です。",[43,514,515],{"id":515},"整理後の結果",[10,517,518],{},"整理前と整理後のDocker使用量は、次のようになりました。",[279,520,521,533],{},[282,522,523],{},[285,524,525,527,530],{},[288,526,290],{},[288,528,529],{"align":293},"整理前",[288,531,532],{"align":293},"整理後",[296,534,535,544,553],{},[285,536,537,539,541],{},[301,538,303],{},[301,540,306],{"align":293},[301,542,543],{"align":293},"50.4GB",[285,545,546,548,550],{},[301,547,311],{},[301,549,314],{"align":293},[301,551,552],{"align":293},"53.89GB",[285,554,555,557,559],{},[301,556,319],{},[301,558,322],{"align":293},[301,560,561],{"align":293},"0B",[10,563,564],{},"Build Cacheの削除と、不要なImage、DBスキーマの整理によって、Docker関連のデータを100GB以上削減できました。",[10,566,567,568,571],{},"Docker Desktopの仮想ディスクはスパースファイルとして管理されるため、Docker上でデータを削除しても、ファイル自体の見かけの最大サイズがすぐに小さくならない場合があります。実際の空き容量はmacOSのストレージ画面や ",[59,569,570],{},"df -h"," でも確認すると確実です。",[43,573,574],{"id":574},"まとめ",[10,576,577],{},"Macのシステムデータが異常に増えた場合は、次の順番で調べると原因を絞り込めます。",[579,580,581,590,596,602,605],"ol",{},[582,583,584,586,587,589],"li",{},[59,585,94],{}," で ",[59,588,139],{}," の使用量を確認する",[582,591,592,595],{},[59,593,594],{},"~\u002FLibrary\u002FContainers"," に大きなディレクトリがないか確認する",[582,597,598,599,601],{},"Docker Desktopが大きい場合は ",[59,600,327],{}," で内訳を確認する",[582,603,604],{},"不要なBuild CacheやImageを整理する",[582,606,607],{},"大きなVolumeは削除せず、保存されているデータの中身まで確認する",[10,609,610],{},"特にDocker Desktopを長期間使っていると、過去のBuild CacheやImage、開発用DBのデータが蓄積します。",[10,612,613],{},"Macの容量不足に気づいてから慌てないよう、定期的に次のコマンドで使用量を確認しておくと安心です。",[51,615,616],{"className":81,"code":252,"language":83,"meta":57,"style":57},[59,617,618],{"__ignoreMap":57},[87,619,620,622,624],{"class":89,"line":90},[87,621,259],{"class":93},[87,623,262],{"class":97},[87,625,265],{"class":97},[10,627,628],{},"Macのシステムデータが数百GBまで増えている場合は、Docker Desktopのデータが原因になっていないか確認してみてください。",[630,631,632],"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);}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 pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":57,"searchDepth":634,"depth":634,"links":635},2,[636,637,638,639,640,641,642,643],{"id":45,"depth":634,"text":46},{"id":75,"depth":634,"text":75},{"id":245,"depth":634,"text":246},{"id":331,"depth":634,"text":332},{"id":374,"depth":634,"text":375},{"id":427,"depth":634,"text":428},{"id":515,"depth":634,"text":515},{"id":574,"depth":634,"text":574},"Macの容量不足をきっかけに「システムデータ」が267GBまで肥大化した原因を調査し、DockerのBuild Cache、Image、DB Volumeを整理した手順を紹介します。","md",{},true,"\u002Farticles\u002F2026\u002Fresolve-mac-system-data-storage-shortage-with-docker","2026-08-10",{"title":5,"description":644},"articles\u002F2026\u002Fresolve-mac-system-data-storage-shortage-with-docker",[653,654],"Mac","Docker","\u002Fimages\u002Farticles\u002Fresolve-mac-system-data-storage-shortage-with-docker.png","KWp9gSbK5ytqT20G5ObWg3n5uQyKFKVp9aGSMNPqbgs",[658,1122,1848,3518,4007,4495,4923,5315],{"id":4,"title":5,"body":659,"description":644,"extension":645,"meta":1119,"navigation":647,"path":648,"publishDate":649,"published":647,"seo":1120,"stem":651,"tags":1121,"thumbnail":655,"updated":649,"__hash__":656},{"type":7,"value":660,"toc":1109},[661,663,667,669,673,675,679,681,683,688,690,695,697,699,701,727,733,737,742,746,772,776,781,785,811,813,818,820,822,824,826,838,840,845,847,877,881,883,885,899,903,905,910,912,914,916,926,928,940,942,947,951,953,955,969,971,976,978,980,988,994,996,1001,1003,1015,1017,1019,1021,1059,1061,1065,1067,1069,1089,1091,1093,1105,1107],[10,662,12],{},[10,664,15,665,20],{},[17,666,19],{},[10,668,23],{},[10,670,26,671,30],{},[17,672,29],{},[10,674,33],{},[35,676,677],{"title":37,"type":38},[10,678,41],{},[43,680,46],{"id":45},[10,682,49],{},[51,684,686],{"className":685,"code":55,"language":56,"meta":57},[54],[59,687,55],{"__ignoreMap":57},[10,689,63],{},[51,691,693],{"className":692,"code":67,"language":56,"meta":57},[54],[59,694,67],{"__ignoreMap":57},[10,696,72],{},[43,698,75],{"id":75},[10,700,78],{},[51,702,703],{"className":81,"code":82,"language":83,"meta":57,"style":57},[59,704,705],{"__ignoreMap":57},[87,706,707,709,711,713,715,717,719,721,723,725],{"class":89,"line":90},[87,708,94],{"class":93},[87,710,98],{"class":97},[87,712,101],{"class":97},[87,714,105],{"class":104},[87,716,108],{"class":97},[87,718,112],{"class":111},[87,720,115],{"class":97},[87,722,118],{"class":111},[87,724,121],{"class":93},[87,726,124],{"class":97},[10,728,729,129,731,133],{},[59,730,94],{},[59,732,132],{},[10,734,136,735,140],{},[59,736,139],{},[51,738,740],{"className":739,"code":144,"language":56,"meta":57},[54],[59,741,144],{"__ignoreMap":57},[10,743,149,744,152],{},[59,745,139],{},[51,747,748],{"className":81,"code":155,"language":83,"meta":57,"style":57},[59,749,750],{"__ignoreMap":57},[87,751,752,754,756,758,760,762,764,766,768,770],{"class":89,"line":90},[87,753,94],{"class":93},[87,755,98],{"class":97},[87,757,101],{"class":97},[87,759,105],{"class":104},[87,761,170],{"class":97},[87,763,112],{"class":111},[87,765,115],{"class":97},[87,767,118],{"class":111},[87,769,121],{"class":93},[87,771,124],{"class":97},[10,773,183,774,187],{},[59,775,186],{},[51,777,779],{"className":778,"code":191,"language":56,"meta":57},[54],[59,780,191],{"__ignoreMap":57},[10,782,196,783,199],{},[59,784,186],{},[51,786,787],{"className":81,"code":202,"language":83,"meta":57,"style":57},[59,788,789],{"__ignoreMap":57},[87,790,791,793,795,797,799,801,803,805,807,809],{"class":89,"line":90},[87,792,94],{"class":93},[87,794,98],{"class":97},[87,796,101],{"class":97},[87,798,105],{"class":104},[87,800,217],{"class":97},[87,802,112],{"class":111},[87,804,115],{"class":97},[87,806,118],{"class":111},[87,808,121],{"class":93},[87,810,124],{"class":97},[10,812,230],{},[51,814,816],{"className":815,"code":234,"language":56,"meta":57},[54],[59,817,234],{"__ignoreMap":57},[10,819,239],{},[10,821,242],{},[43,823,246],{"id":245},[10,825,249],{},[51,827,828],{"className":81,"code":252,"language":83,"meta":57,"style":57},[59,829,830],{"__ignoreMap":57},[87,831,832,834,836],{"class":89,"line":90},[87,833,259],{"class":93},[87,835,262],{"class":97},[87,837,265],{"class":97},[10,839,268],{},[51,841,843],{"className":842,"code":272,"language":56,"meta":57},[54],[59,844,272],{"__ignoreMap":57},[10,846,277],{},[279,848,849,857],{},[282,850,851],{},[285,852,853,855],{},[288,854,290],{},[288,856,294],{"align":293},[296,858,859,865,871],{},[285,860,861,863],{},[301,862,303],{},[301,864,306],{"align":293},[285,866,867,869],{},[301,868,311],{},[301,870,314],{"align":293},[285,872,873,875],{},[301,874,319],{},[301,876,322],{"align":293},[10,878,879,328],{},[59,880,327],{},[43,882,332],{"id":331},[10,884,335],{},[51,886,887],{"className":81,"code":338,"language":83,"meta":57,"style":57},[59,888,889],{"__ignoreMap":57},[87,890,891,893,895,897],{"class":89,"line":90},[87,892,259],{"class":93},[87,894,347],{"class":97},[87,896,350],{"class":97},[87,898,353],{"class":97},[10,900,901,359],{},[59,902,358],{},[10,904,362],{},[51,906,908],{"className":907,"code":366,"language":56,"meta":57},[54],[59,909,366],{"__ignoreMap":57},[10,911,371],{},[43,913,375],{"id":374},[10,915,378],{},[51,917,918],{"className":81,"code":381,"language":83,"meta":57,"style":57},[59,919,920],{"__ignoreMap":57},[87,921,922,924],{"class":89,"line":90},[87,923,259],{"class":93},[87,925,390],{"class":97},[10,927,393],{},[51,929,930],{"className":81,"code":396,"language":83,"meta":57,"style":57},[59,931,932],{"__ignoreMap":57},[87,933,934,936,938],{"class":89,"line":90},[87,935,259],{"class":93},[87,937,405],{"class":97},[87,939,408],{"class":97},[10,941,411],{},[51,943,945],{"className":944,"code":415,"language":56,"meta":57},[54],[59,946,415],{"__ignoreMap":57},[10,948,420,949,424],{},[59,950,423],{},[43,952,428],{"id":427},[10,954,431],{},[51,956,957],{"className":81,"code":434,"language":83,"meta":57,"style":57},[59,958,959],{"__ignoreMap":57},[87,960,961,963,965,967],{"class":89,"line":90},[87,962,259],{"class":93},[87,964,262],{"class":97},[87,966,445],{"class":97},[87,968,448],{"class":97},[10,970,451],{},[51,972,974],{"className":973,"code":455,"language":56,"meta":57},[54],[59,975,455],{"__ignoreMap":57},[10,977,460],{},[10,979,463],{},[51,981,982],{"className":466,"code":467,"language":468,"meta":57,"style":57},[59,983,984],{"__ignoreMap":57},[87,985,986],{"class":89,"line":90},[87,987,467],{},[35,989,990],{"title":477,"type":38},[10,991,992,483],{},[59,993,482],{},[10,995,486],{},[51,997,999],{"className":998,"code":490,"language":56,"meta":57},[54],[59,1000,490],{"__ignoreMap":57},[10,1002,495],{},[51,1004,1005],{"className":81,"code":498,"language":83,"meta":57,"style":57},[59,1006,1007],{"__ignoreMap":57},[87,1008,1009,1011,1013],{"class":89,"line":90},[87,1010,259],{"class":93},[87,1012,507],{"class":97},[87,1014,408],{"class":97},[10,1016,512],{},[43,1018,515],{"id":515},[10,1020,518],{},[279,1022,1023,1033],{},[282,1024,1025],{},[285,1026,1027,1029,1031],{},[288,1028,290],{},[288,1030,529],{"align":293},[288,1032,532],{"align":293},[296,1034,1035,1043,1051],{},[285,1036,1037,1039,1041],{},[301,1038,303],{},[301,1040,306],{"align":293},[301,1042,543],{"align":293},[285,1044,1045,1047,1049],{},[301,1046,311],{},[301,1048,314],{"align":293},[301,1050,552],{"align":293},[285,1052,1053,1055,1057],{},[301,1054,319],{},[301,1056,322],{"align":293},[301,1058,561],{"align":293},[10,1060,564],{},[10,1062,567,1063,571],{},[59,1064,570],{},[43,1066,574],{"id":574},[10,1068,577],{},[579,1070,1071,1077,1081,1085,1087],{},[582,1072,1073,586,1075,589],{},[59,1074,94],{},[59,1076,139],{},[582,1078,1079,595],{},[59,1080,594],{},[582,1082,598,1083,601],{},[59,1084,327],{},[582,1086,604],{},[582,1088,607],{},[10,1090,610],{},[10,1092,613],{},[51,1094,1095],{"className":81,"code":252,"language":83,"meta":57,"style":57},[59,1096,1097],{"__ignoreMap":57},[87,1098,1099,1101,1103],{"class":89,"line":90},[87,1100,259],{"class":93},[87,1102,262],{"class":97},[87,1104,265],{"class":97},[10,1106,628],{},[630,1108,632],{},{"title":57,"searchDepth":634,"depth":634,"links":1110},[1111,1112,1113,1114,1115,1116,1117,1118],{"id":45,"depth":634,"text":46},{"id":75,"depth":634,"text":75},{"id":245,"depth":634,"text":246},{"id":331,"depth":634,"text":332},{"id":374,"depth":634,"text":375},{"id":427,"depth":634,"text":428},{"id":515,"depth":634,"text":515},{"id":574,"depth":634,"text":574},{},{"title":5,"description":644},[653,654],{"id":1123,"title":1124,"body":1125,"description":1838,"extension":645,"meta":1839,"navigation":647,"path":1840,"publishDate":1841,"published":647,"seo":1842,"stem":1843,"tags":1844,"thumbnail":1846,"updated":1841,"__hash__":1847},"articles\u002Farticles\u002F2024\u002Flately-learned-js-tip.md","最近学んだJavaScriptのTipsをアウトプット",{"type":7,"value":1126,"toc":1821},[1127,1129,1132,1135,1138,1196,1200,1203,1276,1294,1309,1324,1339,1342,1345,1381,1391,1399,1413,1439,1455,1458,1473,1476,1483,1540,1543,1550,1583,1593,1597,1606,1625,1628,1636,1674,1677,1701,1708,1714,1725,1753,1774,1777,1783,1786,1804,1806,1809,1818],[10,1128,12],{},[10,1130,1131],{},"今回は、最近学んだJavaScriptの小さなTipsとして、オブジェクトの分割代入とオプショナルチェーンを整理します。",[43,1133,1134],{"id":1134},"オブジェクトの分割代入",[10,1136,1137],{},"オブジェクトの分割代入を使うと、プロパティの値を取り出して変数へ代入できます。",[51,1139,1143],{"className":1140,"code":1141,"language":1142,"meta":57,"style":57},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","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","javascript",[59,1144,1145,1150,1155,1161,1167,1173,1179,1184,1190],{"__ignoreMap":57},[87,1146,1147],{"class":89,"line":90},[87,1148,1149],{},"const user = {\n",[87,1151,1152],{"class":89,"line":634},[87,1153,1154],{},"  greeting: 'Hello',\n",[87,1156,1158],{"class":89,"line":1157},3,[87,1159,1160],{},"  farewell: 'Bye',\n",[87,1162,1164],{"class":89,"line":1163},4,[87,1165,1166],{},"}\n",[87,1168,1170],{"class":89,"line":1169},5,[87,1171,1172],{"emptyLinePlaceholder":647},"\n",[87,1174,1176],{"class":89,"line":1175},6,[87,1177,1178],{},"const { greeting, farewell } = user\n",[87,1180,1182],{"class":89,"line":1181},7,[87,1183,1172],{"emptyLinePlaceholder":647},[87,1185,1187],{"class":89,"line":1186},8,[87,1188,1189],{},"console.log(greeting) \u002F\u002F 'Hello'\n",[87,1191,1193],{"class":89,"line":1192},9,[87,1194,1195],{},"console.log(farewell) \u002F\u002F 'Bye'\n",[1197,1198,1199],"h3",{"id":1199},"ネストしたプロパティを取り出す",[10,1201,1202],{},"オブジェクトの中にオブジェクトがある場合は、データの構造に合わせて分割代入のパターンもネストできます。",[51,1204,1206],{"className":1140,"code":1205,"language":1142,"meta":57,"style":57},"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",[59,1207,1208,1212,1216,1221,1226,1231,1235,1239,1244,1249,1255,1261,1266,1271],{"__ignoreMap":57},[87,1209,1210],{"class":89,"line":90},[87,1211,1149],{},[87,1213,1214],{"class":89,"line":634},[87,1215,1154],{},[87,1217,1218],{"class":89,"line":1157},[87,1219,1220],{},"  message: {\n",[87,1222,1223],{"class":89,"line":1163},[87,1224,1225],{},"    farewell: 'Bye',\n",[87,1227,1228],{"class":89,"line":1169},[87,1229,1230],{},"  },\n",[87,1232,1233],{"class":89,"line":1175},[87,1234,1166],{},[87,1236,1237],{"class":89,"line":1181},[87,1238,1172],{"emptyLinePlaceholder":647},[87,1240,1241],{"class":89,"line":1186},[87,1242,1243],{},"const {\n",[87,1245,1246],{"class":89,"line":1192},[87,1247,1248],{},"  greeting,\n",[87,1250,1252],{"class":89,"line":1251},10,[87,1253,1254],{},"  message: { farewell },\n",[87,1256,1258],{"class":89,"line":1257},11,[87,1259,1260],{},"} = user\n",[87,1262,1264],{"class":89,"line":1263},12,[87,1265,1172],{"emptyLinePlaceholder":647},[87,1267,1269],{"class":89,"line":1268},13,[87,1270,1189],{},[87,1272,1274],{"class":89,"line":1273},14,[87,1275,1195],{},[10,1277,1278,1279,1282,1283,1286,1287,1290,1291,1293],{},"この例で作られる変数は",[59,1280,1281],{},"greeting","と",[59,1284,1285],{},"farewell","です。",[59,1288,1289],{},"message","は、内側の",[59,1292,1285],{},"へたどるためのパターンとして使われているだけなので、変数として宣言されません。",[51,1295,1297],{"className":1140,"code":1296,"language":1142,"meta":57,"style":57},"console.log(message)\n\u002F\u002F ReferenceError: message is not defined\n",[59,1298,1299,1304],{"__ignoreMap":57},[87,1300,1301],{"class":89,"line":90},[87,1302,1303],{},"console.log(message)\n",[87,1305,1306],{"class":89,"line":634},[87,1307,1308],{},"\u002F\u002F ReferenceError: message is not defined\n",[35,1310,1313],{"title":1311,"type":1312},"親オブジェクトも使いたい場合","note",[10,1314,1315,1317,1318,1320,1321,1323],{},[59,1316,1289],{},"自体と、その中の",[59,1319,1285],{},"を両方使いたい場合は、分割代入を分けるか、先に",[59,1322,1289],{},"を取り出してから再度分割代入します。",[51,1325,1327],{"className":1140,"code":1326,"language":1142,"meta":57,"style":57},"const { message } = user\nconst { farewell } = message\n",[59,1328,1329,1334],{"__ignoreMap":57},[87,1330,1331],{"class":89,"line":90},[87,1332,1333],{},"const { message } = user\n",[87,1335,1336],{"class":89,"line":634},[87,1337,1338],{},"const { farewell } = message\n",[1197,1340,1341],{"id":1341},"プロパティ名とは異なる変数名で受け取る",[10,1343,1344],{},"コロンの右側へ名前を書くと、プロパティ名とは異なる変数名で値を受け取れます。",[51,1346,1348],{"className":1140,"code":1347,"language":1142,"meta":57,"style":57},"const user = {\n  name: 'Yuri',\n}\n\nconst { name: userName } = user\n\nconsole.log(userName) \u002F\u002F 'Yuri'\n",[59,1349,1350,1354,1359,1363,1367,1372,1376],{"__ignoreMap":57},[87,1351,1352],{"class":89,"line":90},[87,1353,1149],{},[87,1355,1356],{"class":89,"line":634},[87,1357,1358],{},"  name: 'Yuri',\n",[87,1360,1361],{"class":89,"line":1157},[87,1362,1166],{},[87,1364,1365],{"class":89,"line":1163},[87,1366,1172],{"emptyLinePlaceholder":647},[87,1368,1369],{"class":89,"line":1169},[87,1370,1371],{},"const { name: userName } = user\n",[87,1373,1374],{"class":89,"line":1175},[87,1375,1172],{"emptyLinePlaceholder":647},[87,1377,1378],{"class":89,"line":1181},[87,1379,1380],{},"console.log(userName) \u002F\u002F 'Yuri'\n",[10,1382,1383,1384,1387,1388,1286],{},"この場合も",[59,1385,1386],{},"name","という変数は作られず、作られるのは",[59,1389,1390],{},"userName",[43,1392,1394,1395,1398],{"id":1393},"オプショナルチェーン","オプショナルチェーン（",[59,1396,1397],{},"?.","）",[10,1400,1401,1402,1405,1406,1409,1410,1412],{},"オプショナルチェーンは、参照の途中にある値が",[59,1403,1404],{},"null","または",[59,1407,1408],{},"undefined","だった場合、エラーを発生させずに",[59,1411,1408],{},"を返す演算子です。",[51,1414,1416],{"className":1140,"code":1415,"language":1142,"meta":57,"style":57},"const user = {\n  name: 'Yuri',\n}\n\nconsole.log(user.profile?.hobby) \u002F\u002F undefined\n",[59,1417,1418,1422,1426,1430,1434],{"__ignoreMap":57},[87,1419,1420],{"class":89,"line":90},[87,1421,1149],{},[87,1423,1424],{"class":89,"line":634},[87,1425,1358],{},[87,1427,1428],{"class":89,"line":1157},[87,1429,1166],{},[87,1431,1432],{"class":89,"line":1163},[87,1433,1172],{"emptyLinePlaceholder":647},[87,1435,1436],{"class":89,"line":1169},[87,1437,1438],{},"console.log(user.profile?.hobby) \u002F\u002F undefined\n",[10,1440,1441,1444,1445,1447,1448,1450,1451,1454],{},[59,1442,1443],{},"user.profile","は",[59,1446,1408],{},"ですが、",[59,1449,1397],{},"を使っているため、その先の",[59,1452,1453],{},"hobby","へアクセスせず評価を終了します。",[10,1456,1457],{},"通常のプロパティアクセスではエラーになります。",[51,1459,1461],{"className":1140,"code":1460,"language":1142,"meta":57,"style":57},"console.log(user.profile.hobby)\n\u002F\u002F TypeError: Cannot read properties of undefined\n",[59,1462,1463,1468],{"__ignoreMap":57},[87,1464,1465],{"class":89,"line":90},[87,1466,1467],{},"console.log(user.profile.hobby)\n",[87,1469,1470],{"class":89,"line":634},[87,1471,1472],{},"\u002F\u002F TypeError: Cannot read properties of undefined\n",[1197,1474,1475],{"id":1475},"配列の要素へアクセスする",[10,1477,1478,1479,1482],{},"角括弧によるアクセスでは、",[59,1480,1481],{},"?.[]","の形で使用します。",[51,1484,1486],{"className":1140,"code":1485,"language":1142,"meta":57,"style":57},"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",[59,1487,1488,1493,1498,1503,1508,1512,1517,1522,1526,1531,1535],{"__ignoreMap":57},[87,1489,1490],{"class":89,"line":90},[87,1491,1492],{},"const items = [\n",[87,1494,1495],{"class":89,"line":634},[87,1496,1497],{},"  { name: 'Item 1' },\n",[87,1499,1500],{"class":89,"line":1157},[87,1501,1502],{},"  { name: 'Item 2' },\n",[87,1504,1505],{"class":89,"line":1163},[87,1506,1507],{},"]\n",[87,1509,1510],{"class":89,"line":1169},[87,1511,1172],{"emptyLinePlaceholder":647},[87,1513,1514],{"class":89,"line":1175},[87,1515,1516],{},"console.log(items[1]?.name) \u002F\u002F 'Item 2'\n",[87,1518,1519],{"class":89,"line":1181},[87,1520,1521],{},"console.log(items[3]?.name) \u002F\u002F undefined\n",[87,1523,1524],{"class":89,"line":1186},[87,1525,1172],{"emptyLinePlaceholder":647},[87,1527,1528],{"class":89,"line":1192},[87,1529,1530],{},"const emptyItems = undefined\n",[87,1532,1533],{"class":89,"line":1251},[87,1534,1172],{"emptyLinePlaceholder":647},[87,1536,1537],{"class":89,"line":1257},[87,1538,1539],{},"console.log(emptyItems?.[0]) \u002F\u002F undefined\n",[1197,1541,1542],{"id":1542},"関数やメソッドを呼び出す",[10,1544,1545,1546,1549],{},"関数が存在するときだけ呼び出したい場合は、",[59,1547,1548],{},"?.()","を使用します。",[51,1551,1553],{"className":1140,"code":1552,"language":1142,"meta":57,"style":57},"const actions = {\n  greet: () => 'Hello',\n}\n\nconsole.log(actions.greet?.()) \u002F\u002F 'Hello'\nconsole.log(actions.sayGoodbye?.()) \u002F\u002F undefined\n",[59,1554,1555,1560,1565,1569,1573,1578],{"__ignoreMap":57},[87,1556,1557],{"class":89,"line":90},[87,1558,1559],{},"const actions = {\n",[87,1561,1562],{"class":89,"line":634},[87,1563,1564],{},"  greet: () => 'Hello',\n",[87,1566,1567],{"class":89,"line":1157},[87,1568,1166],{},[87,1570,1571],{"class":89,"line":1163},[87,1572,1172],{"emptyLinePlaceholder":647},[87,1574,1575],{"class":89,"line":1169},[87,1576,1577],{},"console.log(actions.greet?.()) \u002F\u002F 'Hello'\n",[87,1579,1580],{"class":89,"line":1175},[87,1581,1582],{},"console.log(actions.sayGoodbye?.()) \u002F\u002F undefined\n",[10,1584,1585,1586,1589,1590,1592],{},"プロパティが存在していても、その値が関数でなければ",[59,1587,1588],{},"TypeError","になります。",[59,1591,1548],{},"は「呼び出し可能かどうか」まで確認するものではありません。",[1197,1594,1596],{"id":1595},"dom要素へアクセスする","DOM要素へアクセスする",[10,1598,1599,1602,1603,1605],{},[59,1600,1601],{},"querySelector","は対象が見つからなかった場合に",[59,1604,1404],{},"を返します。要素が存在するときだけプロパティを参照したい場合にも利用できます。",[51,1607,1609],{"className":1140,"code":1608,"language":1142,"meta":57,"style":57},"const button = document.querySelector('.sample-button')\n\nconsole.log(button?.textContent) \u002F\u002F 要素がなければundefined\n",[59,1610,1611,1616,1620],{"__ignoreMap":57},[87,1612,1613],{"class":89,"line":90},[87,1614,1615],{},"const button = document.querySelector('.sample-button')\n",[87,1617,1618],{"class":89,"line":634},[87,1619,1172],{"emptyLinePlaceholder":647},[87,1621,1622],{"class":89,"line":1157},[87,1623,1624],{},"console.log(button?.textContent) \u002F\u002F 要素がなければundefined\n",[1197,1626,1627],{"id":1627},"短絡評価される範囲",[10,1629,1630,1631,1405,1633,1635],{},"オプショナルチェーンでは、左側が",[59,1632,1404],{},[59,1634,1408],{},"の場合、そのチェーンの残りは評価されません。",[51,1637,1639],{"className":1140,"code":1638,"language":1142,"meta":57,"style":57},"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",[59,1640,1641,1646,1651,1655,1660,1664,1669],{"__ignoreMap":57},[87,1642,1643],{"class":89,"line":90},[87,1644,1645],{},"let index = 0\n",[87,1647,1648],{"class":89,"line":634},[87,1649,1650],{},"const items = null\n",[87,1652,1653],{"class":89,"line":1157},[87,1654,1172],{"emptyLinePlaceholder":647},[87,1656,1657],{"class":89,"line":1163},[87,1658,1659],{},"const item = items?.[index++]\n",[87,1661,1662],{"class":89,"line":1169},[87,1663,1172],{"emptyLinePlaceholder":647},[87,1665,1666],{"class":89,"line":1175},[87,1667,1668],{},"console.log(item) \u002F\u002F undefined\n",[87,1670,1671],{"class":89,"line":1181},[87,1672,1673],{},"console.log(index) \u002F\u002F 0\n",[10,1675,1676],{},"ただし、オプショナルチェーンが途切れた後のアクセスは保護されません。",[51,1678,1680],{"className":1140,"code":1679,"language":1142,"meta":57,"style":57},"const user = null\n\nuser?.profile.name \u002F\u002F undefined\n(user?.profile).name \u002F\u002F TypeError\n",[59,1681,1682,1687,1691,1696],{"__ignoreMap":57},[87,1683,1684],{"class":89,"line":90},[87,1685,1686],{},"const user = null\n",[87,1688,1689],{"class":89,"line":634},[87,1690,1172],{"emptyLinePlaceholder":647},[87,1692,1693],{"class":89,"line":1157},[87,1694,1695],{},"user?.profile.name \u002F\u002F undefined\n",[87,1697,1698],{"class":89,"line":1163},[87,1699,1700],{},"(user?.profile).name \u002F\u002F TypeError\n",[10,1702,1703,1704,1707],{},"括弧で区切ると、その後の",[59,1705,1706],{},".name","は別のプロパティアクセスとして評価されます。",[43,1709,1711,1710],{"id":1710},"と組み合わせて既定値を設定する",[59,1712,1713],{},"??",[10,1715,1716,1717,1405,1719,1721,1722,1724],{},"オプショナルチェーンで取得した結果が",[59,1718,1404],{},[59,1720,1408],{},"だった場合、ヌル値合体演算子（",[59,1723,1713],{},"）で既定値を設定できます。",[51,1726,1728],{"className":1140,"code":1727,"language":1142,"meta":57,"style":57},"const user = {}\n\nconst hobby = user.profile?.hobby ?? '未設定'\n\nconsole.log(hobby) \u002F\u002F '未設定'\n",[59,1729,1730,1735,1739,1744,1748],{"__ignoreMap":57},[87,1731,1732],{"class":89,"line":90},[87,1733,1734],{},"const user = {}\n",[87,1736,1737],{"class":89,"line":634},[87,1738,1172],{"emptyLinePlaceholder":647},[87,1740,1741],{"class":89,"line":1157},[87,1742,1743],{},"const hobby = user.profile?.hobby ?? '未設定'\n",[87,1745,1746],{"class":89,"line":1163},[87,1747,1172],{"emptyLinePlaceholder":647},[87,1749,1750],{"class":89,"line":1169},[87,1751,1752],{},"console.log(hobby) \u002F\u002F '未設定'\n",[10,1754,1755,1444,1758,1761,1762,1765,1766,1768,1769,1405,1771,1773],{},[59,1756,1757],{},"||",[59,1759,1760],{},"0","、空文字列、",[59,1763,1764],{},"false","も右側の値へ置き換えますが、",[59,1767,1713],{},"が右側を返すのは",[59,1770,1404],{},[59,1772,1408],{},"の場合だけです。",[43,1775,1776],{"id":1776},"オプショナルチェーンを使うときの注意点",[10,1778,1779,1780,1782],{},"オプショナルチェーンは条件分岐を簡潔にできますが、必須であるはずの値にまで使用すると、不具合を",[59,1781,1408],{},"として見逃す可能性があります。",[10,1784,1785],{},"次のように使い分けることが大切です。",[1787,1788,1789,1795,1798],"ul",{},[582,1790,1791,1792,1794],{},"値が存在しないことを仕様として許容する場合は",[59,1793,1397],{},"を使う",[582,1796,1797],{},"値が必須の場合は明示的に確認し、存在しなければエラーとして扱う",[582,1799,1800,1801,1803],{},"取得結果に既定値が必要な場合は",[59,1802,1713],{},"を組み合わせる",[43,1805,574],{"id":574},[10,1807,1808],{},"ネストした分割代入を使うと、深い階層の値を簡潔に変数へ取り出せます。ただし、途中のプロパティ名がそのまま変数になるわけではありません。",[10,1810,1811,1812,1814,1815,1817],{},"オプショナルチェーンを使うと、",[59,1813,1404],{},"や",[59,1816,1408],{},"の可能性があるプロパティ、配列、関数へ安全にアクセスできます。便利さだけで多用せず、その値が本当に省略可能なのかを考えて使っていきたいです。",[630,1819,1820],{},"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":57,"searchDepth":634,"depth":634,"links":1822},[1823,1827,1834,1836,1837],{"id":1134,"depth":634,"text":1134,"children":1824},[1825,1826],{"id":1199,"depth":1157,"text":1199},{"id":1341,"depth":1157,"text":1341},{"id":1393,"depth":634,"text":1828,"children":1829},"オプショナルチェーン（?.）",[1830,1831,1832,1833],{"id":1475,"depth":1157,"text":1475},{"id":1542,"depth":1157,"text":1542},{"id":1595,"depth":1157,"text":1596},{"id":1627,"depth":1157,"text":1627},{"id":1710,"depth":634,"text":1835},"??と組み合わせて既定値を設定する",{"id":1776,"depth":634,"text":1776},{"id":574,"depth":634,"text":574},"JavaScriptのネストしたオブジェクトの分割代入とオプショナルチェーンについて、コード例と注意点を交えて整理します。",{},"\u002Farticles\u002F2024\u002Flately-learned-js-tip","2024-12-28",{"title":1124,"description":1838},"articles\u002F2024\u002Flately-learned-js-tip",[1845],"JavaScript","\u002Fimages\u002Farticles\u002Flately-learned-js-tip.png","Xi5F4LrgdP-cQxce9jEEPhpLiC086mIJfek4NR0cS3g",{"id":1849,"title":1850,"body":1851,"description":3509,"extension":645,"meta":3510,"navigation":647,"path":3511,"publishDate":3512,"published":647,"seo":3513,"stem":3514,"tags":3515,"thumbnail":3516,"updated":3512,"__hash__":3517},"articles\u002Farticles\u002F2024\u002Forganize-learned-from-todo.md","Todoアプリのハンズオンで学んだことを整理する",{"type":7,"value":1852,"toc":3480},[1853,1855,1866,1879,1882,1889,1898,1933,1936,1942,1944,1947,1950,1992,1995,1999,2002,2012,2015,2018,2024,2033,2242,2253,2256,2259,2361,2364,2367,2455,2458,2461,2489,2492,2495,2506,2655,2658,2661,2664,2667,2670,2678,2690,2758,2764,2769,2775,2818,2823,2826,2829,2895,2902,2905,2912,3025,3034,3041,3046,3106,3109,3112,3115,3209,3212,3218,3237,3247,3250,3253,3332,3339,3342,3345,3466,3469,3471,3474,3477],[10,1854,12],{},[10,1856,1857,1858,1865],{},"今回は「",[1859,1860,1864],"a",{"href":1861,"rel":1862},"https:\u002F\u002Fzenn.dev\u002Fsprout2000\u002Fbooks\u002F76a279bb90c3f3",[1863],"nofollow","React Hooks と TypeScript でつくる Todo PWA ～入門 React ハンズオン～","」を進める中で学んだことを、次の4つに分けて整理します。",[1787,1867,1868,1871,1873,1876],{},[582,1869,1870],{},"HTML",[582,1872,1845],{},[582,1874,1875],{},"React",[582,1877,1878],{},"TypeScript",[43,1880,1870],{"id":1881},"html",[1197,1883,1885,1888],{"id":1884},"autofocus属性",[59,1886,1887],{},"autofocus","属性",[10,1890,1891,1893,1894,1897],{},[59,1892,1887],{},"は、ページの読み込み時や",[59,1895,1896],{},"dialog","要素の表示時に、指定した要素へ自動的にフォーカスするための属性です。",[51,1899,1902],{"className":1900,"code":1901,"language":1881,"meta":57,"style":57},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cinput type=\"text\" autofocus>\n",[59,1903,1904],{"__ignoreMap":57},[87,1905,1906,1909,1913,1917,1920,1923,1925,1927,1930],{"class":89,"line":90},[87,1907,1908],{"class":111},"\u003C",[87,1910,1912],{"class":1911},"swJcz","input",[87,1914,1916],{"class":1915},"spNyl"," type",[87,1918,1919],{"class":111},"=",[87,1921,1922],{"class":111},"\"",[87,1924,56],{"class":97},[87,1926,1922],{"class":111},[87,1928,1929],{"class":1915}," autofocus",[87,1931,1932],{"class":111},">\n",[10,1934,1935],{},"1つの文書やダイアログ内では、複数の要素へ指定しないようにします。複数指定した場合、最初に見つかった要素がフォーカスされます。",[35,1937,1939],{"title":1938,"type":38},"アクセシビリティへの配慮",[10,1940,1941],{},"ページを開いた直後にフォーカスが移動すると、スクリーンリーダー利用者やモバイル利用者を混乱させる場合があります。本当に自動フォーカスが必要かを検討して使用しましょう。",[43,1943,1845],{"id":1142},[1197,1945,1946],{"id":1946},"オブジェクトのプロパティ名を動的にする",[10,1948,1949],{},"オブジェクトリテラルのプロパティ名を角括弧で囲むと、式の評価結果をプロパティ名として使用できます。これは計算プロパティ名と呼ばれます。",[51,1951,1953],{"className":1140,"code":1952,"language":1142,"meta":57,"style":57},"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",[59,1954,1955,1960,1964,1969,1974,1978,1982,1987],{"__ignoreMap":57},[87,1956,1957],{"class":89,"line":90},[87,1958,1959],{},"const key = 'sampleKey'\n",[87,1961,1962],{"class":89,"line":634},[87,1963,1172],{"emptyLinePlaceholder":647},[87,1965,1966],{"class":89,"line":1157},[87,1967,1968],{},"const sample = {\n",[87,1970,1971],{"class":89,"line":1163},[87,1972,1973],{},"  [key]: 'sampleValue',\n",[87,1975,1976],{"class":89,"line":1169},[87,1977,1166],{},[87,1979,1980],{"class":89,"line":1175},[87,1981,1172],{"emptyLinePlaceholder":647},[87,1983,1984],{"class":89,"line":1181},[87,1985,1986],{},"console.log(sample) \u002F\u002F { sampleKey: 'sampleValue' }\n",[87,1988,1989],{"class":89,"line":1186},[87,1990,1991],{},"console.log(sample[key]) \u002F\u002F 'sampleValue'\n",[10,1993,1994],{},"入力項目の名前をキーとしてオブジェクトを更新する場合などに利用できます。",[1197,1996,1998],{"id":1997},"tree-shaking","Tree Shaking",[10,2000,2001],{},"Tree Shakingは、利用されていないコードをビルド結果から取り除く最適化です。",[10,2003,2004,2005,1282,2008,2011],{},"主にバンドラーがES Modulesの",[59,2006,2007],{},"import",[59,2009,2010],{},"export","を静的に解析し、参照されていないエクスポートを出力対象から除外します。",[10,2013,2014],{},"実際に削除できる範囲は、バンドラーの設定やコードに副作用があるかどうかによって変わります。",[43,2016,1875],{"id":2017},"react",[1197,2019,2021],{"id":2020},"createroot",[59,2022,2023],{},"createRoot",[10,2025,2026,2028,2029,2032],{},[59,2027,2023],{},"は、Reactが管理するルートをブラウザのDOM要素へ作成するAPIです。作成したルートの",[59,2030,2031],{},"render","メソッドへReact要素を渡して表示します。",[51,2034,2038],{"className":2035,"code":2036,"language":2037,"meta":57,"style":57},"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",[59,2039,2040,2066,2086,2103,2107,2141,2145,2162,2184,2188,2192,2206,2216,2227,2237],{"__ignoreMap":57},[87,2041,2042,2045,2048,2052,2055,2058,2061,2063],{"class":89,"line":90},[87,2043,2007],{"class":2044},"s7zQu",[87,2046,2047],{"class":111}," {",[87,2049,2051],{"class":2050},"sTEyZ"," StrictMode",[87,2053,2054],{"class":111}," }",[87,2056,2057],{"class":2044}," from",[87,2059,2060],{"class":111}," '",[87,2062,2017],{"class":97},[87,2064,2065],{"class":111},"'\n",[87,2067,2068,2070,2072,2075,2077,2079,2081,2084],{"class":89,"line":634},[87,2069,2007],{"class":2044},[87,2071,2047],{"class":111},[87,2073,2074],{"class":2050}," createRoot",[87,2076,2054],{"class":111},[87,2078,2057],{"class":2044},[87,2080,2060],{"class":111},[87,2082,2083],{"class":97},"react-dom\u002Fclient",[87,2085,2065],{"class":111},[87,2087,2088,2090,2093,2096,2098,2101],{"class":89,"line":1157},[87,2089,2007],{"class":2044},[87,2091,2092],{"class":2050}," App ",[87,2094,2095],{"class":2044},"from",[87,2097,2060],{"class":111},[87,2099,2100],{"class":97},".\u002FApp",[87,2102,2065],{"class":111},[87,2104,2105],{"class":89,"line":1163},[87,2106,1172],{"emptyLinePlaceholder":647},[87,2108,2109,2112,2115,2117,2120,2123,2127,2130,2133,2136,2138],{"class":89,"line":1169},[87,2110,2111],{"class":1915},"const",[87,2113,2114],{"class":2050}," container ",[87,2116,1919],{"class":111},[87,2118,2119],{"class":2050}," document",[87,2121,2122],{"class":111},".",[87,2124,2126],{"class":2125},"s2Zo4","getElementById",[87,2128,2129],{"class":2050},"(",[87,2131,2132],{"class":111},"'",[87,2134,2135],{"class":97},"root",[87,2137,2132],{"class":111},[87,2139,2140],{"class":2050},")\n",[87,2142,2143],{"class":89,"line":1175},[87,2144,1172],{"emptyLinePlaceholder":647},[87,2146,2147,2150,2153,2156,2159],{"class":89,"line":1181},[87,2148,2149],{"class":2044},"if",[87,2151,2152],{"class":2050}," (",[87,2154,2155],{"class":111},"!",[87,2157,2158],{"class":2050},"container) ",[87,2160,2161],{"class":111},"{\n",[87,2163,2164,2167,2170,2173,2175,2177,2180,2182],{"class":89,"line":1186},[87,2165,2166],{"class":2044},"  throw",[87,2168,2169],{"class":111}," new",[87,2171,2172],{"class":2125}," Error",[87,2174,2129],{"class":1911},[87,2176,2132],{"class":111},[87,2178,2179],{"class":97},"root要素が見つかりません",[87,2181,2132],{"class":111},[87,2183,2140],{"class":1911},[87,2185,2186],{"class":89,"line":1192},[87,2187,1166],{"class":111},[87,2189,2190],{"class":89,"line":1251},[87,2191,1172],{"emptyLinePlaceholder":647},[87,2193,2194,2196,2199,2201,2203],{"class":89,"line":1257},[87,2195,2023],{"class":2125},[87,2197,2198],{"class":2050},"(container)",[87,2200,2122],{"class":111},[87,2202,2031],{"class":2125},[87,2204,2205],{"class":2050},"(\n",[87,2207,2208,2211,2214],{"class":89,"line":1263},[87,2209,2210],{"class":111},"  \u003C",[87,2212,2213],{"class":93},"StrictMode",[87,2215,1932],{"class":111},[87,2217,2218,2221,2224],{"class":89,"line":1268},[87,2219,2220],{"class":111},"    \u003C",[87,2222,2223],{"class":93},"App",[87,2225,2226],{"class":111}," \u002F>\n",[87,2228,2229,2232,2234],{"class":89,"line":1273},[87,2230,2231],{"class":111},"  \u003C\u002F",[87,2233,2213],{"class":93},[87,2235,2236],{"class":111},">,\n",[87,2238,2240],{"class":89,"line":2239},15,[87,2241,2140],{"class":2050},[10,2243,2244,2246,2247,2249,2250,1549],{},[59,2245,2023],{},"へ渡したDOM要素の内側はReactが管理します。サーバー側でReactが生成したHTMLを再利用する場合は、",[59,2248,2023],{},"ではなく",[59,2251,2252],{},"hydrateRoot",[1197,2254,2255],{"id":2255},"stateを直接変更しない",[10,2257,2258],{},"Reactのstateに保存したオブジェクトや配列は、読み取り専用として扱います。値を直接変更せず、新しい値を作ってset関数へ渡します。",[51,2260,2262],{"className":2035,"code":2261,"language":2037,"meta":57,"style":57},"setTodos(currentTodos =>\n  currentTodos.map(todo =>\n    todo.id === id\n      ? { ...todo, completed: true }\n      : todo,\n  ),\n)\n",[59,2263,2264,2278,2295,2311,2339,2350,2357],{"__ignoreMap":57},[87,2265,2266,2269,2271,2275],{"class":89,"line":90},[87,2267,2268],{"class":2125},"setTodos",[87,2270,2129],{"class":2050},[87,2272,2274],{"class":2273},"sHdIc","currentTodos",[87,2276,2277],{"class":1915}," =>\n",[87,2279,2280,2283,2285,2288,2290,2293],{"class":89,"line":634},[87,2281,2282],{"class":2050},"  currentTodos",[87,2284,2122],{"class":111},[87,2286,2287],{"class":2125},"map",[87,2289,2129],{"class":2050},[87,2291,2292],{"class":2273},"todo",[87,2294,2277],{"class":1915},[87,2296,2297,2300,2302,2305,2308],{"class":89,"line":1157},[87,2298,2299],{"class":2050},"    todo",[87,2301,2122],{"class":111},[87,2303,2304],{"class":2050},"id ",[87,2306,2307],{"class":111},"===",[87,2309,2310],{"class":2050}," id\n",[87,2312,2313,2316,2318,2321,2323,2326,2329,2332,2336],{"class":89,"line":1163},[87,2314,2315],{"class":111},"      ?",[87,2317,2047],{"class":111},[87,2319,2320],{"class":111}," ...",[87,2322,2292],{"class":2050},[87,2324,2325],{"class":111},",",[87,2327,2328],{"class":1911}," completed",[87,2330,2331],{"class":111},":",[87,2333,2335],{"class":2334},"sfNiH"," true",[87,2337,2338],{"class":111}," }\n",[87,2340,2341,2344,2347],{"class":89,"line":1169},[87,2342,2343],{"class":111},"      :",[87,2345,2346],{"class":2050}," todo",[87,2348,2349],{"class":111},",\n",[87,2351,2352,2355],{"class":89,"line":1175},[87,2353,2354],{"class":2050},"  )",[87,2356,2349],{"class":111},[87,2358,2359],{"class":89,"line":1181},[87,2360,2140],{"class":2050},[10,2362,2363],{},"配列を新しく作っても、その中にあるオブジェクトまでは自動的に複製されません。更新対象のオブジェクトもスプレッド構文などで新しく作る必要があります。",[10,2365,2366],{},"配列を更新する際は、次のように破壊的な操作を避けます。",[279,2368,2369,2382],{},[282,2370,2371],{},[285,2372,2373,2376,2379],{},[288,2374,2375],{},"操作",[288,2377,2378],{},"避けたい方法",[288,2380,2381],{},"利用する方法",[296,2383,2384,2404,2425,2439],{},[285,2385,2386,2389,2398],{},[301,2387,2388],{},"追加",[301,2390,2391,2394,2395],{},[59,2392,2393],{},"push","、",[59,2396,2397],{},"unshift",[301,2399,2400,2401],{},"スプレッド構文、",[59,2402,2403],{},"concat",[285,2405,2406,2409,2417],{},[301,2407,2408],{},"削除",[301,2410,2411,2394,2414],{},[59,2412,2413],{},"pop",[59,2415,2416],{},"splice",[301,2418,2419,2394,2422],{},[59,2420,2421],{},"filter",[59,2423,2424],{},"slice",[285,2426,2427,2430,2435],{},[301,2428,2429],{},"置換",[301,2431,2432,2433],{},"添字への代入、",[59,2434,2416],{},[301,2436,2437],{},[59,2438,2287],{},[285,2440,2441,2444,2450],{},[301,2442,2443],{},"並び替え",[301,2445,2446,2447],{},"元配列への",[59,2448,2449],{},"sort",[301,2451,2452,2453],{},"コピー後に",[59,2454,2449],{},[1197,2456,2457],{"id":2457},"直前のstateを基に更新する",[10,2459,2460],{},"更新後のstateが更新前の値に依存する場合は、set関数へ値ではなく更新用の関数を渡します。",[51,2462,2464],{"className":2035,"code":2463,"language":2037,"meta":57,"style":57},"setCount(currentCount => currentCount + 1)\n",[59,2465,2466],{"__ignoreMap":57},[87,2467,2468,2471,2473,2476,2479,2482,2485,2487],{"class":89,"line":90},[87,2469,2470],{"class":2125},"setCount",[87,2472,2129],{"class":2050},[87,2474,2475],{"class":2273},"currentCount",[87,2477,2478],{"class":1915}," =>",[87,2480,2481],{"class":2050}," currentCount ",[87,2483,2484],{"class":111},"+",[87,2486,105],{"class":104},[87,2488,2140],{"class":2050},[10,2490,2491],{},"Reactはイベントハンドラーの処理をまとめてからstateを更新することがあります。更新用関数を使うことで、その時点の最新のstateを基に次の値を計算できます。",[1197,2493,2494],{"id":2494},"イベントハンドラーの命名",[10,2496,2497,2498,2501,2502,2505],{},"イベントを処理する関数には",[59,2499,2500],{},"handle","、propsとして受け渡すイベントには",[59,2503,2504],{},"on","を付けると役割が伝わりやすくなります。",[51,2507,2509],{"className":2035,"code":2508,"language":2037,"meta":57,"style":57},"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",[59,2510,2511,2525,2550,2554,2558,2581,2598,2610,2615,2619,2651],{"__ignoreMap":57},[87,2512,2513,2516,2519,2522],{"class":89,"line":90},[87,2514,2515],{"class":1915},"type",[87,2517,2518],{"class":93}," TodoItemProps",[87,2520,2521],{"class":111}," =",[87,2523,2524],{"class":111}," {\n",[87,2526,2527,2530,2532,2534,2537,2539,2542,2545,2547],{"class":89,"line":634},[87,2528,2529],{"class":1911},"  onChange",[87,2531,2331],{"class":111},[87,2533,2152],{"class":111},[87,2535,2536],{"class":2273},"id",[87,2538,2331],{"class":111},[87,2540,2541],{"class":93}," number",[87,2543,2544],{"class":111},")",[87,2546,2478],{"class":1915},[87,2548,2549],{"class":93}," void\n",[87,2551,2552],{"class":89,"line":1157},[87,2553,1166],{"class":111},[87,2555,2556],{"class":89,"line":1163},[87,2557,1172],{"emptyLinePlaceholder":647},[87,2559,2560,2563,2566,2569,2572,2575,2577,2579],{"class":89,"line":1169},[87,2561,2562],{"class":1915},"function",[87,2564,2565],{"class":2125}," TodoItem",[87,2567,2568],{"class":111},"({",[87,2570,2571],{"class":2273}," onChange",[87,2573,2574],{"class":111}," }:",[87,2576,2518],{"class":93},[87,2578,2544],{"class":111},[87,2580,2524],{"class":111},[87,2582,2583,2586,2589,2591,2594,2596],{"class":89,"line":1175},[87,2584,2585],{"class":1915},"  const",[87,2587,2588],{"class":2050}," handleChange",[87,2590,2521],{"class":111},[87,2592,2593],{"class":111}," ()",[87,2595,2478],{"class":1915},[87,2597,2524],{"class":111},[87,2599,2600,2603,2605,2608],{"class":89,"line":1181},[87,2601,2602],{"class":2125},"    onChange",[87,2604,2129],{"class":1911},[87,2606,2607],{"class":104},"1",[87,2609,2140],{"class":1911},[87,2611,2612],{"class":89,"line":1186},[87,2613,2614],{"class":111},"  }\n",[87,2616,2617],{"class":89,"line":1192},[87,2618,1172],{"emptyLinePlaceholder":647},[87,2620,2621,2624,2627,2629,2631,2633,2635,2638,2640,2642,2645,2648],{"class":89,"line":1251},[87,2622,2623],{"class":2044},"  return",[87,2625,2626],{"class":111}," \u003C",[87,2628,1912],{"class":1911},[87,2630,1916],{"class":1915},[87,2632,1919],{"class":111},[87,2634,1922],{"class":111},[87,2636,2637],{"class":97},"checkbox",[87,2639,1922],{"class":111},[87,2641,2571],{"class":1915},[87,2643,2644],{"class":111},"={",[87,2646,2647],{"class":2050},"handleChange",[87,2649,2650],{"class":111},"} \u002F>\n",[87,2652,2653],{"class":89,"line":1257},[87,2654,1166],{"class":111},[10,2656,2657],{},"これはReactが強制する規則ではありませんが、一貫した命名はコードを読みやすくします。",[1197,2659,2660],{"id":2660},"propsの分割代入",[10,2662,2663],{},"propsを分割代入すると記述は短くなりますが、変数がprops由来なのかコンポーネント内で定義されたものなのか分かりにくくなる場合があります。",[10,2665,2666],{},"コンポーネントが大きくなった場合は、変数名やコンポーネントの責務を見直し、値の出所を追いやすくすることが大切です。",[43,2668,1878],{"id":2669},"typescript",[1197,2671,2673,1282,2676],{"id":2672},"documentgetelementbyidとnull",[59,2674,2675],{},"document.getElementById",[59,2677,1404],{},[10,2679,2680,2682,2683,2686,2687,2689],{},[59,2681,2675],{},"の戻り値は",[59,2684,2685],{},"HTMLElement | null","です。対象の要素が存在しない可能性があるため、利用前に",[59,2688,1404],{},"を確認します。",[51,2691,2694],{"className":2692,"code":2693,"language":2669,"meta":57,"style":57},"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",[59,2695,2696,2720,2724,2736,2754],{"__ignoreMap":57},[87,2697,2698,2700,2702,2704,2706,2708,2710,2712,2714,2716,2718],{"class":89,"line":90},[87,2699,2111],{"class":1915},[87,2701,2114],{"class":2050},[87,2703,1919],{"class":111},[87,2705,2119],{"class":2050},[87,2707,2122],{"class":111},[87,2709,2126],{"class":2125},[87,2711,2129],{"class":2050},[87,2713,2132],{"class":111},[87,2715,2135],{"class":97},[87,2717,2132],{"class":111},[87,2719,2140],{"class":2050},[87,2721,2722],{"class":89,"line":634},[87,2723,1172],{"emptyLinePlaceholder":647},[87,2725,2726,2728,2730,2732,2734],{"class":89,"line":1157},[87,2727,2149],{"class":2044},[87,2729,2152],{"class":2050},[87,2731,2155],{"class":111},[87,2733,2158],{"class":2050},[87,2735,2161],{"class":111},[87,2737,2738,2740,2742,2744,2746,2748,2750,2752],{"class":89,"line":1163},[87,2739,2166],{"class":2044},[87,2741,2169],{"class":111},[87,2743,2172],{"class":2125},[87,2745,2129],{"class":1911},[87,2747,2132],{"class":111},[87,2749,2179],{"class":97},[87,2751,2132],{"class":111},[87,2753,2140],{"class":1911},[87,2755,2756],{"class":89,"line":1169},[87,2757,1166],{"class":111},[10,2759,2760,2761,2763],{},"Non-nullアサーション演算子（",[59,2762,2155],{},"）で確認を省略することもできますが、実行時に要素が必ず存在することをTypeScriptが保証するわけではありません。",[1197,2765,2767],{"id":2766},"readonly",[59,2768,2766],{},[10,2770,2771,2772,2774],{},"プロパティへ",[59,2773,2766],{},"を指定すると、そのプロパティへの再代入を型チェックで防げます。",[51,2776,2778],{"className":2692,"code":2777,"language":2669,"meta":57,"style":57},"type Todo = {\n  readonly id: number\n  title: string\n}\n",[59,2779,2780,2791,2804,2814],{"__ignoreMap":57},[87,2781,2782,2784,2787,2789],{"class":89,"line":90},[87,2783,2515],{"class":1915},[87,2785,2786],{"class":93}," Todo",[87,2788,2521],{"class":111},[87,2790,2524],{"class":111},[87,2792,2793,2796,2799,2801],{"class":89,"line":634},[87,2794,2795],{"class":1915},"  readonly",[87,2797,2798],{"class":1911}," id",[87,2800,2331],{"class":111},[87,2802,2803],{"class":93}," number\n",[87,2805,2806,2809,2811],{"class":89,"line":1157},[87,2807,2808],{"class":1911},"  title",[87,2810,2331],{"class":111},[87,2812,2813],{"class":93}," string\n",[87,2815,2816],{"class":89,"line":1163},[87,2817,1166],{"class":111},[10,2819,2820,2822],{},[59,2821,2766],{},"はコンパイル時の制約です。また、入れ子になったオブジェクトまで自動的に読み取り専用にするものではありません。",[1197,2824,2825],{"id":2825},"イベントごとの型",[10,2827,2828],{},"Reactのイベントハンドラーでは、対象に応じたイベント型を利用できます。",[51,2830,2832],{"className":2035,"code":2831,"language":2037,"meta":57,"style":57},"function handleChange(event: React.ChangeEvent\u003CHTMLInputElement>) {\n  console.log(event.target.checked)\n}\n",[59,2833,2834,2865,2891],{"__ignoreMap":57},[87,2835,2836,2838,2840,2842,2845,2847,2850,2852,2855,2857,2860,2863],{"class":89,"line":90},[87,2837,2562],{"class":1915},[87,2839,2588],{"class":2125},[87,2841,2129],{"class":111},[87,2843,2844],{"class":2273},"event",[87,2846,2331],{"class":111},[87,2848,2849],{"class":93}," React",[87,2851,2122],{"class":111},[87,2853,2854],{"class":93},"ChangeEvent",[87,2856,1908],{"class":111},[87,2858,2859],{"class":93},"HTMLInputElement",[87,2861,2862],{"class":111},">)",[87,2864,2524],{"class":111},[87,2866,2867,2870,2872,2875,2877,2879,2881,2884,2886,2889],{"class":89,"line":634},[87,2868,2869],{"class":2050},"  console",[87,2871,2122],{"class":111},[87,2873,2874],{"class":2125},"log",[87,2876,2129],{"class":1911},[87,2878,2844],{"class":2050},[87,2880,2122],{"class":111},[87,2882,2883],{"class":2050},"target",[87,2885,2122],{"class":111},[87,2887,2888],{"class":2050},"checked",[87,2890,2140],{"class":1911},[87,2892,2893],{"class":89,"line":1157},[87,2894,1166],{"class":111},[10,2896,2897,2898,2901],{},"イベント型だけでなく、",[59,2899,2900],{},"ChangeEventHandler\u003CHTMLInputElement>","のようなハンドラー全体の型を付ける方法もあります。",[1197,2903,2904],{"id":2904},"ジェネリクスの型引数へ制約を付ける",[10,2906,2907,2908,2911],{},"型引数に",[59,2909,2910],{},"extends","を指定すると、ジェネリクスで受け取れる型に必要なプロパティを保証できます。",[51,2913,2915],{"className":2692,"code":2914,"language":2669,"meta":57,"style":57},"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",[59,2916,2917,2928,2937,2941,2945,2988,3021],{"__ignoreMap":57},[87,2918,2919,2921,2924,2926],{"class":89,"line":90},[87,2920,2515],{"class":1915},[87,2922,2923],{"class":93}," Identifiable",[87,2925,2521],{"class":111},[87,2927,2524],{"class":111},[87,2929,2930,2933,2935],{"class":89,"line":634},[87,2931,2932],{"class":1911},"  id",[87,2934,2331],{"class":111},[87,2936,2803],{"class":93},[87,2938,2939],{"class":89,"line":1157},[87,2940,1166],{"class":111},[87,2942,2943],{"class":89,"line":1163},[87,2944,1172],{"emptyLinePlaceholder":647},[87,2946,2947,2949,2952,2954,2957,2960,2962,2965,2968,2970,2973,2976,2978,2980,2982,2984,2986],{"class":89,"line":1169},[87,2948,2562],{"class":1915},[87,2950,2951],{"class":2125}," findById",[87,2953,1908],{"class":111},[87,2955,2956],{"class":93},"T",[87,2958,2959],{"class":1915}," extends",[87,2961,2923],{"class":93},[87,2963,2964],{"class":111},">(",[87,2966,2967],{"class":2273},"items",[87,2969,2331],{"class":111},[87,2971,2972],{"class":93}," T",[87,2974,2975],{"class":2050},"[]",[87,2977,2325],{"class":111},[87,2979,2798],{"class":2273},[87,2981,2331],{"class":111},[87,2983,2541],{"class":93},[87,2985,2544],{"class":111},[87,2987,2524],{"class":111},[87,2989,2990,2992,2995,2997,3000,3002,3005,3007,3010,3012,3014,3017,3019],{"class":89,"line":1175},[87,2991,2623],{"class":2044},[87,2993,2994],{"class":2050}," items",[87,2996,2122],{"class":111},[87,2998,2999],{"class":2125},"find",[87,3001,2129],{"class":1911},[87,3003,3004],{"class":2273},"item",[87,3006,2478],{"class":1915},[87,3008,3009],{"class":2050}," item",[87,3011,2122],{"class":111},[87,3013,2536],{"class":2050},[87,3015,3016],{"class":111}," ===",[87,3018,2798],{"class":2050},[87,3020,2140],{"class":1911},[87,3022,3023],{"class":89,"line":1181},[87,3024,1166],{"class":111},[10,3026,3027,3028,3030,3031,3033],{},"制約がなければ",[59,3029,2956],{},"にどのような型が渡されるか分からないため、関数内で",[59,3032,2536],{},"へ安全にアクセスできません。",[1197,3035,3037,3040],{"id":3036},"keyof型演算子",[59,3038,3039],{},"keyof","型演算子",[10,3042,3043,3045],{},[59,3044,3039],{},"は、オブジェクト型のプロパティ名からユニオン型を作る型演算子です。",[51,3047,3049],{"className":2692,"code":3048,"language":2669,"meta":57,"style":57},"type Todo = {\n  id: number\n  title: string\n}\n\ntype TodoKey = keyof Todo\n\u002F\u002F 'id' | 'title'\n",[59,3050,3051,3061,3069,3077,3081,3085,3100],{"__ignoreMap":57},[87,3052,3053,3055,3057,3059],{"class":89,"line":90},[87,3054,2515],{"class":1915},[87,3056,2786],{"class":93},[87,3058,2521],{"class":111},[87,3060,2524],{"class":111},[87,3062,3063,3065,3067],{"class":89,"line":634},[87,3064,2932],{"class":1911},[87,3066,2331],{"class":111},[87,3068,2803],{"class":93},[87,3070,3071,3073,3075],{"class":89,"line":1157},[87,3072,2808],{"class":1911},[87,3074,2331],{"class":111},[87,3076,2813],{"class":93},[87,3078,3079],{"class":89,"line":1163},[87,3080,1166],{"class":111},[87,3082,3083],{"class":89,"line":1169},[87,3084,1172],{"emptyLinePlaceholder":647},[87,3086,3087,3089,3092,3094,3097],{"class":89,"line":1175},[87,3088,2515],{"class":1915},[87,3090,3091],{"class":93}," TodoKey",[87,3093,2521],{"class":111},[87,3095,3096],{"class":111}," keyof",[87,3098,3099],{"class":93}," Todo\n",[87,3101,3102],{"class":89,"line":1181},[87,3103,3105],{"class":3104},"sHwdD","\u002F\u002F 'id' | 'title'\n",[10,3107,3108],{},"プロパティを追加・削除したときにユニオン型を手作業で更新する必要がなくなり、型定義との不整合を防ぎやすくなります。",[1197,3110,3111],{"id":3111},"インデックスアクセス型",[10,3113,3114],{},"インデックスアクセス型を使うと、オブジェクト型から特定のプロパティの型を取り出せます。",[51,3116,3118],{"className":2692,"code":3117,"language":2669,"meta":57,"style":57},"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",[59,3119,3120,3130,3138,3146,3150,3154,3176,3181,3185,3204],{"__ignoreMap":57},[87,3121,3122,3124,3126,3128],{"class":89,"line":90},[87,3123,2515],{"class":1915},[87,3125,2786],{"class":93},[87,3127,2521],{"class":111},[87,3129,2524],{"class":111},[87,3131,3132,3134,3136],{"class":89,"line":634},[87,3133,2932],{"class":1911},[87,3135,2331],{"class":111},[87,3137,2803],{"class":93},[87,3139,3140,3142,3144],{"class":89,"line":1157},[87,3141,2808],{"class":1911},[87,3143,2331],{"class":111},[87,3145,2813],{"class":93},[87,3147,3148],{"class":89,"line":1163},[87,3149,1166],{"class":111},[87,3151,3152],{"class":89,"line":1169},[87,3153,1172],{"emptyLinePlaceholder":647},[87,3155,3156,3158,3161,3163,3165,3168,3170,3172,3174],{"class":89,"line":1175},[87,3157,2515],{"class":1915},[87,3159,3160],{"class":93}," TodoId",[87,3162,2521],{"class":111},[87,3164,2786],{"class":93},[87,3166,3167],{"class":2050},"[",[87,3169,2132],{"class":111},[87,3171,2536],{"class":97},[87,3173,2132],{"class":111},[87,3175,1507],{"class":2050},[87,3177,3178],{"class":89,"line":1181},[87,3179,3180],{"class":3104},"\u002F\u002F number\n",[87,3182,3183],{"class":89,"line":1186},[87,3184,1172],{"emptyLinePlaceholder":647},[87,3186,3187,3189,3192,3194,3196,3198,3200,3202],{"class":89,"line":1192},[87,3188,2515],{"class":1915},[87,3190,3191],{"class":93}," TodoValue",[87,3193,2521],{"class":111},[87,3195,2786],{"class":93},[87,3197,3167],{"class":2050},[87,3199,3039],{"class":111},[87,3201,2786],{"class":93},[87,3203,1507],{"class":2050},[87,3205,3206],{"class":89,"line":1251},[87,3207,3208],{"class":3104},"\u002F\u002F number | string\n",[1197,3210,3211],{"id":3211},"アンビエント宣言",[10,3213,3214,3217],{},[59,3215,3216],{},"declare","を使うと、実装が別の場所に存在する値や型をTypeScriptへ伝えられます。JavaScriptライブラリや実行環境が提供するグローバル変数の型を補う場合などに使用します。",[51,3219,3221],{"className":2692,"code":3220,"language":2669,"meta":57,"style":57},"declare const appVersion: string\n",[59,3222,3223],{"__ignoreMap":57},[87,3224,3225,3227,3230,3233,3235],{"class":89,"line":90},[87,3226,3216],{"class":1915},[87,3228,3229],{"class":1915}," const",[87,3231,3232],{"class":2050}," appVersion",[87,3234,2331],{"class":111},[87,3236,2813],{"class":93},[10,3238,3239,3240,3243,3244,3246],{},"一般的には",[59,3241,3242],{},".d.ts","形式の型定義ファイルへ記述します。",[59,3245,3216],{},"は実行時の値を作成しないため、実体が存在しなければ実行時エラーになります。",[1197,3248,3249],{"id":3249},"メソッドの型注釈",[10,3251,3252],{},"オブジェクト型のメソッドは、メソッド構文と関数プロパティ構文のどちらでも表現できます。",[51,3254,3256],{"className":2692,"code":3255,"language":2669,"meta":57,"style":57},"type Formatter = {\n  format(value: string): string\n}\n\ntype FormatterProperty = {\n  format: (value: string) => string\n}\n",[59,3257,3258,3269,3289,3293,3297,3308,3328],{"__ignoreMap":57},[87,3259,3260,3262,3265,3267],{"class":89,"line":90},[87,3261,2515],{"class":1915},[87,3263,3264],{"class":93}," Formatter",[87,3266,2521],{"class":111},[87,3268,2524],{"class":111},[87,3270,3271,3274,3276,3279,3281,3284,3287],{"class":89,"line":634},[87,3272,3273],{"class":1911},"  format",[87,3275,2129],{"class":111},[87,3277,3278],{"class":2273},"value",[87,3280,2331],{"class":111},[87,3282,3283],{"class":93}," string",[87,3285,3286],{"class":111},"):",[87,3288,2813],{"class":93},[87,3290,3291],{"class":89,"line":1157},[87,3292,1166],{"class":111},[87,3294,3295],{"class":89,"line":1163},[87,3296,1172],{"emptyLinePlaceholder":647},[87,3298,3299,3301,3304,3306],{"class":89,"line":1169},[87,3300,2515],{"class":1915},[87,3302,3303],{"class":93}," FormatterProperty",[87,3305,2521],{"class":111},[87,3307,2524],{"class":111},[87,3309,3310,3312,3314,3316,3318,3320,3322,3324,3326],{"class":89,"line":1175},[87,3311,3273],{"class":1911},[87,3313,2331],{"class":111},[87,3315,2152],{"class":111},[87,3317,3278],{"class":2273},[87,3319,2331],{"class":111},[87,3321,3283],{"class":93},[87,3323,2544],{"class":111},[87,3325,2478],{"class":1915},[87,3327,2813],{"class":93},[87,3329,3330],{"class":89,"line":1181},[87,3331,1166],{"class":111},[10,3333,3334,3335,3338],{},"両者には、継承や",[59,3336,3337],{},"strictFunctionTypes","における引数型の扱いなどで違いがあります。プロジェクト内で意図に合った書き方へ揃えることが大切です。",[1197,3340,3341],{"id":3341},"型ガード",[10,3343,3344],{},"型ガードは、実行時の確認を通して変数の型を絞り込む仕組みです。ユーザー定義型ガードでは、戻り値の型に型述語を指定します。",[51,3346,3348],{"className":2692,"code":3347,"language":2669,"meta":57,"style":57},"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",[59,3349,3350,3378,3396,3400,3404,3419,3423,3437,3462],{"__ignoreMap":57},[87,3351,3352,3354,3357,3359,3361,3363,3366,3368,3371,3374,3376],{"class":89,"line":90},[87,3353,2562],{"class":1915},[87,3355,3356],{"class":2125}," isNumber",[87,3358,2129],{"class":111},[87,3360,3278],{"class":2273},[87,3362,2331],{"class":111},[87,3364,3365],{"class":93}," unknown",[87,3367,3286],{"class":111},[87,3369,3370],{"class":2273}," value",[87,3372,3373],{"class":111}," is",[87,3375,2541],{"class":93},[87,3377,2524],{"class":111},[87,3379,3380,3382,3385,3387,3389,3391,3394],{"class":89,"line":634},[87,3381,2623],{"class":2044},[87,3383,3384],{"class":111}," typeof",[87,3386,3370],{"class":2050},[87,3388,3016],{"class":111},[87,3390,2060],{"class":111},[87,3392,3393],{"class":97},"number",[87,3395,2065],{"class":111},[87,3397,3398],{"class":89,"line":1157},[87,3399,1166],{"class":111},[87,3401,3402],{"class":89,"line":1163},[87,3403,1172],{"emptyLinePlaceholder":647},[87,3405,3406,3408,3410,3412,3414,3416],{"class":89,"line":1169},[87,3407,2111],{"class":1915},[87,3409,3370],{"class":2050},[87,3411,2331],{"class":111},[87,3413,3365],{"class":93},[87,3415,2521],{"class":111},[87,3417,3418],{"class":104}," 10\n",[87,3420,3421],{"class":89,"line":1175},[87,3422,1172],{"emptyLinePlaceholder":647},[87,3424,3425,3427,3429,3432,3435],{"class":89,"line":1181},[87,3426,2149],{"class":2044},[87,3428,2152],{"class":2050},[87,3430,3431],{"class":2125},"isNumber",[87,3433,3434],{"class":2050},"(value)) ",[87,3436,2161],{"class":111},[87,3438,3439,3441,3443,3445,3447,3449,3451,3454,3456,3459],{"class":89,"line":1186},[87,3440,2869],{"class":2050},[87,3442,2122],{"class":111},[87,3444,2874],{"class":2125},[87,3446,2129],{"class":1911},[87,3448,3278],{"class":2050},[87,3450,2122],{"class":111},[87,3452,3453],{"class":2125},"toFixed",[87,3455,2129],{"class":1911},[87,3457,3458],{"class":104},"2",[87,3460,3461],{"class":1911},"))\n",[87,3463,3464],{"class":89,"line":1192},[87,3465,1166],{"class":111},[10,3467,3468],{},"APIレスポンスなど外部から受け取った値は、型アサーションで決めつけるのではなく、実行時に検証してから利用すると安全です。",[43,3470,574],{"id":574},[10,3472,3473],{},"Todoアプリの実装を通して、HTML属性の使い方からReactのstate更新、TypeScriptの型操作まで、幅広い内容を学べました。",[10,3475,3476],{},"個々の構文を覚えるだけでなく、「なぜその書き方が必要なのか」を実際のアプリ開発と結び付けて理解することが大切だと感じました。",[630,3478,3479],{},"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":57,"searchDepth":634,"depth":634,"links":3481},[3482,3485,3489,3496,3508],{"id":1881,"depth":634,"text":1870,"children":3483},[3484],{"id":1884,"depth":1157,"text":1884},{"id":1142,"depth":634,"text":1845,"children":3486},[3487,3488],{"id":1946,"depth":1157,"text":1946},{"id":1997,"depth":1157,"text":1998},{"id":2017,"depth":634,"text":1875,"children":3490},[3491,3492,3493,3494,3495],{"id":2020,"depth":1157,"text":2023},{"id":2255,"depth":1157,"text":2255},{"id":2457,"depth":1157,"text":2457},{"id":2494,"depth":1157,"text":2494},{"id":2660,"depth":1157,"text":2660},{"id":2669,"depth":634,"text":1878,"children":3497},[3498,3500,3501,3502,3503,3504,3505,3506,3507],{"id":2672,"depth":1157,"text":3499},"document.getElementByIdとnull",{"id":2766,"depth":1157,"text":2766},{"id":2825,"depth":1157,"text":2825},{"id":2904,"depth":1157,"text":2904},{"id":3036,"depth":1157,"text":3036},{"id":3111,"depth":1157,"text":3111},{"id":3211,"depth":1157,"text":3211},{"id":3249,"depth":1157,"text":3249},{"id":3341,"depth":1157,"text":3341},{"id":574,"depth":634,"text":574},"React HooksとTypeScriptでTodoアプリを作るハンズオンを通して学んだ、HTML、JavaScript、React、TypeScriptのポイントを整理します。",{},"\u002Farticles\u002F2024\u002Forganize-learned-from-todo","2024-12-23",{"title":1850,"description":3509},"articles\u002F2024\u002Forganize-learned-from-todo",[1875,1878],"\u002Fimages\u002Farticles\u002Forganize-learned-from-todo.png","ic1Do2Gie9Gb4WmAmZ2IL55ETNgmySMOwEHT_s3q0bk",{"id":3519,"title":3520,"body":3521,"description":3997,"extension":645,"meta":3998,"navigation":647,"path":3999,"publishDate":4000,"published":647,"seo":4001,"stem":4002,"tags":4003,"thumbnail":4005,"updated":4000,"__hash__":4006},"articles\u002Farticles\u002F2024\u002Fdescribe-webstorage-indexeddb.md","Web StorageとIndexedDBについて整理する",{"type":7,"value":3522,"toc":3987},[3523,3525,3528,3538,3541,3544,3547,3550,3633,3636,3641,3644,3672,3683,3734,3737,3740,3748,3767,3770,3773,3776,3779,3782,3884,3887,3901,3904,3907,3910,3934,3940,3943,3946,3953,3956,3959,3974,3977,3979,3982,3985],[10,3524,12],{},[10,3526,3527],{},"Todoアプリを作った際にIndexedDBを利用したのですが、ブラウザにデータを保存する方法としてはWeb Storageもあります。",[10,3529,3530,3531,2394,3534,3537],{},"今回は、",[59,3532,3533],{},"localStorage",[59,3535,3536],{},"sessionStorage","、IndexedDBの特徴と使い分けを整理します。",[43,3539,3540],{"id":3540},"ブラウザにデータを保存する仕組み",[10,3542,3543],{},"Web StorageとIndexedDBは、どちらもブラウザ側にデータを保存するためのWeb APIです。",[10,3545,3546],{},"保存したデータが自動的にサーバーへ送信されることはなく、同一オリジンの制約を受けます。ただし、保存容量やデータが削除される条件はブラウザや利用状況によって異なるため、永続性を前提にしすぎないことが大切です。",[10,3548,3549],{},"主な違いは次のとおりです。",[279,3551,3552,3565],{},[282,3553,3554],{},[285,3555,3556,3558,3560,3562],{},[288,3557,290],{},[288,3559,3533],{},[288,3561,3536],{},[288,3563,3564],{},"IndexedDB",[296,3566,3567,3580,3593,3606,3619],{},[285,3568,3569,3572,3575,3577],{},[301,3570,3571],{},"保存形式",[301,3573,3574],{},"文字列のキーバリュー",[301,3576,3574],{},[301,3578,3579],{},"オブジェクトやBlobなど",[285,3581,3582,3585,3588,3590],{},[301,3583,3584],{},"API",[301,3586,3587],{},"同期",[301,3589,3587],{},[301,3591,3592],{},"非同期",[285,3594,3595,3598,3601,3604],{},[301,3596,3597],{},"データの範囲",[301,3599,3600],{},"同一オリジン",[301,3602,3603],{},"同一オリジンかつタブ単位",[301,3605,3600],{},[285,3607,3608,3611,3614,3617],{},[301,3609,3610],{},"データの寿命",[301,3612,3613],{},"明示的に削除されるまで",[301,3615,3616],{},"タブを閉じるまで",[301,3618,3613],{},[285,3620,3621,3624,3627,3630],{},[301,3622,3623],{},"得意な用途",[301,3625,3626],{},"小さな設定値",[301,3628,3629],{},"一時的な入力状態",[301,3631,3632],{},"大量・構造化データ",[43,3634,3533],{"id":3635},"localstorage",[10,3637,3638,3640],{},[59,3639,3533],{},"は、文字列をキーバリュー形式で保存する同期APIです。",[10,3642,3643],{},"ブラウザやタブを閉じてもデータが残るため、テーマや表示設定など、小さく単純なデータの保存に向いています。",[51,3645,3647],{"className":1140,"code":3646,"language":1142,"meta":57,"style":57},"localStorage.setItem('theme', 'dark')\n\nconst theme = localStorage.getItem('theme')\n\nlocalStorage.removeItem('theme')\n",[59,3648,3649,3654,3658,3663,3667],{"__ignoreMap":57},[87,3650,3651],{"class":89,"line":90},[87,3652,3653],{},"localStorage.setItem('theme', 'dark')\n",[87,3655,3656],{"class":89,"line":634},[87,3657,1172],{"emptyLinePlaceholder":647},[87,3659,3660],{"class":89,"line":1157},[87,3661,3662],{},"const theme = localStorage.getItem('theme')\n",[87,3664,3665],{"class":89,"line":1163},[87,3666,1172],{"emptyLinePlaceholder":647},[87,3668,3669],{"class":89,"line":1169},[87,3670,3671],{},"localStorage.removeItem('theme')\n",[10,3673,3674,3675,3678,3679,3682],{},"値は文字列として保存されます。オブジェクトを扱う場合は、保存時に",[59,3676,3677],{},"JSON.stringify()","、取得時に",[59,3680,3681],{},"JSON.parse()","が必要です。",[51,3684,3686],{"className":1140,"code":3685,"language":1142,"meta":57,"style":57},"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",[59,3687,3688,3693,3698,3703,3707,3711,3716,3720,3725,3730],{"__ignoreMap":57},[87,3689,3690],{"class":89,"line":90},[87,3691,3692],{},"const settings = {\n",[87,3694,3695],{"class":89,"line":634},[87,3696,3697],{},"  theme: 'dark',\n",[87,3699,3700],{"class":89,"line":1157},[87,3701,3702],{},"  fontSize: 16,\n",[87,3704,3705],{"class":89,"line":1163},[87,3706,1166],{},[87,3708,3709],{"class":89,"line":1169},[87,3710,1172],{"emptyLinePlaceholder":647},[87,3712,3713],{"class":89,"line":1175},[87,3714,3715],{},"localStorage.setItem('settings', JSON.stringify(settings))\n",[87,3717,3718],{"class":89,"line":1181},[87,3719,1172],{"emptyLinePlaceholder":647},[87,3721,3722],{"class":89,"line":1186},[87,3723,3724],{},"const storedSettings = JSON.parse(\n",[87,3726,3727],{"class":89,"line":1192},[87,3728,3729],{},"  localStorage.getItem('settings') ?? '{}',\n",[87,3731,3732],{"class":89,"line":1251},[87,3733,2140],{},[10,3735,3736],{},"同期APIのため、大きなデータを頻繁に読み書きするとメインスレッドを塞ぐ可能性があります。",[43,3738,3536],{"id":3739},"sessionstorage",[10,3741,3742,3744,3745,3747],{},[59,3743,3536],{},"も、文字列をキーバリュー形式で保存する同期APIです。基本的な操作方法は",[59,3746,3533],{},"と同じです。",[51,3749,3751],{"className":1140,"code":3750,"language":1142,"meta":57,"style":57},"sessionStorage.setItem('draft', '入力途中の内容')\n\nconst draft = sessionStorage.getItem('draft')\n",[59,3752,3753,3758,3762],{"__ignoreMap":57},[87,3754,3755],{"class":89,"line":90},[87,3756,3757],{},"sessionStorage.setItem('draft', '入力途中の内容')\n",[87,3759,3760],{"class":89,"line":634},[87,3761,1172],{"emptyLinePlaceholder":647},[87,3763,3764],{"class":89,"line":1157},[87,3765,3766],{},"const draft = sessionStorage.getItem('draft')\n",[10,3768,3769],{},"ページを再読み込みしてもデータは残りますが、保存領域はタブごとのページセッションに分かれ、タブを閉じるとデータも削除されます。",[10,3771,3772],{},"そのため、フォームの入力途中の状態や、画面遷移中だけ保持したい一時的な情報に向いています。",[43,3774,3564],{"id":3775},"indexeddb",[10,3777,3778],{},"IndexedDBは、大量の構造化データをブラウザへ保存するための非同期APIです。",[10,3780,3781],{},"JavaScriptのオブジェクトだけでなく、ファイルやBlobなども保存できます。また、オブジェクトストア、インデックス、トランザクションを利用できるため、検索や更新を伴うデータ管理に向いています。",[51,3783,3785],{"className":1140,"code":3784,"language":1142,"meta":57,"style":57},"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",[59,3786,3787,3792,3796,3801,3806,3810,3815,3820,3825,3830,3835,3839,3843,3847,3852,3856,3862,3868,3873,3879],{"__ignoreMap":57},[87,3788,3789],{"class":89,"line":90},[87,3790,3791],{},"const request = indexedDB.open('todo-app', 1)\n",[87,3793,3794],{"class":89,"line":634},[87,3795,1172],{"emptyLinePlaceholder":647},[87,3797,3798],{"class":89,"line":1157},[87,3799,3800],{},"request.onupgradeneeded = () => {\n",[87,3802,3803],{"class":89,"line":1163},[87,3804,3805],{},"  const database = request.result\n",[87,3807,3808],{"class":89,"line":1169},[87,3809,1172],{"emptyLinePlaceholder":647},[87,3811,3812],{"class":89,"line":1175},[87,3813,3814],{},"  if (!database.objectStoreNames.contains('todos')) {\n",[87,3816,3817],{"class":89,"line":1181},[87,3818,3819],{},"    database.createObjectStore('todos', {\n",[87,3821,3822],{"class":89,"line":1186},[87,3823,3824],{},"      keyPath: 'id',\n",[87,3826,3827],{"class":89,"line":1192},[87,3828,3829],{},"      autoIncrement: true,\n",[87,3831,3832],{"class":89,"line":1251},[87,3833,3834],{},"    })\n",[87,3836,3837],{"class":89,"line":1257},[87,3838,2614],{},[87,3840,3841],{"class":89,"line":1263},[87,3842,1166],{},[87,3844,3845],{"class":89,"line":1268},[87,3846,1172],{"emptyLinePlaceholder":647},[87,3848,3849],{"class":89,"line":1273},[87,3850,3851],{},"request.onsuccess = () => {\n",[87,3853,3854],{"class":89,"line":2239},[87,3855,3805],{},[87,3857,3859],{"class":89,"line":3858},16,[87,3860,3861],{},"  const transaction = database.transaction('todos', 'readwrite')\n",[87,3863,3865],{"class":89,"line":3864},17,[87,3866,3867],{},"  const todos = transaction.objectStore('todos')\n",[87,3869,3871],{"class":89,"line":3870},18,[87,3872,1172],{"emptyLinePlaceholder":647},[87,3874,3876],{"class":89,"line":3875},19,[87,3877,3878],{},"  todos.add({ title: '記事を書く', completed: false })\n",[87,3880,3882],{"class":89,"line":3881},20,[87,3883,1166],{},[10,3885,3886],{},"Web Storageよりも扱う概念は多いものの、次のような用途で力を発揮します。",[1787,3888,3889,3892,3895,3898],{},[582,3890,3891],{},"オフラインでも利用するアプリ",[582,3893,3894],{},"Todoやメモなど、件数が増えるデータ",[582,3896,3897],{},"検索や並び替えにインデックスを使いたいデータ",[582,3899,3900],{},"画像やファイルを含むデータ",[43,3902,3903],{"id":3903},"保存容量とデータの削除",[10,3905,3906],{},"ブラウザストレージの容量は、特定の数値をどの環境でも保証できるものではありません。ブラウザ、端末の空き容量、ユーザー設定などによって変わります。",[10,3908,3909],{},"利用状況はStorage APIから概算できます。",[51,3911,3913],{"className":1140,"code":3912,"language":1142,"meta":57,"style":57},"const estimate = await navigator.storage.estimate()\n\nconsole.log(estimate.usage)\nconsole.log(estimate.quota)\n",[59,3914,3915,3920,3924,3929],{"__ignoreMap":57},[87,3916,3917],{"class":89,"line":90},[87,3918,3919],{},"const estimate = await navigator.storage.estimate()\n",[87,3921,3922],{"class":89,"line":634},[87,3923,1172],{"emptyLinePlaceholder":647},[87,3925,3926],{"class":89,"line":1157},[87,3927,3928],{},"console.log(estimate.usage)\n",[87,3930,3931],{"class":89,"line":1163},[87,3932,3933],{},"console.log(estimate.quota)\n",[35,3935,3937],{"title":3936,"type":38},"ブラウザストレージを唯一の保存先にしない",[10,3938,3939],{},"保存したデータは、ユーザーによるサイトデータの削除や、ブラウザのストレージ管理によって失われる場合があります。失われると困るデータはサーバーにも保存しましょう。",[43,3941,3942],{"id":3942},"セキュリティ上の注意",[10,3944,3945],{},"Web StorageとIndexedDBは、認証された同一オリジンのJavaScriptからアクセスできます。",[35,3947,3950],{"title":3948,"type":3949},"機密情報の保存に注意する","warning",[10,3951,3952],{},"クロスサイトスクリプティング（XSS）が発生すると、保存内容を読み取られる可能性があります。アクセストークンや個人情報などの機密情報を、安易に保存しないようにしましょう。",[43,3954,3955],{"id":3955},"どれを選ぶか",[10,3957,3958],{},"選び方を簡単にまとめると、次のようになります。",[1787,3960,3961,3966,3971],{},[582,3962,3963,3964],{},"小さな設定をブラウザを閉じた後も残したい場合は",[59,3965,3533],{},[582,3967,3968,3969],{},"タブを開いている間だけ一時的に残したい場合は",[59,3970,3536],{},[582,3972,3973],{},"大量のデータや構造化データを非同期で扱いたい場合はIndexedDB",[10,3975,3976],{},"Web Storageは手軽ですが、同期APIであり文字列しか保存できません。データ量が増えるアプリや、検索・更新を伴うデータにはIndexedDBを検討するとよいでしょう。",[43,3978,574],{"id":574},[10,3980,3981],{},"Web StorageとIndexedDBは、どちらもブラウザ側へデータを保存できますが、得意な用途が異なります。",[10,3983,3984],{},"保存するデータの量や形式だけでなく、同期処理による影響、データを保持する期間、失われた場合の影響まで考えて選ぶことが大切です。",[630,3986,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":3988},[3989,3990,3991,3992,3993,3994,3995,3996],{"id":3540,"depth":634,"text":3540},{"id":3635,"depth":634,"text":3533},{"id":3739,"depth":634,"text":3536},{"id":3775,"depth":634,"text":3564},{"id":3903,"depth":634,"text":3903},{"id":3942,"depth":634,"text":3942},{"id":3955,"depth":634,"text":3955},{"id":574,"depth":634,"text":574},"localStorage、sessionStorage、IndexedDBの違いを、保存形式、同期・非同期、データの寿命、用途から整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-webstorage-indexeddb","2024-12-22",{"title":3520,"description":3997},"articles\u002F2024\u002Fdescribe-webstorage-indexeddb",[4004,3564],"Web Storage","\u002Fimages\u002Farticles\u002Fdescribe-webstorage-indexeddb.png","3W_8UP01CjjLWIG3qOQhJB7e1YiLPuYONYyx_372v98",{"id":4008,"title":4009,"body":4010,"description":4486,"extension":645,"meta":4487,"navigation":647,"path":4488,"publishDate":4489,"published":647,"seo":4490,"stem":4491,"tags":4492,"thumbnail":4493,"updated":4489,"__hash__":4494},"articles\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime.md","JavaScriptのランタイム構成からイベントループを学ぶ",{"type":7,"value":4011,"toc":4476},[4012,4014,4023,4026,4030,4033,4036,4039,4056,4058,4061,4064,4128,4131,4164,4167,4170,4173,4176,4190,4193,4236,4239,4241,4244,4247,4261,4266,4269,4271,4274,4299,4302,4305,4307,4310,4313,4330,4333,4336,4411,4414,4420,4431,4440,4442,4462,4465,4474],[10,4013,12],{},[10,4015,4016,4017,4022],{},"今回は、JavaScriptのイベントループについて、動画「",[1859,4018,4021],{"href":4019,"rel":4020},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=eiC58R16hb8",[1863],"JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue","」で学んだ内容を整理します。",[10,4024,4025],{},"ブラウザでJavaScriptがどのように同期処理と非同期処理を扱っているのか、ランタイムを構成する要素から確認していきます。",[43,4027,4029],{"id":4028},"javascriptエンジンとホスト環境","JavaScriptエンジンとホスト環境",[10,4031,4032],{},"ブラウザでJavaScriptを実行するためには、JavaScriptエンジンとブラウザというホスト環境が連携します。",[10,4034,4035],{},"JavaScriptエンジンはコードを解析・実行し、ブラウザはタイマー、ネットワーク通信、DOMイベントなどの環境固有の機能を提供します。",[10,4037,4038],{},"イベントループを理解するうえでは、次の要素を押さえておくと全体像が見えやすくなります。",[1787,4040,4041,4044,4047,4050,4053],{},[582,4042,4043],{},"コールスタック",[582,4045,4046],{},"Web APIs",[582,4048,4049],{},"タスクキュー",[582,4051,4052],{},"マイクロタスクキュー",[582,4054,4055],{},"イベントループ",[43,4057,4043],{"id":4043},[10,4059,4060],{},"コールスタックは、実行中の関数や実行コンテキストを管理するスタックです。",[10,4062,4063],{},"後から追加されたものが先に取り出される、後入れ先出し（LIFO）の構造になっています。",[51,4065,4067],{"className":1140,"code":4066,"language":1142,"meta":57,"style":57},"function a() {\n  console.log('a')\n}\n\nfunction b() {\n  a()\n}\n\nfunction c() {\n  b()\n}\n\nc()\n",[59,4068,4069,4074,4079,4083,4087,4092,4097,4101,4105,4110,4115,4119,4123],{"__ignoreMap":57},[87,4070,4071],{"class":89,"line":90},[87,4072,4073],{},"function a() {\n",[87,4075,4076],{"class":89,"line":634},[87,4077,4078],{},"  console.log('a')\n",[87,4080,4081],{"class":89,"line":1157},[87,4082,1166],{},[87,4084,4085],{"class":89,"line":1163},[87,4086,1172],{"emptyLinePlaceholder":647},[87,4088,4089],{"class":89,"line":1169},[87,4090,4091],{},"function b() {\n",[87,4093,4094],{"class":89,"line":1175},[87,4095,4096],{},"  a()\n",[87,4098,4099],{"class":89,"line":1181},[87,4100,1166],{},[87,4102,4103],{"class":89,"line":1186},[87,4104,1172],{"emptyLinePlaceholder":647},[87,4106,4107],{"class":89,"line":1192},[87,4108,4109],{},"function c() {\n",[87,4111,4112],{"class":89,"line":1251},[87,4113,4114],{},"  b()\n",[87,4116,4117],{"class":89,"line":1257},[87,4118,1166],{},[87,4120,4121],{"class":89,"line":1263},[87,4122,1172],{"emptyLinePlaceholder":647},[87,4124,4125],{"class":89,"line":1268},[87,4126,4127],{},"c()\n",[10,4129,4130],{},"このコードは、次の流れで実行されます。",[579,4132,4133,4139,4148,4155],{},[582,4134,4135,4138],{},[59,4136,4137],{},"c()"," がスタックへ追加される",[582,4140,4141,4143,4144,4147],{},[59,4142,4137],{}," から呼ばれた ",[59,4145,4146],{},"b()"," が追加される",[582,4149,4150,4143,4152,4147],{},[59,4151,4146],{},[59,4153,4154],{},"a()",[582,4156,4157,2394,4159,2394,4161,4163],{},[59,4158,4154],{},[59,4160,4146],{},[59,4162,4137],{}," の順に処理を終えてスタックから取り除かれる",[10,4165,4166],{},"1つの長い同期処理がコールスタックを占有すると、その処理が終わるまでクリックや描画など、同じスレッド上のほかの処理を進められません。",[43,4168,4046],{"id":4169},"web-apis",[10,4171,4172],{},"Web APIsは、ブラウザというホスト環境が提供する機能です。",[10,4174,4175],{},"代表的なものには、次があります。",[1787,4177,4178,4181,4184,4187],{},[582,4179,4180],{},"Fetch API",[582,4182,4183],{},"タイマー",[582,4185,4186],{},"Geolocation API",[582,4188,4189],{},"DOMイベント",[10,4191,4192],{},"JavaScriptからこれらの非同期APIを呼び出すと、ブラウザ側でタイマーの計測やネットワーク通信などが進みます。JavaScriptはその完了を待ってコールスタックを占有し続ける必要がないため、別のコードを実行できます。",[51,4194,4196],{"className":1140,"code":4195,"language":1142,"meta":57,"style":57},"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",[59,4197,4198,4203,4208,4213,4217,4221,4226,4231],{"__ignoreMap":57},[87,4199,4200],{"class":89,"line":90},[87,4201,4202],{},"navigator.geolocation.getCurrentPosition(\n",[87,4204,4205],{"class":89,"line":634},[87,4206,4207],{},"  position => console.log(position),\n",[87,4209,4210],{"class":89,"line":1157},[87,4211,4212],{},"  error => console.error(error),\n",[87,4214,4215],{"class":89,"line":1163},[87,4216,2140],{},[87,4218,4219],{"class":89,"line":1169},[87,4220,1172],{"emptyLinePlaceholder":647},[87,4222,4223],{"class":89,"line":1175},[87,4224,4225],{},"fetch('https:\u002F\u002Fexample.com\u002Fapi\u002Fdata')\n",[87,4227,4228],{"class":89,"line":1181},[87,4229,4230],{},"  .then(response => response.json())\n",[87,4232,4233],{"class":89,"line":1186},[87,4234,4235],{},"  .then(data => console.log(data))\n",[10,4237,4238],{},"APIの処理が完了しても、コールバックがその場ですぐに実行されるとは限りません。実行可能になった処理は、タスクやマイクロタスクとしてキューへ登録されます。",[43,4240,4049],{"id":4049},[10,4242,4243],{},"タスクキューには、タイマーやイベントなどをきっかけに実行可能になったタスクが並びます。",[10,4245,4246],{},"代表的な例は次のとおりです。",[1787,4248,4249,4255,4258],{},[582,4250,4251,4254],{},[59,4252,4253],{},"setTimeout()"," のコールバック",[582,4256,4257],{},"ユーザー操作のイベントハンドラー",[582,4259,4260],{},"メッセージイベント",[10,4262,4263,4265],{},[59,4264,4253],{}," に指定する時間は、コールバックが必ずその時間後に実行されるという意味ではありません。指定時間を経過したあとにタスクとして実行可能になるまでの最低待機時間です。",[10,4267,4268],{},"コールスタックや先に処理されるタスクが残っていれば、実際の実行はさらに遅くなります。",[43,4270,4052],{"id":4052},[10,4272,4273],{},"マイクロタスクキューには、主に次の処理が登録されます。",[1787,4275,4276,4288,4294],{},[582,4277,4278,4279,2394,4282,2394,4285],{},"Promiseの ",[59,4280,4281],{},"then()",[59,4283,4284],{},"catch()",[59,4286,4287],{},"finally()",[582,4289,4290,4293],{},[59,4291,4292],{},"queueMicrotask()"," に渡したコールバック",[582,4295,4296,4254],{},[59,4297,4298],{},"MutationObserver",[10,4300,4301],{},"現在のタスクと同期処理が終わってコールスタックが空になると、次のタスクへ進む前にマイクロタスクキューが空になるまで処理されます。",[10,4303,4304],{},"マイクロタスクの実行中に新しいマイクロタスクが追加された場合も、同じタイミングで続けて処理されます。そのため、マイクロタスクを追加し続ける処理は、次のタスクや画面描画を遅らせる可能性があります。",[43,4306,4055],{"id":4055},[10,4308,4309],{},"イベントループは、コールスタックと各キューの状態を見ながら、実行する処理を選び続けます。",[10,4311,4312],{},"ブラウザ上の流れを単純化すると、次のようになります。",[579,4314,4315,4318,4321,4324,4327],{},[582,4316,4317],{},"1つのタスクを実行する",[582,4319,4320],{},"コールスタック上の同期処理を最後まで実行する",[582,4322,4323],{},"マイクロタスクキューを空になるまで処理する",[582,4325,4326],{},"必要に応じて画面を描画する",[582,4328,4329],{},"次のタスクへ進む",[43,4331,4332],{"id":4332},"コードで実行順を確認する",[10,4334,4335],{},"タスクとマイクロタスクの実行順を、コードで確認してみましょう。",[51,4337,4339],{"className":1140,"code":4338,"language":1142,"meta":57,"style":57},"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",[59,4340,4341,4346,4350,4355,4360,4365,4369,4374,4379,4384,4388,4393,4398,4402,4406],{"__ignoreMap":57},[87,4342,4343],{"class":89,"line":90},[87,4344,4345],{},"console.log('start')\n",[87,4347,4348],{"class":89,"line":634},[87,4349,1172],{"emptyLinePlaceholder":647},[87,4351,4352],{"class":89,"line":1157},[87,4353,4354],{},"setTimeout(() => {\n",[87,4356,4357],{"class":89,"line":1163},[87,4358,4359],{},"  console.log('timeout')\n",[87,4361,4362],{"class":89,"line":1169},[87,4363,4364],{},"}, 0)\n",[87,4366,4367],{"class":89,"line":1175},[87,4368,1172],{"emptyLinePlaceholder":647},[87,4370,4371],{"class":89,"line":1181},[87,4372,4373],{},"Promise.resolve().then(() => {\n",[87,4375,4376],{"class":89,"line":1186},[87,4377,4378],{},"  console.log('promise')\n",[87,4380,4381],{"class":89,"line":1192},[87,4382,4383],{},"})\n",[87,4385,4386],{"class":89,"line":1251},[87,4387,1172],{"emptyLinePlaceholder":647},[87,4389,4390],{"class":89,"line":1257},[87,4391,4392],{},"queueMicrotask(() => {\n",[87,4394,4395],{"class":89,"line":1263},[87,4396,4397],{},"  console.log('microtask')\n",[87,4399,4400],{"class":89,"line":1268},[87,4401,4383],{},[87,4403,4404],{"class":89,"line":1273},[87,4405,1172],{"emptyLinePlaceholder":647},[87,4407,4408],{"class":89,"line":2239},[87,4409,4410],{},"console.log('end')\n",[10,4412,4413],{},"出力順は次のようになります。",[51,4415,4418],{"className":4416,"code":4417,"language":56,"meta":57},[54],"start\nend\npromise\nmicrotask\ntimeout\n",[59,4419,4417],{"__ignoreMap":57},[10,4421,4422,4423,4426,4427,4430],{},"まず同期処理の ",[59,4424,4425],{},"start"," と ",[59,4428,4429],{},"end"," が出力されます。",[10,4432,4433,4434,4436,4437,4439],{},"続いて、登録された順にPromiseのコールバックと ",[59,4435,4292],{}," のコールバックがマイクロタスクとして実行されます。マイクロタスクキューが空になったあと、",[59,4438,4253],{}," のコールバックが次のタスクとして実行されます。",[43,4441,574],{"id":574},[1787,4443,4444,4447,4450,4453,4456,4459],{},[582,4445,4446],{},"コールスタックは、実行中の関数をLIFOで管理する",[582,4448,4449],{},"ブラウザは、タイマーやネットワーク通信などのWeb APIsを提供する",[582,4451,4452],{},"タイマーやイベントのコールバックなどは、タスクとしてキューへ登録される",[582,4454,4455],{},"Promiseのコールバックなどは、マイクロタスクとして登録される",[582,4457,4458],{},"現在のタスクが完了すると、次のタスクより先にマイクロタスクが処理される",[582,4460,4461],{},"長い同期処理や増え続けるマイクロタスクは、画面の応答を遅らせる可能性がある",[10,4463,4464],{},"非同期処理の実行順で迷ったときは、「現在の同期処理」「マイクロタスク」「次のタスク」の順に分けて考えると整理しやすくなります。",[10,4466,4467,4468,4473],{},"より詳しい実行モデルは、",[1859,4469,4472],{"href":4470,"rel":4471},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FExecution_model",[1863],"MDNのJavaScript実行モデル","も参考になります。",[630,4475,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":4477},[4478,4479,4480,4481,4482,4483,4484,4485],{"id":4028,"depth":634,"text":4029},{"id":4043,"depth":634,"text":4043},{"id":4169,"depth":634,"text":4046},{"id":4049,"depth":634,"text":4049},{"id":4052,"depth":634,"text":4052},{"id":4055,"depth":634,"text":4055},{"id":4332,"depth":634,"text":4332},{"id":574,"depth":634,"text":574},"ブラウザのJavaScriptランタイムを構成するコールスタック、Web APIs、タスクキュー、マイクロタスクキューとイベントループの関係を整理します。",{},"\u002Farticles\u002F2024\u002Flearn-javascript-eventloop-from-runtime","2024-11-25",{"title":4009,"description":4486},"articles\u002F2024\u002Flearn-javascript-eventloop-from-runtime",[1845],"\u002Fimages\u002Farticles\u002Flearn-javascript-eventloop-from-runtime.png","BcnDDE_gLqK4tjYoVA9O89QF7-dNwS-6lyORZ07cH5g",{"id":4496,"title":4497,"body":4498,"description":4914,"extension":645,"meta":4915,"navigation":647,"path":4916,"publishDate":4917,"published":647,"seo":4918,"stem":4919,"tags":4920,"thumbnail":4921,"updated":4917,"__hash__":4922},"articles\u002Farticles\u002F2024\u002Fhow-to-use-javascript-built-in-objects.md","JavaScriptのビルトインオブジェクトのメソッドをどう使うか",{"type":7,"value":4499,"toc":4906},[4500,4502,4505,4508,4512,4515,4527,4536,4540,4550,4577,4594,4602,4605,4612,4652,4663,4671,4684,4708,4712,4719,4757,4763,4768,4789,4792,4801,4839,4849,4867,4869,4901,4904],[10,4501,12],{},[10,4503,4504],{},"今回は、プロジェクトで「なるほど」と思った、JavaScriptのビルトインオブジェクトのメソッドの使い方を紹介します。",[10,4506,4507],{},"具体的には、オブジェクトが自身のプロパティを持っているか、安全に確認する方法です。仕組みを知っておくと、オブジェクトに同名のメソッドが定義されている場合も意図した判定ができます。",[43,4509,4511],{"id":4510},"ビルトインオブジェクトってなに","「ビルトインオブジェクト」ってなに？",[10,4513,4514],{},"ビルトインオブジェクトは「組み込みオブジェクト」とも呼ばれ、JavaScriptの実行環境にあらかじめ用意されているオブジェクトです。",[10,4516,4517,2394,4520,2394,4523,4526],{},[59,4518,4519],{},"Object",[59,4521,4522],{},"Array",[59,4524,4525],{},"String"," など、さまざまな種類があります。",[10,4528,4529,4530,4535],{},"詳しくは、",[1859,4531,4534],{"href":4532,"rel":4533},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects",[1863],"MDNの標準組み込みオブジェクト","を参照してください。",[43,4537,4539],{"id":4538},"hasownpropertyをインスタンスから呼び出す","hasOwnPropertyをインスタンスから呼び出す",[10,4541,4542,4543,4545,4546,4549],{},"まずは、オブジェクト自身が ",[59,4544,1386],{}," プロパティを持っているか、",[59,4547,4548],{},"hasOwnProperty()"," で確認してみます。",[51,4551,4553],{"className":1140,"code":4552,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n}\n\nobj.hasOwnProperty('name') \u002F\u002F true\n",[59,4554,4555,4560,4564,4568,4572],{"__ignoreMap":57},[87,4556,4557],{"class":89,"line":90},[87,4558,4559],{},"const obj = {\n",[87,4561,4562],{"class":89,"line":634},[87,4563,1358],{},[87,4565,4566],{"class":89,"line":1157},[87,4567,1166],{},[87,4569,4570],{"class":89,"line":1163},[87,4571,1172],{"emptyLinePlaceholder":647},[87,4573,4574],{"class":89,"line":1169},[87,4575,4576],{},"obj.hasOwnProperty('name') \u002F\u002F true\n",[10,4578,4579,4580,4583,4584,4587,4588,4590,4591,4593],{},"オブジェクトリテラルで作成した ",[59,4581,4582],{},"obj"," は、通常 ",[59,4585,4586],{},"Object.prototype"," を継承しています。そのため、",[59,4589,4586],{}," に定義されている ",[59,4592,4548],{}," を呼び出せます。",[10,4595,4596,4597,4473],{},"プロトタイプ継承については、",[1859,4598,4601],{"href":4599,"rel":4600},"https:\u002F\u002Fja.javascript.info\u002Fprototype-inheritance",[1863],"JavaScript.infoのプロトタイプ継承",[43,4603,4604],{"id":4604},"インスタンスから呼び出す場合の問題",[10,4606,4607,4608,4611],{},"では、オブジェクト自身が ",[59,4609,4610],{},"hasOwnProperty"," という同名のメソッドを持っていたらどうなるでしょうか。",[51,4613,4615],{"className":1140,"code":4614,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nobj.hasOwnProperty('name') \u002F\u002F 「Hello」と出力される\n",[59,4616,4617,4621,4625,4630,4635,4639,4643,4647],{"__ignoreMap":57},[87,4618,4619],{"class":89,"line":90},[87,4620,4559],{},[87,4622,4623],{"class":89,"line":634},[87,4624,1358],{},[87,4626,4627],{"class":89,"line":1157},[87,4628,4629],{},"  hasOwnProperty() {\n",[87,4631,4632],{"class":89,"line":1163},[87,4633,4634],{},"    console.log('Hello')\n",[87,4636,4637],{"class":89,"line":1169},[87,4638,1230],{},[87,4640,4641],{"class":89,"line":1175},[87,4642,1166],{},[87,4644,4645],{"class":89,"line":1181},[87,4646,1172],{"emptyLinePlaceholder":647},[87,4648,4649],{"class":89,"line":1186},[87,4650,4651],{},"obj.hasOwnProperty('name') \u002F\u002F 「Hello」と出力される\n",[10,4653,4654,4655,4658,4659,4662],{},"先ほどは ",[59,4656,4657],{},"true"," を返していた呼び出しが、今度は ",[59,4660,4661],{},"Hello"," を出力しました。",[10,4664,4665,4667,4668,4670],{},[59,4666,4582],{}," 自身の ",[59,4669,4610],{}," が、プロトタイプから継承した同名メソッドよりも優先されたためです。外部から受け取ったオブジェクトなど、自分で構造を完全に管理できない値では、インスタンスから直接呼び出す方法は意図しない結果につながる可能性があります。",[10,4672,4673,4674,4677,4678,4680,4681,4683],{},"また、",[59,4675,4676],{},"Object.create(null)"," で作ったオブジェクトは ",[59,4679,4586],{}," を継承しないため、そもそも ",[59,4682,4548],{}," を持っていません。",[51,4685,4687],{"className":1140,"code":4686,"language":1142,"meta":57,"style":57},"const obj = Object.create(null)\nobj.name = 'Yuri'\n\nobj.hasOwnProperty('name') \u002F\u002F TypeError\n",[59,4688,4689,4694,4699,4703],{"__ignoreMap":57},[87,4690,4691],{"class":89,"line":90},[87,4692,4693],{},"const obj = Object.create(null)\n",[87,4695,4696],{"class":89,"line":634},[87,4697,4698],{},"obj.name = 'Yuri'\n",[87,4700,4701],{"class":89,"line":1157},[87,4702,1172],{"emptyLinePlaceholder":647},[87,4704,4705],{"class":89,"line":1163},[87,4706,4707],{},"obj.hasOwnProperty('name') \u002F\u002F TypeError\n",[43,4709,4711],{"id":4710},"objecthasownを使う","Object.hasOwnを使う",[10,4713,4714,4715,4718],{},"現在は、オブジェクト自身のプロパティを調べる場合、静的メソッドの ",[59,4716,4717],{},"Object.hasOwn()"," を使うと簡潔です。",[51,4720,4722],{"className":1140,"code":4721,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nObject.hasOwn(obj, 'name') \u002F\u002F true\n",[59,4723,4724,4728,4732,4736,4740,4744,4748,4752],{"__ignoreMap":57},[87,4725,4726],{"class":89,"line":90},[87,4727,4559],{},[87,4729,4730],{"class":89,"line":634},[87,4731,1358],{},[87,4733,4734],{"class":89,"line":1157},[87,4735,4629],{},[87,4737,4738],{"class":89,"line":1163},[87,4739,4634],{},[87,4741,4742],{"class":89,"line":1169},[87,4743,1230],{},[87,4745,4746],{"class":89,"line":1175},[87,4747,1166],{},[87,4749,4750],{"class":89,"line":1181},[87,4751,1172],{"emptyLinePlaceholder":647},[87,4753,4754],{"class":89,"line":1186},[87,4755,4756],{},"Object.hasOwn(obj, 'name') \u002F\u002F true\n",[10,4758,4759,4760,4762],{},"第1引数に調べたいオブジェクト、第2引数にプロパティ名を渡します。対象のオブジェクトに同名の ",[59,4761,4610],{}," が定義されていても影響を受けません。",[10,4764,4765,4767],{},[59,4766,4676],{}," で作ったオブジェクトにも使用できます。",[51,4769,4771],{"className":1140,"code":4770,"language":1142,"meta":57,"style":57},"const obj = Object.create(null)\nobj.name = 'Yuri'\n\nObject.hasOwn(obj, 'name') \u002F\u002F true\n",[59,4772,4773,4777,4781,4785],{"__ignoreMap":57},[87,4774,4775],{"class":89,"line":90},[87,4776,4693],{},[87,4778,4779],{"class":89,"line":634},[87,4780,4698],{},[87,4782,4783],{"class":89,"line":1157},[87,4784,1172],{"emptyLinePlaceholder":647},[87,4786,4787],{"class":89,"line":1163},[87,4788,4756],{},[43,4790,4791],{"id":4791},"古い実行環境も考慮する場合",[10,4793,4794,4796,4797,4800],{},[59,4795,4717],{}," を利用できない古い実行環境まで考慮する場合は、",[59,4798,4799],{},"Object.prototype.hasOwnProperty.call()"," という書き方もできます。",[51,4802,4804],{"className":1140,"code":4803,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n  hasOwnProperty() {\n    console.log('Hello')\n  },\n}\n\nObject.prototype.hasOwnProperty.call(obj, 'name') \u002F\u002F true\n",[59,4805,4806,4810,4814,4818,4822,4826,4830,4834],{"__ignoreMap":57},[87,4807,4808],{"class":89,"line":90},[87,4809,4559],{},[87,4811,4812],{"class":89,"line":634},[87,4813,1358],{},[87,4815,4816],{"class":89,"line":1157},[87,4817,4629],{},[87,4819,4820],{"class":89,"line":1163},[87,4821,4634],{},[87,4823,4824],{"class":89,"line":1169},[87,4825,1230],{},[87,4827,4828],{"class":89,"line":1175},[87,4829,1166],{},[87,4831,4832],{"class":89,"line":1181},[87,4833,1172],{"emptyLinePlaceholder":647},[87,4835,4836],{"class":89,"line":1186},[87,4837,4838],{},"Object.prototype.hasOwnProperty.call(obj, 'name') \u002F\u002F true\n",[10,4840,4841,4844,4845,4848],{},[59,4842,4843],{},"call()"," の第1引数に ",[59,4846,4847],{},"this"," として扱うオブジェクトを指定し、それ以降の引数を元のメソッドへ渡しています。",[10,4850,4851,4852,4854,4855,4857,4858,4860,4861,4863,4864,4866],{},"この例では ",[59,4853,4586],{}," が持つ本来の ",[59,4856,4548],{}," を直接取得し、",[59,4859,4582],{}," を ",[59,4862,4847],{}," として呼び出しています。そのため、",[59,4865,4582],{}," 自身に定義された同名メソッドの影響を受けません。",[43,4868,574],{"id":574},[1787,4870,4871,4877,4880,4887,4894],{},[582,4872,4873,4874,4876],{},"オブジェクトリテラルは通常、",[59,4875,4586],{}," のメソッドを継承する",[582,4878,4879],{},"オブジェクト自身が同名メソッドを持つと、継承したメソッドは隠される",[582,4881,4882,4677,4884,4886],{},[59,4883,4676],{},[59,4885,4548],{}," を継承しない",[582,4888,4889,4890,4893],{},"自身のプロパティを確認する場合は、基本的に ",[59,4891,4892],{},"Object.hasOwn(obj, property)"," を使う",[582,4895,4896,4897,4900],{},"古い実行環境も考慮する場合は、",[59,4898,4899],{},"Object.prototype.hasOwnProperty.call(obj, property)"," を使える",[10,4902,4903],{},"オブジェクトの出所や構造を完全には把握できない場合も、インスタンスの同名メソッドに依存しない呼び出し方を選ぶと安全です。",[630,4905,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":4907},[4908,4909,4910,4911,4912,4913],{"id":4510,"depth":634,"text":4511},{"id":4538,"depth":634,"text":4539},{"id":4604,"depth":634,"text":4604},{"id":4710,"depth":634,"text":4711},{"id":4791,"depth":634,"text":4791},{"id":574,"depth":634,"text":574},"JavaScriptでオブジェクト自身のプロパティを安全に確認する方法を、hasOwnPropertyとObject.hasOwnの違いから整理します。",{},"\u002Farticles\u002F2024\u002Fhow-to-use-javascript-built-in-objects","2024-11-24",{"title":4497,"description":4914},"articles\u002F2024\u002Fhow-to-use-javascript-built-in-objects",[1845],"\u002Fimages\u002Farticles\u002Fhow-to-use-javascript-built-in-objects.png","nujvvO9Kj5xXhtbuHUxO1l6JeNtgWjuj3S4rljZKkdU",{"id":4924,"title":4925,"body":4926,"description":5306,"extension":645,"meta":5307,"navigation":647,"path":5308,"publishDate":5309,"published":647,"seo":5310,"stem":5311,"tags":5312,"thumbnail":5313,"updated":5309,"__hash__":5314},"articles\u002Farticles\u002F2024\u002Fdescribe-javascript-deepcopy.md","JavaScriptのディープコピーとは？",{"type":7,"value":4927,"toc":5299},[4928,4930,4933,4936,4940,4943,4946,4955,4958,4965,5016,5030,5045,5048,5072,5075,5084,5088,5095,5141,5146,5161,5164,5188,5203,5210,5219,5223,5226,5235,5238,5263,5269,5271,5294,5297],[10,4929,12],{},[10,4931,4932],{},"今回は、JavaScriptにおけるオブジェクトのディープコピーについて紹介します。",[10,4934,4935],{},"シャローコピーとの違いや実装方法を理解しておくと、コピー先の変更が意図せずコピー元へ影響する問題を避けられます。",[43,4937,4939],{"id":4938},"ディープコピーとは","ディープコピーとは？",[10,4941,4942],{},"ディープコピーとは、コピー元とコピー先が、内部にあるオブジェクトの参照を共有しないコピーのことです。",[10,4944,4945],{},"たとえば、入れ子になったオブジェクトをコピーしたあと、コピー先の内側にある値を変更しても、コピー元の値には影響しません。",[10,4947,4948,4949,4954],{},"詳しい定義は、",[1859,4950,4953],{"href":4951,"rel":4952},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FGlossary\u002FDeep_copy",[1863],"MDNのディープコピー","も参照してください。",[43,4956,4957],{"id":4957},"シャローコピーでは参照が共有される",[10,4959,4960,4961,4964],{},"まずは、",[59,4962,4963],{},"Object.assign()"," を使ったシャローコピーを確認します。",[51,4966,4968],{"className":1140,"code":4967,"language":1142,"meta":57,"style":57},"const original = {\n  user: {\n    name: 'Yuri',\n  },\n  settings: {\n    theme: 'light',\n  },\n}\n\nconst shallowCopy = Object.assign({}, original)\n",[59,4969,4970,4975,4980,4985,4989,4994,4999,5003,5007,5011],{"__ignoreMap":57},[87,4971,4972],{"class":89,"line":90},[87,4973,4974],{},"const original = {\n",[87,4976,4977],{"class":89,"line":634},[87,4978,4979],{},"  user: {\n",[87,4981,4982],{"class":89,"line":1157},[87,4983,4984],{},"    name: 'Yuri',\n",[87,4986,4987],{"class":89,"line":1163},[87,4988,1230],{},[87,4990,4991],{"class":89,"line":1169},[87,4992,4993],{},"  settings: {\n",[87,4995,4996],{"class":89,"line":1175},[87,4997,4998],{},"    theme: 'light',\n",[87,5000,5001],{"class":89,"line":1181},[87,5002,1230],{},[87,5004,5005],{"class":89,"line":1186},[87,5006,1166],{},[87,5008,5009],{"class":89,"line":1192},[87,5010,1172],{"emptyLinePlaceholder":647},[87,5012,5013],{"class":89,"line":1251},[87,5014,5015],{},"const shallowCopy = Object.assign({}, original)\n",[10,5017,5018,5021,5022,5025,5026,5029],{},[59,5019,5020],{},"Object.assign({}, original)"," で新しい外側のオブジェクトは作られますが、",[59,5023,5024],{},"user"," や ",[59,5027,5028],{},"settings"," はコピー元と同じオブジェクトを参照しています。",[51,5031,5033],{"className":1140,"code":5032,"language":1142,"meta":57,"style":57},"console.log(original === shallowCopy) \u002F\u002F false\nconsole.log(original.user === shallowCopy.user) \u002F\u002F true\n",[59,5034,5035,5040],{"__ignoreMap":57},[87,5036,5037],{"class":89,"line":90},[87,5038,5039],{},"console.log(original === shallowCopy) \u002F\u002F false\n",[87,5041,5042],{"class":89,"line":634},[87,5043,5044],{},"console.log(original.user === shallowCopy.user) \u002F\u002F true\n",[10,5046,5047],{},"そのため、コピー先にある入れ子の値を変更すると、コピー元にも影響します。",[51,5049,5051],{"className":1140,"code":5050,"language":1142,"meta":57,"style":57},"shallowCopy.user.name = 'Kohei'\n\nconsole.log(original.user.name) \u002F\u002F 「Kohei」\nconsole.log(shallowCopy.user.name) \u002F\u002F 「Kohei」\n",[59,5052,5053,5058,5062,5067],{"__ignoreMap":57},[87,5054,5055],{"class":89,"line":90},[87,5056,5057],{},"shallowCopy.user.name = 'Kohei'\n",[87,5059,5060],{"class":89,"line":634},[87,5061,1172],{"emptyLinePlaceholder":647},[87,5063,5064],{"class":89,"line":1157},[87,5065,5066],{},"console.log(original.user.name) \u002F\u002F 「Kohei」\n",[87,5068,5069],{"class":89,"line":1163},[87,5070,5071],{},"console.log(shallowCopy.user.name) \u002F\u002F 「Kohei」\n",[10,5073,5074],{},"オブジェクトスプレッド構文も、同様にシャローコピーです。",[51,5076,5078],{"className":1140,"code":5077,"language":1142,"meta":57,"style":57},"const shallowCopy = { ...original }\n",[59,5079,5080],{"__ignoreMap":57},[87,5081,5082],{"class":89,"line":90},[87,5083,5077],{},[43,5085,5087],{"id":5086},"structuredcloneでディープコピーする","structuredCloneでディープコピーする",[10,5089,5090,5091,5094],{},"ディープコピーには、",[59,5092,5093],{},"structuredClone()"," を利用できます。",[51,5096,5098],{"className":1140,"code":5097,"language":1142,"meta":57,"style":57},"const original = {\n  user: {\n    name: 'Yuri',\n  },\n  settings: {\n    theme: 'light',\n  },\n}\n\nconst deepCopy = structuredClone(original)\n",[59,5099,5100,5104,5108,5112,5116,5120,5124,5128,5132,5136],{"__ignoreMap":57},[87,5101,5102],{"class":89,"line":90},[87,5103,4974],{},[87,5105,5106],{"class":89,"line":634},[87,5107,4979],{},[87,5109,5110],{"class":89,"line":1157},[87,5111,4984],{},[87,5113,5114],{"class":89,"line":1163},[87,5115,1230],{},[87,5117,5118],{"class":89,"line":1169},[87,5119,4993],{},[87,5121,5122],{"class":89,"line":1175},[87,5123,4998],{},[87,5125,5126],{"class":89,"line":1181},[87,5127,1230],{},[87,5129,5130],{"class":89,"line":1186},[87,5131,1166],{},[87,5133,5134],{"class":89,"line":1192},[87,5135,1172],{"emptyLinePlaceholder":647},[87,5137,5138],{"class":89,"line":1251},[87,5139,5140],{},"const deepCopy = structuredClone(original)\n",[10,5142,5143,5145],{},[59,5144,5093],{}," で作ったコピーは、入れ子のオブジェクトもコピー元とは異なる参照になります。",[51,5147,5149],{"className":1140,"code":5148,"language":1142,"meta":57,"style":57},"console.log(original === deepCopy) \u002F\u002F false\nconsole.log(original.user === deepCopy.user) \u002F\u002F false\n",[59,5150,5151,5156],{"__ignoreMap":57},[87,5152,5153],{"class":89,"line":90},[87,5154,5155],{},"console.log(original === deepCopy) \u002F\u002F false\n",[87,5157,5158],{"class":89,"line":634},[87,5159,5160],{},"console.log(original.user === deepCopy.user) \u002F\u002F false\n",[10,5162,5163],{},"コピー先を変更しても、コピー元には影響しません。",[51,5165,5167],{"className":1140,"code":5166,"language":1142,"meta":57,"style":57},"deepCopy.user.name = 'Kohei'\n\nconsole.log(original.user.name) \u002F\u002F 「Yuri」\nconsole.log(deepCopy.user.name) \u002F\u002F 「Kohei」\n",[59,5168,5169,5174,5178,5183],{"__ignoreMap":57},[87,5170,5171],{"class":89,"line":90},[87,5172,5173],{},"deepCopy.user.name = 'Kohei'\n",[87,5175,5176],{"class":89,"line":634},[87,5177,1172],{"emptyLinePlaceholder":647},[87,5179,5180],{"class":89,"line":1157},[87,5181,5182],{},"console.log(original.user.name) \u002F\u002F 「Yuri」\n",[87,5184,5185],{"class":89,"line":1163},[87,5186,5187],{},"console.log(deepCopy.user.name) \u002F\u002F 「Kohei」\n",[10,5189,5190,5192,5193,2394,5196,2394,5199,5202],{},[59,5191,5093],{}," は通常のオブジェクトや配列だけでなく、",[59,5194,5195],{},"Date",[59,5197,5198],{},"Map",[59,5200,5201],{},"Set"," など、構造化複製アルゴリズムが対応している型をコピーできます。また、循環参照を持つオブジェクトにも対応しています。",[10,5204,5205,5206,5209],{},"ただし、関数など構造化複製できない値が含まれている場合は ",[59,5207,5208],{},"DataCloneError"," が発生します。すべてのJavaScriptの値を無条件にコピーできるわけではありません。",[10,5211,5212,5213,5218],{},"詳しい対応範囲は、",[1859,5214,5217],{"href":5215,"rel":5216},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002FstructuredClone",[1863],"MDNのstructuredClone()","を確認してください。",[43,5220,5222],{"id":5221},"jsonを使ったディープコピーの注意点","JSONを使ったディープコピーの注意点",[10,5224,5225],{},"単純なデータだけを扱う場合、JSONへ変換して戻す方法もあります。",[51,5227,5229],{"className":1140,"code":5228,"language":1142,"meta":57,"style":57},"const deepCopy = JSON.parse(JSON.stringify(original))\n",[59,5230,5231],{"__ignoreMap":57},[87,5232,5233],{"class":89,"line":90},[87,5234,5228],{},[10,5236,5237],{},"ただし、この方法はJSONとして表現できる値に限られます。",[1787,5239,5240,5245,5254,5260],{},[582,5241,5242,5244],{},[59,5243,5195],{}," は文字列へ変換される",[582,5246,5247,5249,5250,5253],{},[59,5248,1408],{},"、関数、",[59,5251,5252],{},"Symbol"," などは正しく保持できない",[582,5255,5256,5259],{},[59,5257,5258],{},"BigInt"," を含むと例外が発生する",[582,5261,5262],{},"循環参照を持つオブジェクトは変換できない",[10,5264,5265,5266,5268],{},"対象がJSON互換のデータだと分かっている場合には使えますが、一般的なディープコピーとしては ",[59,5267,5093],{}," の方が意図を表しやすく、扱える型も多くなります。",[43,5270,574],{"id":574},[1787,5272,5273,5278,5281,5286,5291],{},[582,5274,5275,5277],{},[59,5276,4963],{}," とオブジェクトスプレッド構文はシャローコピーになる",[582,5279,5280],{},"シャローコピーでは、入れ子のオブジェクトの参照がコピー元と共有される",[582,5282,5283,5285],{},[59,5284,5093],{}," を使うと、対応している値をディープコピーできる",[582,5287,5288,5290],{},[59,5289,5093],{}," でも、関数などコピーできない値がある",[582,5292,5293],{},"JSONによるコピーは、JSON互換データだけに限定して使う",[10,5295,5296],{},"コピー方法を選ぶときは、対象のデータ構造と、コピー後にどの階層まで独立して変更したいかを確認することが大切です。",[630,5298,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":5300},[5301,5302,5303,5304,5305],{"id":4938,"depth":634,"text":4939},{"id":4957,"depth":634,"text":4957},{"id":5086,"depth":634,"text":5087},{"id":5221,"depth":634,"text":5222},{"id":574,"depth":634,"text":574},"JavaScriptのシャローコピーとディープコピーの違いを確認し、structuredCloneを使った実装方法と注意点を整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-javascript-deepcopy","2024-11-23",{"title":4925,"description":5306},"articles\u002F2024\u002Fdescribe-javascript-deepcopy",[1845],"\u002Fimages\u002Farticles\u002Fdescribe-javascript-deepcopy.png","dtSQ5LrS1Kfo1hFYE2MzMKOvrhU_5JGE1X1eQ9eHhIY",{"id":5316,"title":5317,"body":5318,"description":5731,"extension":645,"meta":5732,"navigation":647,"path":5733,"publishDate":5734,"published":647,"seo":5735,"stem":5736,"tags":5737,"thumbnail":5738,"updated":5739,"__hash__":5740},"articles\u002Farticles\u002F2024\u002Fdescribe-behavior-javascript-this.md","JavaScriptのthisの挙動について呼び出し元で整理する",{"type":7,"value":5319,"toc":5723},[5320,5322,5328,5332,5337,5343,5346,5349,5355,5363,5365,5371,5377,5386,5389,5429,5436,5455,5457,5463,5483,5486,5523,5535,5556,5562,5565,5568,5610,5628,5638,5652,5662,5677,5679,5684,5716,5721],[10,5321,12],{},[10,5323,5324,5325,5327],{},"今回は、プロジェクトや個人開発で振り回されることが多かったJavaScriptの ",[59,5326,4847],{}," の挙動について、あらためて振り返ります。自分をはじめ、初学者の方も知っておくと開発が楽になるかと思います。",[43,5329,5331],{"id":5330},"そもそもthisってなんだ","そもそも「this」ってなんだ？",[10,5333,5334,5336],{},[59,5335,4847],{}," は、関数が実行されたときのコンテキストを参照するためのキーワードです。",[10,5338,5339,5340,5342],{},"同じ関数であっても、どのように呼び出されたかによって ",[59,5341,4847],{}," が参照する値は変わります。この特徴が便利なところでもあり、難しいところでもあります。",[10,5344,5345],{},"それでは、呼び出し方によって参照先がどう変わるのか見てみましょう。",[43,5347,5348],{"id":5348},"使用する場所ごとのthis",[10,5350,5351,5352,5354],{},"この記事では、",[59,5353,4847],{}," を使用するケースを次の2つに分けて確認します。",[1787,5356,5357,5360],{},[582,5358,5359],{},"オブジェクトのメソッドとして呼び出す場合",[582,5361,5362],{},"通常の関数として呼び出す場合",[43,5364,5359],{"id":5359},[10,5366,5367,5368,5370],{},"オブジェクトのメソッドとして呼び出した場合、",[59,5369,4847],{}," は基本的に呼び出し元のオブジェクトを参照します。",[10,5372,5373,5374,5376],{},"ここでいう呼び出し元のオブジェクトとは、次の例では ",[59,5375,4582],{}," のことです。",[51,5378,5380],{"className":1140,"code":5379,"language":1142,"meta":57,"style":57},"const obj = {}\n",[59,5381,5382],{"__ignoreMap":57},[87,5383,5384],{"class":89,"line":90},[87,5385,5379],{},[10,5387,5388],{},"実際に挙動を見てみましょう。",[51,5390,5392],{"className":1140,"code":5391,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n  message: function () {\n    console.log('Hello ' + this.name)\n  },\n}\n\nobj.message()\n",[59,5393,5394,5398,5402,5407,5412,5416,5420,5424],{"__ignoreMap":57},[87,5395,5396],{"class":89,"line":90},[87,5397,4559],{},[87,5399,5400],{"class":89,"line":634},[87,5401,1358],{},[87,5403,5404],{"class":89,"line":1157},[87,5405,5406],{},"  message: function () {\n",[87,5408,5409],{"class":89,"line":1163},[87,5410,5411],{},"    console.log('Hello ' + this.name)\n",[87,5413,5414],{"class":89,"line":1169},[87,5415,1230],{},[87,5417,5418],{"class":89,"line":1175},[87,5419,1166],{},[87,5421,5422],{"class":89,"line":1181},[87,5423,1172],{"emptyLinePlaceholder":647},[87,5425,5426],{"class":89,"line":1186},[87,5427,5428],{},"obj.message()\n",[10,5430,5431,5432,5435],{},"この例では、",[59,5433,5434],{},"Hello Yuri"," と出力されます。",[10,5437,5438,5441,5442,5444,5445,5447,5448,5444,5451,5454],{},[59,5439,5440],{},"obj.message()"," という形で呼び出しているため、メソッド内の ",[59,5443,4847],{}," は ",[59,5446,4582],{}," を参照します。したがって、",[59,5449,5450],{},"this.name",[59,5452,5453],{},"obj.name"," として評価されます。",[43,5456,5362],{"id":5362},[10,5458,5459,5460,5462],{},"通常の関数として呼び出した場合、",[59,5461,4847],{}," の値は実行モードによって異なります。",[1787,5464,5465,5475],{},[582,5466,5467,5468,5470,5471,5474],{},"非厳格モードのブラウザでは、",[59,5469,4847],{}," はグローバルオブジェクトの ",[59,5472,5473],{},"window"," を参照する",[582,5476,5477,5478,5444,5480,5482],{},"厳格モードやES Modulesでは、",[59,5479,4847],{},[59,5481,1408],{}," になる",[10,5484,5485],{},"次のコードは、ブラウザの非厳格モードで実行する例です。",[51,5487,5489],{"className":1140,"code":5488,"language":1142,"meta":57,"style":57},"window.name = 'Yuri'\n\nfunction message() {\n  console.log('Hello ' + this.name)\n}\n\nmessage()\n",[59,5490,5491,5496,5500,5505,5510,5514,5518],{"__ignoreMap":57},[87,5492,5493],{"class":89,"line":90},[87,5494,5495],{},"window.name = 'Yuri'\n",[87,5497,5498],{"class":89,"line":634},[87,5499,1172],{"emptyLinePlaceholder":647},[87,5501,5502],{"class":89,"line":1157},[87,5503,5504],{},"function message() {\n",[87,5506,5507],{"class":89,"line":1163},[87,5508,5509],{},"  console.log('Hello ' + this.name)\n",[87,5511,5512],{"class":89,"line":1169},[87,5513,1166],{},[87,5515,5516],{"class":89,"line":1175},[87,5517,1172],{"emptyLinePlaceholder":647},[87,5519,5520],{"class":89,"line":1181},[87,5521,5522],{},"message()\n",[10,5524,5525,5526,5528,5529,5532,5533,5435],{},"非厳格モードでは ",[59,5527,5450],{}," が ",[59,5530,5531],{},"window.name"," として評価されるため、",[59,5534,5434],{},[5536,5537,5538],"blockquote",{},[10,5539,5540,5025,5543,5545,5546,5548,5549,5552,5553,5555],{},[59,5541,5542],{},"let",[59,5544,2111],{}," で宣言した変数は、",[59,5547,5473],{}," オブジェクトのプロパティとして追加されません。一方、ブラウザでトップレベルに ",[59,5550,5551],{},"var"," を使って宣言した変数は、",[59,5554,5473],{}," のプロパティになります。",[10,5557,5558,5559,5561],{},"現在のフロントエンド開発ではES Modulesが広く使われています。ES Modulesは自動的に厳格モードとして扱われるため、通常の関数呼び出しで ",[59,5560,4847],{}," に依存する実装は避けた方が安全です。",[43,5563,5564],{"id":5564},"オブジェクトのメソッドを変数へ代入した場合",[10,5566,5567],{},"ここまでを踏まえて、オブジェクトのメソッドを変数へ代入した場合の挙動を見てみましょう。",[51,5569,5571],{"className":1140,"code":5570,"language":1142,"meta":57,"style":57},"const obj = {\n  name: 'Yuri',\n  message: function () {\n    console.log('Hello ' + this.name)\n  },\n}\n\nconst message = obj.message\nmessage()\n",[59,5572,5573,5577,5581,5585,5589,5593,5597,5601,5606],{"__ignoreMap":57},[87,5574,5575],{"class":89,"line":90},[87,5576,4559],{},[87,5578,5579],{"class":89,"line":634},[87,5580,1358],{},[87,5582,5583],{"class":89,"line":1157},[87,5584,5406],{},[87,5586,5587],{"class":89,"line":1163},[87,5588,5411],{},[87,5590,5591],{"class":89,"line":1169},[87,5592,1230],{},[87,5594,5595],{"class":89,"line":1175},[87,5596,1166],{},[87,5598,5599],{"class":89,"line":1181},[87,5600,1172],{"emptyLinePlaceholder":647},[87,5602,5603],{"class":89,"line":1186},[87,5604,5605],{},"const message = obj.message\n",[87,5607,5608],{"class":89,"line":1192},[87,5609,5522],{},[10,5611,5612,5615,5616,5618,5619,5622,5623,4426,5625,5627],{},[59,5613,5614],{},"const message = obj.message"," では、関数そのものを変数へ代入しています。その後は ",[59,5617,5440],{}," ではなく ",[59,5620,5621],{},"message()"," として呼び出しているため、",[59,5624,4847],{},[59,5626,4582],{}," の結び付きは失われます。",[10,5629,5525,5630,5528,5632,5634,5635,5637],{},[59,5631,4847],{},[59,5633,5473],{}," を参照します。",[59,5636,5531],{}," が設定されていなければ、実行環境に応じて空文字などが返ります。",[10,5639,5640,5641,5528,5643,5645,5646,5648,5649,5651],{},"厳格モードやES Modulesでは ",[59,5642,4847],{},[59,5644,1408],{}," になるため、",[59,5647,5450],{}," を読み取ろうとすると ",[59,5650,1588],{}," が発生します。",[10,5653,5654,5655,5658,5659,5661],{},"このような場合は、",[59,5656,5657],{},"bind()"," を使って ",[59,5660,4847],{}," の参照先を固定できます。",[51,5663,5665],{"className":1140,"code":5664,"language":1142,"meta":57,"style":57},"const message = obj.message.bind(obj)\nmessage() \u002F\u002F 「Hello Yuri」と出力される\n",[59,5666,5667,5672],{"__ignoreMap":57},[87,5668,5669],{"class":89,"line":90},[87,5670,5671],{},"const message = obj.message.bind(obj)\n",[87,5673,5674],{"class":89,"line":634},[87,5675,5676],{},"message() \u002F\u002F 「Hello Yuri」と出力される\n",[43,5678,574],{"id":574},[10,5680,5681,5683],{},[59,5682,4847],{}," の参照先は、関数を定義した場所だけではなく、主に関数の呼び出し方によって決まります。",[1787,5685,5686,5695,5705,5708],{},[582,5687,5688,5690,5691,5444,5693,5474],{},[59,5689,5440],{}," のようなメソッド呼び出しでは、",[59,5692,4847],{},[59,5694,4582],{},[582,5696,5697,5699,5700,5702,5703,5482],{},[59,5698,5621],{}," のような通常の関数呼び出しでは、非厳格モードのブラウザなら ",[59,5701,5473],{},"、厳格モードやES Modulesなら ",[59,5704,1408],{},[582,5706,5707],{},"メソッドを変数へ代入すると、元のオブジェクトとの結び付きは失われる",[582,5709,5710,5711,586,5713,5715],{},"元のオブジェクトを参照させたい場合は、",[59,5712,5657],{},[59,5714,4847],{}," を固定できる",[10,5717,5718,5720],{},[59,5719,4847],{}," で迷ったときは「この関数はどのような形で呼び出されているか」を確認すると、参照先を判断しやすくなります。",[630,5722,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":5724},[5725,5726,5727,5728,5729,5730],{"id":5330,"depth":634,"text":5331},{"id":5348,"depth":634,"text":5348},{"id":5359,"depth":634,"text":5359},{"id":5362,"depth":634,"text":5362},{"id":5564,"depth":634,"text":5564},{"id":574,"depth":634,"text":574},"JavaScriptのthisが何を参照するのか、メソッド呼び出しと関数呼び出しの違いから整理します。",{},"\u002Farticles\u002F2024\u002Fdescribe-behavior-javascript-this","2024-11-20",{"title":5317,"description":5731},"articles\u002F2024\u002Fdescribe-behavior-javascript-this",[1845],"\u002Fimages\u002Farticles\u002Fdescribe-behavior-javascript-this.png","2025-03-21","Kay_1TeIK8YsouKEwYLRPzbQMnabHxZ_GWvHciKSZBs",[5742,6206,6751,8098,8476,8847,9173,9472],{"id":4,"title":5,"body":5743,"description":644,"extension":645,"meta":6203,"navigation":647,"path":648,"publishDate":649,"published":647,"seo":6204,"stem":651,"tags":6205,"thumbnail":655,"updated":649,"__hash__":656},{"type":7,"value":5744,"toc":6193},[5745,5747,5751,5753,5757,5759,5763,5765,5767,5772,5774,5779,5781,5783,5785,5811,5817,5821,5826,5830,5856,5860,5865,5869,5895,5897,5902,5904,5906,5908,5910,5922,5924,5929,5931,5961,5965,5967,5969,5983,5987,5989,5994,5996,5998,6000,6010,6012,6024,6026,6031,6035,6037,6039,6053,6055,6060,6062,6064,6072,6078,6080,6085,6087,6099,6101,6103,6105,6143,6145,6149,6151,6153,6173,6175,6177,6189,6191],[10,5746,12],{},[10,5748,15,5749,20],{},[17,5750,19],{},[10,5752,23],{},[10,5754,26,5755,30],{},[17,5756,29],{},[10,5758,33],{},[35,5760,5761],{"title":37,"type":38},[10,5762,41],{},[43,5764,46],{"id":45},[10,5766,49],{},[51,5768,5770],{"className":5769,"code":55,"language":56,"meta":57},[54],[59,5771,55],{"__ignoreMap":57},[10,5773,63],{},[51,5775,5777],{"className":5776,"code":67,"language":56,"meta":57},[54],[59,5778,67],{"__ignoreMap":57},[10,5780,72],{},[43,5782,75],{"id":75},[10,5784,78],{},[51,5786,5787],{"className":81,"code":82,"language":83,"meta":57,"style":57},[59,5788,5789],{"__ignoreMap":57},[87,5790,5791,5793,5795,5797,5799,5801,5803,5805,5807,5809],{"class":89,"line":90},[87,5792,94],{"class":93},[87,5794,98],{"class":97},[87,5796,101],{"class":97},[87,5798,105],{"class":104},[87,5800,108],{"class":97},[87,5802,112],{"class":111},[87,5804,115],{"class":97},[87,5806,118],{"class":111},[87,5808,121],{"class":93},[87,5810,124],{"class":97},[10,5812,5813,129,5815,133],{},[59,5814,94],{},[59,5816,132],{},[10,5818,136,5819,140],{},[59,5820,139],{},[51,5822,5824],{"className":5823,"code":144,"language":56,"meta":57},[54],[59,5825,144],{"__ignoreMap":57},[10,5827,149,5828,152],{},[59,5829,139],{},[51,5831,5832],{"className":81,"code":155,"language":83,"meta":57,"style":57},[59,5833,5834],{"__ignoreMap":57},[87,5835,5836,5838,5840,5842,5844,5846,5848,5850,5852,5854],{"class":89,"line":90},[87,5837,94],{"class":93},[87,5839,98],{"class":97},[87,5841,101],{"class":97},[87,5843,105],{"class":104},[87,5845,170],{"class":97},[87,5847,112],{"class":111},[87,5849,115],{"class":97},[87,5851,118],{"class":111},[87,5853,121],{"class":93},[87,5855,124],{"class":97},[10,5857,183,5858,187],{},[59,5859,186],{},[51,5861,5863],{"className":5862,"code":191,"language":56,"meta":57},[54],[59,5864,191],{"__ignoreMap":57},[10,5866,196,5867,199],{},[59,5868,186],{},[51,5870,5871],{"className":81,"code":202,"language":83,"meta":57,"style":57},[59,5872,5873],{"__ignoreMap":57},[87,5874,5875,5877,5879,5881,5883,5885,5887,5889,5891,5893],{"class":89,"line":90},[87,5876,94],{"class":93},[87,5878,98],{"class":97},[87,5880,101],{"class":97},[87,5882,105],{"class":104},[87,5884,217],{"class":97},[87,5886,112],{"class":111},[87,5888,115],{"class":97},[87,5890,118],{"class":111},[87,5892,121],{"class":93},[87,5894,124],{"class":97},[10,5896,230],{},[51,5898,5900],{"className":5899,"code":234,"language":56,"meta":57},[54],[59,5901,234],{"__ignoreMap":57},[10,5903,239],{},[10,5905,242],{},[43,5907,246],{"id":245},[10,5909,249],{},[51,5911,5912],{"className":81,"code":252,"language":83,"meta":57,"style":57},[59,5913,5914],{"__ignoreMap":57},[87,5915,5916,5918,5920],{"class":89,"line":90},[87,5917,259],{"class":93},[87,5919,262],{"class":97},[87,5921,265],{"class":97},[10,5923,268],{},[51,5925,5927],{"className":5926,"code":272,"language":56,"meta":57},[54],[59,5928,272],{"__ignoreMap":57},[10,5930,277],{},[279,5932,5933,5941],{},[282,5934,5935],{},[285,5936,5937,5939],{},[288,5938,290],{},[288,5940,294],{"align":293},[296,5942,5943,5949,5955],{},[285,5944,5945,5947],{},[301,5946,303],{},[301,5948,306],{"align":293},[285,5950,5951,5953],{},[301,5952,311],{},[301,5954,314],{"align":293},[285,5956,5957,5959],{},[301,5958,319],{},[301,5960,322],{"align":293},[10,5962,5963,328],{},[59,5964,327],{},[43,5966,332],{"id":331},[10,5968,335],{},[51,5970,5971],{"className":81,"code":338,"language":83,"meta":57,"style":57},[59,5972,5973],{"__ignoreMap":57},[87,5974,5975,5977,5979,5981],{"class":89,"line":90},[87,5976,259],{"class":93},[87,5978,347],{"class":97},[87,5980,350],{"class":97},[87,5982,353],{"class":97},[10,5984,5985,359],{},[59,5986,358],{},[10,5988,362],{},[51,5990,5992],{"className":5991,"code":366,"language":56,"meta":57},[54],[59,5993,366],{"__ignoreMap":57},[10,5995,371],{},[43,5997,375],{"id":374},[10,5999,378],{},[51,6001,6002],{"className":81,"code":381,"language":83,"meta":57,"style":57},[59,6003,6004],{"__ignoreMap":57},[87,6005,6006,6008],{"class":89,"line":90},[87,6007,259],{"class":93},[87,6009,390],{"class":97},[10,6011,393],{},[51,6013,6014],{"className":81,"code":396,"language":83,"meta":57,"style":57},[59,6015,6016],{"__ignoreMap":57},[87,6017,6018,6020,6022],{"class":89,"line":90},[87,6019,259],{"class":93},[87,6021,405],{"class":97},[87,6023,408],{"class":97},[10,6025,411],{},[51,6027,6029],{"className":6028,"code":415,"language":56,"meta":57},[54],[59,6030,415],{"__ignoreMap":57},[10,6032,420,6033,424],{},[59,6034,423],{},[43,6036,428],{"id":427},[10,6038,431],{},[51,6040,6041],{"className":81,"code":434,"language":83,"meta":57,"style":57},[59,6042,6043],{"__ignoreMap":57},[87,6044,6045,6047,6049,6051],{"class":89,"line":90},[87,6046,259],{"class":93},[87,6048,262],{"class":97},[87,6050,445],{"class":97},[87,6052,448],{"class":97},[10,6054,451],{},[51,6056,6058],{"className":6057,"code":455,"language":56,"meta":57},[54],[59,6059,455],{"__ignoreMap":57},[10,6061,460],{},[10,6063,463],{},[51,6065,6066],{"className":466,"code":467,"language":468,"meta":57,"style":57},[59,6067,6068],{"__ignoreMap":57},[87,6069,6070],{"class":89,"line":90},[87,6071,467],{},[35,6073,6074],{"title":477,"type":38},[10,6075,6076,483],{},[59,6077,482],{},[10,6079,486],{},[51,6081,6083],{"className":6082,"code":490,"language":56,"meta":57},[54],[59,6084,490],{"__ignoreMap":57},[10,6086,495],{},[51,6088,6089],{"className":81,"code":498,"language":83,"meta":57,"style":57},[59,6090,6091],{"__ignoreMap":57},[87,6092,6093,6095,6097],{"class":89,"line":90},[87,6094,259],{"class":93},[87,6096,507],{"class":97},[87,6098,408],{"class":97},[10,6100,512],{},[43,6102,515],{"id":515},[10,6104,518],{},[279,6106,6107,6117],{},[282,6108,6109],{},[285,6110,6111,6113,6115],{},[288,6112,290],{},[288,6114,529],{"align":293},[288,6116,532],{"align":293},[296,6118,6119,6127,6135],{},[285,6120,6121,6123,6125],{},[301,6122,303],{},[301,6124,306],{"align":293},[301,6126,543],{"align":293},[285,6128,6129,6131,6133],{},[301,6130,311],{},[301,6132,314],{"align":293},[301,6134,552],{"align":293},[285,6136,6137,6139,6141],{},[301,6138,319],{},[301,6140,322],{"align":293},[301,6142,561],{"align":293},[10,6144,564],{},[10,6146,567,6147,571],{},[59,6148,570],{},[43,6150,574],{"id":574},[10,6152,577],{},[579,6154,6155,6161,6165,6169,6171],{},[582,6156,6157,586,6159,589],{},[59,6158,94],{},[59,6160,139],{},[582,6162,6163,595],{},[59,6164,594],{},[582,6166,598,6167,601],{},[59,6168,327],{},[582,6170,604],{},[582,6172,607],{},[10,6174,610],{},[10,6176,613],{},[51,6178,6179],{"className":81,"code":252,"language":83,"meta":57,"style":57},[59,6180,6181],{"__ignoreMap":57},[87,6182,6183,6185,6187],{"class":89,"line":90},[87,6184,259],{"class":93},[87,6186,262],{"class":97},[87,6188,265],{"class":97},[10,6190,628],{},[630,6192,632],{},{"title":57,"searchDepth":634,"depth":634,"links":6194},[6195,6196,6197,6198,6199,6200,6201,6202],{"id":45,"depth":634,"text":46},{"id":75,"depth":634,"text":75},{"id":245,"depth":634,"text":246},{"id":331,"depth":634,"text":332},{"id":374,"depth":634,"text":375},{"id":427,"depth":634,"text":428},{"id":515,"depth":634,"text":515},{"id":574,"depth":634,"text":574},{},{"title":5,"description":644},[653,654],{"id":1123,"title":1124,"body":6207,"description":1838,"extension":645,"meta":6748,"navigation":647,"path":1840,"publishDate":1841,"published":647,"seo":6749,"stem":1843,"tags":6750,"thumbnail":1846,"updated":1841,"__hash__":1847},{"type":7,"value":6208,"toc":6733},[6209,6211,6213,6215,6217,6257,6259,6261,6321,6331,6343,6353,6365,6367,6369,6401,6407,6411,6419,6443,6453,6455,6467,6469,6473,6521,6523,6527,6555,6561,6563,6569,6585,6587,6593,6625,6627,6647,6651,6655,6663,6687,6701,6703,6707,6709,6721,6723,6725,6731],[10,6210,12],{},[10,6212,1131],{},[43,6214,1134],{"id":1134},[10,6216,1137],{},[51,6218,6219],{"className":1140,"code":1141,"language":1142,"meta":57,"style":57},[59,6220,6221,6225,6229,6233,6237,6241,6245,6249,6253],{"__ignoreMap":57},[87,6222,6223],{"class":89,"line":90},[87,6224,1149],{},[87,6226,6227],{"class":89,"line":634},[87,6228,1154],{},[87,6230,6231],{"class":89,"line":1157},[87,6232,1160],{},[87,6234,6235],{"class":89,"line":1163},[87,6236,1166],{},[87,6238,6239],{"class":89,"line":1169},[87,6240,1172],{"emptyLinePlaceholder":647},[87,6242,6243],{"class":89,"line":1175},[87,6244,1178],{},[87,6246,6247],{"class":89,"line":1181},[87,6248,1172],{"emptyLinePlaceholder":647},[87,6250,6251],{"class":89,"line":1186},[87,6252,1189],{},[87,6254,6255],{"class":89,"line":1192},[87,6256,1195],{},[1197,6258,1199],{"id":1199},[10,6260,1202],{},[51,6262,6263],{"className":1140,"code":1205,"language":1142,"meta":57,"style":57},[59,6264,6265,6269,6273,6277,6281,6285,6289,6293,6297,6301,6305,6309,6313,6317],{"__ignoreMap":57},[87,6266,6267],{"class":89,"line":90},[87,6268,1149],{},[87,6270,6271],{"class":89,"line":634},[87,6272,1154],{},[87,6274,6275],{"class":89,"line":1157},[87,6276,1220],{},[87,6278,6279],{"class":89,"line":1163},[87,6280,1225],{},[87,6282,6283],{"class":89,"line":1169},[87,6284,1230],{},[87,6286,6287],{"class":89,"line":1175},[87,6288,1166],{},[87,6290,6291],{"class":89,"line":1181},[87,6292,1172],{"emptyLinePlaceholder":647},[87,6294,6295],{"class":89,"line":1186},[87,6296,1243],{},[87,6298,6299],{"class":89,"line":1192},[87,6300,1248],{},[87,6302,6303],{"class":89,"line":1251},[87,6304,1254],{},[87,6306,6307],{"class":89,"line":1257},[87,6308,1260],{},[87,6310,6311],{"class":89,"line":1263},[87,6312,1172],{"emptyLinePlaceholder":647},[87,6314,6315],{"class":89,"line":1268},[87,6316,1189],{},[87,6318,6319],{"class":89,"line":1273},[87,6320,1195],{},[10,6322,1278,6323,1282,6325,1286,6327,1290,6329,1293],{},[59,6324,1281],{},[59,6326,1285],{},[59,6328,1289],{},[59,6330,1285],{},[51,6332,6333],{"className":1140,"code":1296,"language":1142,"meta":57,"style":57},[59,6334,6335,6339],{"__ignoreMap":57},[87,6336,6337],{"class":89,"line":90},[87,6338,1303],{},[87,6340,6341],{"class":89,"line":634},[87,6342,1308],{},[35,6344,6345],{"title":1311,"type":1312},[10,6346,6347,1317,6349,1320,6351,1323],{},[59,6348,1289],{},[59,6350,1285],{},[59,6352,1289],{},[51,6354,6355],{"className":1140,"code":1326,"language":1142,"meta":57,"style":57},[59,6356,6357,6361],{"__ignoreMap":57},[87,6358,6359],{"class":89,"line":90},[87,6360,1333],{},[87,6362,6363],{"class":89,"line":634},[87,6364,1338],{},[1197,6366,1341],{"id":1341},[10,6368,1344],{},[51,6370,6371],{"className":1140,"code":1347,"language":1142,"meta":57,"style":57},[59,6372,6373,6377,6381,6385,6389,6393,6397],{"__ignoreMap":57},[87,6374,6375],{"class":89,"line":90},[87,6376,1149],{},[87,6378,6379],{"class":89,"line":634},[87,6380,1358],{},[87,6382,6383],{"class":89,"line":1157},[87,6384,1166],{},[87,6386,6387],{"class":89,"line":1163},[87,6388,1172],{"emptyLinePlaceholder":647},[87,6390,6391],{"class":89,"line":1169},[87,6392,1371],{},[87,6394,6395],{"class":89,"line":1175},[87,6396,1172],{"emptyLinePlaceholder":647},[87,6398,6399],{"class":89,"line":1181},[87,6400,1380],{},[10,6402,1383,6403,1387,6405,1286],{},[59,6404,1386],{},[59,6406,1390],{},[43,6408,1394,6409,1398],{"id":1393},[59,6410,1397],{},[10,6412,1401,6413,1405,6415,1409,6417,1412],{},[59,6414,1404],{},[59,6416,1408],{},[59,6418,1408],{},[51,6420,6421],{"className":1140,"code":1415,"language":1142,"meta":57,"style":57},[59,6422,6423,6427,6431,6435,6439],{"__ignoreMap":57},[87,6424,6425],{"class":89,"line":90},[87,6426,1149],{},[87,6428,6429],{"class":89,"line":634},[87,6430,1358],{},[87,6432,6433],{"class":89,"line":1157},[87,6434,1166],{},[87,6436,6437],{"class":89,"line":1163},[87,6438,1172],{"emptyLinePlaceholder":647},[87,6440,6441],{"class":89,"line":1169},[87,6442,1438],{},[10,6444,6445,1444,6447,1447,6449,1450,6451,1454],{},[59,6446,1443],{},[59,6448,1408],{},[59,6450,1397],{},[59,6452,1453],{},[10,6454,1457],{},[51,6456,6457],{"className":1140,"code":1460,"language":1142,"meta":57,"style":57},[59,6458,6459,6463],{"__ignoreMap":57},[87,6460,6461],{"class":89,"line":90},[87,6462,1467],{},[87,6464,6465],{"class":89,"line":634},[87,6466,1472],{},[1197,6468,1475],{"id":1475},[10,6470,1478,6471,1482],{},[59,6472,1481],{},[51,6474,6475],{"className":1140,"code":1485,"language":1142,"meta":57,"style":57},[59,6476,6477,6481,6485,6489,6493,6497,6501,6505,6509,6513,6517],{"__ignoreMap":57},[87,6478,6479],{"class":89,"line":90},[87,6480,1492],{},[87,6482,6483],{"class":89,"line":634},[87,6484,1497],{},[87,6486,6487],{"class":89,"line":1157},[87,6488,1502],{},[87,6490,6491],{"class":89,"line":1163},[87,6492,1507],{},[87,6494,6495],{"class":89,"line":1169},[87,6496,1172],{"emptyLinePlaceholder":647},[87,6498,6499],{"class":89,"line":1175},[87,6500,1516],{},[87,6502,6503],{"class":89,"line":1181},[87,6504,1521],{},[87,6506,6507],{"class":89,"line":1186},[87,6508,1172],{"emptyLinePlaceholder":647},[87,6510,6511],{"class":89,"line":1192},[87,6512,1530],{},[87,6514,6515],{"class":89,"line":1251},[87,6516,1172],{"emptyLinePlaceholder":647},[87,6518,6519],{"class":89,"line":1257},[87,6520,1539],{},[1197,6522,1542],{"id":1542},[10,6524,1545,6525,1549],{},[59,6526,1548],{},[51,6528,6529],{"className":1140,"code":1552,"language":1142,"meta":57,"style":57},[59,6530,6531,6535,6539,6543,6547,6551],{"__ignoreMap":57},[87,6532,6533],{"class":89,"line":90},[87,6534,1559],{},[87,6536,6537],{"class":89,"line":634},[87,6538,1564],{},[87,6540,6541],{"class":89,"line":1157},[87,6542,1166],{},[87,6544,6545],{"class":89,"line":1163},[87,6546,1172],{"emptyLinePlaceholder":647},[87,6548,6549],{"class":89,"line":1169},[87,6550,1577],{},[87,6552,6553],{"class":89,"line":1175},[87,6554,1582],{},[10,6556,1585,6557,1589,6559,1592],{},[59,6558,1588],{},[59,6560,1548],{},[1197,6562,1596],{"id":1595},[10,6564,6565,1602,6567,1605],{},[59,6566,1601],{},[59,6568,1404],{},[51,6570,6571],{"className":1140,"code":1608,"language":1142,"meta":57,"style":57},[59,6572,6573,6577,6581],{"__ignoreMap":57},[87,6574,6575],{"class":89,"line":90},[87,6576,1615],{},[87,6578,6579],{"class":89,"line":634},[87,6580,1172],{"emptyLinePlaceholder":647},[87,6582,6583],{"class":89,"line":1157},[87,6584,1624],{},[1197,6586,1627],{"id":1627},[10,6588,1630,6589,1405,6591,1635],{},[59,6590,1404],{},[59,6592,1408],{},[51,6594,6595],{"className":1140,"code":1638,"language":1142,"meta":57,"style":57},[59,6596,6597,6601,6605,6609,6613,6617,6621],{"__ignoreMap":57},[87,6598,6599],{"class":89,"line":90},[87,6600,1645],{},[87,6602,6603],{"class":89,"line":634},[87,6604,1650],{},[87,6606,6607],{"class":89,"line":1157},[87,6608,1172],{"emptyLinePlaceholder":647},[87,6610,6611],{"class":89,"line":1163},[87,6612,1659],{},[87,6614,6615],{"class":89,"line":1169},[87,6616,1172],{"emptyLinePlaceholder":647},[87,6618,6619],{"class":89,"line":1175},[87,6620,1668],{},[87,6622,6623],{"class":89,"line":1181},[87,6624,1673],{},[10,6626,1676],{},[51,6628,6629],{"className":1140,"code":1679,"language":1142,"meta":57,"style":57},[59,6630,6631,6635,6639,6643],{"__ignoreMap":57},[87,6632,6633],{"class":89,"line":90},[87,6634,1686],{},[87,6636,6637],{"class":89,"line":634},[87,6638,1172],{"emptyLinePlaceholder":647},[87,6640,6641],{"class":89,"line":1157},[87,6642,1695],{},[87,6644,6645],{"class":89,"line":1163},[87,6646,1700],{},[10,6648,1703,6649,1707],{},[59,6650,1706],{},[43,6652,6653,1710],{"id":1710},[59,6654,1713],{},[10,6656,1716,6657,1405,6659,1721,6661,1724],{},[59,6658,1404],{},[59,6660,1408],{},[59,6662,1713],{},[51,6664,6665],{"className":1140,"code":1727,"language":1142,"meta":57,"style":57},[59,6666,6667,6671,6675,6679,6683],{"__ignoreMap":57},[87,6668,6669],{"class":89,"line":90},[87,6670,1734],{},[87,6672,6673],{"class":89,"line":634},[87,6674,1172],{"emptyLinePlaceholder":647},[87,6676,6677],{"class":89,"line":1157},[87,6678,1743],{},[87,6680,6681],{"class":89,"line":1163},[87,6682,1172],{"emptyLinePlaceholder":647},[87,6684,6685],{"class":89,"line":1169},[87,6686,1752],{},[10,6688,6689,1444,6691,1761,6693,1765,6695,1768,6697,1405,6699,1773],{},[59,6690,1757],{},[59,6692,1760],{},[59,6694,1764],{},[59,6696,1713],{},[59,6698,1404],{},[59,6700,1408],{},[43,6702,1776],{"id":1776},[10,6704,1779,6705,1782],{},[59,6706,1408],{},[10,6708,1785],{},[1787,6710,6711,6715,6717],{},[582,6712,1791,6713,1794],{},[59,6714,1397],{},[582,6716,1797],{},[582,6718,1800,6719,1803],{},[59,6720,1713],{},[43,6722,574],{"id":574},[10,6724,1808],{},[10,6726,1811,6727,1814,6729,1817],{},[59,6728,1404],{},[59,6730,1408],{},[630,6732,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":6734},[6735,6739,6745,6746,6747],{"id":1134,"depth":634,"text":1134,"children":6736},[6737,6738],{"id":1199,"depth":1157,"text":1199},{"id":1341,"depth":1157,"text":1341},{"id":1393,"depth":634,"text":1828,"children":6740},[6741,6742,6743,6744],{"id":1475,"depth":1157,"text":1475},{"id":1542,"depth":1157,"text":1542},{"id":1595,"depth":1157,"text":1596},{"id":1627,"depth":1157,"text":1627},{"id":1710,"depth":634,"text":1835},{"id":1776,"depth":634,"text":1776},{"id":574,"depth":634,"text":574},{},{"title":1124,"description":1838},[1845],{"id":1849,"title":1850,"body":6752,"description":3509,"extension":645,"meta":8095,"navigation":647,"path":3511,"publishDate":3512,"published":647,"seo":8096,"stem":3514,"tags":8097,"thumbnail":3516,"updated":3512,"__hash__":3517},{"type":7,"value":6753,"toc":8067},[6754,6756,6761,6771,6773,6777,6783,6807,6809,6813,6815,6817,6819,6855,6857,6859,6861,6867,6869,6871,6875,6881,7045,7053,7055,7057,7135,7137,7139,7207,7209,7211,7233,7235,7237,7243,7365,7367,7369,7371,7373,7375,7381,7389,7455,7459,7463,7467,7503,7507,7509,7511,7567,7571,7573,7577,7675,7681,7685,7689,7743,7745,7747,7749,7837,7839,7843,7859,7865,7867,7869,7941,7945,7947,7949,8057,8059,8061,8063,8065],[10,6755,12],{},[10,6757,1857,6758,1865],{},[1859,6759,1864],{"href":1861,"rel":6760},[1863],[1787,6762,6763,6765,6767,6769],{},[582,6764,1870],{},[582,6766,1845],{},[582,6768,1875],{},[582,6770,1878],{},[43,6772,1870],{"id":1881},[1197,6774,6775,1888],{"id":1884},[59,6776,1887],{},[10,6778,6779,1893,6781,1897],{},[59,6780,1887],{},[59,6782,1896],{},[51,6784,6785],{"className":1900,"code":1901,"language":1881,"meta":57,"style":57},[59,6786,6787],{"__ignoreMap":57},[87,6788,6789,6791,6793,6795,6797,6799,6801,6803,6805],{"class":89,"line":90},[87,6790,1908],{"class":111},[87,6792,1912],{"class":1911},[87,6794,1916],{"class":1915},[87,6796,1919],{"class":111},[87,6798,1922],{"class":111},[87,6800,56],{"class":97},[87,6802,1922],{"class":111},[87,6804,1929],{"class":1915},[87,6806,1932],{"class":111},[10,6808,1935],{},[35,6810,6811],{"title":1938,"type":38},[10,6812,1941],{},[43,6814,1845],{"id":1142},[1197,6816,1946],{"id":1946},[10,6818,1949],{},[51,6820,6821],{"className":1140,"code":1952,"language":1142,"meta":57,"style":57},[59,6822,6823,6827,6831,6835,6839,6843,6847,6851],{"__ignoreMap":57},[87,6824,6825],{"class":89,"line":90},[87,6826,1959],{},[87,6828,6829],{"class":89,"line":634},[87,6830,1172],{"emptyLinePlaceholder":647},[87,6832,6833],{"class":89,"line":1157},[87,6834,1968],{},[87,6836,6837],{"class":89,"line":1163},[87,6838,1973],{},[87,6840,6841],{"class":89,"line":1169},[87,6842,1166],{},[87,6844,6845],{"class":89,"line":1175},[87,6846,1172],{"emptyLinePlaceholder":647},[87,6848,6849],{"class":89,"line":1181},[87,6850,1986],{},[87,6852,6853],{"class":89,"line":1186},[87,6854,1991],{},[10,6856,1994],{},[1197,6858,1998],{"id":1997},[10,6860,2001],{},[10,6862,2004,6863,1282,6865,2011],{},[59,6864,2007],{},[59,6866,2010],{},[10,6868,2014],{},[43,6870,1875],{"id":2017},[1197,6872,6873],{"id":2020},[59,6874,2023],{},[10,6876,6877,2028,6879,2032],{},[59,6878,2023],{},[59,6880,2031],{},[51,6882,6883],{"className":2035,"code":2036,"language":2037,"meta":57,"style":57},[59,6884,6885,6903,6921,6935,6939,6963,6967,6979,6997,7001,7005,7017,7025,7033,7041],{"__ignoreMap":57},[87,6886,6887,6889,6891,6893,6895,6897,6899,6901],{"class":89,"line":90},[87,6888,2007],{"class":2044},[87,6890,2047],{"class":111},[87,6892,2051],{"class":2050},[87,6894,2054],{"class":111},[87,6896,2057],{"class":2044},[87,6898,2060],{"class":111},[87,6900,2017],{"class":97},[87,6902,2065],{"class":111},[87,6904,6905,6907,6909,6911,6913,6915,6917,6919],{"class":89,"line":634},[87,6906,2007],{"class":2044},[87,6908,2047],{"class":111},[87,6910,2074],{"class":2050},[87,6912,2054],{"class":111},[87,6914,2057],{"class":2044},[87,6916,2060],{"class":111},[87,6918,2083],{"class":97},[87,6920,2065],{"class":111},[87,6922,6923,6925,6927,6929,6931,6933],{"class":89,"line":1157},[87,6924,2007],{"class":2044},[87,6926,2092],{"class":2050},[87,6928,2095],{"class":2044},[87,6930,2060],{"class":111},[87,6932,2100],{"class":97},[87,6934,2065],{"class":111},[87,6936,6937],{"class":89,"line":1163},[87,6938,1172],{"emptyLinePlaceholder":647},[87,6940,6941,6943,6945,6947,6949,6951,6953,6955,6957,6959,6961],{"class":89,"line":1169},[87,6942,2111],{"class":1915},[87,6944,2114],{"class":2050},[87,6946,1919],{"class":111},[87,6948,2119],{"class":2050},[87,6950,2122],{"class":111},[87,6952,2126],{"class":2125},[87,6954,2129],{"class":2050},[87,6956,2132],{"class":111},[87,6958,2135],{"class":97},[87,6960,2132],{"class":111},[87,6962,2140],{"class":2050},[87,6964,6965],{"class":89,"line":1175},[87,6966,1172],{"emptyLinePlaceholder":647},[87,6968,6969,6971,6973,6975,6977],{"class":89,"line":1181},[87,6970,2149],{"class":2044},[87,6972,2152],{"class":2050},[87,6974,2155],{"class":111},[87,6976,2158],{"class":2050},[87,6978,2161],{"class":111},[87,6980,6981,6983,6985,6987,6989,6991,6993,6995],{"class":89,"line":1186},[87,6982,2166],{"class":2044},[87,6984,2169],{"class":111},[87,6986,2172],{"class":2125},[87,6988,2129],{"class":1911},[87,6990,2132],{"class":111},[87,6992,2179],{"class":97},[87,6994,2132],{"class":111},[87,6996,2140],{"class":1911},[87,6998,6999],{"class":89,"line":1192},[87,7000,1166],{"class":111},[87,7002,7003],{"class":89,"line":1251},[87,7004,1172],{"emptyLinePlaceholder":647},[87,7006,7007,7009,7011,7013,7015],{"class":89,"line":1257},[87,7008,2023],{"class":2125},[87,7010,2198],{"class":2050},[87,7012,2122],{"class":111},[87,7014,2031],{"class":2125},[87,7016,2205],{"class":2050},[87,7018,7019,7021,7023],{"class":89,"line":1263},[87,7020,2210],{"class":111},[87,7022,2213],{"class":93},[87,7024,1932],{"class":111},[87,7026,7027,7029,7031],{"class":89,"line":1268},[87,7028,2220],{"class":111},[87,7030,2223],{"class":93},[87,7032,2226],{"class":111},[87,7034,7035,7037,7039],{"class":89,"line":1273},[87,7036,2231],{"class":111},[87,7038,2213],{"class":93},[87,7040,2236],{"class":111},[87,7042,7043],{"class":89,"line":2239},[87,7044,2140],{"class":2050},[10,7046,7047,2246,7049,2249,7051,1549],{},[59,7048,2023],{},[59,7050,2023],{},[59,7052,2252],{},[1197,7054,2255],{"id":2255},[10,7056,2258],{},[51,7058,7059],{"className":2035,"code":2261,"language":2037,"meta":57,"style":57},[59,7060,7061,7071,7085,7097,7117,7125,7131],{"__ignoreMap":57},[87,7062,7063,7065,7067,7069],{"class":89,"line":90},[87,7064,2268],{"class":2125},[87,7066,2129],{"class":2050},[87,7068,2274],{"class":2273},[87,7070,2277],{"class":1915},[87,7072,7073,7075,7077,7079,7081,7083],{"class":89,"line":634},[87,7074,2282],{"class":2050},[87,7076,2122],{"class":111},[87,7078,2287],{"class":2125},[87,7080,2129],{"class":2050},[87,7082,2292],{"class":2273},[87,7084,2277],{"class":1915},[87,7086,7087,7089,7091,7093,7095],{"class":89,"line":1157},[87,7088,2299],{"class":2050},[87,7090,2122],{"class":111},[87,7092,2304],{"class":2050},[87,7094,2307],{"class":111},[87,7096,2310],{"class":2050},[87,7098,7099,7101,7103,7105,7107,7109,7111,7113,7115],{"class":89,"line":1163},[87,7100,2315],{"class":111},[87,7102,2047],{"class":111},[87,7104,2320],{"class":111},[87,7106,2292],{"class":2050},[87,7108,2325],{"class":111},[87,7110,2328],{"class":1911},[87,7112,2331],{"class":111},[87,7114,2335],{"class":2334},[87,7116,2338],{"class":111},[87,7118,7119,7121,7123],{"class":89,"line":1169},[87,7120,2343],{"class":111},[87,7122,2346],{"class":2050},[87,7124,2349],{"class":111},[87,7126,7127,7129],{"class":89,"line":1175},[87,7128,2354],{"class":2050},[87,7130,2349],{"class":111},[87,7132,7133],{"class":89,"line":1181},[87,7134,2140],{"class":2050},[10,7136,2363],{},[10,7138,2366],{},[279,7140,7141,7151],{},[282,7142,7143],{},[285,7144,7145,7147,7149],{},[288,7146,2375],{},[288,7148,2378],{},[288,7150,2381],{},[296,7152,7153,7167,7183,7195],{},[285,7154,7155,7157,7163],{},[301,7156,2388],{},[301,7158,7159,2394,7161],{},[59,7160,2393],{},[59,7162,2397],{},[301,7164,2400,7165],{},[59,7166,2403],{},[285,7168,7169,7171,7177],{},[301,7170,2408],{},[301,7172,7173,2394,7175],{},[59,7174,2413],{},[59,7176,2416],{},[301,7178,7179,2394,7181],{},[59,7180,2421],{},[59,7182,2424],{},[285,7184,7185,7187,7191],{},[301,7186,2429],{},[301,7188,2432,7189],{},[59,7190,2416],{},[301,7192,7193],{},[59,7194,2287],{},[285,7196,7197,7199,7203],{},[301,7198,2443],{},[301,7200,2446,7201],{},[59,7202,2449],{},[301,7204,2452,7205],{},[59,7206,2449],{},[1197,7208,2457],{"id":2457},[10,7210,2460],{},[51,7212,7213],{"className":2035,"code":2463,"language":2037,"meta":57,"style":57},[59,7214,7215],{"__ignoreMap":57},[87,7216,7217,7219,7221,7223,7225,7227,7229,7231],{"class":89,"line":90},[87,7218,2470],{"class":2125},[87,7220,2129],{"class":2050},[87,7222,2475],{"class":2273},[87,7224,2478],{"class":1915},[87,7226,2481],{"class":2050},[87,7228,2484],{"class":111},[87,7230,105],{"class":104},[87,7232,2140],{"class":2050},[10,7234,2491],{},[1197,7236,2494],{"id":2494},[10,7238,2497,7239,2501,7241,2505],{},[59,7240,2500],{},[59,7242,2504],{},[51,7244,7245],{"className":2035,"code":2508,"language":2037,"meta":57,"style":57},[59,7246,7247,7257,7277,7281,7285,7303,7317,7327,7331,7335,7361],{"__ignoreMap":57},[87,7248,7249,7251,7253,7255],{"class":89,"line":90},[87,7250,2515],{"class":1915},[87,7252,2518],{"class":93},[87,7254,2521],{"class":111},[87,7256,2524],{"class":111},[87,7258,7259,7261,7263,7265,7267,7269,7271,7273,7275],{"class":89,"line":634},[87,7260,2529],{"class":1911},[87,7262,2331],{"class":111},[87,7264,2152],{"class":111},[87,7266,2536],{"class":2273},[87,7268,2331],{"class":111},[87,7270,2541],{"class":93},[87,7272,2544],{"class":111},[87,7274,2478],{"class":1915},[87,7276,2549],{"class":93},[87,7278,7279],{"class":89,"line":1157},[87,7280,1166],{"class":111},[87,7282,7283],{"class":89,"line":1163},[87,7284,1172],{"emptyLinePlaceholder":647},[87,7286,7287,7289,7291,7293,7295,7297,7299,7301],{"class":89,"line":1169},[87,7288,2562],{"class":1915},[87,7290,2565],{"class":2125},[87,7292,2568],{"class":111},[87,7294,2571],{"class":2273},[87,7296,2574],{"class":111},[87,7298,2518],{"class":93},[87,7300,2544],{"class":111},[87,7302,2524],{"class":111},[87,7304,7305,7307,7309,7311,7313,7315],{"class":89,"line":1175},[87,7306,2585],{"class":1915},[87,7308,2588],{"class":2050},[87,7310,2521],{"class":111},[87,7312,2593],{"class":111},[87,7314,2478],{"class":1915},[87,7316,2524],{"class":111},[87,7318,7319,7321,7323,7325],{"class":89,"line":1181},[87,7320,2602],{"class":2125},[87,7322,2129],{"class":1911},[87,7324,2607],{"class":104},[87,7326,2140],{"class":1911},[87,7328,7329],{"class":89,"line":1186},[87,7330,2614],{"class":111},[87,7332,7333],{"class":89,"line":1192},[87,7334,1172],{"emptyLinePlaceholder":647},[87,7336,7337,7339,7341,7343,7345,7347,7349,7351,7353,7355,7357,7359],{"class":89,"line":1251},[87,7338,2623],{"class":2044},[87,7340,2626],{"class":111},[87,7342,1912],{"class":1911},[87,7344,1916],{"class":1915},[87,7346,1919],{"class":111},[87,7348,1922],{"class":111},[87,7350,2637],{"class":97},[87,7352,1922],{"class":111},[87,7354,2571],{"class":1915},[87,7356,2644],{"class":111},[87,7358,2647],{"class":2050},[87,7360,2650],{"class":111},[87,7362,7363],{"class":89,"line":1257},[87,7364,1166],{"class":111},[10,7366,2657],{},[1197,7368,2660],{"id":2660},[10,7370,2663],{},[10,7372,2666],{},[43,7374,1878],{"id":2669},[1197,7376,7377,1282,7379],{"id":2672},[59,7378,2675],{},[59,7380,1404],{},[10,7382,7383,2682,7385,2686,7387,2689],{},[59,7384,2675],{},[59,7386,2685],{},[59,7388,1404],{},[51,7390,7391],{"className":2692,"code":2693,"language":2669,"meta":57,"style":57},[59,7392,7393,7417,7421,7433,7451],{"__ignoreMap":57},[87,7394,7395,7397,7399,7401,7403,7405,7407,7409,7411,7413,7415],{"class":89,"line":90},[87,7396,2111],{"class":1915},[87,7398,2114],{"class":2050},[87,7400,1919],{"class":111},[87,7402,2119],{"class":2050},[87,7404,2122],{"class":111},[87,7406,2126],{"class":2125},[87,7408,2129],{"class":2050},[87,7410,2132],{"class":111},[87,7412,2135],{"class":97},[87,7414,2132],{"class":111},[87,7416,2140],{"class":2050},[87,7418,7419],{"class":89,"line":634},[87,7420,1172],{"emptyLinePlaceholder":647},[87,7422,7423,7425,7427,7429,7431],{"class":89,"line":1157},[87,7424,2149],{"class":2044},[87,7426,2152],{"class":2050},[87,7428,2155],{"class":111},[87,7430,2158],{"class":2050},[87,7432,2161],{"class":111},[87,7434,7435,7437,7439,7441,7443,7445,7447,7449],{"class":89,"line":1163},[87,7436,2166],{"class":2044},[87,7438,2169],{"class":111},[87,7440,2172],{"class":2125},[87,7442,2129],{"class":1911},[87,7444,2132],{"class":111},[87,7446,2179],{"class":97},[87,7448,2132],{"class":111},[87,7450,2140],{"class":1911},[87,7452,7453],{"class":89,"line":1169},[87,7454,1166],{"class":111},[10,7456,2760,7457,2763],{},[59,7458,2155],{},[1197,7460,7461],{"id":2766},[59,7462,2766],{},[10,7464,2771,7465,2774],{},[59,7466,2766],{},[51,7468,7469],{"className":2692,"code":2777,"language":2669,"meta":57,"style":57},[59,7470,7471,7481,7491,7499],{"__ignoreMap":57},[87,7472,7473,7475,7477,7479],{"class":89,"line":90},[87,7474,2515],{"class":1915},[87,7476,2786],{"class":93},[87,7478,2521],{"class":111},[87,7480,2524],{"class":111},[87,7482,7483,7485,7487,7489],{"class":89,"line":634},[87,7484,2795],{"class":1915},[87,7486,2798],{"class":1911},[87,7488,2331],{"class":111},[87,7490,2803],{"class":93},[87,7492,7493,7495,7497],{"class":89,"line":1157},[87,7494,2808],{"class":1911},[87,7496,2331],{"class":111},[87,7498,2813],{"class":93},[87,7500,7501],{"class":89,"line":1163},[87,7502,1166],{"class":111},[10,7504,7505,2822],{},[59,7506,2766],{},[1197,7508,2825],{"id":2825},[10,7510,2828],{},[51,7512,7513],{"className":2035,"code":2831,"language":2037,"meta":57,"style":57},[59,7514,7515,7541,7563],{"__ignoreMap":57},[87,7516,7517,7519,7521,7523,7525,7527,7529,7531,7533,7535,7537,7539],{"class":89,"line":90},[87,7518,2562],{"class":1915},[87,7520,2588],{"class":2125},[87,7522,2129],{"class":111},[87,7524,2844],{"class":2273},[87,7526,2331],{"class":111},[87,7528,2849],{"class":93},[87,7530,2122],{"class":111},[87,7532,2854],{"class":93},[87,7534,1908],{"class":111},[87,7536,2859],{"class":93},[87,7538,2862],{"class":111},[87,7540,2524],{"class":111},[87,7542,7543,7545,7547,7549,7551,7553,7555,7557,7559,7561],{"class":89,"line":634},[87,7544,2869],{"class":2050},[87,7546,2122],{"class":111},[87,7548,2874],{"class":2125},[87,7550,2129],{"class":1911},[87,7552,2844],{"class":2050},[87,7554,2122],{"class":111},[87,7556,2883],{"class":2050},[87,7558,2122],{"class":111},[87,7560,2888],{"class":2050},[87,7562,2140],{"class":1911},[87,7564,7565],{"class":89,"line":1157},[87,7566,1166],{"class":111},[10,7568,2897,7569,2901],{},[59,7570,2900],{},[1197,7572,2904],{"id":2904},[10,7574,2907,7575,2911],{},[59,7576,2910],{},[51,7578,7579],{"className":2692,"code":2914,"language":2669,"meta":57,"style":57},[59,7580,7581,7591,7599,7603,7607,7643,7671],{"__ignoreMap":57},[87,7582,7583,7585,7587,7589],{"class":89,"line":90},[87,7584,2515],{"class":1915},[87,7586,2923],{"class":93},[87,7588,2521],{"class":111},[87,7590,2524],{"class":111},[87,7592,7593,7595,7597],{"class":89,"line":634},[87,7594,2932],{"class":1911},[87,7596,2331],{"class":111},[87,7598,2803],{"class":93},[87,7600,7601],{"class":89,"line":1157},[87,7602,1166],{"class":111},[87,7604,7605],{"class":89,"line":1163},[87,7606,1172],{"emptyLinePlaceholder":647},[87,7608,7609,7611,7613,7615,7617,7619,7621,7623,7625,7627,7629,7631,7633,7635,7637,7639,7641],{"class":89,"line":1169},[87,7610,2562],{"class":1915},[87,7612,2951],{"class":2125},[87,7614,1908],{"class":111},[87,7616,2956],{"class":93},[87,7618,2959],{"class":1915},[87,7620,2923],{"class":93},[87,7622,2964],{"class":111},[87,7624,2967],{"class":2273},[87,7626,2331],{"class":111},[87,7628,2972],{"class":93},[87,7630,2975],{"class":2050},[87,7632,2325],{"class":111},[87,7634,2798],{"class":2273},[87,7636,2331],{"class":111},[87,7638,2541],{"class":93},[87,7640,2544],{"class":111},[87,7642,2524],{"class":111},[87,7644,7645,7647,7649,7651,7653,7655,7657,7659,7661,7663,7665,7667,7669],{"class":89,"line":1175},[87,7646,2623],{"class":2044},[87,7648,2994],{"class":2050},[87,7650,2122],{"class":111},[87,7652,2999],{"class":2125},[87,7654,2129],{"class":1911},[87,7656,3004],{"class":2273},[87,7658,2478],{"class":1915},[87,7660,3009],{"class":2050},[87,7662,2122],{"class":111},[87,7664,2536],{"class":2050},[87,7666,3016],{"class":111},[87,7668,2798],{"class":2050},[87,7670,2140],{"class":1911},[87,7672,7673],{"class":89,"line":1181},[87,7674,1166],{"class":111},[10,7676,3027,7677,3030,7679,3033],{},[59,7678,2956],{},[59,7680,2536],{},[1197,7682,7683,3040],{"id":3036},[59,7684,3039],{},[10,7686,7687,3045],{},[59,7688,3039],{},[51,7690,7691],{"className":2692,"code":3048,"language":2669,"meta":57,"style":57},[59,7692,7693,7703,7711,7719,7723,7727,7739],{"__ignoreMap":57},[87,7694,7695,7697,7699,7701],{"class":89,"line":90},[87,7696,2515],{"class":1915},[87,7698,2786],{"class":93},[87,7700,2521],{"class":111},[87,7702,2524],{"class":111},[87,7704,7705,7707,7709],{"class":89,"line":634},[87,7706,2932],{"class":1911},[87,7708,2331],{"class":111},[87,7710,2803],{"class":93},[87,7712,7713,7715,7717],{"class":89,"line":1157},[87,7714,2808],{"class":1911},[87,7716,2331],{"class":111},[87,7718,2813],{"class":93},[87,7720,7721],{"class":89,"line":1163},[87,7722,1166],{"class":111},[87,7724,7725],{"class":89,"line":1169},[87,7726,1172],{"emptyLinePlaceholder":647},[87,7728,7729,7731,7733,7735,7737],{"class":89,"line":1175},[87,7730,2515],{"class":1915},[87,7732,3091],{"class":93},[87,7734,2521],{"class":111},[87,7736,3096],{"class":111},[87,7738,3099],{"class":93},[87,7740,7741],{"class":89,"line":1181},[87,7742,3105],{"class":3104},[10,7744,3108],{},[1197,7746,3111],{"id":3111},[10,7748,3114],{},[51,7750,7751],{"className":2692,"code":3117,"language":2669,"meta":57,"style":57},[59,7752,7753,7763,7771,7779,7783,7787,7807,7811,7815,7833],{"__ignoreMap":57},[87,7754,7755,7757,7759,7761],{"class":89,"line":90},[87,7756,2515],{"class":1915},[87,7758,2786],{"class":93},[87,7760,2521],{"class":111},[87,7762,2524],{"class":111},[87,7764,7765,7767,7769],{"class":89,"line":634},[87,7766,2932],{"class":1911},[87,7768,2331],{"class":111},[87,7770,2803],{"class":93},[87,7772,7773,7775,7777],{"class":89,"line":1157},[87,7774,2808],{"class":1911},[87,7776,2331],{"class":111},[87,7778,2813],{"class":93},[87,7780,7781],{"class":89,"line":1163},[87,7782,1166],{"class":111},[87,7784,7785],{"class":89,"line":1169},[87,7786,1172],{"emptyLinePlaceholder":647},[87,7788,7789,7791,7793,7795,7797,7799,7801,7803,7805],{"class":89,"line":1175},[87,7790,2515],{"class":1915},[87,7792,3160],{"class":93},[87,7794,2521],{"class":111},[87,7796,2786],{"class":93},[87,7798,3167],{"class":2050},[87,7800,2132],{"class":111},[87,7802,2536],{"class":97},[87,7804,2132],{"class":111},[87,7806,1507],{"class":2050},[87,7808,7809],{"class":89,"line":1181},[87,7810,3180],{"class":3104},[87,7812,7813],{"class":89,"line":1186},[87,7814,1172],{"emptyLinePlaceholder":647},[87,7816,7817,7819,7821,7823,7825,7827,7829,7831],{"class":89,"line":1192},[87,7818,2515],{"class":1915},[87,7820,3191],{"class":93},[87,7822,2521],{"class":111},[87,7824,2786],{"class":93},[87,7826,3167],{"class":2050},[87,7828,3039],{"class":111},[87,7830,2786],{"class":93},[87,7832,1507],{"class":2050},[87,7834,7835],{"class":89,"line":1251},[87,7836,3208],{"class":3104},[1197,7838,3211],{"id":3211},[10,7840,7841,3217],{},[59,7842,3216],{},[51,7844,7845],{"className":2692,"code":3220,"language":2669,"meta":57,"style":57},[59,7846,7847],{"__ignoreMap":57},[87,7848,7849,7851,7853,7855,7857],{"class":89,"line":90},[87,7850,3216],{"class":1915},[87,7852,3229],{"class":1915},[87,7854,3232],{"class":2050},[87,7856,2331],{"class":111},[87,7858,2813],{"class":93},[10,7860,3239,7861,3243,7863,3246],{},[59,7862,3242],{},[59,7864,3216],{},[1197,7866,3249],{"id":3249},[10,7868,3252],{},[51,7870,7871],{"className":2692,"code":3255,"language":2669,"meta":57,"style":57},[59,7872,7873,7883,7899,7903,7907,7917,7937],{"__ignoreMap":57},[87,7874,7875,7877,7879,7881],{"class":89,"line":90},[87,7876,2515],{"class":1915},[87,7878,3264],{"class":93},[87,7880,2521],{"class":111},[87,7882,2524],{"class":111},[87,7884,7885,7887,7889,7891,7893,7895,7897],{"class":89,"line":634},[87,7886,3273],{"class":1911},[87,7888,2129],{"class":111},[87,7890,3278],{"class":2273},[87,7892,2331],{"class":111},[87,7894,3283],{"class":93},[87,7896,3286],{"class":111},[87,7898,2813],{"class":93},[87,7900,7901],{"class":89,"line":1157},[87,7902,1166],{"class":111},[87,7904,7905],{"class":89,"line":1163},[87,7906,1172],{"emptyLinePlaceholder":647},[87,7908,7909,7911,7913,7915],{"class":89,"line":1169},[87,7910,2515],{"class":1915},[87,7912,3303],{"class":93},[87,7914,2521],{"class":111},[87,7916,2524],{"class":111},[87,7918,7919,7921,7923,7925,7927,7929,7931,7933,7935],{"class":89,"line":1175},[87,7920,3273],{"class":1911},[87,7922,2331],{"class":111},[87,7924,2152],{"class":111},[87,7926,3278],{"class":2273},[87,7928,2331],{"class":111},[87,7930,3283],{"class":93},[87,7932,2544],{"class":111},[87,7934,2478],{"class":1915},[87,7936,2813],{"class":93},[87,7938,7939],{"class":89,"line":1181},[87,7940,1166],{"class":111},[10,7942,3334,7943,3338],{},[59,7944,3337],{},[1197,7946,3341],{"id":3341},[10,7948,3344],{},[51,7950,7951],{"className":2692,"code":3347,"language":2669,"meta":57,"style":57},[59,7952,7953,7977,7993,7997,8001,8015,8019,8031,8053],{"__ignoreMap":57},[87,7954,7955,7957,7959,7961,7963,7965,7967,7969,7971,7973,7975],{"class":89,"line":90},[87,7956,2562],{"class":1915},[87,7958,3356],{"class":2125},[87,7960,2129],{"class":111},[87,7962,3278],{"class":2273},[87,7964,2331],{"class":111},[87,7966,3365],{"class":93},[87,7968,3286],{"class":111},[87,7970,3370],{"class":2273},[87,7972,3373],{"class":111},[87,7974,2541],{"class":93},[87,7976,2524],{"class":111},[87,7978,7979,7981,7983,7985,7987,7989,7991],{"class":89,"line":634},[87,7980,2623],{"class":2044},[87,7982,3384],{"class":111},[87,7984,3370],{"class":2050},[87,7986,3016],{"class":111},[87,7988,2060],{"class":111},[87,7990,3393],{"class":97},[87,7992,2065],{"class":111},[87,7994,7995],{"class":89,"line":1157},[87,7996,1166],{"class":111},[87,7998,7999],{"class":89,"line":1163},[87,8000,1172],{"emptyLinePlaceholder":647},[87,8002,8003,8005,8007,8009,8011,8013],{"class":89,"line":1169},[87,8004,2111],{"class":1915},[87,8006,3370],{"class":2050},[87,8008,2331],{"class":111},[87,8010,3365],{"class":93},[87,8012,2521],{"class":111},[87,8014,3418],{"class":104},[87,8016,8017],{"class":89,"line":1175},[87,8018,1172],{"emptyLinePlaceholder":647},[87,8020,8021,8023,8025,8027,8029],{"class":89,"line":1181},[87,8022,2149],{"class":2044},[87,8024,2152],{"class":2050},[87,8026,3431],{"class":2125},[87,8028,3434],{"class":2050},[87,8030,2161],{"class":111},[87,8032,8033,8035,8037,8039,8041,8043,8045,8047,8049,8051],{"class":89,"line":1186},[87,8034,2869],{"class":2050},[87,8036,2122],{"class":111},[87,8038,2874],{"class":2125},[87,8040,2129],{"class":1911},[87,8042,3278],{"class":2050},[87,8044,2122],{"class":111},[87,8046,3453],{"class":2125},[87,8048,2129],{"class":1911},[87,8050,3458],{"class":104},[87,8052,3461],{"class":1911},[87,8054,8055],{"class":89,"line":1192},[87,8056,1166],{"class":111},[10,8058,3468],{},[43,8060,574],{"id":574},[10,8062,3473],{},[10,8064,3476],{},[630,8066,3479],{},{"title":57,"searchDepth":634,"depth":634,"links":8068},[8069,8072,8076,8083,8094],{"id":1881,"depth":634,"text":1870,"children":8070},[8071],{"id":1884,"depth":1157,"text":1884},{"id":1142,"depth":634,"text":1845,"children":8073},[8074,8075],{"id":1946,"depth":1157,"text":1946},{"id":1997,"depth":1157,"text":1998},{"id":2017,"depth":634,"text":1875,"children":8077},[8078,8079,8080,8081,8082],{"id":2020,"depth":1157,"text":2023},{"id":2255,"depth":1157,"text":2255},{"id":2457,"depth":1157,"text":2457},{"id":2494,"depth":1157,"text":2494},{"id":2660,"depth":1157,"text":2660},{"id":2669,"depth":634,"text":1878,"children":8084},[8085,8086,8087,8088,8089,8090,8091,8092,8093],{"id":2672,"depth":1157,"text":3499},{"id":2766,"depth":1157,"text":2766},{"id":2825,"depth":1157,"text":2825},{"id":2904,"depth":1157,"text":2904},{"id":3036,"depth":1157,"text":3036},{"id":3111,"depth":1157,"text":3111},{"id":3211,"depth":1157,"text":3211},{"id":3249,"depth":1157,"text":3249},{"id":3341,"depth":1157,"text":3341},{"id":574,"depth":634,"text":574},{},{"title":1850,"description":3509},[1875,1878],{"id":3519,"title":3520,"body":8099,"description":3997,"extension":645,"meta":8473,"navigation":647,"path":3999,"publishDate":4000,"published":647,"seo":8474,"stem":4002,"tags":8475,"thumbnail":4005,"updated":4000,"__hash__":4006},{"type":7,"value":8100,"toc":8463},[8101,8103,8105,8111,8113,8115,8117,8119,8185,8187,8191,8193,8217,8223,8267,8269,8271,8277,8293,8295,8297,8299,8301,8303,8387,8389,8399,8401,8403,8405,8425,8429,8431,8433,8437,8439,8441,8453,8455,8457,8459,8461],[10,8102,12],{},[10,8104,3527],{},[10,8106,3530,8107,2394,8109,3537],{},[59,8108,3533],{},[59,8110,3536],{},[43,8112,3540],{"id":3540},[10,8114,3543],{},[10,8116,3546],{},[10,8118,3549],{},[279,8120,8121,8133],{},[282,8122,8123],{},[285,8124,8125,8127,8129,8131],{},[288,8126,290],{},[288,8128,3533],{},[288,8130,3536],{},[288,8132,3564],{},[296,8134,8135,8145,8155,8165,8175],{},[285,8136,8137,8139,8141,8143],{},[301,8138,3571],{},[301,8140,3574],{},[301,8142,3574],{},[301,8144,3579],{},[285,8146,8147,8149,8151,8153],{},[301,8148,3584],{},[301,8150,3587],{},[301,8152,3587],{},[301,8154,3592],{},[285,8156,8157,8159,8161,8163],{},[301,8158,3597],{},[301,8160,3600],{},[301,8162,3603],{},[301,8164,3600],{},[285,8166,8167,8169,8171,8173],{},[301,8168,3610],{},[301,8170,3613],{},[301,8172,3616],{},[301,8174,3613],{},[285,8176,8177,8179,8181,8183],{},[301,8178,3623],{},[301,8180,3626],{},[301,8182,3629],{},[301,8184,3632],{},[43,8186,3533],{"id":3635},[10,8188,8189,3640],{},[59,8190,3533],{},[10,8192,3643],{},[51,8194,8195],{"className":1140,"code":3646,"language":1142,"meta":57,"style":57},[59,8196,8197,8201,8205,8209,8213],{"__ignoreMap":57},[87,8198,8199],{"class":89,"line":90},[87,8200,3653],{},[87,8202,8203],{"class":89,"line":634},[87,8204,1172],{"emptyLinePlaceholder":647},[87,8206,8207],{"class":89,"line":1157},[87,8208,3662],{},[87,8210,8211],{"class":89,"line":1163},[87,8212,1172],{"emptyLinePlaceholder":647},[87,8214,8215],{"class":89,"line":1169},[87,8216,3671],{},[10,8218,3674,8219,3678,8221,3682],{},[59,8220,3677],{},[59,8222,3681],{},[51,8224,8225],{"className":1140,"code":3685,"language":1142,"meta":57,"style":57},[59,8226,8227,8231,8235,8239,8243,8247,8251,8255,8259,8263],{"__ignoreMap":57},[87,8228,8229],{"class":89,"line":90},[87,8230,3692],{},[87,8232,8233],{"class":89,"line":634},[87,8234,3697],{},[87,8236,8237],{"class":89,"line":1157},[87,8238,3702],{},[87,8240,8241],{"class":89,"line":1163},[87,8242,1166],{},[87,8244,8245],{"class":89,"line":1169},[87,8246,1172],{"emptyLinePlaceholder":647},[87,8248,8249],{"class":89,"line":1175},[87,8250,3715],{},[87,8252,8253],{"class":89,"line":1181},[87,8254,1172],{"emptyLinePlaceholder":647},[87,8256,8257],{"class":89,"line":1186},[87,8258,3724],{},[87,8260,8261],{"class":89,"line":1192},[87,8262,3729],{},[87,8264,8265],{"class":89,"line":1251},[87,8266,2140],{},[10,8268,3736],{},[43,8270,3536],{"id":3739},[10,8272,8273,3744,8275,3747],{},[59,8274,3536],{},[59,8276,3533],{},[51,8278,8279],{"className":1140,"code":3750,"language":1142,"meta":57,"style":57},[59,8280,8281,8285,8289],{"__ignoreMap":57},[87,8282,8283],{"class":89,"line":90},[87,8284,3757],{},[87,8286,8287],{"class":89,"line":634},[87,8288,1172],{"emptyLinePlaceholder":647},[87,8290,8291],{"class":89,"line":1157},[87,8292,3766],{},[10,8294,3769],{},[10,8296,3772],{},[43,8298,3564],{"id":3775},[10,8300,3778],{},[10,8302,3781],{},[51,8304,8305],{"className":1140,"code":3784,"language":1142,"meta":57,"style":57},[59,8306,8307,8311,8315,8319,8323,8327,8331,8335,8339,8343,8347,8351,8355,8359,8363,8367,8371,8375,8379,8383],{"__ignoreMap":57},[87,8308,8309],{"class":89,"line":90},[87,8310,3791],{},[87,8312,8313],{"class":89,"line":634},[87,8314,1172],{"emptyLinePlaceholder":647},[87,8316,8317],{"class":89,"line":1157},[87,8318,3800],{},[87,8320,8321],{"class":89,"line":1163},[87,8322,3805],{},[87,8324,8325],{"class":89,"line":1169},[87,8326,1172],{"emptyLinePlaceholder":647},[87,8328,8329],{"class":89,"line":1175},[87,8330,3814],{},[87,8332,8333],{"class":89,"line":1181},[87,8334,3819],{},[87,8336,8337],{"class":89,"line":1186},[87,8338,3824],{},[87,8340,8341],{"class":89,"line":1192},[87,8342,3829],{},[87,8344,8345],{"class":89,"line":1251},[87,8346,3834],{},[87,8348,8349],{"class":89,"line":1257},[87,8350,2614],{},[87,8352,8353],{"class":89,"line":1263},[87,8354,1166],{},[87,8356,8357],{"class":89,"line":1268},[87,8358,1172],{"emptyLinePlaceholder":647},[87,8360,8361],{"class":89,"line":1273},[87,8362,3851],{},[87,8364,8365],{"class":89,"line":2239},[87,8366,3805],{},[87,8368,8369],{"class":89,"line":3858},[87,8370,3861],{},[87,8372,8373],{"class":89,"line":3864},[87,8374,3867],{},[87,8376,8377],{"class":89,"line":3870},[87,8378,1172],{"emptyLinePlaceholder":647},[87,8380,8381],{"class":89,"line":3875},[87,8382,3878],{},[87,8384,8385],{"class":89,"line":3881},[87,8386,1166],{},[10,8388,3886],{},[1787,8390,8391,8393,8395,8397],{},[582,8392,3891],{},[582,8394,3894],{},[582,8396,3897],{},[582,8398,3900],{},[43,8400,3903],{"id":3903},[10,8402,3906],{},[10,8404,3909],{},[51,8406,8407],{"className":1140,"code":3912,"language":1142,"meta":57,"style":57},[59,8408,8409,8413,8417,8421],{"__ignoreMap":57},[87,8410,8411],{"class":89,"line":90},[87,8412,3919],{},[87,8414,8415],{"class":89,"line":634},[87,8416,1172],{"emptyLinePlaceholder":647},[87,8418,8419],{"class":89,"line":1157},[87,8420,3928],{},[87,8422,8423],{"class":89,"line":1163},[87,8424,3933],{},[35,8426,8427],{"title":3936,"type":38},[10,8428,3939],{},[43,8430,3942],{"id":3942},[10,8432,3945],{},[35,8434,8435],{"title":3948,"type":3949},[10,8436,3952],{},[43,8438,3955],{"id":3955},[10,8440,3958],{},[1787,8442,8443,8447,8451],{},[582,8444,3963,8445],{},[59,8446,3533],{},[582,8448,3968,8449],{},[59,8450,3536],{},[582,8452,3973],{},[10,8454,3976],{},[43,8456,574],{"id":574},[10,8458,3981],{},[10,8460,3984],{},[630,8462,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":8464},[8465,8466,8467,8468,8469,8470,8471,8472],{"id":3540,"depth":634,"text":3540},{"id":3635,"depth":634,"text":3533},{"id":3739,"depth":634,"text":3536},{"id":3775,"depth":634,"text":3564},{"id":3903,"depth":634,"text":3903},{"id":3942,"depth":634,"text":3942},{"id":3955,"depth":634,"text":3955},{"id":574,"depth":634,"text":574},{},{"title":3520,"description":3997},[4004,3564],{"id":4008,"title":4009,"body":8477,"description":4486,"extension":645,"meta":8844,"navigation":647,"path":4488,"publishDate":4489,"published":647,"seo":8845,"stem":4491,"tags":8846,"thumbnail":4493,"updated":4489,"__hash__":4494},{"type":7,"value":8478,"toc":8834},[8479,8481,8486,8488,8490,8492,8494,8496,8508,8510,8512,8514,8570,8572,8598,8600,8602,8604,8606,8616,8618,8654,8656,8658,8660,8662,8672,8676,8678,8680,8682,8700,8702,8704,8706,8708,8710,8722,8724,8726,8790,8792,8797,8803,8809,8811,8825,8827,8832],[10,8480,12],{},[10,8482,4016,8483,4022],{},[1859,8484,4021],{"href":4019,"rel":8485},[1863],[10,8487,4025],{},[43,8489,4029],{"id":4028},[10,8491,4032],{},[10,8493,4035],{},[10,8495,4038],{},[1787,8497,8498,8500,8502,8504,8506],{},[582,8499,4043],{},[582,8501,4046],{},[582,8503,4049],{},[582,8505,4052],{},[582,8507,4055],{},[43,8509,4043],{"id":4043},[10,8511,4060],{},[10,8513,4063],{},[51,8515,8516],{"className":1140,"code":4066,"language":1142,"meta":57,"style":57},[59,8517,8518,8522,8526,8530,8534,8538,8542,8546,8550,8554,8558,8562,8566],{"__ignoreMap":57},[87,8519,8520],{"class":89,"line":90},[87,8521,4073],{},[87,8523,8524],{"class":89,"line":634},[87,8525,4078],{},[87,8527,8528],{"class":89,"line":1157},[87,8529,1166],{},[87,8531,8532],{"class":89,"line":1163},[87,8533,1172],{"emptyLinePlaceholder":647},[87,8535,8536],{"class":89,"line":1169},[87,8537,4091],{},[87,8539,8540],{"class":89,"line":1175},[87,8541,4096],{},[87,8543,8544],{"class":89,"line":1181},[87,8545,1166],{},[87,8547,8548],{"class":89,"line":1186},[87,8549,1172],{"emptyLinePlaceholder":647},[87,8551,8552],{"class":89,"line":1192},[87,8553,4109],{},[87,8555,8556],{"class":89,"line":1251},[87,8557,4114],{},[87,8559,8560],{"class":89,"line":1257},[87,8561,1166],{},[87,8563,8564],{"class":89,"line":1263},[87,8565,1172],{"emptyLinePlaceholder":647},[87,8567,8568],{"class":89,"line":1268},[87,8569,4127],{},[10,8571,4130],{},[579,8573,8574,8578,8584,8590],{},[582,8575,8576,4138],{},[59,8577,4137],{},[582,8579,8580,4143,8582,4147],{},[59,8581,4137],{},[59,8583,4146],{},[582,8585,8586,4143,8588,4147],{},[59,8587,4146],{},[59,8589,4154],{},[582,8591,8592,2394,8594,2394,8596,4163],{},[59,8593,4154],{},[59,8595,4146],{},[59,8597,4137],{},[10,8599,4166],{},[43,8601,4046],{"id":4169},[10,8603,4172],{},[10,8605,4175],{},[1787,8607,8608,8610,8612,8614],{},[582,8609,4180],{},[582,8611,4183],{},[582,8613,4186],{},[582,8615,4189],{},[10,8617,4192],{},[51,8619,8620],{"className":1140,"code":4195,"language":1142,"meta":57,"style":57},[59,8621,8622,8626,8630,8634,8638,8642,8646,8650],{"__ignoreMap":57},[87,8623,8624],{"class":89,"line":90},[87,8625,4202],{},[87,8627,8628],{"class":89,"line":634},[87,8629,4207],{},[87,8631,8632],{"class":89,"line":1157},[87,8633,4212],{},[87,8635,8636],{"class":89,"line":1163},[87,8637,2140],{},[87,8639,8640],{"class":89,"line":1169},[87,8641,1172],{"emptyLinePlaceholder":647},[87,8643,8644],{"class":89,"line":1175},[87,8645,4225],{},[87,8647,8648],{"class":89,"line":1181},[87,8649,4230],{},[87,8651,8652],{"class":89,"line":1186},[87,8653,4235],{},[10,8655,4238],{},[43,8657,4049],{"id":4049},[10,8659,4243],{},[10,8661,4246],{},[1787,8663,8664,8668,8670],{},[582,8665,8666,4254],{},[59,8667,4253],{},[582,8669,4257],{},[582,8671,4260],{},[10,8673,8674,4265],{},[59,8675,4253],{},[10,8677,4268],{},[43,8679,4052],{"id":4052},[10,8681,4273],{},[1787,8683,8684,8692,8696],{},[582,8685,4278,8686,2394,8688,2394,8690],{},[59,8687,4281],{},[59,8689,4284],{},[59,8691,4287],{},[582,8693,8694,4293],{},[59,8695,4292],{},[582,8697,8698,4254],{},[59,8699,4298],{},[10,8701,4301],{},[10,8703,4304],{},[43,8705,4055],{"id":4055},[10,8707,4309],{},[10,8709,4312],{},[579,8711,8712,8714,8716,8718,8720],{},[582,8713,4317],{},[582,8715,4320],{},[582,8717,4323],{},[582,8719,4326],{},[582,8721,4329],{},[43,8723,4332],{"id":4332},[10,8725,4335],{},[51,8727,8728],{"className":1140,"code":4338,"language":1142,"meta":57,"style":57},[59,8729,8730,8734,8738,8742,8746,8750,8754,8758,8762,8766,8770,8774,8778,8782,8786],{"__ignoreMap":57},[87,8731,8732],{"class":89,"line":90},[87,8733,4345],{},[87,8735,8736],{"class":89,"line":634},[87,8737,1172],{"emptyLinePlaceholder":647},[87,8739,8740],{"class":89,"line":1157},[87,8741,4354],{},[87,8743,8744],{"class":89,"line":1163},[87,8745,4359],{},[87,8747,8748],{"class":89,"line":1169},[87,8749,4364],{},[87,8751,8752],{"class":89,"line":1175},[87,8753,1172],{"emptyLinePlaceholder":647},[87,8755,8756],{"class":89,"line":1181},[87,8757,4373],{},[87,8759,8760],{"class":89,"line":1186},[87,8761,4378],{},[87,8763,8764],{"class":89,"line":1192},[87,8765,4383],{},[87,8767,8768],{"class":89,"line":1251},[87,8769,1172],{"emptyLinePlaceholder":647},[87,8771,8772],{"class":89,"line":1257},[87,8773,4392],{},[87,8775,8776],{"class":89,"line":1263},[87,8777,4397],{},[87,8779,8780],{"class":89,"line":1268},[87,8781,4383],{},[87,8783,8784],{"class":89,"line":1273},[87,8785,1172],{"emptyLinePlaceholder":647},[87,8787,8788],{"class":89,"line":2239},[87,8789,4410],{},[10,8791,4413],{},[51,8793,8795],{"className":8794,"code":4417,"language":56,"meta":57},[54],[59,8796,4417],{"__ignoreMap":57},[10,8798,4422,8799,4426,8801,4430],{},[59,8800,4425],{},[59,8802,4429],{},[10,8804,4433,8805,4436,8807,4439],{},[59,8806,4292],{},[59,8808,4253],{},[43,8810,574],{"id":574},[1787,8812,8813,8815,8817,8819,8821,8823],{},[582,8814,4446],{},[582,8816,4449],{},[582,8818,4452],{},[582,8820,4455],{},[582,8822,4458],{},[582,8824,4461],{},[10,8826,4464],{},[10,8828,4467,8829,4473],{},[1859,8830,4472],{"href":4470,"rel":8831},[1863],[630,8833,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":8835},[8836,8837,8838,8839,8840,8841,8842,8843],{"id":4028,"depth":634,"text":4029},{"id":4043,"depth":634,"text":4043},{"id":4169,"depth":634,"text":4046},{"id":4049,"depth":634,"text":4049},{"id":4052,"depth":634,"text":4052},{"id":4055,"depth":634,"text":4055},{"id":4332,"depth":634,"text":4332},{"id":574,"depth":634,"text":574},{},{"title":4009,"description":4486},[1845],{"id":4496,"title":4497,"body":8848,"description":4914,"extension":645,"meta":9170,"navigation":647,"path":4916,"publishDate":4917,"published":647,"seo":9171,"stem":4919,"tags":9172,"thumbnail":4921,"updated":4917,"__hash__":4922},{"type":7,"value":8849,"toc":9162},[8850,8852,8854,8856,8858,8860,8868,8873,8875,8881,8905,8915,8920,8922,8926,8962,8968,8974,8982,9002,9004,9008,9044,9048,9052,9072,9074,9080,9116,9122,9134,9136,9158,9160],[10,8851,12],{},[10,8853,4504],{},[10,8855,4507],{},[43,8857,4511],{"id":4510},[10,8859,4514],{},[10,8861,8862,2394,8864,2394,8866,4526],{},[59,8863,4519],{},[59,8865,4522],{},[59,8867,4525],{},[10,8869,4529,8870,4535],{},[1859,8871,4534],{"href":4532,"rel":8872},[1863],[43,8874,4539],{"id":4538},[10,8876,4542,8877,4545,8879,4549],{},[59,8878,1386],{},[59,8880,4548],{},[51,8882,8883],{"className":1140,"code":4552,"language":1142,"meta":57,"style":57},[59,8884,8885,8889,8893,8897,8901],{"__ignoreMap":57},[87,8886,8887],{"class":89,"line":90},[87,8888,4559],{},[87,8890,8891],{"class":89,"line":634},[87,8892,1358],{},[87,8894,8895],{"class":89,"line":1157},[87,8896,1166],{},[87,8898,8899],{"class":89,"line":1163},[87,8900,1172],{"emptyLinePlaceholder":647},[87,8902,8903],{"class":89,"line":1169},[87,8904,4576],{},[10,8906,4579,8907,4583,8909,4587,8911,4590,8913,4593],{},[59,8908,4582],{},[59,8910,4586],{},[59,8912,4586],{},[59,8914,4548],{},[10,8916,4596,8917,4473],{},[1859,8918,4601],{"href":4599,"rel":8919},[1863],[43,8921,4604],{"id":4604},[10,8923,4607,8924,4611],{},[59,8925,4610],{},[51,8927,8928],{"className":1140,"code":4614,"language":1142,"meta":57,"style":57},[59,8929,8930,8934,8938,8942,8946,8950,8954,8958],{"__ignoreMap":57},[87,8931,8932],{"class":89,"line":90},[87,8933,4559],{},[87,8935,8936],{"class":89,"line":634},[87,8937,1358],{},[87,8939,8940],{"class":89,"line":1157},[87,8941,4629],{},[87,8943,8944],{"class":89,"line":1163},[87,8945,4634],{},[87,8947,8948],{"class":89,"line":1169},[87,8949,1230],{},[87,8951,8952],{"class":89,"line":1175},[87,8953,1166],{},[87,8955,8956],{"class":89,"line":1181},[87,8957,1172],{"emptyLinePlaceholder":647},[87,8959,8960],{"class":89,"line":1186},[87,8961,4651],{},[10,8963,4654,8964,4658,8966,4662],{},[59,8965,4657],{},[59,8967,4661],{},[10,8969,8970,4667,8972,4670],{},[59,8971,4582],{},[59,8973,4610],{},[10,8975,4673,8976,4677,8978,4680,8980,4683],{},[59,8977,4676],{},[59,8979,4586],{},[59,8981,4548],{},[51,8983,8984],{"className":1140,"code":4686,"language":1142,"meta":57,"style":57},[59,8985,8986,8990,8994,8998],{"__ignoreMap":57},[87,8987,8988],{"class":89,"line":90},[87,8989,4693],{},[87,8991,8992],{"class":89,"line":634},[87,8993,4698],{},[87,8995,8996],{"class":89,"line":1157},[87,8997,1172],{"emptyLinePlaceholder":647},[87,8999,9000],{"class":89,"line":1163},[87,9001,4707],{},[43,9003,4711],{"id":4710},[10,9005,4714,9006,4718],{},[59,9007,4717],{},[51,9009,9010],{"className":1140,"code":4721,"language":1142,"meta":57,"style":57},[59,9011,9012,9016,9020,9024,9028,9032,9036,9040],{"__ignoreMap":57},[87,9013,9014],{"class":89,"line":90},[87,9015,4559],{},[87,9017,9018],{"class":89,"line":634},[87,9019,1358],{},[87,9021,9022],{"class":89,"line":1157},[87,9023,4629],{},[87,9025,9026],{"class":89,"line":1163},[87,9027,4634],{},[87,9029,9030],{"class":89,"line":1169},[87,9031,1230],{},[87,9033,9034],{"class":89,"line":1175},[87,9035,1166],{},[87,9037,9038],{"class":89,"line":1181},[87,9039,1172],{"emptyLinePlaceholder":647},[87,9041,9042],{"class":89,"line":1186},[87,9043,4756],{},[10,9045,4759,9046,4762],{},[59,9047,4610],{},[10,9049,9050,4767],{},[59,9051,4676],{},[51,9053,9054],{"className":1140,"code":4770,"language":1142,"meta":57,"style":57},[59,9055,9056,9060,9064,9068],{"__ignoreMap":57},[87,9057,9058],{"class":89,"line":90},[87,9059,4693],{},[87,9061,9062],{"class":89,"line":634},[87,9063,4698],{},[87,9065,9066],{"class":89,"line":1157},[87,9067,1172],{"emptyLinePlaceholder":647},[87,9069,9070],{"class":89,"line":1163},[87,9071,4756],{},[43,9073,4791],{"id":4791},[10,9075,9076,4796,9078,4800],{},[59,9077,4717],{},[59,9079,4799],{},[51,9081,9082],{"className":1140,"code":4803,"language":1142,"meta":57,"style":57},[59,9083,9084,9088,9092,9096,9100,9104,9108,9112],{"__ignoreMap":57},[87,9085,9086],{"class":89,"line":90},[87,9087,4559],{},[87,9089,9090],{"class":89,"line":634},[87,9091,1358],{},[87,9093,9094],{"class":89,"line":1157},[87,9095,4629],{},[87,9097,9098],{"class":89,"line":1163},[87,9099,4634],{},[87,9101,9102],{"class":89,"line":1169},[87,9103,1230],{},[87,9105,9106],{"class":89,"line":1175},[87,9107,1166],{},[87,9109,9110],{"class":89,"line":1181},[87,9111,1172],{"emptyLinePlaceholder":647},[87,9113,9114],{"class":89,"line":1186},[87,9115,4838],{},[10,9117,9118,4844,9120,4848],{},[59,9119,4843],{},[59,9121,4847],{},[10,9123,4851,9124,4854,9126,4857,9128,4860,9130,4863,9132,4866],{},[59,9125,4586],{},[59,9127,4548],{},[59,9129,4582],{},[59,9131,4847],{},[59,9133,4582],{},[43,9135,574],{"id":574},[1787,9137,9138,9142,9144,9150,9154],{},[582,9139,4873,9140,4876],{},[59,9141,4586],{},[582,9143,4879],{},[582,9145,9146,4677,9148,4886],{},[59,9147,4676],{},[59,9149,4548],{},[582,9151,4889,9152,4893],{},[59,9153,4892],{},[582,9155,4896,9156,4900],{},[59,9157,4899],{},[10,9159,4903],{},[630,9161,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":9163},[9164,9165,9166,9167,9168,9169],{"id":4510,"depth":634,"text":4511},{"id":4538,"depth":634,"text":4539},{"id":4604,"depth":634,"text":4604},{"id":4710,"depth":634,"text":4711},{"id":4791,"depth":634,"text":4791},{"id":574,"depth":634,"text":574},{},{"title":4497,"description":4914},[1845],{"id":4924,"title":4925,"body":9174,"description":5306,"extension":645,"meta":9469,"navigation":647,"path":5308,"publishDate":5309,"published":647,"seo":9470,"stem":5311,"tags":9471,"thumbnail":5313,"updated":5309,"__hash__":5314},{"type":7,"value":9175,"toc":9462},[9176,9178,9180,9182,9184,9186,9188,9193,9195,9199,9243,9251,9263,9265,9285,9287,9295,9297,9301,9345,9349,9361,9363,9383,9393,9397,9402,9404,9406,9414,9416,9434,9438,9440,9458,9460],[10,9177,12],{},[10,9179,4932],{},[10,9181,4935],{},[43,9183,4939],{"id":4938},[10,9185,4942],{},[10,9187,4945],{},[10,9189,4948,9190,4954],{},[1859,9191,4953],{"href":4951,"rel":9192},[1863],[43,9194,4957],{"id":4957},[10,9196,4960,9197,4964],{},[59,9198,4963],{},[51,9200,9201],{"className":1140,"code":4967,"language":1142,"meta":57,"style":57},[59,9202,9203,9207,9211,9215,9219,9223,9227,9231,9235,9239],{"__ignoreMap":57},[87,9204,9205],{"class":89,"line":90},[87,9206,4974],{},[87,9208,9209],{"class":89,"line":634},[87,9210,4979],{},[87,9212,9213],{"class":89,"line":1157},[87,9214,4984],{},[87,9216,9217],{"class":89,"line":1163},[87,9218,1230],{},[87,9220,9221],{"class":89,"line":1169},[87,9222,4993],{},[87,9224,9225],{"class":89,"line":1175},[87,9226,4998],{},[87,9228,9229],{"class":89,"line":1181},[87,9230,1230],{},[87,9232,9233],{"class":89,"line":1186},[87,9234,1166],{},[87,9236,9237],{"class":89,"line":1192},[87,9238,1172],{"emptyLinePlaceholder":647},[87,9240,9241],{"class":89,"line":1251},[87,9242,5015],{},[10,9244,9245,5021,9247,5025,9249,5029],{},[59,9246,5020],{},[59,9248,5024],{},[59,9250,5028],{},[51,9252,9253],{"className":1140,"code":5032,"language":1142,"meta":57,"style":57},[59,9254,9255,9259],{"__ignoreMap":57},[87,9256,9257],{"class":89,"line":90},[87,9258,5039],{},[87,9260,9261],{"class":89,"line":634},[87,9262,5044],{},[10,9264,5047],{},[51,9266,9267],{"className":1140,"code":5050,"language":1142,"meta":57,"style":57},[59,9268,9269,9273,9277,9281],{"__ignoreMap":57},[87,9270,9271],{"class":89,"line":90},[87,9272,5057],{},[87,9274,9275],{"class":89,"line":634},[87,9276,1172],{"emptyLinePlaceholder":647},[87,9278,9279],{"class":89,"line":1157},[87,9280,5066],{},[87,9282,9283],{"class":89,"line":1163},[87,9284,5071],{},[10,9286,5074],{},[51,9288,9289],{"className":1140,"code":5077,"language":1142,"meta":57,"style":57},[59,9290,9291],{"__ignoreMap":57},[87,9292,9293],{"class":89,"line":90},[87,9294,5077],{},[43,9296,5087],{"id":5086},[10,9298,5090,9299,5094],{},[59,9300,5093],{},[51,9302,9303],{"className":1140,"code":5097,"language":1142,"meta":57,"style":57},[59,9304,9305,9309,9313,9317,9321,9325,9329,9333,9337,9341],{"__ignoreMap":57},[87,9306,9307],{"class":89,"line":90},[87,9308,4974],{},[87,9310,9311],{"class":89,"line":634},[87,9312,4979],{},[87,9314,9315],{"class":89,"line":1157},[87,9316,4984],{},[87,9318,9319],{"class":89,"line":1163},[87,9320,1230],{},[87,9322,9323],{"class":89,"line":1169},[87,9324,4993],{},[87,9326,9327],{"class":89,"line":1175},[87,9328,4998],{},[87,9330,9331],{"class":89,"line":1181},[87,9332,1230],{},[87,9334,9335],{"class":89,"line":1186},[87,9336,1166],{},[87,9338,9339],{"class":89,"line":1192},[87,9340,1172],{"emptyLinePlaceholder":647},[87,9342,9343],{"class":89,"line":1251},[87,9344,5140],{},[10,9346,9347,5145],{},[59,9348,5093],{},[51,9350,9351],{"className":1140,"code":5148,"language":1142,"meta":57,"style":57},[59,9352,9353,9357],{"__ignoreMap":57},[87,9354,9355],{"class":89,"line":90},[87,9356,5155],{},[87,9358,9359],{"class":89,"line":634},[87,9360,5160],{},[10,9362,5163],{},[51,9364,9365],{"className":1140,"code":5166,"language":1142,"meta":57,"style":57},[59,9366,9367,9371,9375,9379],{"__ignoreMap":57},[87,9368,9369],{"class":89,"line":90},[87,9370,5173],{},[87,9372,9373],{"class":89,"line":634},[87,9374,1172],{"emptyLinePlaceholder":647},[87,9376,9377],{"class":89,"line":1157},[87,9378,5182],{},[87,9380,9381],{"class":89,"line":1163},[87,9382,5187],{},[10,9384,9385,5192,9387,2394,9389,2394,9391,5202],{},[59,9386,5093],{},[59,9388,5195],{},[59,9390,5198],{},[59,9392,5201],{},[10,9394,5205,9395,5209],{},[59,9396,5208],{},[10,9398,5212,9399,5218],{},[1859,9400,5217],{"href":5215,"rel":9401},[1863],[43,9403,5222],{"id":5221},[10,9405,5225],{},[51,9407,9408],{"className":1140,"code":5228,"language":1142,"meta":57,"style":57},[59,9409,9410],{"__ignoreMap":57},[87,9411,9412],{"class":89,"line":90},[87,9413,5228],{},[10,9415,5237],{},[1787,9417,9418,9422,9428,9432],{},[582,9419,9420,5244],{},[59,9421,5195],{},[582,9423,9424,5249,9426,5253],{},[59,9425,1408],{},[59,9427,5252],{},[582,9429,9430,5259],{},[59,9431,5258],{},[582,9433,5262],{},[10,9435,5265,9436,5268],{},[59,9437,5093],{},[43,9439,574],{"id":574},[1787,9441,9442,9446,9448,9452,9456],{},[582,9443,9444,5277],{},[59,9445,4963],{},[582,9447,5280],{},[582,9449,9450,5285],{},[59,9451,5093],{},[582,9453,9454,5290],{},[59,9455,5093],{},[582,9457,5293],{},[10,9459,5296],{},[630,9461,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":9463},[9464,9465,9466,9467,9468],{"id":4938,"depth":634,"text":4939},{"id":4957,"depth":634,"text":4957},{"id":5086,"depth":634,"text":5087},{"id":5221,"depth":634,"text":5222},{"id":574,"depth":634,"text":574},{},{"title":4925,"description":5306},[1845],{"id":5316,"title":5317,"body":9473,"description":5731,"extension":645,"meta":9795,"navigation":647,"path":5733,"publishDate":5734,"published":647,"seo":9796,"stem":5736,"tags":9797,"thumbnail":5738,"updated":5739,"__hash__":5740},{"type":7,"value":9474,"toc":9787},[9475,9477,9481,9483,9487,9491,9493,9495,9499,9505,9507,9511,9515,9523,9525,9561,9565,9577,9579,9583,9597,9599,9631,9639,9653,9657,9659,9661,9701,9713,9721,9731,9737,9749,9751,9755,9781,9785],[10,9476,12],{},[10,9478,5324,9479,5327],{},[59,9480,4847],{},[43,9482,5331],{"id":5330},[10,9484,9485,5336],{},[59,9486,4847],{},[10,9488,5339,9489,5342],{},[59,9490,4847],{},[10,9492,5345],{},[43,9494,5348],{"id":5348},[10,9496,5351,9497,5354],{},[59,9498,4847],{},[1787,9500,9501,9503],{},[582,9502,5359],{},[582,9504,5362],{},[43,9506,5359],{"id":5359},[10,9508,5367,9509,5370],{},[59,9510,4847],{},[10,9512,5373,9513,5376],{},[59,9514,4582],{},[51,9516,9517],{"className":1140,"code":5379,"language":1142,"meta":57,"style":57},[59,9518,9519],{"__ignoreMap":57},[87,9520,9521],{"class":89,"line":90},[87,9522,5379],{},[10,9524,5388],{},[51,9526,9527],{"className":1140,"code":5391,"language":1142,"meta":57,"style":57},[59,9528,9529,9533,9537,9541,9545,9549,9553,9557],{"__ignoreMap":57},[87,9530,9531],{"class":89,"line":90},[87,9532,4559],{},[87,9534,9535],{"class":89,"line":634},[87,9536,1358],{},[87,9538,9539],{"class":89,"line":1157},[87,9540,5406],{},[87,9542,9543],{"class":89,"line":1163},[87,9544,5411],{},[87,9546,9547],{"class":89,"line":1169},[87,9548,1230],{},[87,9550,9551],{"class":89,"line":1175},[87,9552,1166],{},[87,9554,9555],{"class":89,"line":1181},[87,9556,1172],{"emptyLinePlaceholder":647},[87,9558,9559],{"class":89,"line":1186},[87,9560,5428],{},[10,9562,5431,9563,5435],{},[59,9564,5434],{},[10,9566,9567,5441,9569,5444,9571,5447,9573,5444,9575,5454],{},[59,9568,5440],{},[59,9570,4847],{},[59,9572,4582],{},[59,9574,5450],{},[59,9576,5453],{},[43,9578,5362],{"id":5362},[10,9580,5459,9581,5462],{},[59,9582,4847],{},[1787,9584,9585,9591],{},[582,9586,5467,9587,5470,9589,5474],{},[59,9588,4847],{},[59,9590,5473],{},[582,9592,5477,9593,5444,9595,5482],{},[59,9594,4847],{},[59,9596,1408],{},[10,9598,5485],{},[51,9600,9601],{"className":1140,"code":5488,"language":1142,"meta":57,"style":57},[59,9602,9603,9607,9611,9615,9619,9623,9627],{"__ignoreMap":57},[87,9604,9605],{"class":89,"line":90},[87,9606,5495],{},[87,9608,9609],{"class":89,"line":634},[87,9610,1172],{"emptyLinePlaceholder":647},[87,9612,9613],{"class":89,"line":1157},[87,9614,5504],{},[87,9616,9617],{"class":89,"line":1163},[87,9618,5509],{},[87,9620,9621],{"class":89,"line":1169},[87,9622,1166],{},[87,9624,9625],{"class":89,"line":1175},[87,9626,1172],{"emptyLinePlaceholder":647},[87,9628,9629],{"class":89,"line":1181},[87,9630,5522],{},[10,9632,5525,9633,5528,9635,5532,9637,5435],{},[59,9634,5450],{},[59,9636,5531],{},[59,9638,5434],{},[5536,9640,9641],{},[10,9642,9643,5025,9645,5545,9647,5548,9649,5552,9651,5555],{},[59,9644,5542],{},[59,9646,2111],{},[59,9648,5473],{},[59,9650,5551],{},[59,9652,5473],{},[10,9654,5558,9655,5561],{},[59,9656,4847],{},[43,9658,5564],{"id":5564},[10,9660,5567],{},[51,9662,9663],{"className":1140,"code":5570,"language":1142,"meta":57,"style":57},[59,9664,9665,9669,9673,9677,9681,9685,9689,9693,9697],{"__ignoreMap":57},[87,9666,9667],{"class":89,"line":90},[87,9668,4559],{},[87,9670,9671],{"class":89,"line":634},[87,9672,1358],{},[87,9674,9675],{"class":89,"line":1157},[87,9676,5406],{},[87,9678,9679],{"class":89,"line":1163},[87,9680,5411],{},[87,9682,9683],{"class":89,"line":1169},[87,9684,1230],{},[87,9686,9687],{"class":89,"line":1175},[87,9688,1166],{},[87,9690,9691],{"class":89,"line":1181},[87,9692,1172],{"emptyLinePlaceholder":647},[87,9694,9695],{"class":89,"line":1186},[87,9696,5605],{},[87,9698,9699],{"class":89,"line":1192},[87,9700,5522],{},[10,9702,9703,5615,9705,5618,9707,5622,9709,4426,9711,5627],{},[59,9704,5614],{},[59,9706,5440],{},[59,9708,5621],{},[59,9710,4847],{},[59,9712,4582],{},[10,9714,5525,9715,5528,9717,5634,9719,5637],{},[59,9716,4847],{},[59,9718,5473],{},[59,9720,5531],{},[10,9722,5640,9723,5528,9725,5645,9727,5648,9729,5651],{},[59,9724,4847],{},[59,9726,1408],{},[59,9728,5450],{},[59,9730,1588],{},[10,9732,5654,9733,5658,9735,5661],{},[59,9734,5657],{},[59,9736,4847],{},[51,9738,9739],{"className":1140,"code":5664,"language":1142,"meta":57,"style":57},[59,9740,9741,9745],{"__ignoreMap":57},[87,9742,9743],{"class":89,"line":90},[87,9744,5671],{},[87,9746,9747],{"class":89,"line":634},[87,9748,5676],{},[43,9750,574],{"id":574},[10,9752,9753,5683],{},[59,9754,4847],{},[1787,9756,9757,9765,9773,9775],{},[582,9758,9759,5690,9761,5444,9763,5474],{},[59,9760,5440],{},[59,9762,4847],{},[59,9764,4582],{},[582,9766,9767,5699,9769,5702,9771,5482],{},[59,9768,5621],{},[59,9770,5473],{},[59,9772,1408],{},[582,9774,5707],{},[582,9776,5710,9777,586,9779,5715],{},[59,9778,5657],{},[59,9780,4847],{},[10,9782,9783,5720],{},[59,9784,4847],{},[630,9786,1820],{},{"title":57,"searchDepth":634,"depth":634,"links":9788},[9789,9790,9791,9792,9793,9794],{"id":5330,"depth":634,"text":5331},{"id":5348,"depth":634,"text":5348},{"id":5359,"depth":634,"text":5359},{"id":5362,"depth":634,"text":5362},{"id":5564,"depth":634,"text":5564},{"id":574,"depth":634,"text":574},{},{"title":5317,"description":5731},[1845],[9799],{"id":9800,"title":9801,"author":9802,"body":9803,"description":10441,"extension":645,"meta":10442,"navigation":647,"path":10443,"publishDate":10444,"published":647,"publisher":10445,"seo":10446,"stem":10447,"tags":10448,"__hash__":10449},"books\u002Fbooks\u002F2025\u002Forganize-learned-from-docker.md","Docker&仮想サーバー完全入門","リブロワークス",{"type":7,"value":9804,"toc":10428},[9805,9813,9816,9820,9823,9826,9832,9836,9839,9886,9901,9904,9925,9928,9932,9938,9962,9972,9979,9984,9990,10003,10009,10017,10023,10071,10077,10102,10106,10113,10148,10154,10157,10160,10213,10216,10223,10237,10240,10257,10267,10291,10294,10301,10315,10326,10346,10358,10362,10365,10372,10378,10381,10384,10386,10389,10392,10422,10425],[10,9806,9807,9808,9812],{},"『",[1859,9809,9801],{"href":9810,"rel":9811},"https:\u002F\u002Fbook.impress.co.jp\u002Fbooks\u002F1121101138",[1863],"』を読了したため、本書を通して学んだことをまとめます。",[10,9814,9815],{},"まだ1周目で理解が浅い部分もあるため、Dockerを実際に使いながら必要に応じて追記していきます。",[43,9817,9819],{"id":9818},"dockerでホスト環境への影響を抑える","Dockerでホスト環境への影響を抑える",[10,9821,9822],{},"Dockerを利用すると、アプリケーションに必要なランタイムやライブラリをコンテナ内にまとめられます。",[10,9824,9825],{},"ホストOSへ依存関係を直接インストールする場面を減らせるため、開発環境を整理しやすくなります。また、DockerfileやComposeファイルを共有することで、チーム内で環境を再現しやすくなります。",[35,9827,9829],{"title":9828,"type":1312},"ホストOSから完全に独立するわけではない",[10,9830,9831],{},"コンテナはホストのカーネルやDocker Engineを利用します。ボリューム、ポート、CPUアーキテクチャなど、ホスト環境との接点がなくなるわけではありません。",[43,9833,9835],{"id":9834},"dockerコマンドで操作対象を明示する","Dockerコマンドで操作対象を明示する",[10,9837,9838],{},"Docker CLIには、操作対象を含めて記述するコマンドがあります。",[51,9840,9842],{"className":81,"code":9841,"language":83,"meta":57,"style":57},"docker container run nginx\ndocker image pull nginx\ndocker volume ls\ndocker network ls\n",[59,9843,9844,9857,9868,9877],{"__ignoreMap":57},[87,9845,9846,9848,9851,9854],{"class":89,"line":90},[87,9847,259],{"class":93},[87,9849,9850],{"class":97}," container",[87,9852,9853],{"class":97}," run",[87,9855,9856],{"class":97}," nginx\n",[87,9858,9859,9861,9863,9866],{"class":89,"line":634},[87,9860,259],{"class":93},[87,9862,405],{"class":97},[87,9864,9865],{"class":97}," pull",[87,9867,9856],{"class":97},[87,9869,9870,9872,9874],{"class":89,"line":1157},[87,9871,259],{"class":93},[87,9873,507],{"class":97},[87,9875,9876],{"class":97}," ls\n",[87,9878,9879,9881,9884],{"class":89,"line":1163},[87,9880,259],{"class":93},[87,9882,9883],{"class":97}," network",[87,9885,9876],{"class":97},[10,9887,9888,2394,9891,2394,9894,2394,9897,9900],{},[59,9889,9890],{},"container",[59,9892,9893],{},"image",[59,9895,9896],{},"volume",[59,9898,9899],{},"network","のように対象が明示されるため、何を操作するコマンドなのか把握しやすくなります。",[10,9902,9903],{},"一方で、次の短い形式も現在利用できます。",[51,9905,9907],{"className":81,"code":9906,"language":83,"meta":57,"style":57},"docker run nginx\ndocker pull nginx\n",[59,9908,9909,9917],{"__ignoreMap":57},[87,9910,9911,9913,9915],{"class":89,"line":90},[87,9912,259],{"class":93},[87,9914,9853],{"class":97},[87,9916,9856],{"class":97},[87,9918,9919,9921,9923],{"class":89,"line":634},[87,9920,259],{"class":93},[87,9922,9865],{"class":97},[87,9924,9856],{"class":97},[10,9926,9927],{},"短い形式を古いという理由だけで避ける必要はありません。学習時には対象を含む形式も知っておくと、CLIの構造を理解しやすいと感じました。",[43,9929,9931],{"id":9930},"docker-compose-v2を利用する","Docker Compose V2を利用する",[10,9933,9934,9935,1549],{},"現在のCompose CLIでは、ハイフンのない",[59,9936,9937],{},"docker compose",[51,9939,9941],{"className":81,"code":9940,"language":83,"meta":57,"style":57},"docker compose up\ndocker compose down\n",[59,9942,9943,9953],{"__ignoreMap":57},[87,9944,9945,9947,9950],{"class":89,"line":90},[87,9946,259],{"class":93},[87,9948,9949],{"class":97}," compose",[87,9951,9952],{"class":97}," up\n",[87,9954,9955,9957,9959],{"class":89,"line":634},[87,9956,259],{"class":93},[87,9958,9949],{"class":97},[87,9960,9961],{"class":97}," down\n",[10,9963,9964,9965,9968,9969,9971],{},"旧Compose V1で使われていた",[59,9966,9967],{},"docker-compose","とはコマンド形式が異なります。Docker DesktopにはCompose CLIが含まれているため、基本的には",[59,9970,9937],{},"を利用します。",[43,9973,9975,9976,1794],{"id":9974},"composeファイルはcomposeyamlを使う","Composeファイルは",[59,9977,9978],{},"compose.yaml",[10,9980,9981,9982,1286],{},"Composeファイルの推奨ファイル名は",[59,9983,9978],{},[51,9985,9988],{"className":9986,"code":9987,"language":56,"meta":57},[54],"compose.yaml\n",[59,9989,9987],{"__ignoreMap":57},[10,9991,9992,9995,9996,1282,9999,10002],{},[59,9993,9994],{},"compose.yml","も利用できます。また、",[59,9997,9998],{},"docker-compose.yaml",[59,10000,10001],{},"docker-compose.yml","も後方互換性のためサポートされています。",[10,10004,10005,10006,10008],{},"複数の候補が同じ場所にある場合は",[59,10007,9978],{},"が優先されるため、新しく作る場合はこの名前へ揃えると分かりやすくなります。",[43,10010,10012,10013,10016],{"id":10011},"トップレベルのversionは不要","トップレベルの",[59,10014,10015],{},"version","は不要",[10,10018,10019,10020,10022],{},"以前のComposeファイルでは、先頭に次のような",[59,10021,10015],{},"を書く例がありました。",[51,10024,10028],{"className":10025,"code":10026,"language":10027,"meta":57,"style":57},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","version: '3'\n\nservices:\n  web:\n    image: nginx\n","yaml",[59,10029,10030,10043,10047,10055,10062],{"__ignoreMap":57},[87,10031,10032,10034,10036,10038,10041],{"class":89,"line":90},[87,10033,10015],{"class":1911},[87,10035,2331],{"class":111},[87,10037,2060],{"class":111},[87,10039,10040],{"class":97},"3",[87,10042,2065],{"class":111},[87,10044,10045],{"class":89,"line":634},[87,10046,1172],{"emptyLinePlaceholder":647},[87,10048,10049,10052],{"class":89,"line":1157},[87,10050,10051],{"class":1911},"services",[87,10053,10054],{"class":111},":\n",[87,10056,10057,10060],{"class":89,"line":1163},[87,10058,10059],{"class":1911},"  web",[87,10061,10054],{"class":111},[87,10063,10064,10067,10069],{"class":89,"line":1169},[87,10065,10066],{"class":1911},"    image",[87,10068,2331],{"class":111},[87,10070,9856],{"class":97},[10,10072,10073,10074,10076],{},"現在、トップレベルの",[59,10075,10015],{},"は後方互換性のために残されたobsoleteな項目です。指定してもComposeは最新のスキーマでファイルを検証するため、新しいComposeファイルでは省略します。",[51,10078,10080],{"className":10025,"code":10079,"language":10027,"meta":57,"style":57},"services:\n  web:\n    image: nginx\n",[59,10081,10082,10088,10094],{"__ignoreMap":57},[87,10083,10084,10086],{"class":89,"line":90},[87,10085,10051],{"class":1911},[87,10087,10054],{"class":111},[87,10089,10090,10092],{"class":89,"line":634},[87,10091,10059],{"class":1911},[87,10093,10054],{"class":111},[87,10095,10096,10098,10100],{"class":89,"line":1157},[87,10097,10066],{"class":1911},[87,10099,2331],{"class":111},[87,10101,9856],{"class":97},[43,10103,10105],{"id":10104},"restart-policyは用途に合わせて設定する","restart policyは用途に合わせて設定する",[10,10107,10108,10109,10112],{},"Composeのサービスには、コンテナを再起動する条件を",[59,10110,10111],{},"restart","で設定できます。",[51,10114,10116],{"className":10025,"code":10115,"language":10027,"meta":57,"style":57},"services:\n  web:\n    image: nginx\n    restart: always\n",[59,10117,10118,10124,10130,10138],{"__ignoreMap":57},[87,10119,10120,10122],{"class":89,"line":90},[87,10121,10051],{"class":1911},[87,10123,10054],{"class":111},[87,10125,10126,10128],{"class":89,"line":634},[87,10127,10059],{"class":1911},[87,10129,10054],{"class":111},[87,10131,10132,10134,10136],{"class":89,"line":1157},[87,10133,10066],{"class":1911},[87,10135,2331],{"class":111},[87,10137,9856],{"class":97},[87,10139,10140,10143,10145],{"class":89,"line":1163},[87,10141,10142],{"class":1911},"    restart",[87,10144,2331],{"class":111},[87,10146,10147],{"class":97}," always\n",[10,10149,10150,10153],{},[59,10151,10152],{},"always","を指定したコンテナは、停止した場合やDockerデーモンが再起動した場合に再起動されます。",[10,10155,10156],{},"常時稼働が必要なサービスでは便利ですが、学習用コンテナへ一律に指定すると、Docker起動時に意図しないコンテナまで立ち上がることがあります。必要性を考えて設定することが大切です。",[10,10158,10159],{},"主なrestart policyには次があります。",[279,10161,10162,10172],{},[282,10163,10164],{},[285,10165,10166,10169],{},[288,10167,10168],{},"値",[288,10170,10171],{},"動作",[296,10173,10174,10184,10194,10203],{},[285,10175,10176,10181],{},[301,10177,10178],{},[59,10179,10180],{},"no",[301,10182,10183],{},"自動的に再起動しない",[285,10185,10186,10191],{},[301,10187,10188],{},[59,10189,10190],{},"on-failure",[301,10192,10193],{},"エラー終了した場合に再起動する",[285,10195,10196,10200],{},[301,10197,10198],{},[59,10199,10152],{},[301,10201,10202],{},"停止した場合に常に再起動する",[285,10204,10205,10210],{},[301,10206,10207],{},[59,10208,10209],{},"unless-stopped",[301,10211,10212],{},"明示的に停止されていない限り再起動する",[43,10214,10215],{"id":10215},"コンテナのログを確認する",[10,10217,10218,10219,10222],{},"Composeで起動したサービスのログは",[59,10220,10221],{},"docker compose logs","で確認できます。",[51,10224,10226],{"className":81,"code":10225,"language":83,"meta":57,"style":57},"docker compose logs\n",[59,10227,10228],{"__ignoreMap":57},[87,10229,10230,10232,10234],{"class":89,"line":90},[87,10231,259],{"class":93},[87,10233,9949],{"class":97},[87,10235,10236],{"class":97}," logs\n",[10,10238,10239],{},"サービスを指定すると、対象のログだけを表示できます。",[51,10241,10243],{"className":81,"code":10242,"language":83,"meta":57,"style":57},"docker compose logs web\n",[59,10244,10245],{"__ignoreMap":57},[87,10246,10247,10249,10251,10254],{"class":89,"line":90},[87,10248,259],{"class":93},[87,10250,9949],{"class":97},[87,10252,10253],{"class":97}," logs",[87,10255,10256],{"class":97}," web\n",[10,10258,10259,10260,10263,10264,1549],{},"ログを継続して追いかける場合は",[59,10261,10262],{},"--follow","、末尾の行数を限定する場合は",[59,10265,10266],{},"--tail",[51,10268,10270],{"className":81,"code":10269,"language":83,"meta":57,"style":57},"docker compose logs --follow --tail 100 web\n",[59,10271,10272],{"__ignoreMap":57},[87,10273,10274,10276,10278,10280,10283,10286,10289],{"class":89,"line":90},[87,10275,259],{"class":93},[87,10277,9949],{"class":97},[87,10279,10253],{"class":97},[87,10281,10282],{"class":97}," --follow",[87,10284,10285],{"class":97}," --tail",[87,10287,10288],{"class":104}," 100",[87,10290,10256],{"class":97},[43,10292,10293],{"id":10293},"イメージを再ビルドする",[10,10295,10296,10297,10300],{},"Composeでイメージをビルドするには",[59,10298,10299],{},"docker compose build","を使います。",[51,10302,10304],{"className":81,"code":10303,"language":83,"meta":57,"style":57},"docker compose build\n",[59,10305,10306],{"__ignoreMap":57},[87,10307,10308,10310,10312],{"class":89,"line":90},[87,10309,259],{"class":93},[87,10311,9949],{"class":97},[87,10313,10314],{"class":97}," build\n",[10,10316,10317,10318,10321,10322,10325],{},"コンテナの起動前にビルドも実行したい場合は、",[59,10319,10320],{},"docker compose up","へ",[59,10323,10324],{},"--build","を付けられます。",[51,10327,10329],{"className":81,"code":10328,"language":83,"meta":57,"style":57},"docker compose up --detach --build\n",[59,10330,10331],{"__ignoreMap":57},[87,10332,10333,10335,10337,10340,10343],{"class":89,"line":90},[87,10334,259],{"class":93},[87,10336,9949],{"class":97},[87,10338,10339],{"class":97}," up",[87,10341,10342],{"class":97}," --detach",[87,10344,10345],{"class":97}," --build\n",[10,10347,10348,10350,10351,1405,10354,10357],{},[59,10349,10320],{},"は、サービスの設定やイメージが変更されている場合にコンテナを再作成します。ただし、Dockerfileやビルド対象を確実に再ビルドしてから起動したい場合は、",[59,10352,10353],{},"build",[59,10355,10356],{},"up --build","を明示すると意図が分かりやすくなります。",[43,10359,10361],{"id":10360},"dev-containerで開発環境をコンテナ化する","Dev Containerで開発環境をコンテナ化する",[10,10363,10364],{},"VS CodeのDev Containers拡張機能を使うと、コンテナを開発環境として利用できます。",[10,10366,10367,10368,10371],{},"プロジェクト内の",[59,10369,10370],{},".devcontainer\u002Fdevcontainer.json","へ設定を記述し、コンテナ内のランタイム、ツール、VS Code拡張機能などを揃えられます。",[51,10373,10376],{"className":10374,"code":10375,"language":56,"meta":57},[54],".devcontainer\u002F\n  devcontainer.json\n",[59,10377,10375],{"__ignoreMap":57},[10,10379,10380],{},"ソースコードをコンテナへマウントし、ターミナル、補完、コードナビゲーション、デバッグなどを普段のVS Codeと近い操作感で利用できます。",[10,10382,10383],{},"環境構築手順を文章だけで共有するよりも、実行環境そのものを設定として共有できる点が便利だと感じました。",[43,10385,574],{"id":574},[10,10387,10388],{},"本書を通して、Dockerの基本操作だけでなく、Composeによる複数コンテナの管理や、開発環境をコンテナ化する考え方を学べました。",[10,10390,10391],{},"特に、次の点を今後の開発でも意識したいです。",[1787,10393,10394,10397,10402,10407,10413,10416,10419],{},[582,10395,10396],{},"Docker CLIで何を操作しているか理解する",[582,10398,10399,10400,1794],{},"Compose V2の",[59,10401,9937],{},[582,10403,9975,10404,10406],{},[59,10405,9978],{},"へ揃える",[582,10408,10409,10410,10412],{},"不要な",[59,10411,10015],{},"を記述しない",[582,10414,10415],{},"restart policyを用途に合わせて設定する",[582,10417,10418],{},"ログ確認と再ビルドのコマンドを使い分ける",[582,10420,10421],{},"Dev Containerで再現可能な開発環境を試す",[10,10423,10424],{},"Dockerはコマンドを覚えるだけでなく、イメージ、コンテナ、ボリューム、ネットワークの関係を実際に操作しながら理解していきたいです。",[630,10426,10427],{},"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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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}",{"title":57,"searchDepth":634,"depth":634,"links":10429},[10430,10431,10432,10433,10435,10436,10437,10438,10439,10440],{"id":9818,"depth":634,"text":9819},{"id":9834,"depth":634,"text":9835},{"id":9930,"depth":634,"text":9931},{"id":9974,"depth":634,"text":10434},"Composeファイルはcompose.yamlを使う",{"id":10011,"depth":634,"text":10011},{"id":10104,"depth":634,"text":10105},{"id":10215,"depth":634,"text":10215},{"id":10293,"depth":634,"text":10293},{"id":10360,"depth":634,"text":10361},{"id":574,"depth":634,"text":574},"『Docker&仮想サーバー完全入門』を読了したため、本書を通して学んだことをまとめます。",{},"\u002Fbooks\u002F2025\u002Forganize-learned-from-docker","2025-02-22","インプレス",{"title":9801,"description":10441},"books\u002F2025\u002Forganize-learned-from-docker",[654],"4hv6HyIEs4h6TVsIp3e5GZVdKj-xdL2YemAEAK3SW10",1786290122426]