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