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