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