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