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