diff --git a/404.html b/404.html new file mode 100644 index 00000000..4a5c1928 --- /dev/null +++ b/404.html @@ -0,0 +1,20 @@ + + + + + + ☻ itsyuimorii.space + + + + + + + + +

404

There's nothing here.
+ Take me home. +
+ + + diff --git a/assets/css/0.styles.8f3dca9f.css b/assets/css/0.styles.8f3dca9f.css new file mode 100644 index 00000000..c214af18 --- /dev/null +++ b/assets/css/0.styles.8f3dca9f.css @@ -0,0 +1 @@ +code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#282c34}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:3.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#3eaf7c}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;-webkit-user-select:none;user-select:none;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}#nprogress{pointer-events:none}#nprogress .bar{background:#3eaf7c;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #3eaf7c,0 0 5px #3eaf7c;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#3eaf7c transparent transparent #3eaf7c;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.algolia-search-wrapper>span{vertical-align:middle}.algolia-search-wrapper .algolia-autocomplete{line-height:normal}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu{background-color:#fff;border:1px solid #999;border-radius:4px;font-size:16px;margin:6px 0 0;padding:4px;text-align:left}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu:before{border-color:#999}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu [class*=ds-dataset-]{border:none;padding:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{border-bottom:1px solid #eaecef}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#2c815b}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion{border-color:#eaecef;padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header{padding:5px 10px;margin-top:0;background:#3eaf7c;color:#fff;font-weight:600}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background:hsla(0,0%,100%,.6)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--wrapper{padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--title{font-weight:600;margin-bottom:0;color:#2c3e50}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{vertical-align:top;padding:5px 7px 5px 5px;border-color:#eaecef;background:#f1f3f5}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{display:none}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column-text{color:#555}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-footer{border-color:#eaecef}.algolia-search-wrapper .algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--content{background-color:#e7edf3!important;color:#2c3e50}@media (min-width:719px){.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{float:none;width:150px;min-width:150px;display:table-cell}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{float:none;display:table-cell;width:100%;vertical-align:top}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .ds-dropdown-menu{min-width:515px!important}}@media (max-width:719px){.algolia-search-wrapper .ds-dropdown-menu{min-width:calc(100vw - 4rem)!important;max-width:calc(100vw - 4rem)!important}.algolia-search-wrapper .algolia-docsearch-suggestion--wrapper{padding:5px 7px 5px 5px!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column{padding:0!important;background:#fff!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column-text:after{content:" > ";font-size:10px;line-height:14.4px;display:inline-block;width:5px;margin:-3px 3px 0;vertical-align:middle}}.home{padding:3.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#3eaf7c;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #389d70}.home .hero .action-button:hover{background-color:#4abf8a}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#3eaf7c}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#3eaf7c}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.badge[data-v-15b7b770]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-15b7b770],.badge.tip[data-v-15b7b770],.badge[data-v-15b7b770]{background-color:#42b983}.badge.error[data-v-15b7b770]{background-color:#da5961}.badge.warn[data-v-15b7b770],.badge.warning[data-v-15b7b770],.badge.yellow[data-v-15b7b770]{background-color:#e7c000}.badge+.badge[data-v-15b7b770]{margin-left:5px}.theme-code-block[data-v-759a7d02]{display:none}.theme-code-block__active[data-v-759a7d02]{display:block}.theme-code-block>pre[data-v-759a7d02]{background-color:orange}.theme-code-group__nav[data-v-deefee04]{margin-bottom:-35px;background-color:#282c34;padding-bottom:22px;border-top-left-radius:6px;border-top-right-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__ul[data-v-deefee04]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__nav-tab[data-v-deefee04]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:hsla(0,0%,100%,.9);font-weight:600}.theme-code-group__nav-tab-active[data-v-deefee04]{border-bottom:1px solid #42b983}.pre-blank[data-v-deefee04]{color:#42b983}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-moz-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;animation-name:sbx-reset-in;animation-duration:.15s}@keyframes sbx-reset-in{0%{transform:translate3d(-20%,0,0);opacity:0}to{transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 012.966 2.966V20.5a2.967 2.967 0 01-2.966 2.964H78.988a2.967 2.967 0 01-2.966-2.964V3.897A2.961 2.961 0 0178.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 00-1.574-.199 5.7 5.7 0 00-.897.069 2.699 2.699 0 00-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 01-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 01-1.471-.636 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 011.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 011.82-.185 8.404 8.404 0 011.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 00-.384-.73 1.784 1.784 0 00-.724-.493 3.164 3.164 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 00-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 012.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 00-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 00-.814.24 1.46 1.46 0 00-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 01.233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 01-1.471-.635 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 012.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 00-.109-.875 1.873 1.873 0 00-.384-.731 1.784 1.784 0 00-.724-.492 3.165 3.165 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 00-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 012.073-.177zm-8.034-1.271a1.626 1.626 0 01-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 01-1.128 1.906 4.986 4.986 0 01-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 01-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 01-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 011.15-1.892 5.133 5.133 0 011.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 011.753 1.216 5.644 5.644 0 011.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 00-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 01-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 01-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 012.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 00-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 01-.582-.271 13.67 13.67 0 01-.55-.287 4.275 4.275 0 01-.567-.351 6.92 6.92 0 01-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 01-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 00-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 00-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 00-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 01-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 00-.978-.977h-2.28a.978.978 0 00-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 011.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 00-1.382 0l-.465.465a.973.973 0 000 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 00-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 01-4.49-4.482 4.488 4.488 0 014.49-4.482 4.488 4.488 0 014.489 4.482 4.484 4.484 0 01-4.49 4.482m0-10.85a6.363 6.363 0 100 12.729 6.37 6.37 0 006.372-6.368 6.358 6.358 0 00-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title,.dropdown-wrapper .mobile-dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:#2c3e50}.dropdown-wrapper .dropdown-title:hover,.dropdown-wrapper .mobile-dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow,.dropdown-wrapper .mobile-dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .mobile-dropdown-title{display:none;font-weight:600}.dropdown-wrapper .mobile-dropdown-title font-size inherit:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:1rem 1.5rem .45rem 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #3eaf7c;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{display:none}.dropdown-wrapper .mobile-dropdown-title{display:block}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#3eaf7c}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #46bd87}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#767676}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page{padding-bottom:2rem;display:block}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-heading.clickable:hover{color:#3eaf7c}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#3eaf7c}a.sidebar-link.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}} \ No newline at end of file diff --git a/assets/img/action.af11efbe.png b/assets/img/action.af11efbe.png new file mode 100644 index 00000000..b2698dcc Binary files /dev/null and b/assets/img/action.af11efbe.png differ diff --git a/assets/img/contenttypebuilder.24db04ba.png b/assets/img/contenttypebuilder.24db04ba.png new file mode 100644 index 00000000..306edd48 Binary files /dev/null and b/assets/img/contenttypebuilder.24db04ba.png differ diff --git a/assets/img/contenttypebuilder2.d73df612.png b/assets/img/contenttypebuilder2.d73df612.png new file mode 100644 index 00000000..30af1bde Binary files /dev/null and b/assets/img/contenttypebuilder2.d73df612.png differ diff --git a/assets/img/destrcturing.1503f4e8.png b/assets/img/destrcturing.1503f4e8.png new file mode 100644 index 00000000..984a7c3e Binary files /dev/null and b/assets/img/destrcturing.1503f4e8.png differ diff --git a/assets/img/errorobject.51c51d3f.png b/assets/img/errorobject.51c51d3f.png new file mode 100644 index 00000000..372fbb77 Binary files /dev/null and b/assets/img/errorobject.51c51d3f.png differ diff --git a/assets/img/gitrebase.175e6a7f.png b/assets/img/gitrebase.175e6a7f.png new file mode 100644 index 00000000..8cee5b84 Binary files /dev/null and b/assets/img/gitrebase.175e6a7f.png differ diff --git a/assets/img/heapandstack.5e7d479c.png b/assets/img/heapandstack.5e7d479c.png new file mode 100644 index 00000000..4767cde0 Binary files /dev/null and b/assets/img/heapandstack.5e7d479c.png differ diff --git a/assets/img/mapobject.7b1842a0.png b/assets/img/mapobject.7b1842a0.png new file mode 100644 index 00000000..05ea59ae Binary files /dev/null and b/assets/img/mapobject.7b1842a0.png differ diff --git a/assets/img/redux.e6057df8.png b/assets/img/redux.e6057df8.png new file mode 100644 index 00000000..5166886d Binary files /dev/null and b/assets/img/redux.e6057df8.png differ diff --git a/assets/img/reduxasync.0f79d5bf.png b/assets/img/reduxasync.0f79d5bf.png new file mode 100644 index 00000000..9acf6000 Binary files /dev/null and b/assets/img/reduxasync.0f79d5bf.png differ diff --git a/assets/img/search.83621669.svg b/assets/img/search.83621669.svg new file mode 100644 index 00000000..03d83913 --- /dev/null +++ b/assets/img/search.83621669.svg @@ -0,0 +1 @@ + diff --git a/assets/js/1.8d37d391.js b/assets/js/1.8d37d391.js new file mode 100644 index 00000000..89e82e91 --- /dev/null +++ b/assets/js/1.8d37d391.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1,12,14,21,22,25],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return s})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return h})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return p})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return k}));n(90);const s=/#.*$/,i=/\.(md|html)$/,r=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(s,"").replace(i,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function h(t){if(l(t))return t;const e=t.match(s),n=e?e[0]:"",i=a(t);return r.test(i)?t:i+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(s);if(e)return e[0]}(e);if(i&&n!==i)return!1;return a(t.path)===a(e)}function p(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const s=t.charAt(0);if("/"===s)return t;if("?"===s||"#"===s)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,s,i=1){if("string"==typeof e)return p(n,e,s);if(Array.isArray(e))return Object.assign(p(n,e[0],s),{title:e[1]});{const r=e.children||[];return 0===r.length&&e.path?Object.assign(p(n,e.path,s),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:r.map(e=>t(e,n,s,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function g(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function k(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){"use strict";n.r(e);var s=n(239),i={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(s.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(s.g)(this.link)||Object(s.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(s.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(s.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},r=n(14),o=Object(r.a)(i,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=o.exports},242:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(243),n(14)),r=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},243:function(t,e,n){"use strict";n(240)},244:function(t,e,n){},247:function(t,e,n){},251:function(t,e,n){"use strict";n(244)},254:function(t,e,n){"use strict";n.r(e);var s=n(241),i=n(242),r=n(91),o=n.n(r),a={name:"DropdownLink",components:{NavLink:s.default,DropdownTransition:i.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>o()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(251),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,s){return e("li",{key:n.link||s,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(s){return e("li",{key:s.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},257:function(t,e,n){"use strict";n(247)},258:function(t,e,n){},265:function(t,e,n){"use strict";n.r(e);var s=n(254),i=n(239),r={name:"NavLinks",components:{NavLink:n(241).default,DropdownLink:s.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,s=this.$site.themeConfig.locales||{},i={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(i=>{const r=t[i],o=s[i]&&s[i].label||r.lang;let a;return r.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,i),n.some(t=>t.path===a)||(a=i)),{text:o,link:a}})};return[...this.userNav,i]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(i.j)(t),{items:(t.items||[]).map(i.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n{let s=i()(e,"title","");return i()(e,"frontmatter.tags")&&(s+=" "+e.frontmatter.tags.join(" ")),n&&(s+=" "+n),o(t,s)};const o=(t,e)=>{const n=t=>t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),s=new RegExp("[^\0-]"),i=t.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t);if(s.test(t))return i.some(t=>e.toLowerCase().indexOf(t)>-1);{const s=t.endsWith(" ");return new RegExp(i.map((t,e)=>i.length!==e+1||s?`(?=.*\\b${n(t)}\\b)`:`(?=.*\\b${n(t)})`).join("")+".+","gi").test(e)}};var a={name:"SearchBox",data:()=>({query:"",focused:!1,focusIndex:0,placeholder:void 0}),computed:{showSuggestions(){return this.focused&&this.suggestions&&this.suggestions.length},suggestions(){const t=this.query.trim().toLowerCase();if(!t)return;const{pages:e}=this.$site,n=this.$site.themeConfig.searchMaxSuggestions||5,s=this.$localePath,i=[];for(let o=0;o=n);o++){const a=e[o];if(this.getPageLocalePath(a)===s&&this.isSearchable(a))if(r(t,a))i.push(a);else if(a.headers)for(let e=0;e=n);e++){const n=a.headers[e];n.title&&r(t,a,n.title)&&i.push(Object.assign({},a,{path:a.path+"#"+n.slug,header:n}))}}return i},alignRight(){return(this.$site.themeConfig.nav||[]).length+(this.$site.repo?1:0)<=2}},mounted(){this.placeholder=this.$site.themeConfig.searchPlaceholder||"",document.addEventListener("keydown",this.onHotkey)},beforeDestroy(){document.removeEventListener("keydown",this.onHotkey)},methods:{getPageLocalePath(t){for(const e in this.$site.locales||{})if("/"!==e&&0===t.path.indexOf(e))return e;return"/"},isSearchable(t){let e=null;return null===e||(e=Array.isArray(e)?e:new Array(e),e.filter(e=>t.path.match(e)).length>0)},onHotkey(t){t.srcElement===document.body&&["s","/"].includes(t.key)&&(this.$refs.input.focus(),t.preventDefault())},onUp(){this.showSuggestions&&(this.focusIndex>0?this.focusIndex--:this.focusIndex=this.suggestions.length-1)},onDown(){this.showSuggestions&&(this.focusIndex "+t._s(n.header.title))]):t._e()])])})),0):t._e()])}),[],!1,null,null,null).exports,c=n(283),h=n(265);function f(t,e){return t.ownerDocument.defaultView.getComputedStyle(t,null)[e]}var p={name:"Navbar",components:{SidebarButton:c.default,NavLinks:h.default,SearchBox:u,AlgoliaSearchBox:{}},data:()=>({linksWrapMaxWidth:null}),computed:{algolia(){return this.$themeLocaleConfig.algolia||this.$site.themeConfig.algolia||{}},isAlgoliaSearch(){return this.algolia&&this.algolia.apiKey&&this.algolia.indexName}},mounted(){const t=parseInt(f(this.$el,"paddingLeft"))+parseInt(f(this.$el,"paddingRight")),e=()=>{document.documentElement.clientWidth<719?this.linksWrapMaxWidth=null:this.linksWrapMaxWidth=this.$el.offsetWidth-t-(this.$refs.siteName&&this.$refs.siteName.offsetWidth||0)};e(),window.addEventListener("resize",e,!1)}},d=(n(290),Object(l.a)(p,(function(){var t=this,e=t._self._c;return e("header",{staticClass:"navbar"},[e("SidebarButton",{on:{"toggle-sidebar":function(e){return t.$emit("toggle-sidebar")}}}),t._v(" "),e("RouterLink",{staticClass:"home-link",attrs:{to:t.$localePath}},[t.$site.themeConfig.logo?e("img",{staticClass:"logo",attrs:{src:t.$withBase(t.$site.themeConfig.logo),alt:t.$siteTitle}}):t._e(),t._v(" "),t.$siteTitle?e("span",{ref:"siteName",staticClass:"site-name",class:{"can-hide":t.$site.themeConfig.logo}},[t._v(t._s(t.$siteTitle))]):t._e()]),t._v(" "),e("div",{staticClass:"links",style:t.linksWrapMaxWidth?{"max-width":t.linksWrapMaxWidth+"px"}:{}},[t.isAlgoliaSearch?e("AlgoliaSearchBox",{attrs:{options:t.algolia}}):!1!==t.$site.themeConfig.search&&!1!==t.$page.frontmatter.search?e("SearchBox"):t._e(),t._v(" "),e("NavLinks",{staticClass:"can-hide"})],1)],1)}),[],!1,null,null,null));e.default=d.exports}}]); \ No newline at end of file diff --git a/assets/js/10.d8df69df.js b/assets/js/10.d8df69df.js new file mode 100644 index 00000000..4debec43 --- /dev/null +++ b/assets/js/10.d8df69df.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[10,3,12,14,18,21,25],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return h})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return g}));n(90);const i=/#.*$/,s=/\.(md|html)$/,r=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(s,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",s=o(t);return r.test(s)?t:s+".html"+n}function h(t,e){const n=decodeURIComponent(t.hash),s=function(t){const e=t.match(i);if(e)return e[0]}(e);if(s&&n!==s)return!1;return o(t.path)===o(e)}function d(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const s=e.split("/");n&&s[s.length-1]||s.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,s=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{const r=e.children||[];return 0===r.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:r.map(e=>t(e,n,i,s+1)),collapsable:!1!==e.collapsable}}}(t,s,n)):[]}return[]}function b(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){"use strict";n.r(e);var i=n(239),s={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},r=n(14),a=Object(r.a)(s,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=a.exports},242:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},s=(n(243),n(14)),r=Object(s.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},243:function(t,e,n){"use strict";n(240)},244:function(t,e,n){},245:function(t,e,n){},247:function(t,e,n){},250:function(t,e,n){},251:function(t,e,n){"use strict";n(244)},252:function(t,e,n){"use strict";n(245)},253:function(t,e,n){"use strict";n.r(e);var i=n(266),s=n(255),r=n(239);function a(t,e){if("group"===e.type){const n=e.path&&Object(r.e)(t,e.path),i=e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(r.e)(t,e.path));return n||i}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:i.default,SidebarLink:s.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(r.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,i){return e("li",{key:i},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:i===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(i)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},254:function(t,e,n){"use strict";n.r(e);var i=n(241),s=n(242),r=n(91),a=n.n(r),o={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:s.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>a()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(251),n(14)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},255:function(t,e,n){"use strict";n.r(e);var i=n(239);function s(t,e,n,i,s){const r={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:i,"sidebar-link":!0}};return s>2&&(r.style={"padding-left":s+"rem"}),t("RouterLink",r,n)}function r(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(i.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[s(t,n+"#"+e.slug,e.title,u,e.level-1),r(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(i.e)(a,u.path),h="auto"===u.type?p||u.children.some(t=>Object(i.e)(a,u.basePath+"#"+t.slug)):p,d="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):s(t,u.path,u.title||u.path,h),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[d,r(t,u.children,u.basePath,a,f)];if((h||b)&&u.headers&&!i.d.test(u.path)){return[d,r(t,Object(i.c)(u.headers),u.path,a,f)]}return d}},o=(n(252),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);e.default=l.exports},257:function(t,e,n){"use strict";n(247)},263:function(t,e,n){"use strict";n(250)},264:function(t,e,n){},265:function(t,e,n){"use strict";n.r(e);var i=n(254),s=n(239),r={name:"NavLinks",components:{NavLink:n(241).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},s={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(s=>{const r=t[s],a=i[s]&&i[s].label||r.lang;let o;return r.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,s),n.some(t=>t.path===o)||(o=s)),{text:a,link:o}})};return[...this.userNav,s]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(s.j)(t),{items:(t.items||[]).map(s.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;nfunction t(e,n,r,i=1){if("string"==typeof e)return d(n,e,r);if(Array.isArray(e))return Object.assign(d(n,e[0],r),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function g(t){const e=v(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function v(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},246:function(t,e){t.exports=function(t){return null==t}},248:function(t,e,n){},249:function(t,e,n){},259:function(t,e,n){"use strict";n(248)},260:function(t,e,n){var r=n(11),i=n(4),a=n(10);t.exports=function(t){return"string"==typeof t||!i(t)&&a(t)&&"[object String]"==r(t)}},261:function(t,e,n){"use strict";n(249)},262:function(t,e,n){},267:function(t,e,n){"use strict";n.r(e);var r=n(246),i=n.n(r),a=n(239),s={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=i()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:n="",docsBranch:r="master",docsRepo:a=e}=this.$site.themeConfig;return t&&a&&this.$page.relativePath?this.createEditLink(e,a,n,r,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,n,r,i){if(/bitbucket.org/.test(e)){return e.replace(a.a,"")+"/src"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i+`?mode=edit&spa=0&at=${r}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(a.a,"")+"/-/edit"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i}return(a.i.test(e)?e:"https://github.com/"+e).replace(a.a,"")+"/edit"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i}}},o=(n(259),n(14)),u=Object(o.a)(s,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=u.exports},268:function(t,e,n){"use strict";n.r(e);n(90);var r=n(239),i=n(260),a=n.n(i),s=n(246),o=n.n(s),u={name:"PageNav",props:["sidebarItems"],computed:{prev(){return l(c.PREV,this)},next(){return l(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return p(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return p(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function l(t,{$themeConfig:e,$page:n,$route:i,$site:s,sidebarItems:u}){const{resolveLink:c,getThemeLinkConfig:l,getPageLinkConfig:p}=t,f=l(e),d=p(n),h=o()(d)?f:d;return!1===h?void 0:a()(h)?Object(r.k)(s.pages,h,i.path):c(n,u)}function p(t,e,n){const r=[];!function t(e,n){for(let r=0,i=e.length;rfunction t(e,n,i,r=1){if("string"==typeof e)return f(n,e,i);if(Array.isArray(e))return Object.assign(f(n,e[0],i),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(f(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){"use strict";n.r(e);var i=n(239),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=n(14),a=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=a.exports},242:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(243),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},243:function(t,e,n){"use strict";n(240)},244:function(t,e,n){},247:function(t,e,n){},251:function(t,e,n){"use strict";n(244)},254:function(t,e,n){"use strict";n.r(e);var i=n(241),r=n(242),s=n(91),a=n.n(s),o={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:r.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>a()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(251),n(14)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},257:function(t,e,n){"use strict";n(247)},265:function(t,e,n){"use strict";n.r(e);var i=n(254),r=n(239),s={name:"NavLinks",components:{NavLink:n(241).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},r={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(r=>{const s=t[r],a=i[r]&&i[r].label||s.lang;let o;return s.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,r),n.some(t=>t.path===o)||(o=r)),{text:a,link:o}})};return[...this.userNav,r]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(r.j)(t),{items:(t.items||[]).map(r.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n({placeholder:void 0}),watch:{$lang(e){this.update(this.options,e)},options(e){this.update(e,this.$lang)}},mounted(){this.initialize(this.options,this.$lang),this.placeholder=this.$site.themeConfig.searchPlaceholder||""},methods:{initialize(e,t){Promise.all([Promise.all([a.e(0),a.e(9)]).then(a.t.bind(null,306,7)),Promise.all([a.e(0),a.e(9)]).then(a.t.bind(null,307,7))]).then(([a])=>{a=a.default;const{algoliaOptions:i={}}=e;a(Object.assign({},e,{inputSelector:"#algolia-search-input",algoliaOptions:{...i,facetFilters:["lang:"+t].concat(i.facetFilters||[])},handleSelected:(e,t,a)=>{const{pathname:i,hash:n}=new URL(a.url),r=i.replace(this.$site.base,"/"),s=decodeURIComponent(n);this.$router.push(`${r}${s}`)}}))})},update(e,t){this.$el.innerHTML='',this.initialize(e,t)}}},n=(a(288),a(14)),r=Object(n.a)(i,(function(){var e=this._self._c;return e("form",{staticClass:"algolia-search-wrapper search-box",attrs:{id:"search-form",role:"search"}},[e("input",{staticClass:"search-query",attrs:{id:"algolia-search-input",placeholder:this.placeholder}})])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/14.09112e04.js b/assets/js/14.09112e04.js new file mode 100644 index 00000000..309cee7a --- /dev/null +++ b/assets/js/14.09112e04.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[14,21,25],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return b})),n.d(e,"j",(function(){return g}));n(90);const i=/#.*$/,r=/\.(md|html)$/,s=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(i,"").replace(r,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",r=a(t);return s.test(r)?t:r+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return a(t.path)===a(e)}function h(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,r=1){if("string"==typeof e)return h(n,e,i);if(Array.isArray(e))return Object.assign(h(n,e[0],i),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){"use strict";n.r(e);var i=n(239),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=n(14),o=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=o.exports},242:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(243),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},243:function(t,e,n){"use strict";n(240)},244:function(t,e,n){},251:function(t,e,n){"use strict";n(244)},254:function(t,e,n){"use strict";n.r(e);var i=n(241),r=n(242),s=n(91),o=n.n(s),a={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:r.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>o()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(251),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/15.2d87bde7.js b/assets/js/15.2d87bde7.js new file mode 100644 index 00000000..77d5618f --- /dev/null +++ b/assets/js/15.2d87bde7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[15],{239:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return o})),e.d(n,"i",(function(){return a})),e.d(n,"f",(function(){return u})),e.d(n,"g",(function(){return c})),e.d(n,"h",(function(){return p})),e.d(n,"b",(function(){return l})),e.d(n,"e",(function(){return f})),e.d(n,"k",(function(){return h})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return v})),e.d(n,"j",(function(){return b}));e(90);const r=/#.*$/,i=/\.(md|html)$/,o=/\/$/,a=/^[a-z]+:/i;function s(t){return decodeURI(t).replace(r,"").replace(i,"")}function u(t){return a.test(t)}function c(t){return/^mailto:/.test(t)}function p(t){return/^tel:/.test(t)}function l(t){if(u(t))return t;const n=t.match(r),e=n?n[0]:"",i=s(t);return o.test(i)?t:i+".html"+e}function f(t,n){const e=decodeURIComponent(t.hash),i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return s(t.path)===s(n)}function h(t,n,e){if(u(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const o=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(n,e,r,i=1){if("string"==typeof n)return h(e,n,r);if(Array.isArray(n))return Object.assign(h(e,n[0],r),{title:n[1]});{const o=n.children||[];return 0===o.length&&n.path?Object.assign(h(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,initialOpenGroupIndex:n.initialOpenGroupIndex,children:o.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(t,i,e)):[]}return[]}function g(t){const n=v(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:n.map(n=>({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}function v(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},246:function(t,n){t.exports=function(t){return null==t}},249:function(t,n,e){},260:function(t,n,e){var r=e(11),i=e(4),o=e(10);t.exports=function(t){return"string"==typeof t||!i(t)&&o(t)&&"[object String]"==r(t)}},261:function(t,n,e){"use strict";e(249)},268:function(t,n,e){"use strict";e.r(n);e(90);var r=e(239),i=e(260),o=e.n(i),a=e(246),s=e.n(a),u={name:"PageNav",props:["sidebarItems"],computed:{prev(){return p(c.PREV,this)},next(){return p(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,n){return l(t,n,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,n){return l(t,n,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function p(t,{$themeConfig:n,$page:e,$route:i,$site:a,sidebarItems:u}){const{resolveLink:c,getThemeLinkConfig:p,getPageLinkConfig:l}=t,f=p(n),h=l(e),d=s()(h)?f:h;return!1===d?void 0:o()(d)?Object(r.k)(a.pages,d,i.path):c(e,u)}function l(t,n,e){const r=[];!function t(n,e){for(let r=0,i=n.length;rfunction t(e,n,i,r=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},241:function(t,e,n){"use strict";n.r(e);var i=n(239),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},a=n(14),s=Object(a.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=s.exports},256:function(t,e,n){},269:function(t,e,n){"use strict";n(256)},280:function(t,e,n){"use strict";n.r(e);var i={name:"Home",components:{NavLink:n(241).default},computed:{data(){return this.$page.frontmatter},actionLink(){return{link:this.data.actionLink,text:this.data.actionText}}}},r=(n(269),n(14)),a=Object(r.a)(i,(function(){var t=this,e=t._self._c;return e("main",{staticClass:"home",attrs:{"aria-labelledby":null!==t.data.heroText?"main-title":null}},[e("header",{staticClass:"hero"},[t.data.heroImage?e("img",{attrs:{src:t.$withBase(t.data.heroImage),alt:t.data.heroAlt||"hero"}}):t._e(),t._v(" "),null!==t.data.heroText?e("h1",{attrs:{id:"main-title"}},[t._v("\n "+t._s(t.data.heroText||t.$title||"Hello")+"\n ")]):t._e(),t._v(" "),null!==t.data.tagline?e("p",{staticClass:"description"},[t._v("\n "+t._s(t.data.tagline||t.$description||"Welcome to your VuePress site")+"\n ")]):t._e(),t._v(" "),t.data.actionText&&t.data.actionLink?e("p",{staticClass:"action"},[e("NavLink",{staticClass:"action-button",attrs:{item:t.actionLink}})],1):t._e()]),t._v(" "),t.data.features&&t.data.features.length?e("div",{staticClass:"features"},t._l(t.data.features,(function(n,i){return e("div",{key:i,staticClass:"feature"},[e("h2",[t._v(t._s(n.title))]),t._v(" "),e("p",[t._v(t._s(n.details))])])})),0):t._e(),t._v(" "),e("Content",{staticClass:"theme-default-content custom"}),t._v(" "),t.data.footer?e("div",{staticClass:"footer"},[t._v("\n "+t._s(t.data.footer)+"\n ")]):e("Content",{staticClass:"footer",attrs:{"slot-key":"footer"}})],1)}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/17.3dbcb51f.js b/assets/js/17.3dbcb51f.js new file mode 100644 index 00000000..affb29da --- /dev/null +++ b/assets/js/17.3dbcb51f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return c})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return d})),n.d(e,"e",(function(){return p})),n.d(e,"k",(function(){return f})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return b}));n(90);const i=/#.*$/,r=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(r,"")}function c(t){return s.test(t)}function u(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function d(t){if(c(t))return t;const e=t.match(i),n=e?e[0]:"",r=o(t);return a.test(r)?t:r+".html"+n}function p(t,e){const n=decodeURIComponent(t.hash),r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return o(t.path)===o(e)}function f(t,e,n){if(c(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,r=1){if("string"==typeof e)return f(n,e,i);if(Array.isArray(e))return Object.assign(f(n,e[0],i),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(f(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function g(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},246:function(t,e){t.exports=function(t){return null==t}},248:function(t,e,n){},259:function(t,e,n){"use strict";n(248)},267:function(t,e,n){"use strict";n.r(e);var i=n(246),r=n.n(i),a=n(239),s={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=r()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:n="",docsBranch:i="master",docsRepo:a=e}=this.$site.themeConfig;return t&&a&&this.$page.relativePath?this.createEditLink(e,a,n,i,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,n,i,r){if(/bitbucket.org/.test(e)){return e.replace(a.a,"")+"/src"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r+`?mode=edit&spa=0&at=${i}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(a.a,"")+"/-/edit"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r}return(a.i.test(e)?e:"https://github.com/"+e).replace(a.a,"")+"/edit"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r}}},o=(n(259),n(14)),c=Object(o.a)(s,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/18.4c170722.js b/assets/js/18.4c170722.js new file mode 100644 index 00000000..07ed4beb --- /dev/null +++ b/assets/js/18.4c170722.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return o})),n.d(e,"g",(function(){return c})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(90);const r=/#.*$/,i=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function u(t){return decodeURI(t).replace(r,"").replace(i,"")}function o(t){return s.test(t)}function c(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function p(t){if(o(t))return t;const e=t.match(r),n=e?e[0]:"",i=u(t);return a.test(i)?t:i+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return u(t.path)===u(e)}function d(t,e,n){if(o(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,r,i=1){if("string"==typeof e)return d(n,e,r);if(Array.isArray(e))return Object.assign(d(n,e[0],r),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function b(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},245:function(t,e,n){},252:function(t,e,n){"use strict";n(245)},255:function(t,e,n){"use strict";n.r(e);var r=n(239);function i(t,e,n,r,i){const a={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}};return i>2&&(a.style={"padding-left":i+"rem"}),t("RouterLink",a,n)}function a(t,e,n,s,u,o=1){return!e||o>u?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(r.e)(s,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,c,e.level-1),a(t,e.children,n,s,u,o+1)])}))}var s={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:s,$themeConfig:u,$themeLocaleConfig:o},props:{item:c,sidebarDepth:l}}){const p=Object(r.e)(s,c.path),f="auto"===c.type?p||c.children.some(t=>Object(r.e)(s,c.basePath+"#"+t.slug)):p,d="external"===c.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,f),h=[e.frontmatter.sidebarDepth,l,o.sidebarDepth,u.sidebarDepth,1].find(t=>void 0!==t),b=o.displayAllHeaders||u.displayAllHeaders;if("auto"===c.type)return[d,a(t,c.children,c.basePath,s,h)];if((f||b)&&c.headers&&!r.d.test(c.path)){return[d,a(t,Object(r.c)(c.headers),c.path,s,h)]}return d}},u=(n(252),n(14)),o=Object(u.a)(s,void 0,void 0,!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/19.1b72b4a4.js b/assets/js/19.1b72b4a4.js new file mode 100644 index 00000000..aaa711c4 --- /dev/null +++ b/assets/js/19.1b72b4a4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{297:function(t,s,a){t.exports=a.p+"assets/img/heapandstack.5e7d479c.png"},298:function(t,s,a){t.exports=a.p+"assets/img/destrcturing.1503f4e8.png"},299:function(t,s,a){t.exports=a.p+"assets/img/mapobject.7b1842a0.png"},339:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-javascript-深い理解と実践"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-javascript-深い理解と実践"}},[t._v("#")]),t._v(" ⚪️ JavaScript 深い理解と実践")]),t._v(" "),s("h2",{attrs:{id:"🔶-reference-vs-primitive"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-reference-vs-primitive"}},[t._v("#")]),t._v(" 🔶 Reference vs Primitive")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.youtube.com/watch?v=9ooYYRLdg_g&t=102s",target:"_blank",rel:"noopener noreferrer"}},[t._v("Reference vs Primitive Values/ Types"),s("OutboundLink")],1)])]),t._v(" "),s("blockquote",[s("p",[t._v("In JavaScript, "),s("strong",[t._v("objects")]),t._v(" and "),s("strong",[t._v("arrays")]),t._v(" are examples of "),s("em",[t._v("reference")]),t._v(" types, which are distinct from "),s("strong",[t._v("primitive types")]),t._v(" like "),s("code",[t._v("strings")]),t._v("and "),s("code",[t._v("Boolean")]),t._v(", "),s("code",[t._v("numbers")]),t._v(", "),s("code",[t._v("undefined")]),t._v(", "),s("code",[t._v("Null")]),t._v(".")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(297),alt:"heapandstack"}})]),t._v(" "),s("h3",{attrs:{id:"▫️-reference-types-in-javascript"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-reference-types-in-javascript"}},[t._v("#")]),t._v(" ▫️ "),s("strong",[t._v("Reference Types in JavaScript:")])]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("Objects and Arrays:")])]),t._v(" "),s("ul",[s("li",[t._v("Objects, like the "),s("code",[t._v("person")]),t._v(" object, are reference types.")]),t._v(" "),s("li",[t._v("They can hold properties with primitive values or other reference types.")]),t._v(" "),s("li",[t._v("Nesting of objects or arrays inside a reference type doesn't change its reference type nature.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Hobbies Array:")])]),t._v(" "),s("ul",[s("li",[t._v("The "),s("code",[t._v("hobbies")]),t._v(" array, though holding strings (primitive values), is a reference type.")]),t._v(" "),s("li",[t._v("Arrays in JavaScript are always considered reference types.")])])])]),t._v(" "),s("p",[s("strong",[t._v("Difference in Memory Management:")])]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("Memory Types:")])]),t._v(" "),s("ul",[s("li",[t._v("JavaScript uses two types of memory: The Stack and the Heap.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Stack Memory:")])]),t._v(" "),s("ul",[s("li",[t._v("The stack is easy-to-access memory, managing items in a stack-like structure.")]),t._v(" "),s("li",[t._v("Suitable for items with known sizes in advance (numbers, strings, booleans).")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Heap Memory:")])]),t._v(" "),s("ul",[s("li",[t._v("The heap is used for items with dynamic · s and structures, like objects and arrays.")]),t._v(" "),s("li",[t._v("Objects and arrays go into the heap since they can be mutated and change at runtime.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Pointer Mechanism:")])]),t._v(" "),s("ul",[s("li",[t._v("Each heap item has an exact address stored in a pointer.")]),t._v(" "),s("li",[t._v("The pointer, pointing at the item in the heap, is stored on the stack.")])])])]),t._v(" "),s("h3",{attrs:{id:"▫️-strange-behavior-of-reference-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-strange-behavior-of-reference-types"}},[t._v("#")]),t._v(' ▫️ Strange Behavior of "Reference Types"')]),t._v(" "),s("ul",[s("li",[t._v("What's actually stored in the person variable in the following snippet?\nb. "),s("code",[t._v("var person = { name: 'Max' }")])])]),t._v(" "),s("p",[t._v("It's b. A pointer to the person object is stored in the variable. The same would be the case for the hobbies array.")]),t._v(" "),s("ul",[s("li",[t._v("What does the following code spit out then?")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Max"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" newPerson "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nnewPerson"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Anna"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What does this line print? 'Anna'")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("strong",[t._v("Why?")])]),t._v(" "),s("ul",[s("li",[t._v("Because you never copied the person object itself to newPerson.")]),t._v(" "),s("li",[t._v("You only copied the pointer!")]),t._v(" "),s("li",[t._v("It still points at the same address in memory though. Hence changing "),s("code",[t._v("newPerson.name")]),t._v(" also changes "),s("code",[t._v("person.name")]),t._v(" because "),s("code",[t._v("newPerson")]),t._v(" points at the exactly same object!")])])])]),t._v(" "),s("h3",{attrs:{id:"▫️-how-to-copy-objects-and-arrays"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-how-to-copy-objects-and-arrays"}},[t._v("#")]),t._v(" ▫️ "),s("strong",[t._v("How to Copy Objects and Arrays:")])]),t._v(" "),s("p",[t._v("Now that we know that we only copy the pointer - how can we actually copy the value behind the pointer? The actual object or array?")]),t._v(" "),s("p",[t._v("You basically need to construct a new object or array and immediately fill it with the properties or elements of the old object or array.")]),t._v(" "),s("p",[t._v("You got multiple ways of doing this - also depending on which kind of JavaScript version you're using (during development).")]),t._v(" "),s("p",[t._v("Here are the two most popular approaches for arrays:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("Use the "),s("code",[t._v("slice()")]),t._v(" is a standard array method provided by JavaScript. You can check out its full documentation here.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" hobbies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sports"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cooking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" copiedHobbies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" hobbies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("p",[t._v("It basically returns a "),s("em",[t._v("new array")]),t._v(" which contains "),s("strong",[t._v("all elements of the old element")]),t._v(", starting at the starting index you passed (and then up to the max number of elements you defined). If you just call "),s("code",[t._v("slice()")]),t._v(", without arguments, you get a new array with all elements of the old array.")]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("p",[t._v("Use the spread operator\nIf you're using ES6+, you can use the spread operator.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" hobbies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sports"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cooking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" copiedHobbies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("hobbies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("p",[t._v("Here, you also create a new array (manually, by using "),s("code",[t._v("[]")]),t._v(") and you then use the spread operator "),s("code",[t._v("(...)")]),t._v('to "pull all elements of the old array out" and add them to the new array.')]),t._v(" "),s("p",[t._v("For objects")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("You can use the Object.assign() syntax which is explained in greater detail here.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Max"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" copiedPerson "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("assign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("p",[t._v("This syntax creates a new object (the {} part) and assigns all properties of the old object (the second argument) to that newly created one. This creates a copy.")]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("p",[t._v("Just as with arrays, you can also use the spread operator on objects.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Max"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" copiedPerson "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("person "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("p",[t._v("This will also create a new object (because you used { }) and will then pull all properties of person out of it, into the brand-new objects.")]),t._v(" "),s("h2",{attrs:{id:"🔶-deconstruction-assignment"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-deconstruction-assignment"}},[t._v("#")]),t._v(" 🔶 Deconstruction Assignment")]),t._v(" "),s("blockquote",[s("p",[t._v("ES6 Practical Deep "),s("code",[t._v("Deconstruction Assignment Methods")]),t._v(" for Deconstructed "),s("code",[t._v("Objects")]),t._v(", "),s("code",[t._v("Arrays")]),t._v(", "),s("code",[t._v("Hybrid Deconstruction")]),t._v(", and "),s("code",[t._v("Continuous Deconstruction")])])]),t._v(" "),s("h3",{attrs:{id:"▫️-deconstructing-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-deconstructing-objects"}},[t._v("#")]),t._v(" ▫️ "),s("strong",[t._v("Deconstructing Objects")])]),t._v(" "),s("p",[t._v("Without destructuring assignment, accessing the properties of an object or the elements of an array requires "),s("code",[t._v("dot notation")]),t._v(" or "),s("code",[t._v("bracket notation")]),t._v(":")]),t._v(" "),s("p",[t._v("1.1 "),s("strong",[t._v("basic deconstruction format")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" object "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// XXX 22")]),t._v("\n")])])]),s("p",[t._v("1.2 "),s("strong",[t._v("variable alias")])]),t._v(" "),s("blockquote",[s("p",[t._v("if you want to use a different variable name than the property name, you can use the following syntax:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" object "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" myName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" myAge "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("myName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" myAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// XXX 22")]),t._v("\n")])])]),s("p",[t._v("1.3 "),s("strong",[t._v("default value")])]),t._v(" "),s("blockquote",[s("p",[t._v("if 目標對象屬性中沒有要解構的屬性,不指定默認值, 那麼將會是 undefined, 此時可以給要解構變量寫 default 值.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" gender "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"female"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("此種為變量設置默認值的方法,常用與函數參數中,加入調用函數時沒傳遞參數,有可能會對函數運行造成錯誤,那就可以形參位置進行對象解構, 對變量指定默認值。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xxx'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// xxx 30")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-deconstructing-arrays"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-deconstructing-arrays"}},[t._v("#")]),t._v(" ▫️ "),s("strong",[t._v("Deconstructing Arrays")])]),t._v(" "),s("blockquote",[s("p",[t._v("解構數組和對象有些不同, 解構對象的時候屬性前後位置不影響, 但是解構數組,需要按照 index 順序解構")])]),t._v(" "),s("p",[t._v("2.1 "),s("strong",[t._v("basic deconstruction format")]),t._v("\nwithout destructuring assignment, accessing the properties of an object or the elements of an array requires "),s("code",[t._v("dot notation")]),t._v(" or "),s("code",[t._v("bracket notation")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// XXX 22")]),t._v("\n")])])]),s("p",[t._v("if with "),s("code",[t._v("deconstructing")]),t._v(" assignment, you can use the following syntax:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// XXX 22")]),t._v("\n")])])]),s("p",[t._v("🔻 Scenario 01: To destructure the nested "),s("code",[t._v("data")]),t._v(" object within the main "),s("code",[t._v("data")]),t._v(" property of a response object to get to the inner "),s("code",[t._v("data")]),t._v(" array.")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assuming the response object is named `response`")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("innerData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("innerData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This will log the inner object represented by the {...} in your screenshot")]),t._v("\n")])])]),s("p",[t._v("This snippet assumes that "),s("code",[t._v("response")]),t._v(" is the name of the variable holding the entire object you've shown in your screenshot. The destructuring pattern "),s("code",[t._v("{ data: { data: [innerData] } }")]),t._v(" navigates through the object structure to the inner "),s("code",[t._v("data")]),t._v(" array and grabs the first item from that array, assigning it to the "),s("code",[t._v("innerData")]),t._v(" variable. If you want to access other properties at the same level, you can add them to the destructuring pattern accordingly.")]),t._v(" "),s("p",[s("img",{attrs:{src:a(298),alt:"destrcturing"}})]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("banner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Simulating the structure from your screenshot")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" db\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("collection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"banner-list"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("orderBy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sort"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"desc"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("limit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Correct destructuring pattern based on the screenshot you provided")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This will log the first object from the data array")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this updated code, "),s("code",[t._v("response")]),t._v(" represents the object returned from the database query. The destructuring pattern "),s("code",[t._v("{ data: { data: [result] } }")]),t._v(" navigates through the first "),s("code",[t._v("data")]),t._v(" object and then the "),s("code",[t._v("data")]),t._v(" array to extract the first item of that array into the "),s("code",[t._v("result")]),t._v(" variable.")]),t._v(" "),s("p",[t._v("Please make sure that the "),s("code",[t._v("db.collection(...).get()")]),t._v(" method indeed returns an object with a structure similar to the one in your screenshot, with nested "),s("code",[t._v("data")]),t._v(" properties. If the structure is different, you'll need to adjust the destructuring pattern accordingly.")]),t._v(" "),s("h2",{attrs:{id:"🔶-arrow-function-の理解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-arrow-function-の理解"}},[t._v("#")]),t._v(" 🔶 Arrow function の理解")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("只有一個參數的函數 (Arrow Function with a Single Parameter):")])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("參數")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" 返回值"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 例如:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("x")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[s("p",[s("strong",[t._v("沒有參數或多個參數的函數 (Arrow Function with No or Multiple Parameters):")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 沒有參數時使用空的小括號")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" 返回值\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 多個參數時使用小括號括起來")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("參數"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 參數"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" 返回值\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 例如:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b\n")])])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("箭頭後面的值就是返回值 (Arrow Function Expression):")])]),t._v(" "),s("ul",[s("li",[t._v("返回值必須是一個表達式。什麼叫表達式?有返回值的語句就是表達式。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("如果返回值是一個對象,需要用括號包起來 (Object as Return Value):")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("如果需要在 arrow function 裡定義邏輯, 可以直接在箭頭後跟一個代碼塊,代碼塊中的語法和普通函數沒有區別。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("參數"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 參數"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 邏輯")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" 返回值"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("h2",{attrs:{id:"🔶-キーワード-this-の理解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-キーワード-this-の理解"}},[t._v("#")]),t._v(' 🔶 キーワード "this "の理解')]),t._v(" "),s("ul",[s("li",[s("p",[s("a",{attrs:{href:"https://qiita.com/suin/items/a44825d253d023e31e4d",target:"_blank",rel:"noopener noreferrer"}},[t._v("JavaScript: 通常の関数とアロー関数の違いは「書き方だけ」ではない。異なる性質が 10 個ほどある"),s("OutboundLink")],1)])]),t._v(" "),s("li",[s("p",[s("a",{attrs:{href:"https://qiita.com/10mi8o/items/2da84ab650f4caffdeea",target:"_blank",rel:"noopener noreferrer"}},[t._v("アロー関数が便利な理由と使いどころ"),s("OutboundLink")],1)])])]),t._v(" "),s("h3",{attrs:{id:"アロー関数で書く理由-1-関数を短く書きたい"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#アロー関数で書く理由-1-関数を短く書きたい"}},[t._v("#")]),t._v(" アロー関数で書く理由 ① 関数を短く書きたい")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//アロー関数")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("arrowAddFunc")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//1個しか評価項目が無い場合は以下のようにも書ける")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//中括弧とreturnの省略が出来る")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("arrowAddFunc")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//評価項目が1個だけ、かつ引数が1個しか無い場合はこのようにも書ける")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//括弧も省略できる")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("arrowDoubleFunc")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("省略して、1行で書ける事も出来ますが、アロー関数を書き慣れていない人がパッと見た時に、やや分かりづらいかもしれません。必ずしも1行で書かなければいけない理由はありません。いずれにしろ、 function をいちいち書く必要がなく、短く書く事が出来ます。しかしアロー関数の真価は this を束縛しないという点にあるでしょう。")]),t._v(" "),s("h3",{attrs:{id:"アロー関数で書く理由-2-this-を束縛しない"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#アロー関数で書く理由-2-this-を束縛しない"}},[t._v("#")]),t._v(" アロー関数で書く理由 ② this を束縛しない")]),t._v(" "),s("p",[t._v("アロー関数で短く書けます!と説明されても、へーそうなんだ。。。で終わると思いますが、アロー関数を使う上でちゃんと理解しておきたいのは、こちらの方かと思います。")]),t._v(" "),s("p",[t._v("それは、this の値は関数定義時に決まる(=this を束縛しない) というルールです。\nthis を束縛しない、という説明はやや分かりづらいので、ここでは、アロー関数を使えば、this の値は関数定義時に決める事ができる、という理解で大丈夫でしょう。")]),t._v(" "),s("p",[t._v("JavaScript で this を扱う時、最初は分かりづらい...直感的でない...という事は、JavaScript を書いてる方なら、分かって頂けるかなと思います。this の呼び出しパターンにはいくつかあるのですが、ここでは、アロー関数を使うメリットを説明する上で、メソッド呼び出しパターンと関数呼び出しパターンを事前に例として挙げておきます。this を理解する上で大切なのは、呼び出し元が何であるかという事です。まずはメソッド呼び出しパターンから説明します。")]),t._v(" "),s("h3",{attrs:{id:"メソッド呼び出しパターン"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#メソッド呼び出しパターン"}},[t._v("#")]),t._v(" メソッド呼び出しパターン")]),t._v(" "),s("p",[t._v("以下のコードを実際に打ち込んで、console.log で確認してみましょう。")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" object "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("method1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//①何が返されるでしょう?")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("method2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//②何が返されるでしょう?")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//① thisはobject自身を参照している")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("method1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//{ value: 'test', method: [Function: method] }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//② thisはobject自身を参照しているので、valueプロパティにもアクセスできる")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("method2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔶-キーワード-class-の理解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-キーワード-class-の理解"}},[t._v("#")]),t._v(' 🔶 キーワード "class"の理解')]),t._v(" "),s("h3",{attrs:{id:"class-の-基本概念"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#class-の-基本概念"}},[t._v("#")]),t._v(" Class の 基本概念")]),t._v(" "),s("p",[t._v("A class is a "),s("strong",[t._v("template")]),t._v(" for an object that defines its "),s("code",[t._v("properties")]),t._v(" and "),s("code",[t._v("methods")]),t._v(". In JavaScript, classes can be defined using the "),s("code",[t._v("class")]),t._v(" keyword.")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// class of constructor functions that are called when the instance is created.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In a constructor function, this points to the instance object.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 類的實例方法")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the method, this still points to the instance object.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 類的靜態方法")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myStaticMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In static methods, this points to the class itself.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Examples of Creation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myInstance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Calling Example Methods")]),t._v("\nmyInstance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Calling the static method")]),t._v("\nMyClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myStaticMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"strict-mode-class"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#strict-mode-class"}},[t._v("#")]),t._v(" Strict mode && Class")]),t._v(" "),s("ul",[s("li",[t._v("All code in the class is executed in strict mode")]),t._v(" "),s("li",[t._v("In strict mode, when a function is called in the global context, this is no longer a global object (usually a window), but is undefined.")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use strict"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在構造函數中,this 仍然指向實例對象")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在方法中,this 仍然指向實例對象")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myStaticMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在靜態方法中,this 是指向類本身")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 創建類的實例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myInstance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 調用實例方法")]),t._v("\nmyInstance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 調用靜態方法")]),t._v("\nMyClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myStaticMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在全局上下文中,調用函數(不是在類中)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("globalFunction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在嚴格模式下,全局上下文中的 this 將是 undefined")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在嚴格模式下,全局上下文中的 this 將是 undefined")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("globalFunction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"箭頭函數在-class-中的影響"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#箭頭函數在-class-中的影響"}},[t._v("#")]),t._v(" 箭頭函數在 Class 中的影響")]),t._v(" "),s("ul",[s("li",[t._v("如果類中的方法是以箭頭函數定義的,則方法中的 this 將指向類的實例對象。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("myArrowMethod")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在箭頭函數中,this 指向類的實例對象")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myInstance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmyInstance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myArrowMethod")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 調用箭頭函數方法")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("この形式の書き方は、アロー関数内の this が常にクラスのインスタンスオブジェクトを指すようにし、関数の呼び出し方法の影響を受けないように確保します。")])]),t._v(" "),s("h3",{attrs:{id:"クラスの継承"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#クラスの継承"}},[t._v("#")]),t._v(" クラスの継承")]),t._v(" "),s("ul",[s("li",[t._v("継承を使用すると、クラス内のプロパティやメソッドを利用でき、さらに新しいプロパティやメソッドをサブクラスに追加できます。")]),t._v(" "),s("li",[t._v("extends を使用してクラスを継承し、継承後はまるでそのクラスのコードが現在のクラスにコピーされたかのようになります。")]),t._v(" "),s("li",[t._v("親クラスのメソッドを上書きすることができますが、親クラスのメソッドは上書きされず、サブクラスに同じ名前のメソッドが追加されます。")])]),t._v(" "),s("blockquote",[s("p",[t._v("サブクラスで親クラスのコンストラクタを上書きする場合、サブクラスのコンストラクタ内で super() を呼び出さなければなりません。そうしないとエラーが発生します。")])]),t._v(" "),s("h2",{attrs:{id:"🔶-static-properties-and-static-methods-in-classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-static-properties-and-static-methods-in-classes"}},[t._v("#")]),t._v(" 🔶 Static Properties and Static Methods in Classes")]),t._v(" "),s("p",[t._v("...待補充")]),t._v(" "),s("h2",{attrs:{id:"🔷-array-主なメソッド"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-array-主なメソッド"}},[t._v("#")]),t._v(" 🔷 Array 主なメソッド")]),t._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Standard built-in objects-Array"),s("OutboundLink")],1)])]),t._v(" "),s("h3",{attrs:{id:"▫️-array-prototype-push"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-array-prototype-push"}},[t._v("#")]),t._v(" ▫️ Array.prototype.push()")]),t._v(" "),s("h3",{attrs:{id:"▫️array-prototype-from"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️array-prototype-from"}},[t._v("#")]),t._v(" ▫️Array.prototype.from()")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("用途")]),t._v(":從具有長度屬性的對象或可迭代對象創建數組。")]),t._v(" "),s("li",[s("strong",[t._v("示例")]),t._v(":")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("hello")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"goodbye"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️array-prototype-fill"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️array-prototype-fill"}},[t._v("#")]),t._v(" ▫️Array.prototype.fill()")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("用途")]),t._v(":填充數組的每個元素為相同的值。")]),t._v(" "),s("li",[s("strong",[t._v("示例")]),t._v(":"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("strong",[t._v("特點")]),t._v(":適用於不可變值(如數字、字符串、布爾值)。")]),t._v(" "),s("li",[s("strong",[t._v("問題")]),t._v(":用於對象時,填充的是對同一對象的引用。"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("hello")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"goodbye"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"填充唯一對象"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#填充唯一對象"}},[t._v("#")]),t._v(" 填充唯一對象")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("方法")]),t._v(":結合 "),s("code",[t._v("fill")]),t._v(" 和 "),s("code",[t._v("map")]),t._v("。"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("hello")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"goodbye"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("strong",[t._v("特點")]),t._v(":創建具有唯一對象引用的數組。")]),t._v(" "),s("li",[s("strong",[t._v("注意")]),t._v(":"),s("code",[t._v("map")]),t._v(" 方法可能對大數據集來說代價昂貴。")])]),t._v(" "),s("h3",{attrs:{id:"使用-for-循環"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用-for-循環"}},[t._v("#")]),t._v(" 使用 for 循環")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("方法")]),t._v(":傳統的 for 循環。"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n filledArray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("hello")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"goodbye"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]),t._v(" "),s("li",[s("strong",[t._v("特點")]),t._v(":避免了使用 "),s("code",[t._v("map")]),t._v(" 方法。")])]),t._v(" "),s("h3",{attrs:{id:"使用展開語法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用展開語法"}},[t._v("#")]),t._v(" 使用展開語法 (...)")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("方法")]),t._v(":結合展開語法和 "),s("code",[t._v("map")]),t._v("。"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filledArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'hello'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'goodbye'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("strong",[t._v("特點")]),t._v(":避免使用 "),s("code",[t._v("fill")]),t._v(",但仍使用 "),s("code",[t._v("map")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"🔸-array-prototype-map"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-array-prototype-map"}},[t._v("#")]),t._v(" 🔸 Array.prototype.map()")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array.prototype.map()\n"),s("OutboundLink")],1)]),t._v(" "),s("ul",[s("li",[t._v("map() メソッドは、新しい配列を作成し、元の配列の各要素をコールバック関数で処理した結果を含みます。")]),t._v(" "),s("li",[t._v("コールバック関数が必要で、その戻り値が新しい配列内の各要素になります。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// マップに関数を渡す")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 回調函數中會出現三個參數:當前元素、當前索引和原始數組。")]),t._v("\nresult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("currentValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" thisArg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 期待される出力: Array [2, 8, 18, 32]")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("使用シーン:ウェブページで配列を表示し、各配列要素にはラベルが必要な場合。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fruits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"banana"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"orange"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fruits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("fruit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("
  • ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("fruit"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("
  • ")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🔻 使用シナリオ")]),t._v(" "),s("p",[s("strong",[t._v("例子 1:使用 "),s("code",[t._v("get")]),t._v(" 方法获取 Map 中的值")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" userPreferences "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加用户喜好设置")]),t._v("\nuserPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"theme"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dark"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"language"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取特定键的值")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" theme "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" userPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"theme"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("theme"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'dark'")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 2:使用 "),s("code",[t._v("set")]),t._v(" 方法添加或更新 Map 中的键值对")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" userData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加用户数据")]),t._v("\nuserData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user123"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user@example.com"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更新用户数据")]),t._v("\nuserData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"newuser@example.com"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 3:使用 "),s("code",[t._v("has")]),t._v(" 方法检查 Map 中是否存在键")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" userPermissions "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 检查是否存在特定权限")]),t._v("\nuserPermissions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserPermissions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"editor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("userPermissions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("has")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"用户是管理员"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"用户不是管理员"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 4:使用 "),s("code",[t._v("delete")]),t._v(" 方法从 Map 中删除键值对")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataStore "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加数据")]),t._v("\ndataStore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ndataStore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 删除数据")]),t._v("\ndataStore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 5:使用 "),s("code",[t._v("size")]),t._v(" 属性获取 Map 的大小")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cartItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加购物车商品")]),t._v("\ncartItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"item1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Product A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncartItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"item2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Product B"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取购物车商品数量")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cartItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("购物车中有 ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("itemCount"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" 件商品")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 6:使用 "),s("code",[t._v("forEach")]),t._v(" 方法迭代 Map 中的键值对")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" userRoles "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加用户角色")]),t._v("\nuserRoles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user123"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserRoles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 遍历用户角色")]),t._v("\nuserRoles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("role"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" username")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("username"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" 的角色是 ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("role"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 7:使用 "),s("code",[t._v("keys")]),t._v(" 方法获取 Map 中的所有键")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加菜单项")]),t._v("\nmenuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"home"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Home Page"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmenuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"about"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"About Us"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmenuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"contact"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Contact Us"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取所有菜单项的键")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItemKeys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("menuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("menuItemKeys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 ['home', 'about', 'contact']")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-array-prototype-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-array-prototype-filter"}},[t._v("#")]),t._v(" ▫️ Array.prototype.filter()")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("filter()")]),t._v(" メソッドは、指定された関数によって評価された元の配列の要素から構成される新しい配列を作成します。\n"),s("ul",[s("li",[t._v("配列から条件に合致する要素を取得できます。")]),t._v(" "),s("li",[t._v("コールバック関数の結果に基づいて、要素の保持または削除が決まります。結果が true なら保持し、false なら削除します。")])])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//代碼處理邏輯: number%2 === 0 ? true : false 如果返回true,就留,否則就不留")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// expected output: Array [2, 4]")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-array-prototype-find"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-array-prototype-find"}},[t._v("#")]),t._v(" ▫️ Array.prototype.find()")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("find()")]),t._v(" メソッドは、与えられたテスト関数を満たす配列内の最初の要素の値を返します。そうでなければ、"),s("code",[t._v("undefined")]),t._v(" を返します。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("130")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("44")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" found "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" element "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("found"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// expected output: 12")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-array-prototype-reduce"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-array-prototype-reduce"}},[t._v("#")]),t._v(" ▫️ "),s("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#syntax",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array.prototype.reduce()"),s("OutboundLink")],1)]),t._v(" "),s("ul",[s("li",[s("p",[s("code",[t._v("reduce()")]),t._v(" メソッドは、アキュムレータと配列の各要素(左から右へ)をコールバック関数に渡し、配列を単一の値にまとめます。")]),t._v(" "),s("ul",[s("li",[t._v("配列の各要素に対して、コールバック関数を実行します。")]),t._v(" "),s("li",[t._v("コールバック関数の戻り値をアキュムレータに代入します。")]),t._v(" "),s("li",[t._v("reduce() メソッドは、関数をアキュムレータとして受け取り、配列の各値を(左から右へ)最終値まで縮小していきます。")]),t._v(" "),s("li",[t._v("配列の要素が結合され、値が返されます。")])])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" array1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 0 + 1 + 2 + 3 + 4")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" sumWithInitial "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("accumulator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" currentValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" accumulator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" currentValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n initialValue\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sumWithInitial"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Expected output: 10")]),t._v("\n")])])]),s("p",[t._v("🔺 応用シナリオ")]),t._v(" "),s("ol",[s("li",[t._v("Calculating "),s("em",[t._v("Total Amount")]),t._v(" in a Shopping Cart\nSuppose you have a shopping cart application, where each item has a price and quantity, and you want to calculate the total amount.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("quantity")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Banana"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("quantity")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Orange"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("quantity")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-array-prototype-foreach"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-array-prototype-foreach"}},[t._v("#")]),t._v(" ▫️ Array.prototype.forEach()")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("forEach()")]),t._v(" メソッドは、与えられた関数を配列の各要素に対して一度ずつ実行します。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\narray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// expected output: 1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔷-object-method"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-object-method"}},[t._v("#")]),t._v(" 🔷 Object method")]),t._v(" "),s("h3",{attrs:{id:"▫️object-defineproperties"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️object-defineproperties"}},[t._v("#")]),t._v(" ▫️Object.defineProperties")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//使用 Object.defineProperties")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//創建和配置對象屬性: Object.defineProperties 被用來在 obj 對象上定義兩個屬性 a 和 b。這些屬性被配置為有特定值(分別為 1 和 2),並且是可枚舉的(enumerable: true)。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//屬性值和可枚舉性: 設置 value 來指定屬性的值,並通過 enumerable 標記屬性是否應該出現在對象的枚舉屬性中。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("defineProperties")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enumerable")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("b")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enumerable")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-object-entries"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-object-entries"}},[t._v("#")]),t._v(" ▫️ Object.entries()")]),t._v(" "),s("ul",[s("li",[t._v("使用 Object.entries(obj) 將 obj 對象轉換為一個鍵值對的數組(二維數組)。每個子數組包含一個鍵和對應的值。")]),t._v(" "),s("li",[t._v("返回值:给定对象自己的"),s("code",[t._v("可枚举")]),t._v("字符串键控属性键值对的数组。每个键值对都是一个包含"),s("strong",[t._v("两个元素的数组")]),t._v(":第一个元素是属性键(始终是字符串),第二个元素是属性值。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" object "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"someString"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("b")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" testArr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("testArr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//遍歷鍵值對列表: 使用 for...of 循環遍歷 Object.entries(obj) 返回的鍵值對列表,並打印每個鍵和對應的值。 `new Map([["a", 1], ["b", 2]])` 創建了一個包含兩個鍵值對的 Map 對象。')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("k"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" testArr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("k"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//用map方法將鍵值對列表轉換成map類型的數據: 通過將鍵值對的數組傳遞給 Map 的構造函數來創建一個新的 Map 對象。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" m "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[s("strong",[t._v("應用 1")]),t._v(": Converting an Object to a Map:\n"),s("ul",[s("li",[t._v("The Map() constructor accepts an iterable of entries. With Object.entries, you can easily convert from Object to Map:")])])])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("foo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bar"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("baz")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Map(2) {"foo" => "bar", "baz" => 42}')]),t._v("\n")])])]),s("ul",[s("li",[s("strong",[t._v("應用 2")]),t._v(": Iterating through an Object")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Using for...of loop")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("b")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("c")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "a 5", "b 7", "c 9"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Using array methods")]),t._v("\nObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "a 5", "b 7", "c 9"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-object-fromentries"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-object-fromentries"}},[t._v("#")]),t._v(" ▫️ Object.fromEntries()")]),t._v(" "),s("ul",[s("li",[t._v("Object.fromEntries() 是 Object.entries() 的逆操作,作用是将一个键值对数组转化为對象,返回的是"),s("strong",[t._v("新對象,不改变原对象")]),t._v("。")]),t._v(" "),s("li",[t._v("只是 Object.entries() 只返回字符串键属性,而 Object.fromEntries() 还可以创建符号键属性。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("也可以传入一个 Map 将其转为对象")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("Object.fromEntries()")]),t._v("實際應用:")]),t._v(" "),s("ol",[s("li",[t._v("過濾屬性")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("foo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"oli"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"12"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("這個 "),s("code",[t._v("foo")]),t._v(" 函數接受一個對象和一系列鍵作為參數,然後返回一個新的對象,其中只包含指定的鍵及其相應的值。具體來說:")]),t._v(" "),s("ol",[s("li",[s("p",[s("code",[t._v("Object.entries(obj)")]),t._v(" 會將 "),s("code",[t._v("obj")]),t._v(" 轉換為一個二維數組,每個內部數組包含一對鍵值(例如 "),s("code",[t._v("[['name', 'oli'], ['age', '12']]")]),t._v(")。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v(".filter(([key]) => keys.includes(key))")]),t._v(" 會過濾這個數組,只保留那些鍵存在於 "),s("code",[t._v("keys")]),t._v(" 參數中的鍵值對。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("Object.fromEntries()")]),t._v(" 將過濾後的二維數組轉回為對象。")])])]),t._v(" "),s("p",[t._v("在您的例子中,調用 "),s("code",[t._v('foo({ name: "oli", age: "12" }, "name")')]),t._v(" 會返回一個只包含 "),s("code",[t._v("name")]),t._v(" 鍵和其對應值的新對象。因此,這個函數調用的輸出將是:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"oli"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("console.table")]),t._v(" 會以表格的形式在控制台輸出這個對象,顯示 "),s("code",[t._v("name")]),t._v(" 這一列及其對應的值 "),s("code",[t._v("oli")]),t._v("。")]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("将 url 查询字符串转为对象")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("query "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("URLSearchParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"foo=bar&baz=qux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🔻 應用 1: 使用 "),s("code",[t._v("Object.entries")]),t._v(" 和 "),s("code",[t._v("Object.fromEntries")]),t._v(" 的代碼例子")]),t._v(" "),s("p",[s("strong",[t._v("例子 1:将对象转换为 Map 并操作数据")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("b")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("c")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Object.entries将对象转换为Map")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在Map上进行数据操作")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Object.fromEntries将Map转换回对象")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newObj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newObj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 { a: 1, c: 3, d: 4 }")]),t._v("\n")])])]),s("p",[s("strong",[t._v("例子 2:将路由参数对象转换为 Map 并重新映射键名")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" routeParamsObj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("userId")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("123")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("actionType")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"edit"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Object.entries将路由参数对象转换为Map")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" routeParamsMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("routeParamsObj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 重新映射键名")]),t._v("\nrouteParamsMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" routeParamsMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"userId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nrouteParamsMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"userId"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Object.fromEntries将Map转换回路由参数对象")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newRouteParamsObj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromEntries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("routeParamsMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newRouteParamsObj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 { id: 123, actionType: 'edit' }")]),t._v("\n")])])]),s("p",[t._v("这些示例演示了如何使用 "),s("code",[t._v("Object.entries")]),t._v(" 和 "),s("code",[t._v("Object.fromEntries")]),t._v(" 来进行对象和 Map 之间的转换,并对数据进行操作和重映射。")]),t._v(" "),s("p",[t._v("🔻 應用 2: 將對象轉換為 Map")]),t._v(" "),s("p",[t._v("當將对象转换为 Map 时,有许多应用场景,以下是其中一些示例:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("API 响应数据解析:")]),t._v(" 当从 API 获取数据时,通常以 JSON 对象的形式返回。将 JSON 对象转换为 Map 可以更容易地提取和操作所需的数据字段。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" apiResponse "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("apiResponse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dataMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'John'")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("表单数据处理:")]),t._v(" 在 Web 应用程序中,用户提交的表单数据通常作为对象传输。将表单数据转换为 Map 可以更容易地验证、操作和处理这些数据。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" formData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("username")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user123"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user@example.com"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" formDataMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("formData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("formDataMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'user@example.com'")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("路由参数:")]),t._v(" 在一些 Web 框架中,路由参数可能作为对象传递给控制器或路由处理程序。将路由参数转换为 Map 可以更方便地访问它们。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" routeParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("123")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"edit"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" routeParamsMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("routeParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("routeParamsMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 123")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("配置管理:")]),t._v(" 在应用程序中,通常需要存储和管理配置数据。将配置对象转换为 Map 可以提供更好的配置管理和访问。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("apiKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"your-api-key"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("apiUrl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" configMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("configMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apiUrl"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'https://api.example.com'")]),t._v("\n")])])]),s("ol",{attrs:{start:"5"}},[s("li",[s("strong",[t._v("数据转换和处理:")]),t._v(" 在某些情况下,需要对数据进行转换或处理,例如将对象中的某些字段重新映射到新的键。将对象转换为 Map 可以帮助执行这些操作。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("first_name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("last_name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Doe"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" personMap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("entries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\npersonMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"full_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("personMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"first_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("personMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"last_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("personMap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"full_name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'John Doe'")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-object-assign"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-object-assign"}},[t._v("#")]),t._v(" ▫️ Object.assign()")]),t._v(" "),s("h3",{attrs:{id:"▫️-object-create"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-object-create"}},[t._v("#")]),t._v(" ▫️ Object.create()")]),t._v(" "),s("p",[t._v("Reference:\n"),s("a",{attrs:{href:"https://juejin.cn/post/6844903789938360333#heading-0",target:"_blank",rel:"noopener noreferrer"}},[t._v("Object.fromEntries"),s("OutboundLink")],1)]),t._v(" "),s("h2",{attrs:{id:"data-structure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-structure"}},[t._v("#")]),t._v(" Data Structure")]),t._v(" "),s("h3",{attrs:{id:"object-和-map-區別"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#object-和-map-區別"}},[t._v("#")]),t._v(" Object 和 Map 區別")]),t._v(" "),s("p",[t._v("共同點: Object 和 Map 都允許你按鍵存取一個值、刪除鍵、檢查一個鍵是否存在、以及迭代其餘的鍵。")]),t._v(" "),s("ol",[s("li",[t._v("構造方法的不同")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Object 的构造方法:"),s("code",[t._v("Object")]),t._v("可以使用对象字面量的方式创建,也可以使用"),s("code",[t._v("new Object()")]),t._v("或"),s("code",[t._v("Object.create(null)")]),t._v("来创建。")]),t._v(" "),s("div",{staticClass:"language-JS extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//構造方法")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ojb2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("Map 的构造方法:Map 需要使用"),s("code",[t._v("new Map()")]),t._v("的方式来创建,也可以通过传入一个包含键值对的数组来初始化。")]),t._v(" "),s("div",{staticClass:"language-JS extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("value 的類型的不同")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Object: 鍵類型必須是 String 或者 Symbol,如果是非 String 類型,會進行數據類型轉換,轉換成 String 類型,再進行操作。")]),t._v(" "),s("div",{staticClass:"language-JS extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Symbol")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value5"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// {1: "value1", true: "value2", undefined: "value3", null: "value4", Symbol(): "value5"}')]),t._v("\n")])])])])]),t._v(" "),s("p",[s("img",{attrs:{src:a(299),alt:"mapobject"}})]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Map: 鍵類型可以是任意類型,包括原始類型和引用類型, 不會進行數據類型轉換。 在添加鍵值對時, 會通過 === 來判斷鍵是否相等。")]),t._v(" "),s("div",{staticClass:"language-JS extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Symbol")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value5"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Map(5) {1 => "value1", true => "value2", undefined => "value3", null => "value4", Symbol() => "value5"}')]),t._v("\n")])])])])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("鍵的順序")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Object")]),t._v(" "),s("ul",[s("li",[t._v("key 是無序的, 不會按照添加的順序返回。 1.對於>=0 的整數, 會按照大小排序。對於小數和負數, 會當作字符串處理。")]),t._v(" "),s("li",[t._v("對於字符串, 會按照定義的順序輸出")]),t._v(" "),s("li",[t._v("symbol 類型,會直接過濾掉,不會進行輸出。如果想輸出, 需要使用"),s("code",[t._v("Object.getOwnPropertySymbols")]),t._v("方法。")])])]),t._v(" "),s("li",[s("p",[t._v("Maps")]),t._v(" "),s("ul",[s("li",[t._v("key 是有序的, 會按照添加的順序返回。")]),t._v(" "),s("li",[t._v("key 可以是任意類型, 包括原始類型和引用類型。")]),t._v(" "),s("li",[t._v("key 的比較是"),s("code",[t._v("===")]),t._v(", 即使是兩個看起來一樣的數字, 也會被認為是不同的鍵。")]),t._v(" "),s("li",[s("code",[t._v("size")]),t._v(" 屬性可以獲取 Map 的大小。")])])])]),t._v(" "),s("ol",{attrs:{start:"4"}},[s("li",[t._v("鍵值對的訪問")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Object")]),t._v(" "),s("ul",[s("li",[t._v("添加或者修改屬性, 通過 點或者中括號的方式訪問。")]),t._v(" "),s("li",[t._v("判斷屬性是否存在, 通過 "),s("code",[t._v("in")]),t._v(" 或者 "),s("code",[t._v("hasOwnProperty")]),t._v("方法。")]),t._v(" "),s("li",[t._v("刪除屬性, 通過 "),s("code",[t._v("delete")]),t._v(" 操作符。")])])]),t._v(" "),s("li",[s("p",[t._v("Map")]),t._v(" "),s("ul",[s("li",[t._v("添加或者修改屬性, 通過"),s("code",[t._v("set")]),t._v("方法。")]),t._v(" "),s("li",[t._v("判斷屬性是否存在, 通過"),s("code",[t._v("has")]),t._v("方法。")]),t._v(" "),s("li",[t._v("刪除屬性, 通過"),s("code",[t._v("delete")]),t._v("方法。")]),t._v(" "),s("li",[s("code",[t._v("get")]),t._v(" 方法可以獲取屬性值。")]),t._v(" "),s("li",[s("code",[t._v("clear")]),t._v(" 方法可以清空所有屬性。")]),t._v(" "),s("li",[t._v("通過"),s("code",[t._v("keys")]),t._v("方法可以獲取所有的 key。")]),t._v(" "),s("li",[t._v("通過"),s("code",[t._v("values")]),t._v("方法可以獲取所有的 value。")]),t._v(" "),s("li",[t._v("通過"),s("code",[t._v("entries")]),t._v("方法可以獲取所有的 key value。")])])])]),t._v(" "),s("ol",{attrs:{start:"5"}},[s("li",[t._v("迭代")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Object")]),t._v(" "),s("ul",[s("li",[t._v("不具備 Iterator 特性,無法使用 for...of 循環迭代。")])])]),t._v(" "),s("li",[s("p",[t._v("Map")]),t._v(" "),s("ul",[s("li",[t._v("具備 Iterator 特性,可以使用 for...of 循環迭代。")])])])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("v")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v("alue"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "key1 value1", "key2 value2"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ol",{attrs:{start:"6"}},[s("li",[s("code",[t._v("JSON.stringify()")]),t._v(" 轉換")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("Map")]),t._v(" 類型的數據無法使用 "),s("code",[t._v("JSON.stringify()")]),t._v(" 方法轉換為 JSON 字符串, 需要先轉換為對象。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("b")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("c")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// {"a":1,"b":2,"c":3}')]),t._v("\n")])])]),s("ol",{attrs:{start:"7"}},[s("li",[s("code",[t._v("Object")]),t._v(" 和 "),s("code",[t._v("Map")]),t._v(" 的性能比較")]),t._v(" "),s("li",[t._v("size-Object")])]),t._v(" "),s("ul",[s("li",[t._v("Object 沒有 size 屬性, 需要通過 Object.keys(obj).length 來獲取對象的大小。")]),t._v(" "),s("li",[t._v("Map 有 size 屬性, 可以直接獲取 Map 的大小。")])]),t._v(" "),s("p",[t._v("🔺 Reference:\n"),s("a",{attrs:{href:"https://medium.com/@wisecobbler/4-ways-to-populate-an-array-in-javascript-836952aea79f",target:"_blank",rel:"noopener noreferrer"}},[t._v("4 Ways to Populate an Array in JavaScript"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"set-和-map-區別"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#set-和-map-區別"}},[t._v("#")]),t._v(" Set 和 Map 區別")]),t._v(" "),s("p",[t._v("以下是 Set 和 Map 之间的一些主要区别和用途:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("Set(集合):")]),t._v(" "),s("ul",[s("li",[t._v("用于存储唯一值,不允许重复的元素。")]),t._v(" "),s("li",[t._v("主要用途是存储一组唯一的元素,如集合、去重和检查元素是否存在。")]),t._v(" "),s("li",[t._v("不需要键值对,只存储单个值。")]),t._v(" "),s("li",[t._v("可以通过"),s("code",[t._v("add")]),t._v("方法添加元素,使用"),s("code",[t._v("has")]),t._v("方法检查元素是否存在,使用"),s("code",[t._v("delete")]),t._v("方法删除元素。")])])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" uniqueNumbers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("uniqueNumbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 Set { 1, 2, 3, 4, 5 }")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("Map(映射):")]),t._v(" "),s("ul",[s("li",[t._v("用于存储键值对,允许根据键来访问值。")]),t._v(" "),s("li",[t._v("主要用途是创建键值对的映射,可以用于任何需要键值关联的场景。")]),t._v(" "),s("li",[t._v("存储键值对,键可以是任何数据类型,值也可以是任何数据类型。")]),t._v(" "),s("li",[t._v("可以通过"),s("code",[t._v("set")]),t._v("方法添加键值对,使用"),s("code",[t._v("get")]),t._v("方法根据键获取值,使用"),s("code",[t._v("delete")]),t._v("方法删除键值对。")])])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" userPreferences "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"theme"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dark"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nuserPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"language"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("userPreferences"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"theme"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 'dark'")]),t._v("\n")])])]),s("p",[t._v("Set 是 JavaScript 中的一种数据结构,它具有许多优势,使其在各种应用场景中非常有用。以下是 Set 的一些主要优势:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("唯一性:")]),t._v(" Set 中的值是唯一的,不会重复。这意味着你可以使用 Set 来存储一组唯一的元素,而不必担心重复值。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" uniqueNumbers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("uniqueNumbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 Set { 1, 2, 3, 4, 5 }")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("查找和去重:")]),t._v(" 使用 Set 可以轻松查找特定元素是否存在于集合中,并且在添加元素时自动去重。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fruits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nfruits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"banana"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("has")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 true")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 2,自动去重")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("集合操作:")]),t._v(" Set 提供了各种集合操作方法,如交集、并集和差集,使你能够方便地进行数据操作。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" set1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" set2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 交集")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" intersection "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("set1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" set2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("has")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("intersection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 Set { 2, 3 }")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 并集")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" union "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("set1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("set2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("union"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 Set { 1, 2, 3, 4 }")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 差集")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" difference "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("set1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("set2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("has")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("difference"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 输出 Set { 1 }")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("队列操作:")]),t._v(" Set 的特性允许你实现一个简单的队列结构。可以使用 Set 来添加元素到队尾,并从队首删除元素。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" queue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nqueue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"item1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nqueue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"item2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" firstItem "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" queue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("values")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取队首元素")]),t._v("\nqueue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("firstItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 删除队首元素")]),t._v("\nqueue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 删除队首元素")]),t._v("\n")])])]),s("p",[t._v("总之,Set 在 JavaScript 中的使用非常灵活,适用于处理唯一值的情况以及各种集合操作。它可以在查找、去重、集合操作和队列等多种场景中提供便利的解决方案。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/2.a44fb3b0.js b/assets/js/2.a44fb3b0.js new file mode 100644 index 00000000..86ac2e28 --- /dev/null +++ b/assets/js/2.a44fb3b0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{245:function(t,e,a){},246:function(t,e){t.exports=function(t){return null==t}},248:function(t,e,a){},249:function(t,e,a){},250:function(t,e,a){},252:function(t,e,a){"use strict";a(245)},253:function(t,e,a){"use strict";a.r(e);var n=a(266),s=a(255),i=a(239);function r(t,e){if("group"===e.type){const a=e.path&&Object(i.e)(t,e.path),n=e.children.some(e=>"group"===e.type?r(t,e):"page"===e.type&&Object(i.e)(t,e.path));return a||n}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:n.default,SidebarLink:s.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let a=0;a-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(i.e)(this.$route,t.regularPath)}}},l=a(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(a,n){return e("li",{key:n},["group"===a.type?e("SidebarGroup",{attrs:{item:a,open:n===t.openGroupIndex,collapsable:a.collapsable||a.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(n)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:a}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},255:function(t,e,a){"use strict";a.r(e);var n=a(239);function s(t,e,a,n,s){const i={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:n,"sidebar-link":!0}};return s>2&&(i.style={"padding-left":s+"rem"}),t("RouterLink",i,a)}function i(t,e,a,r,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(n.e)(r,a+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[s(t,a+"#"+e.slug,e.title,u,e.level-1),i(t,e.children,a,r,o,l+1)])}))}var r={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:a,$route:r,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(n.e)(r,u.path),d="auto"===u.type?p||u.children.some(t=>Object(n.e)(r,u.basePath+"#"+t.slug)):p,h="external"===u.type?function(t,e,a){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[a,t("OutboundLink")])}(t,u.path,u.title||u.path):s(t,u.path,u.title||u.path,d),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[h,i(t,u.children,u.basePath,r,f)];if((d||b)&&u.headers&&!n.d.test(u.path)){return[h,i(t,Object(n.c)(u.headers),u.path,r,f)]}return h}},o=(a(252),a(14)),l=Object(o.a)(r,void 0,void 0,!1,null,null,null);e.default=l.exports},256:function(t,e,a){},259:function(t,e,a){"use strict";a(248)},260:function(t,e,a){var n=a(11),s=a(4),i=a(10);t.exports=function(t){return"string"==typeof t||!s(t)&&i(t)&&"[object String]"==n(t)}},261:function(t,e,a){"use strict";a(249)},262:function(t,e,a){},263:function(t,e,a){"use strict";a(250)},264:function(t,e,a){},266:function(t,e,a){"use strict";a.r(e);var n=a(239),s={name:"SidebarGroup",components:{DropdownTransition:a(242).default},props:["item","open","collapsable","depth"],beforeCreate(){this.$options.components.SidebarLinks=a(253).default},methods:{isActive:n.e}},i=(a(263),a(14)),r=Object(i.a)(s,(function(){var t=this,e=t._self._c;return e("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("RouterLink",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=r.exports},267:function(t,e,a){"use strict";a.r(e);var n=a(246),s=a.n(n),i=a(239),r={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=s()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:a="",docsBranch:n="master",docsRepo:i=e}=this.$site.themeConfig;return t&&i&&this.$page.relativePath?this.createEditLink(e,i,a,n,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,a,n,s){if(/bitbucket.org/.test(e)){return e.replace(i.a,"")+"/src"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s+`?mode=edit&spa=0&at=${n}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(i.a,"")+"/-/edit"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s}return(i.i.test(e)?e:"https://github.com/"+e).replace(i.a,"")+"/edit"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s}}},o=(a(259),a(14)),l=Object(o.a)(r,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=l.exports},268:function(t,e,a){"use strict";a.r(e);a(90);var n=a(239),s=a(260),i=a.n(s),r=a(246),o=a.n(r),l={name:"PageNav",props:["sidebarItems"],computed:{prev(){return c(u.PREV,this)},next(){return c(u.NEXT,this)}}};const u={NEXT:{resolveLink:function(t,e){return p(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return p(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function c(t,{$themeConfig:e,$page:a,$route:s,$site:r,sidebarItems:l}){const{resolveLink:u,getThemeLinkConfig:c,getPageLinkConfig:p}=t,d=c(e),h=p(a),f=o()(h)?d:h;return!1===f?void 0:i()(f)?Object(n.k)(r.pages,f,s.path):u(a,l)}function p(t,e,a){const n=[];!function t(e,a){for(let n=0,s=e.length;n({isSidebarOpen:!1}),computed:{shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:e}=this.$page;return!1!==e.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length},sidebarItems(){return Object(o.l)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar},t]}},mounted(){this.$router.afterEach(()=>{this.isSidebarOpen=!1})},methods:{toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const e=t.changedTouches[0].clientX-this.touchStart.x,a=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(e)>Math.abs(a)&&Math.abs(e)>40&&(e>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},u=a(14),c=Object(u.a)(l,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"theme-container",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?e("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),e("div",{staticClass:"sidebar-mask",on:{click:function(e){return t.toggleSidebar(!1)}}}),t._v(" "),e("Sidebar",{attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar},scopedSlots:t._u([{key:"top",fn:function(){return[t._t("sidebar-top")]},proxy:!0},{key:"bottom",fn:function(){return[t._t("sidebar-bottom")]},proxy:!0}],null,!0)}),t._v(" "),t.$page.frontmatter.home?e("Home"):e("Page",{attrs:{"sidebar-items":t.sidebarItems},scopedSlots:t._u([{key:"top",fn:function(){return[t._t("page-top")]},proxy:!0},{key:"bottom",fn:function(){return[t._t("page-bottom")]},proxy:!0}],null,!0)})],1)}),[],!1,null,null,null);e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/20.9741499c.js b/assets/js/20.9741499c.js new file mode 100644 index 00000000..55efb386 --- /dev/null +++ b/assets/js/20.9741499c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{302:function(t,s,a){t.exports=a.p+"assets/img/redux.e6057df8.png"},303:function(t,s){t.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtUAAAFTCAYAAAD2svAzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAACEKSURBVHgB7d1bjFx1fifwvzc8rMY49qz2hYswO1lhIq4a5yJxGZtJ8gCYy7DSCg8szhIJGNgddi4aLlKGcaJw2ywJswsLSJkMs4B52ckYG3hIMjHXUVZhxWXQMqPNro24PMYGjPISOfU98O8cl6urq/vf7e62Px+pVNV16pzzP/9zqupbv/qf6hUHBgoAADBn/6wAAABNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGxxRgpAP/8EoB4FArfmF9AQ6mUg0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGh1TAI5wX/yN6w/6e8s1l5QtWzaVuciyfvyXD5fF8Nxzr5Stv/fIQfetWbOq/PB//mFZCLv3vF9OXnvc1N//4l9eUP70T+4ol122sQBwMKEaOOLtGoTR7/3Jd8rJJ38SEL/73W3l1dd+Vv7ovm+U2cqyFsv/3/1+OTC4vuPb103dl1C9UK699jvl24N1bdywvvv7e4NAveHT2wAcTKgGjgoXbFxf1n5adU319fO/ctVUqE5F9v77n+hun33WuoOq2K++9vPy6KM7uts33/zlg5aZqnE/4N4/COtbrtk0FXTz92uD+c8665SuulurvllflrlncL3hC+un1pd17d79Xnd/rkeF/n918vFTIbdveN3ff3Rn2TjY5qwz07L+uo3Zjn4FOo99/vlXyurVx05Ny31p5w9+sLPs3fthuXwwf9rVN2q+2paE736/9dcHcCQypho46uzd99HU7QTHDOk4eRBWEzy3/v4jXSis0674N9/spiUkpnLbNzwUI/Pt+3TZX/v6f+mC8aWXbuiur7jiGwetL64ZhODtT+2aWt+rr/68XPs7W7sQO9uKcH/d8YMf7OjWW6d9fdCeLDOh+/Prv9yto27Dd7/7RNfObGfalmlnn31KWTMIy/lAcPbZ60Zu31ODtme+LLPOVx+Xvsr6ssz++gCOVCrVwFHhR9t3DSqqn1RxEyJv/urm7nZXbf7d66aqxRmfnCCd6cPTEh53DY3PHiUV5+1PPVf+3/99qvs7Vd6sP8Fy++D6skEQrRXusweh9XP/+tKp9iSI9qvfo7ajPwQl89V5x8kwjqwrbUkbuvHS5ZMA/L9feWKqkpxqfj505LHZ3oTq4Spz5h3evq76Pqhq17bcN6iy14p61rd9+3NzHscOsBwI1cBRISf5daF4cJ2gWIPrnkE19/5XfzYIhDumHlsrvJm29pp/CoIbJ6wep+KcdfRd/unJfQncrw3W1z95MmG7Dq347AxjpBO6+8NCUk2eRH+56Yes89VUpIdC8+UTnISY/hkO2hnGkqEgVYapVGt7twGOVEI1cFRIEE0VNqE6leiEyoTLXPJrIBs2HhqYM21fb9jC7qExxcPqEIfPrjn2oPmGbdlyySG/oLF2wjHHCcfzNT45y5lpm0apobxv374Pu7HVAEcrY6qBo0qqzanO1nHMl166sRvXnIDZhcxBFbaeYHdW73FR769q5TvyuBo0U03uTjr8NLDmuo4rzsmEWU4qzFMn9n16AmGLT04u/KR9adMkv1Jy8qcV5AzPiLQv7Uzbq1EfDmoYr4/LfPVkSICjlVANHHUyvriG4N/esqmrEmdccwJlqtg1HGaISIYu1GnDMj3DODI9y6ohNWE7Pz+XafWS6nTuT6jP8vPrI1lmpuUXR1p99aubuzHNaUuuJx2qkt/c/to37pvajrTt7E+HruT2lwb9kZMS+7IdmS99lfmyLRlLvdHP7QFHsRUHBgpwiAP/sHi/R8zhl1CcE/RGDa2oFejpfhO6DiUZJRXdVKWHp49bX4txbRlnunbOtMxx83HkWvELPkDBMKEapiFUA4wmVMOhDP8AAIBGi/7rH/v37y+wFH3mnxcARvDezUJYuXJlWc5UqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKDRov9HRViqPv77UwsAwCRUqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0Eqphju68885y/fXXl1tuuaUstj179nRt2bdvX2H20nfpw+XqhRde6LZhOWzH66+/PtXW3F4oO3bs6C4Ah4tQDXOQEPP444+XSy65pFx11VXlcMg6pwtMb7/9dnn66aeXdTBcLPkg8uKLL3b9e7gkTM5noDzppJPK1VdfXT744IPDuh1zsXbt2q6ta9asKQ888EBZKG+88UZ3mQ/jnnssXP8s5PEBC0GoZtnYu3dvaZEX/eFl5O+5LDch9rzzziubNm0qZ555Zpmt6d6AxrXnwQcf7NY7yvnnn1/eeeedadsy0xve4Q4M49Y3rg/q/dNNn8t2rF69urz55ptd0BvXprlMm0725VxD9aj+SVDNMZBtmau5HgOznS9tTFtnet6MW+5cp831+T7uuTfTOseZ6Vif5Hkw6jEL0Z5xZuqfuSwz25DlwnIiVLOk5YX1nHPO6YZYnHvuueXYY4/thl1UF1544UGVuRtuuKE89thj3e1UOU488cTuMbmcdtppZfPmzVOPzfQs86KLLuqmTfpGlGWlPakMZ778XQ0vJ9Nqe9K2tD2PyXpz3R+uUdtTp9XlJHzl73yVnWXk9re+9a2p+dKW3JfLqP5LG7KNw303U3sWQtpT90P2Tb8SlTfe2ta0pz+sJvPkOMg8afdwe7OcutxcTxpY63yjtj3rqX17+umnH/SYft/VaXV/5RuM/jFRt7l/e+fOneXWW2/tbl955ZUTtbW/L4f7Zzpp7wknnNDdznHYv51tqLf7fZe2RZ5X9fH9/qrz1edmna9/bLWYrj11nf1p/eOnTqvP5/4xMO7YGmem516dXtc5aR/M1J4sJ/fX7azHVubJsJkcc5kn8+c5UV8Da3tmu09qe7LcXLKt9VjP8Zx1VllXPb7H9U89Purzdfj1Z9RrZd2OzJNtq/s0l6X+DQyEUM2SlxfufL2damIueSOdJADfdNNN5aWXXupejFNR/uijj8qzzz7bTcsbd94sMv3ll18ut91221RYmEmWcc8995SLL764a09d5iTqOlNVzjbVwJ02pirzzDPPdMvMkJL6BpSKXu5Lde+hhx7qbt97771Ty0xbct+oPskbU7a99l0CSv/Nabr2zCSPq+Nic5n0De+uu+4qN954Y9fndd9UGYKRbc20tDX7vU7Ptm3btq3b1gSATE/FM/fXilbdl3lc/8PTODlG6rJGBfFU3/r90x+j2++79PEkASYV5awvj7/77ru7208++WSZRPbddP0znWxXhlmkj9K/K1as6G5nWES+aYknnniiO+6y3BxfdTtqNbm/jvRznit1+/OYzJfLfISeui9re3KdkFYDXo6frL9OS1v7H3TyvEnfZFp/6Ee2PX1R+y7zTPIaMtNzL8dZvT/rzGvTJP0wrj25zr7OsZXXlmxTv2Kbb1QyLc/BzJ9juK4z7cnxX/sn+2iS9uQDXo7NHMu5pG2TDL2YqX9yjJ5xxhkHvXZP8sE9y0r76/OlrgOWumMKLHF5gc8bR+RFNuOY80aR27Odv8obbu7vV4gORyUkgTIhJ/ImUd9gsu68edZtuv3220urLDsBtN93WUfejOsb1HTtmUneTPv9nzfOSSTIJRglrGaehOQqQTNqqKtBo7Y160tb6xCHXOcxCSDD+zLbnXlnc4yMkg9O/f7pf8Xd77vczgeYhZT9mG2drn+mk+l1DHcCaY613K7nAiRUJ3xlebn0P1zkOMz6Eu7qcVP7NLfrybHZlwlCrfK8zDb1P6Dkg0DalPXlg0ja2p+efZ39l+2qH1DSxno81bbm+Mi3Ajl2s78mPTamk/Xlg1b/+EzgrW0dp7YnHwSyjOyX2p5c53lRg3SWN+r4rMdenZbHpS+Gw/Akx0jm7e+/9F3a1vo6NOq1Ox9Mxw21guVMqGbZGRf8Rk2rbz7Dj8uba/+N93C80LeMeZ2t6cYx9vtjru2ZyzjySB/nDT7hKQExATtVtVoZy315E64haRJ5bA00/fW0hqbZmO0xORcJYQn1CcOz6Z8E3loZzX5LOE7QqvswX81nmdkvw6GsBvKsK/uqH7wyLWE7+zKPydf3P/nJT5qO8fq8HN6X9UNbPrhkvfV522/r8Hr7f9dx8/UDRa0wt1Q/64e6Udswybz99mS7anvydwJtgnUelw8Vu3fvLpPIc3u6vhsnbR7Xf3M1/No7aj1wJDH8gyUvL8R1WELCQL8SlBft/hCBScfSJkTksXkDr29kkw59GCdVp1TSanvGnbzTlzZkvvoVcMJCfxxjZFtnc8JPQmUudbsyb6pfk1aVF0LCQvokoSghon9iVMJZ7s8l/Thp32Uf1iFC9WS9+RrfO04+ANQAldv1mEw70p7+tFFmG7bTH6mcz7Z/6rGVfsol7akfOOrJu6lIDlfiq3zISaDvV2Uj92VZaU/mzzJbf9Eky0qb6rpynX1Zw1mm1Q8AtbJeZdtqyM421edh5DmQ9ma+bE89ZiY16rmX7e2/5tRhG5P8GlDaOV178jzIczR9UV+bJpFl1Kp95ssyso6E8plkXf0hJvV4qfrHRb9fq+lem9Inw6/PdbnZt/W5MZvXSljKVKpZFvKCn0pZ3kT7X93mdoJaXuhrJa6qb/r1ZJcMPXj44Ye7aXnTySUn0tSKU8bwtUq4yFfM9c1i0opu2pI341QN82Yzqj1p/1e+8pVu/GPCVR27mAphfUOqJ8SlChYZX5kqWL/vFvOr16w/VcJsY8JDAkXdl9n+7MsaVietIo7qu2z3JNKWGoBzO8dCHcs5kzw2/V0rb3V/pT35mjvHVvS/Danqtua47h+X42SeHFt1qMaoY70Oh8n+zlCJtCOPO3DgQLee+hwZHrJQtyNtHa4kZh9lndl3fXXIS11vDXMzSaDMdtdAnHXX4znLyHMoy63PyzqGu7al7qfh53s+pGW+Gvr64Tb9kHXWfVK3dVJZVvq4/9zLMjLcpD9+f9JhJenztKUGzn576vj8PK/rfs7+m0S+OajPr7wmpD2TVIbT5zkec9JjJJDX51BtTz1GRr2mTffaVIdl1X3d75+sM9tY99dwv+XvrCttynLSnrl+QwaHy4oDkz5bF8j+/fsLTKcG4pxkmNv1xKu+VEjyoj2Xr/vnOm/eCJ5//vmRYWgx2jOT6fpusSylfTkXCSD1JxWnW+dC9PlCbeO45WY7ElbrB7VR0xfi2JrrMTKuPUvt+TVTv8+1X5dCe/rHzUI83zkyrVy5sixnQjVLWj9ULxWpbKbqlTeJ/ol2HD1qqD4aTrg6mraV+TPThzEYZbmHamOqWdJS2Thc/7FwUnWoyfDX4Rw9EjKPlupa6i4CNbOV1+7ZDLGBI4FKNQAAi06lGgAAjnJCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCg0TEFjlJvfeZvCwCHOvXjXyrA7KhUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjXAPNr56FPlka3/vSykD/d+2F0AWDqEaoB59N7u98r7e94vC+m+r/3n8tz2vyoALB3HFAAWxM9f/dkgZL9bPtr7UXnl+b8p6zf8Stm05dJpp2247IKyas2qrgqdivfmm6+aWtYjWx8q191xQ9n1o78qP3vtrfLhvg+6++vyAFhcKtUACyTBeeu13y7v7XmvbLrm0vLE/Y9NDQ2p0xKQN1x6QXll19+Ub17xn7ppCdXbBo/tq/Mdf/Lxg8sJ5bi1J5RTzlpXAFgaVKoBFtD6Db/aVZjjuju+clBYPm4QkL/xR9/qbm+8/ILy5c//2y5c5/7pnHL2urJq9aqybnCd2wAsDSrVAAto1WdX/dPt1asOmrbu7FMP/vusU8v7g6o2AMuPUA2wRGSc9LFrPgneft0DYHkRqgEWya4f/bi8v/uTynSucxLiurPWdeOmI0NBYtv9jxcAljZjqgEWyfqNv1qu/+LvdNXpjwaV6e/86e9PjafO+OtMS8Ae/oWP/L312t8tu7b/uPzhD/+4ALD4VhwYKIto//79BRbDW5/52wKLZef3n+p+Su+O7/1eV6VOsF61ZtUhj8swkFH3zzQNWpz68S8VONxWrlxZljOVaoBFNu7XPsaFZoEaYOkQqgEWQX4O79g1xxYAjgyGf3DUMvwDYDTDP1gMy334h1//AACARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEb+oyIAAIvOf1QEAICjnFANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQ6JgCLHs7d+4sr7/+ejnppJPKJZdcUlavXt3df+edd5Y9e/aUtWvXlttvv33sMl544YXusVdffXWZyd69e8vjjz9e9u3b161zknmWm/Rpti/OOOOMcuaZZx7ymAceeKC7vummm8pSleMi+3Y+2vjYY491x9L5558/0eOz7vThpI+fRI7RHNc5ntMWgKVCpRqWuVtuuaULdwkYL774YjnnnHOmwuCmTZu6wJvpCSPjvP322134msS5557bPT7rTLi+4YYbDpqedU26rGE1qC629GtCYS6bN2/u/h6W/s72H04JtrORYyEfEOZDtnem46gvfXbllVeW2ar9Pp1sz1yPL4CFIlTDMpZgkYDx7LPPlquuuqo89NBDXVW1BtNUV1MlXLNmzbTLSNV5tuuMe+65p1vnk08+eUjQStAcF3qyzlHrzXIefPDBWc83iQsvvLDM1o033tht55tvvtmFvFRI+7Zt21ZefvnlkfPO1NZx06YLrmnDuBA/0zrHBeK5Ths3Tz545Ric7liYbrk5BqYL1fkg9+6770777UhLHwC0EKphGUugTrDtS9iYpIqXcJGgefrpp5cTTzxx4gpoQlJCS318hpok1NdlnnbaaV0oyiW3+2G2rvOiiy7qqt39kJqqZu6vy8ilvx35oJB58phMm204SsBrkeEG/Ypv2pB+G1VZz3alX1Ph7rc116ncprKfbRmev/ZPna/fP5kn2/7GG29M9U+/D2r/ZL3D07Lttd8zrb8dCa9pR11n/zjItNxX55tNH2bf5QNdvi0ZrpSnrVlnXW4N0HXf5/G33nprd7tf6c58ddvrtzHDfZftz6X/zUL6MX/nW5z00VyOH4CZCNWwjNUxzX2pVE8Sfu66666u6vfOO+90ldhJJUQ//PDD3fwJJwk6NeBkeVlWKry55HYN3JEqa0JWqru59IelpCL8zDPPTC0jlzoWN0EvQw9eeumlbr7bbrvtkCEno6Rd119/fXfJB4F6ey6BKv3cny/tS5tHVVQT4n760592255+6H84SGA877zzuvmzPXls7b9R/VOn5VuIVMazf2v/1DHFWWY+xGR52Z/5oNUP5Gl35q9troEzy06Yrv2a/u+3J9Pqfsy01157rUzq6aefLhdffHG3Pf2gXr+NyDqz3LSrtrXu+8xz9913d7fzTUiVceH1WB2uRud4zPGS7c9l+JuF9FG2IdPyuHHfiADMhRMV4QiTQF1PVBwn4aaevJjHp8L9/PPPl0kk9OSS4JJwkgrgJME860tQrGEnw1Lq2OxxEqgTovrVx0nH1NZhAllGvT1J/wxL0Bw3jKYvJ4umCps+SmU/11Xt68h2f+ELXyg7duzo7kuATbDu90/6eKYT/dIXCdK1fcMnpWb+2se5XT8cZNnp1374XLFiRdeebEOm1RMcM3/um0T6KstIYM72pl21cp39kA8G/fbMx4mMCe4ZFlKl3f0wn31Q+yfrm/RYB5iUUA3LWMJJhgP0JTANV69HGf76fFIJYgnCNTAmONWv8Ef9QkZfqssJWTVkzuYEuuFwOskvjmRd/cDWEt6yfenvSaSinBCZeRLscl2D7nAwT3CtIT9DHvr9M5uTICf9oDD8uITbfl/mdrZz1LjkSY+ZbHu2sz90o4bqUW2YD6OW2W/vQqwToM/wD1jGEoBSEeyP2c3X4MPjrEdJwOmH2kkDbh1S0V9nPxj2HzcswSpDH7LuBP9xv/DQV6vitapZw+pspAo8V2l3+nWmnyWMtC2V+3wISLU0l35Vvf/LKLnd/zAy3D/Dw1TSx6OG9qR/6k8cRv/bgHHq+Pisq64z3wakWp2wXSvM/bZOIsdShm9k+Esu+eBVj686xrpuW5Y/6iTS2X7oy7b0x6enPyZ5HgDMF5VqWMYSsu69995uqEFuJ4gkPNav6RNWEsISYPKYqOOWExAT/hI+anV0kl/WSPhKUMwJX3X89vBvBmdZGY+b8JSgVsdVp22pxtbxrMPDCepvIOcktrQpFd9aoU74SkW8bme2Yzbm8jvNtc+yDQmG/fCbqnsNfmlXti3rqO1N32a+9E+2o0r7++PB+31X+6eOdx+urGfZudT+qfuynhCYdc6mf/rHT21r2lA/IKXd2Y/1sZNW+vNBL+PeqzrkpP5mevopfZZtyTqH25ownD7KcZIPGRnDH2lLgv2o4zn7J/fVDxf15yQBDpcVBwbKItq/f38B2iVo1PGrh2O+BPCEl9nOW+ebyz/uaJn3cBvV1hoGM/58un5frP4ZdxzUMDyfFmpfzvV4BhbfypUry3ImVAMcJv1QDcDBlnuoNqYa4DBJ9bR/siUARw6VagAAFp1KNQAAHOWEagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAZa4O++8s7sAsHQJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAEvQY489Vl5//fVD7s99mQbA0iJUAyxBZ555ZrnyyisPCta5vXnz5m4aAEvLigMDZRHt37+/AHCohOgE64ToFStWdH9v27ZNqAaOSCtXrizLmVANsIQlSF944YVdqH7mmWcEauCIJVQ3EqoBxqtDQARq4EgmVDcSqgEAWO6h2omKAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARscUYKS33vtMAeBQpx7/cQEOplINAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAL6JW/3lW+edMV5dIvfq5c/+++WHb+8NGJ5/3ww73dZT68/87uAsDCEaoBFsiuv/hR2XrbtWX9r20oD//gx2XzNV8tj/y3rWXbo/dPNP+279/fXeZDAv377+4pACwMoRpggdz3B18vX7/9vrJ5y83luBNPLht/6/Ly8P/4cXnkv26dqkD3b0cC9/vv7u4q3K/8r+e6Sw3hu/78R+Xn/+fVbp6tt157UNU78/T//vCDvVPz5TrreOLRP+6WC8D8E6oBFkDC77Gr15SNv3n5Qfcfd8LJ5ZRfPrs89+fbu78TkD/6YN/U9FSm33tndzl+EMKPP2Ftd0mlO577y+3lO4MwHZu+dM0gJN8/FZwzz44/64XqQYiuVe5TTj2rrFq1pqwbXGe5AMy/YwoA8y6V4gTZURKUZ5LwnUskhFfrBrev+493dLdT9c5Y7U1XbBm7rPW/vvHT6wsGy5x53QDMnko1wAJY9Ytrpj3J8MNBZfrYX1xT5qJWres6Etz7lW4AFodQDbAAUmXOL25krHNfgnaGhqz75bO6v1fNMlwPB/XpgvtHH8zPr4YAMBmhGmABJCxf9x/uKN+48YqpYJ0AfN8ffK1s+K3LpoZ2pNJcTx7M9XsjQnjfjh8+OnVfxlNnPRnSkeuE9bquV/76uUPa9OEHf1cAWBhCNcAC2fzbN5eNv3lZ+fJln+/GPl81uM6wjzomOvLrIPmZvUzf+WePluM/DduReZ/7i+3dz+FV6399Q/nmIKhnmQnVGVcdGXe96UtbyiUXfK5b1iFt2XJzt5ycGAnA/FtxYKAsov379xdYit567zMF5kuGguTXQKY7eTHV55mmbb3135f1v7axOzExyztuxC951Cr2qGWNmwazcerxHxeYbytXrizLmV//ADgMjpvhp+zGBd1R06Zb3myXA8D8EKoBlokNv3GZ35kGWKKEaoBlIv+REYClyYmKAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0GjFgYGyiPbv318AADi6rVy5sixnKtUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABotOLAQAEAAOZMpRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI2EagAAaCRUAwBAI6EaAAAaCdUAANBIqAYAgEZCNQAANBKqAQCgkVANAACNhGoAAGgkVAMAQCOhGgAAGgnVAADQSKgGAIBGQjUAADQSqgEAoJFQDQAAjYRqAABoJFQDAEAjoRoAABoJ1QAA0EioBgCARkI1AAA0EqoBAKCRUA0AAI3+EYJdoJc+ESjhAAAAAElFTkSuQmCC"},304:function(t,s,a){t.exports=a.p+"assets/img/reduxasync.0f79d5bf.png"},344:function(t,s,a){"use strict";a.r(s);var e=a(14),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-react-redux-を基礎から理解する"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-react-redux-を基礎から理解する"}},[t._v("#")]),t._v(" ⚪️ React Redux を基礎から理解する")]),t._v(" "),s("h2",{attrs:{id:"redux-の基本概念"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#redux-の基本概念"}},[t._v("#")]),t._v(" Redux の基本概念")]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("Redux Overview:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Redux")]),t._v(" serves as an alternative to React Context, offering a centralized data store for the entire application.")]),t._v(" "),s("li",[t._v("The store manages all states, eg. critical data like authentication status and user input states.")]),t._v(" "),s("li",[t._v("It provides a unified state management approach by acting as a single store applicable to the entire application.")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(302),alt:"redux"}})])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Subscription to Central Store:")])]),t._v(" "),s("ul",[s("li",[t._v("Components subscribe to the central store for updates.")]),t._v(" "),s("li",[t._v("Subscribed components receive notifications when data changes occur in the "),s("strong",[t._v("Redux store")]),t._v(".")]),t._v(" "),s("li",[t._v("Components selectively retrieve needed data, such as "),s("strong",[t._v("authentication status")]),t._v(", from specific portions of the Redux store.")]),t._v(" "),s("li",[t._v("This establishes a "),s("strong",[t._v("unidirectional flow")]),t._v(", enabling components to access and utilize data provided by the "),s("strong",[t._v("Redux store")]),t._v(".")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Important Rule:")])]),t._v(" "),s("ul",[s("li",[t._v("Components refrain from "),s("em",[t._v("direct data manipulation")]),t._v(".")]),t._v(" "),s("li",[s("em",[t._v("Subscriptions")]),t._v(" are established for components to receive updates, ensuring an indirect and controlled data flow.")]),t._v(" "),s("li",[t._v("Components avoid engaging in a direct data flow towards the storage.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Introducing Reducers:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Reducers")]),t._v(" handle data mutations and changes within the stored data.")]),t._v(" "),s("li",[t._v('The term "reducer" in '),s("strong",[t._v("Redux")]),t._v(" differs from the reducer hook in React.")]),t._v(" "),s("li",[t._v("A "),s("strong",[t._v("reducer function")]),t._v(" takes input, transforms it, and produces a new output, adhering to general programming concepts.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Understanding Reducer Functions:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Redux reducer functions")]),t._v(" accept input, transform it, and generate a new output.")]),t._v(" "),s("li",[t._v("They play a crucial role in updating stored data, following general programming principles.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Components and Actions:")])]),t._v(" "),s("ul",[s("li",[t._v("Components do not directly manipulate stored data; they use subscriptions for updates.")]),t._v(" "),s("li",[s("strong",[t._v("Actions")]),t._v(", triggered by components, describe the type of operation a "),s("strong",[t._v("reducer")]),t._v(" should execute.")]),t._v(" "),s("li",[t._v("Components dispatch actions as simple JavaScript objects, specifying the operation type.")]),t._v(" "),s("li",[s("strong",[t._v("Redux")]),t._v(" forwards actions to the appropriate "),s("strong",[t._v("reducer")]),t._v(", which performs the specified operation.")]),t._v(" "),s("li",[t._v("The "),s("strong",[t._v("reducer")]),t._v(" outputs a new state, effectively replacing the existing state in the central data store.")]),t._v(" "),s("li",[t._v("Subscribed components receive notifications of state updates, facilitating UI refresh.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Three Principles of Redux:")])]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("Single Data Source:")]),t._v(" The entire application's state is stored in a single "),s("strong",[t._v("store")]),t._v(".")]),t._v(" "),s("li",[s("strong",[t._v("State is Read-Only:")]),t._v(" State changes occur only through triggering "),s("strong",[t._v("actions")]),t._v(", containing a required "),s("strong",[t._v("type")]),t._v(" attribute.")]),t._v(" "),s("li",[s("strong",[t._v("Use Pure Functions for Actions:")]),t._v(" "),s("strong",[t._v("Reducers")]),t._v(", implemented as pure functions, describe how actions change the state tree.")])])])]),t._v(" "),s("p",[s("img",{attrs:{src:a(303),alt:"redux"}})]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("Store and Reducer Relationship:")])]),t._v(" "),s("ul",[s("li",[t._v("The "),s("strong",[t._v("store")]),t._v(" manages data, and its content is determined by the "),s("strong",[t._v("reducer function")]),t._v(".")]),t._v(" "),s("li",[t._v("The "),s("strong",[t._v("reducer function")]),t._v(" produces a new state snapshot whenever an action reaches it.")]),t._v(" "),s("li",[t._v("Upon the initial code execution, the reducer also executes with a default action, typically setting the initial state.")]),t._v(" "),s("li",[t._v("It is crucial for the reducer function to return a new state object consistently.")]),t._v(" "),s("li",[t._v("The reducer function is a standard JavaScript function, always receiving the old/existing state and the dispatched action.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Reducer Function Structure:")])]),t._v(" "),s("ul",[s("li",[t._v("The "),s("strong",[t._v("reducer function")]),t._v(" is a JavaScript function, typically created using arrow function syntax.")]),t._v(" "),s("li",[t._v("It must always return a new state object, ensuring it adheres to the principles of a pure function.")]),t._v(" "),s("li",[t._v("Pure functions guarantee that the same inputs yield the same outputs and have no internal side effects.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Default State in Reducer:")])]),t._v(" "),s("ul",[s("li",[t._v("During the first execution, when the store initializes, the state might be undefined.")]),t._v(" "),s("li",[t._v("Provide a default value for the state parameter in the reducer function to handle this initial case.")]),t._v(" "),s("li",[t._v("The default value ensures that the state is set to an initial value, preventing undefined errors.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Creating and Subscribing to Store:")])]),t._v(" "),s("ul",[s("li",[t._v("Components subscribe to the store using a subscriber function.")]),t._v(" "),s("li",[t._v("The subscriber function is notified whenever data and the store change.")]),t._v(" "),s("li",[t._v("Use the "),s("code",[t._v("subscribe")]),t._v(" method on the store, passing the subscriber function, to establish the subscription.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Dispatching Actions:")])]),t._v(" "),s("ul",[s("li",[t._v("Dispatch actions using the "),s("code",[t._v("dispatch")]),t._v(" method on the store.")]),t._v(" "),s("li",[t._v("Actions are JavaScript objects with a "),s("code",[t._v("type")]),t._v(" attribute acting as an identifier.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("type")]),t._v(" attribute should be a unique string, representing the type of action to be performed.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Sample Action and State Update:")])]),t._v(" "),s("ul",[s("li",[t._v("Example of dispatching an action to increment a counter.")]),t._v(" "),s("li",[t._v("The dispatched action contains a "),s("code",[t._v("type")]),t._v(" attribute indicating an increment action.")]),t._v(" "),s("li",[t._v("The reducer function interprets the action type and produces a new state with an incremented counter.")]),t._v(" "),s("li",[t._v("Subscribed components are notified of the state update.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Understanding Output:")])]),t._v(" "),s("ul",[s("li",[t._v("Executing the code demonstrates the incrementing counter as actions are dispatched.")]),t._v(" "),s("li",[t._v("The store initialization and dispatching actions lead to state updates reflected in the output.")])])])]),t._v(" "),s("hr"),t._v(" "),s("h2",{attrs:{id:"redux-s-core-api"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#redux-s-core-api"}},[t._v("#")]),t._v(" Redux's Core API:")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("Redux.createStore(reducer, [preloadedState], [enhancer])")])]),t._v(" "),s("li",[s("code",[t._v("store.dispatch(action)")])]),t._v(" "),s("li",[s("code",[t._v("store.subscribe(listener)")])]),t._v(" "),s("li",[s("code",[t._v("store.getState()")])]),t._v(" "),s("li",[s("code",[t._v("store.replaceReducer(nextReducer)")])])]),t._v(" "),s("h3",{attrs:{id:"createstore"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#createstore"}},[t._v("#")]),t._v(" createStore")]),t._v(" "),s("p",[s("strong",[t._v("createStore(reducer, [preloadedState], [enhancer])")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Creates a Redux store that holds the complete state tree of the app.")])]),t._v(" "),s("li",[s("p",[t._v("There should only be a single store in the app.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("createStore")]),t._v(" accepts three parameters:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("reducer:")]),t._v(" A reducing function that returns the next state tree, given the current state tree and an action to handle.")]),t._v(" "),s("li",[s("strong",[t._v("[preloadedState]:")]),t._v(" The initial state.")]),t._v(" "),s("li",[s("strong",[t._v("[enhancer]:")]),t._v(" The store enhancer. You may optionally specify it to enhance the store with third-party capabilities such as middleware, time travel, persistence, etc. The only store enhancer that ships with Redux is "),s("code",[t._v("applyMiddleware()")]),t._v(".")])])])]),t._v(" "),s("blockquote",[s("p",[t._v("store/index.js")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" createStore "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("counterReducer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("counter")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"increment"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("counter")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"decrement"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("counter")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" store "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createStore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("counterReducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" store"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("index.js")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" ReactDOM "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-dom/client"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Provider "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./index.css"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" App "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./App"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" store "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./store/index"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReactDOM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createRoot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nroot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Provider store"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("store"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("App "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Provider"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("Counter.js")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" classes "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Counter.module.css"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useSelector"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useDispatch "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Counter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Again, this function will be executed for us by React Redux. it will then pass the Redux state in order to manage the data into this function when it is executed, and then basically execute this code to retrieve the state portion of this component that is needed. then use select or overall to return the value. useSelector((state) => state.counter);")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useSelector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Redux automatically sets up a subscription to the Redux store for this component. So whenever the data in the Redux store changes, your component will be updated and automatically receive the latest counter. So it's an automatic reaction that changes to the Redux store will cause this component function to be re-executed. So you'll always have the most up-to-date counter.")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dispatch "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useDispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// dispatch is a function we can call, that will dispatch an action on our Redux store.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("decrementHandler")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"decrement"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("toggleCounterHandler")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("main className"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("classes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Redux Counter"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div className"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("classes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("incrementHandler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Increment"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("decrementHandler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Decrement"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("toggleCounterHandler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Toggle Counter"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("main"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"useselector"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#useselector"}},[t._v("#")]),t._v(" "),s("strong",[t._v("useSelector")])]),t._v(" "),s("p",[t._v("In React Redux, the "),s("code",[t._v("useSelector")]),t._v(" hook requires two parameters:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Selector Function:")])]),t._v(" "),s("ul",[s("li",[t._v("This is a function that takes the entire Redux state as a parameter and returns the portion of the state you want to extract. For example, if you have a Redux state tree with an object named "),s("code",[t._v("stock")]),t._v(", and within the "),s("code",[t._v("stock")]),t._v(" object, there's a property named "),s("code",[t._v("counter")]),t._v(", your selector function might be "),s("code",[t._v("(state) => state.stock.counter")]),t._v(". This function determines the data that "),s("code",[t._v("useSelector")]),t._v(" will return.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Equality Function (Optional):")])]),t._v(" "),s("ul",[s("li",[t._v("This is an optional parameter used to compare the values returned by the selector function in consecutive calls to determine if the component should be re-rendered. If omitted, "),s("code",[t._v("useSelector")]),t._v(" will use reference equality ("),s("code",[t._v("===")]),t._v("), meaning it will re-render only if the object references from the previous and current calls are the same. If you need to customize when the component should re-render based on some condition, you can provide a custom equality function.")])])])]),t._v(" "),s("p",[t._v("For example:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useSelector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("stock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" next\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In this example, the first parameter is the selector function, extracting "),s("code",[t._v("state.stock.counter")]),t._v(". The second parameter is a custom equality function that uses reference equality to determine whether to re-render the component based on the returned values from the selector function.")]),t._v(" "),s("h3",{attrs:{id:"dispatch"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dispatch"}},[t._v("#")]),t._v(" dispatch")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dispatch "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useDispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// dispatch is a function we can call, that will dispatch an action on our Redux store.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("decrementHandler")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"decrement"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//Attaching Payloads to Actions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[s("a",{attrs:{href:"https://itsyuimorii.github.io/memo/jsreview.html#reference-vs-primitive",target:"_blank",rel:"noopener noreferrer"}},[t._v("Reference vs Primitive"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"redux-toolkit"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#redux-toolkit"}},[t._v("#")]),t._v(" "),s("a",{attrs:{href:"https://redux-toolkit.js.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Redux Toolkit"),s("OutboundLink")],1)]),t._v(" "),s("blockquote",[s("p",[t._v("When our application grows in complexity, using Redux can become more intricate. In this course, we'll explore a simpler approach to utilizing Redux. Before we proceed, let's consider some potential issues:")])]),t._v(" "),s("p",[s("strong",[t._v("Potential Issues:")])]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Action Type Identifiers:")])]),t._v(" "),s("ul",[s("li",[t._v("As the application grows, there may be numerous operations, leading to confusion with identifiers.")]),t._v(" "),s("li",[t._v("Issues such as misspelling or conflicts in identifiers might arise.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Data Volume Management:")])]),t._v(" "),s("ul",[s("li",[t._v("With an increase in data volume, the state object becomes larger.")]),t._v(" "),s("li",[t._v("The Reducer function becomes more complex and may be challenging to maintain.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Respecting State Immutability:")])]),t._v(" "),s("ul",[s("li",[t._v("Ensuring the consistent return of a new state snapshot and avoiding unintentional alterations to the existing state.")]),t._v(" "),s("li",[t._v("Complex nested object and array data can lead to unpredictable state changes.")])])])]),t._v(" "),s("p",[s("strong",[t._v("Solutions:")])]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Unique Identifier Issue:")])]),t._v(" "),s("ul",[s("li",[t._v("Use constants to store identifiers, avoiding spelling errors and ensuring type consistency.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Data Volume Management and Complex Reducer Issue:")])]),t._v(" "),s("ul",[s("li",[t._v("Redux Toolkit provides solutions, such as splitting the Reducer into smaller ones.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("State Immutability Issue:")])]),t._v(" "),s("ul",[s("li",[t._v("Manual implementation of solutions is possible, or Redux Toolkit tools can be used to automate state copying, ensuring unintentional state edits are avoided.")])])])]),t._v(" "),s("h2",{attrs:{id:"redux-toolkit-s-core-apis"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#redux-toolkit-s-core-apis"}},[t._v("#")]),t._v(" Redux Toolkit's Core APIs:")]),t._v(" "),s("ul",[s("li",[s("p",[s("code",[t._v("configureStore()")]),t._v(": wraps "),s("code",[t._v("createStore")]),t._v(" to provide simplified configuration options and good defaults. It can automatically combine your slice reducers, adds whatever Redux middleware you supply, includes "),s("code",[t._v("redux-thunk")]),t._v(" by default, and enables use of the Redux DevTools Extension.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("createReducer()")]),t._v(": that lets you supply a lookup table of action types to case reducer functions, rather than writing switch statements. In addition, it automatically uses the "),s("code",[t._v("immer")]),t._v(" library to let you write simpler immutable updates with normal mutative code, like "),s("code",[t._v("state.todos[3].completed = true")]),t._v(".")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("createAction()")]),t._v(": generates an action creator function for the given action type string. The function itself has "),s("code",[t._v("toString()")]),t._v(" defined, so that it can be used in place of the type constant.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("createSlice()")]),t._v(": accepts an object of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("createAsyncThunk")]),t._v(": accepts an action type string and a function that returns a promise, and generates a thunk that dispatches pending/fulfilled/rejected action types based on that promise")])])]),t._v(" "),s("h3",{attrs:{id:"state-management-with-redux"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#state-management-with-redux"}},[t._v("#")]),t._v(" State management with Redux")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Redux Store Setup:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" This section is responsible for setting up the global Redux store using the "),s("code",[t._v("configureStore")]),t._v(" function from the "),s("code",[t._v("@reduxjs/toolkit")]),t._v(" library. The store is configured with the combined reducers that handle different parts of the application state.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Wrap the App with the Redux Provider:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" The "),s("code",[t._v("Provider")]),t._v(" component from "),s("code",[t._v("react-redux")]),t._v(" is wrapped around the main application component (in this case, "),s("code",[t._v("App")]),t._v('). This ensures that the Redux store is accessible to all components within the application. It essentially "provides" the Redux store to the entire component tree.')])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Creating a Redux Slice:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" A Redux slice is a unit of the Redux state that corresponds to a specific feature or part of the application. In this example, the "),s("code",[t._v("exampleSlice")]),t._v(" manages a list of items with corresponding actions like adding and removing items. It provides a clean and organized way to define the initial state and actions related to a specific feature.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Using Redux in a Component:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" This section demonstrates how to use the "),s("code",[t._v("useSelector")]),t._v(" hook to access the Redux store's state within a React component. In the example, "),s("code",[t._v("SomeComponent")]),t._v(" uses "),s("code",[t._v("useSelector")]),t._v(" to retrieve a list of items from the Redux store and render them.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Dispatching Actions in Another Component:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" This section shows how to use the "),s("code",[t._v("useDispatch")]),t._v(" hook to dispatch actions to the Redux store from a React component. In the example, "),s("code",[t._v("AnotherComponent")]),t._v(" allows the user to input a new item, and when a button is clicked, the "),s("code",[t._v("addItem")]),t._v(" action is dispatched to add the new item to the Redux store.")])])])]),t._v(" "),s("h3",{attrs:{id:"process-of-using-redux-toolkit"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#process-of-using-redux-toolkit"}},[t._v("#")]),t._v(" Process of using Redux Toolkit")]),t._v(" "),s("p",[t._v("This setup provides a basic structure for handling state management with Redux in a JavaScript app. Action creators generate actions, reducers specify how the state should change, and the store manages the overall application state. The "),s("code",[t._v("useSelector")]),t._v(" hook is used to access the state, and "),s("code",[t._v("useDispatch")]),t._v(" is used to dispatch actions.")]),t._v(" "),s("p",[t._v("🟦 "),s("strong",[t._v("Create the Redux Store:")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// store.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" configureStore "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@reduxjs/toolkit"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" rootReducer "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./reducers"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Import your combined reducers")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" store "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("configureStore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("reducer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" rootReducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" store"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🟦 "),s("strong",[t._v("Wrap the App with the Redux Provider:")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// index.js or App.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Provider "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" store "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./store"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" App "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./App"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("MainApp")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Provider store"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("store"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("App "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Provider"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" MainApp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🟦 "),s("strong",[t._v("Creating a Redux Slice:")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// exampleSlice.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" createSlice "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@reduxjs/toolkit"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("entities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ids")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" exampleSlice "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createSlice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n initialState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("reducers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addItem")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("entities"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ids"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("removeItem")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" idToRemove "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("delete")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("entities"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("idToRemove"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ids "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ids"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" idToRemove"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" addItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" removeItem "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" exampleSlice"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("actions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" exampleSlice"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🟦 "),s("strong",[t._v("Using Redux in a Component:")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// SomeComponent.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useSelector "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SomeComponent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" items "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useSelector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ids"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("entities"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" SomeComponent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🟦 "),s("strong",[t._v("Dispatching Actions in Another Component:")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// AnotherComponent.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useDispatch "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-redux"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" addItem "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./exampleSlice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AnotherComponent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dispatch "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useDispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("newItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setNewItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("handleAddItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("random")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("substring")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a unique ID")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" newItem "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example data structure")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addItem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNewItem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("input\n type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"text"')]),t._v("\n value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("newItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n onChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNewItem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleAddItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Add Item"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" AnotherComponent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🔵 "),s("strong",[t._v("useSelector(): Accessing State")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" "),s("code",[t._v("useSelector")]),t._v(" is a React hook provided by the "),s("code",[t._v("react-redux")]),t._v(" library. Its primary purpose is to select and access the current state from the Redux store. It takes a selector function as an argument, which allows you to extract specific pieces of data from the state. By using "),s("code",[t._v("useSelector")]),t._v(", components can efficiently subscribe to changes in the Redux state and re-render when relevant data is updated.")])]),t._v(" "),s("p",[t._v("🔵 "),s("strong",[t._v("useDispatch(): Modifying State with Actions")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Purpose:")]),t._v(" "),s("code",[t._v("useDispatch")]),t._v(" is another React hook from the "),s("code",[t._v("react-redux")]),t._v(" library. Its primary purpose is to provide a reference to the "),s("code",[t._v("dispatch")]),t._v(" function of the Redux store. This allows components to dispatch actions, which are plain JavaScript objects containing a "),s("code",[t._v("type")]),t._v(" property and, optionally, a "),s("code",[t._v("payload")]),t._v(". By using "),s("code",[t._v("useDispatch")]),t._v(", components can trigger state changes by dispatching actions. These actions are then processed by reducers, modifying the state in a predictable and controlled manner.")])]),t._v(" "),s("p",[t._v("🔵 "),s("strong",[t._v("Summary:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Redux Store Setup:")]),t._v(" Configured a global store using "),s("code",[t._v("configureStore")]),t._v(" from "),s("code",[t._v("@reduxjs/toolkit")]),t._v(".")]),t._v(" "),s("li",[s("strong",[t._v("Provider Usage:")]),t._v(" Wrapped the main application component with "),s("code",[t._v("Provider")]),t._v(" to make the Redux store accessible throughout the component tree.")]),t._v(" "),s("li",[s("strong",[t._v("Redux Slice Creation:")]),t._v(" Created a Redux slice using "),s("code",[t._v("createSlice")]),t._v(" to manage a list of items in the state.")]),t._v(" "),s("li",[s("strong",[t._v("Component Interaction:")]),t._v(" Used "),s("code",[t._v("useSelector")]),t._v(" to access state data and "),s("code",[t._v("useDispatch")]),t._v(" to dispatch actions from React components.")])]),t._v(" "),s("h2",{attrs:{id:"handling-asynchronous-code"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#handling-asynchronous-code"}},[t._v("#")]),t._v(" Handling Asynchronous Code:")]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("Redux Core Principle:")])])]),t._v(" "),s("ul",[s("li",[t._v("Reducer functions in Redux must be pure, without side effects, and synchronous.")]),t._v(" "),s("li",[t._v("Pure functions produce the same output for the same input, ensuring consistency and predictability.")])]),t._v(" "),s("p",[s("strong",[t._v("Handling Asynchronous Code:")])]),t._v(" "),s("ul",[s("li",[t._v("A challenge arises when dealing with asynchronous actions, like HTTP requests, in Redux.")]),t._v(" "),s("li",[t._v("Reducer functions are unsuitable for asynchronous code due to their synchronous nature.")])]),t._v(" "),s("p",[s("strong",[t._v("Options for Handling Asynchronous Code:")])]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Component-Level Side Effects:")])]),t._v(" "),s("ul",[s("li",[t._v("Place side effect code, including asynchronous operations, directly in the component.")]),t._v(" "),s("li",[t._v("Dispatch actions after the side effect completion to inform Redux.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Custom Action Creators:")])]),t._v(" "),s("ul",[s("li",[t._v("Write custom action creators for handling asynchronous tasks without altering the reducer function.")]),t._v(" "),s("li",[t._v("Allows running asynchronous tasks as part of the action creator.")])])])]),t._v(" "),s("p",[s("strong",[t._v("Redux Toolkit Solution:")])]),t._v(" "),s("ul",[s("li",[t._v("Redux Toolkit provides a solution for handling asynchronous tasks within action creators.")]),t._v(" "),s("li",[t._v("It allows the execution of side effects without violating the synchronous nature of reducer functions.")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(304),alt:"reduxasync"}})]),t._v(" "),s("h2",{attrs:{id:"redux-thunk"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#redux-thunk"}},[t._v("#")]),t._v(" Redux Thunk")]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("Redux Thunk:")])])]),t._v(" "),s("ul",[s("li",[t._v("Redux Thunk is a middleware that allows the execution of asynchronous tasks in Redux.")]),t._v(" "),s("li",[t._v("It enables the dispatch of asynchronous actions, such as HTTP requests, in Redux.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendCartData")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("cart")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//instead of return an action object, 如 { type: 'SOME_ACTION', payload: someData }。 我們創建一個一個action creator return another function")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n uiActions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("showNotification")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pending"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sending..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("message")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sending cart data!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendRequest")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://react-http-6b4a6.firebaseio.com/cart.json"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PUT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sending cart data failed."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n uiActions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("showNotification")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"success"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Success!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("message")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sent cart data successfully!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n uiActions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("showNotification")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("message")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sending cart data failed!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("The provided code demonstrates the use of a Redux thunk as an action creator. In contrast to regular action creators, which directly return an action object (e.g., "),s("code",[t._v("{ type: 'SOME_ACTION', payload: someData }")]),t._v("), this action creator returns a function.")]),t._v(" "),s("p",[t._v("Here are some key differences in this approach:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Returning a Function Instead of a Direct Action Object:")])]),t._v(" "),s("ul",[s("li",[t._v("Regular action creators typically return a plain action object. In this case, the action creator returns a function.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Incorporating Asynchronous Logic:")])]),t._v(" "),s("ul",[s("li",[t._v("The returned function contains asynchronous logic. In this example, it involves sending shopping cart data to a server using "),s("code",[t._v("async/await")]),t._v(" with the "),s("code",[t._v("fetch")]),t._v(" function to make a PUT request.")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Dispatching Actions Before and After Asynchronous Logic:")])]),t._v(" "),s("ul",[s("li",[t._v('Before the asynchronous logic starts, an action is dispatched to indicate that the data is pending ("pending" notification). After the asynchronous logic succeeds or fails, corresponding actions are dispatched to display notifications with success or error messages.')])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Error Handling:")])]),t._v(" "),s("ul",[s("li",[t._v("Errors are handled using a "),s("code",[t._v("try-catch")]),t._v(' block. If an error occurs during the asynchronous logic, an action is dispatched to show an "error" notification along with the appropriate error message.')])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("More Flexible Control Flow:")])]),t._v(" "),s("ul",[s("li",[t._v('Thunks provide a more flexible control flow, allowing you to dispatch different actions at different stages of asynchronous logic. For instance, dispatching a "pending" action at the start, a "success" action upon success, and an "error" action upon failure.')])])])]),t._v(" "),s("p",[t._v("In summary, this approach enables action creators to execute more complex logic, including asynchronous operations, conditional checks, and error handling. Thunks allow you to abstract away this logic from the components, allowing them to focus on user interface interactions without having to deal directly with complex asynchronous or side-effect logic.")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/21.7f8f7869.js b/assets/js/21.7f8f7869.js new file mode 100644 index 00000000..19bcbaea --- /dev/null +++ b/assets/js/21.7f8f7869.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{240:function(t,e,n){},242:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(243),n(14)),o=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},243:function(t,e,n){"use strict";n(240)}}]); \ No newline at end of file diff --git a/assets/js/22.3f20ce36.js b/assets/js/22.3f20ce36.js new file mode 100644 index 00000000..80e350d5 --- /dev/null +++ b/assets/js/22.3f20ce36.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{258:function(t,c,n){},270:function(t,c,n){"use strict";n(258)},283:function(t,c,n){"use strict";n.r(c);n(270);var i=n(14),s=Object(i.a)({},(function(){var t=this,c=t._self._c;return c("div",{staticClass:"sidebar-button",on:{click:function(c){return t.$emit("toggle-sidebar")}}},[c("svg",{staticClass:"icon",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",viewBox:"0 0 448 512"}},[c("path",{attrs:{fill:"currentColor",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"}})])])}),[],!1,null,null,null);c.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/23.7c0322e8.js b/assets/js/23.7c0322e8.js new file mode 100644 index 00000000..c7f483c4 --- /dev/null +++ b/assets/js/23.7c0322e8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{294:function(t,a,s){t.exports=s.p+"assets/img/errorobject.51c51d3f.png"},295:function(t,a,s){t.exports=s.p+"assets/img/action.af11efbe.png"},324:function(t,a,s){"use strict";s.r(a);var r=s(14),n=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"⚪️-react-router-を基礎から理解する"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-react-router-を基礎から理解する"}},[t._v("#")]),t._v(" ⚪️ React Router を基礎から理解する")]),t._v(" "),a("h2",{attrs:{id:"🔶-basic-purpose"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔶-basic-purpose"}},[t._v("#")]),t._v(" 🔶 Basic Purpose")]),t._v(" "),a("p",[t._v("当我们谈论浏览器中的 URL 以及它如何与前端和后端路由相关时,我们指的是以下概念:")]),t._v(" "),a("blockquote",[a("p",[t._v("瀏覽器地址欄的 URL "),a("code",[t._v("URL => request => backend server")])])]),t._v(" "),a("p",[a("strong",[t._v("前端路由")]),t._v(":")]),t._v(" "),a("blockquote",[a("p",[t._v("攔截不同的 URL, 去渲染不同的組件,服務器是不知道的。 ("),a("strong",[t._v("組件中")]),t._v("可能向後端請求 API 接口數據)")])]),t._v(" "),a("ul",[a("li",[t._v("前端路由主要负责在浏览器端处理不同的 URL 请求。")]),t._v(" "),a("li",[t._v("它通过拦截 URL 的变化来决定渲染哪个组件,而不是将请求发送到服务器。")]),t._v(" "),a("li",[t._v("在前端路由中,页面不会重新加载;相反,它通常会在当前页面动态地替换显示的内容(组件)。")]),t._v(" "),a("li",[t._v("虽然前端路由处理的是 URL,但服务器通常对此无感知。在这种机制下,组件可能会根据需要向后端请求 API 数据。")])]),t._v(" "),a("p",[a("strong",[t._v("后端路由")]),t._v(":")]),t._v(" "),a("blockquote",[a("p",[t._v("接收不同的 URL,執行不同的代碼處理,響應不同的數據(json)")])]),t._v(" "),a("ul",[a("li",[t._v("后端路由处理来自浏览器的请求,并根据不同的 URL 路径执行服务器上的特定代码。")]),t._v(" "),a("li",[t._v("它负责接收请求,并根据请求的 URL 返回相应的数据(如 JSON 格式的数据)。")]),t._v(" "),a("li",[t._v("后端路由是传统网页应用中常见的模式,每个 URL 请求通常对应服务器上的一个特定处理函数或模块。")])]),t._v(" "),a("p",[a("strong",[t._v("总结")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("前端路由和后端路由共同作用于提供完整的网页应用体验。")]),t._v(" "),a("li",[t._v("前端路由使得单页面应用(SPA)能够动态地更改显示的内容而无需加载新页面,提高用户体验。")]),t._v(" "),a("li",[t._v("后端路由处理实际的数据请求和处理逻辑,为前端提供所需的数据。")]),t._v(" "),a("li",[t._v("这种分离使得应用可以更灵活地响应用户的操作,同时优化性能和用户体验。")])]),t._v(" "),a("p",[a("a",{attrs:{href:"https://reactrouter.com/en/main/start/tutorial",target:"_blank",rel:"noopener noreferrer"}},[t._v("React Router Tutorial"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:"https://github.com/itsyuimorii/--TUTORIAL--React---The-Complete-Guide-2023-incl.-max/tree/main/my-router",target:"_blank",rel:"noopener noreferrer"}},[t._v("代碼例子"),a("OutboundLink")],1)]),t._v(" "),a("blockquote",[a("p",[t._v("main.js")])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" React "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" ReactDOM "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-dom/client"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" createBrowserRouter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" RouterProvider "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./index.css"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Root "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./routes/root"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Root "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nReactDOM"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createRoot")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StrictMode"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 2. 配置使用- 路有對象 */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("RouterProvider router"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("router"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StrictMode"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"🔶-様々なシーン"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔶-様々なシーン"}},[t._v("#")]),t._v(" 🔶 様々なシーン")]),t._v(" "),a("h3",{attrs:{id:"▫️-takeaway-01-理解匹配失敗的處理-對象userouteerror-和-errorelement"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#▫️-takeaway-01-理解匹配失敗的處理-對象userouteerror-和-errorelement"}},[t._v("#")]),t._v(" ▫️ Takeaway 01: 理解匹配失敗的處理: 對象"),a("code",[t._v("useRouteError()")]),t._v(" 和 "),a("code",[t._v("errorElement")])]),t._v(" "),a("ul",[a("li",[a("p",[t._v("對象"),a("code",[t._v("useRouteError()")]),t._v("可以看到匹配失敗的信息")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("errorElement")]),t._v(": 用於渲染匹配失敗的組件")]),t._v(" "),a("blockquote",[a("p",[a("code",[t._v("touch src/error-page.jsx")])])])])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRouteError "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("ErrorPage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//創建了一個error對象, 這個對象包含了匹配失敗的信息")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" error "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRouteError")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//有錯誤才會渲染這個組件,然後在這個裡面獲取錯誤對象,拿到錯誤對象進行打印。")]),t._v("\n\n console"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div id"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"error-page"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h1"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Oops"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h1"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Sorry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" an unexpected error has occurred"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* statusText: 狀態文本 = Not Found */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("statusText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[a("img",{attrs:{src:s(294),alt:"errorobject"}})]),t._v(" "),a("h3",{attrs:{id:"▫️-takeaway-02-理解-nested-routes的概念"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#▫️-takeaway-02-理解-nested-routes的概念"}},[t._v("#")]),t._v(" ▫️ Takeaway 02: 理解 "),a("a",{attrs:{href:"https://reactrouter.com/en/main/start/tutorial#nested-routes",target:"_blank",rel:"noopener noreferrer"}},[t._v("nested-routes"),a("OutboundLink")],1),t._v("的概念")]),t._v(" "),a("ol",[a("li",[t._v("👉 导入联系人组件并创建新路线")])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* existing imports */")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Contact "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./routes/contact"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Root "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("errorElement")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ErrorPage "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"contacts/:contactId"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Contact "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("现在,如果我们单击其中一个链接或访问,"),a("code",[t._v("/contacts/1")]),t._v(" 我们就会得到新组件!但是,它不在我们的"),a("code",[t._v("root")]),t._v("布局内 😠\n我们通过将联系路由设为根路由的子路由来实现这一点。 现在,您将再次看到根布局,但右侧有一个空白页面。我们需要告诉根路由我们希望它在哪里呈现其子路由。我们用 来做到这一点"),a("code",[t._v("")]),t._v("。")]),t._v(" "),a("ul",[a("li",[a("p",[t._v("找到"),a("code",[t._v('
    ')]),t._v("并在里面放一个插座, 👉 渲染"),a("code",[t._v("")])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Root")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* all the other elements */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div id"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"detail"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Outlet "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]),t._v(" "),a("li",[a("p",[t._v("👉 将联系人路由移至根路由的子路由 "),a("code",[t._v("main.js")])])])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Root "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("errorElement")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ErrorPage "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 子路由, 應該是一個對象,裡面配置路由的路徑和組件")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("children")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"contacts/:contactId"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Contact "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"▫️-takeaway-03-👉-将侧边栏更改-a-href-为-link-to"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#▫️-takeaway-03-👉-将侧边栏更改-a-href-为-link-to"}},[t._v("#")]),t._v(" ▫️ Takeaway 03: 👉 将侧边栏更改"),a("code",[t._v("")]),t._v("为"),a("code",[t._v("")])]),t._v(" "),a("blockquote",[a("p",[t._v("為什麼要用"),a("code",[t._v("")]),t._v("而不是"),a("code",[t._v("")]),t._v("?\n因為"),a("code",[t._v("a href")]),t._v("會刷新頁面,而 "),a("code",[t._v("Link")]),t._v(" 不會刷新頁面, 因為從服務器獲取頁面的代價是很大的,所以我們不希望刷新頁面。")])]),t._v(" "),a("blockquote",[a("p",[t._v("以下代碼, "),a("em",[t._v("在浏览器开发工具中打开网络选项卡,以查看它不再请求文档。")])])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Outlet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Link "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Root")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div id"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sidebar"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* other elements */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("nav"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ul"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("li"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Link to"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token template-string"}},[a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("contacts/1")]),a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Your Name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Link"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("li"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("li"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Link to"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token template-string"}},[a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("contacts/2")]),a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Your Friend"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Link"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("li"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("ul"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("nav"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* other elements */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[a("a",{attrs:{href:"../images/react/linktag.png"}},[t._v("linktag")])]),t._v(" "),a("h2",{attrs:{id:"🔶-loader-and-action"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔶-loader-and-action"}},[t._v("#")]),t._v(" 🔶 "),a("code",[t._v("loader")]),t._v(" and "),a("code",[t._v("action")])]),t._v(" "),a("h3",{attrs:{id:"▫️-takeaway-01-傳統式-form-表單的提交"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#▫️-takeaway-01-傳統式-form-表單的提交"}},[t._v("#")]),t._v(" ▫️ Takeaway 01: 傳統式 form 表單的提交")]),t._v(" "),a("blockquote",[a("p",[t._v("傳統式 form 表單的提交,會刷新頁面,然後服務器會返回一個新的頁面,然後頁面會重新加載,這樣就不是單頁面應用了。")])]),t._v(" "),a("h3",{attrs:{id:"▫️-takeaway-02-理解-loader-and-actionß"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#▫️-takeaway-02-理解-loader-and-actionß"}},[t._v("#")]),t._v(" ▫️ Takeaway 02: 理解 "),a("code",[t._v("loader")]),t._v(" and "),a("code",[t._v("action")]),t._v("ß")]),t._v(" "),a("blockquote",[a("p",[t._v("loader: 加載器, 用於加載數據, 顯示加載中的組件\naction: 用於加載數據, 顯示加載中的組件")])]),t._v(" "),a("p",[t._v("▫️ 在 react-router 中,為什麼需要用 loader? 因為我們需要在獲取數據的時候,顯示加載中的組件,然後在獲取數據後,再顯示組件。 這樣就不會出現空白頁面的情況。\n▫️ 原因: react-router 希望我們把獲取數據的代碼放在 loader 中,然後在獲取數據後,再顯示組件。")]),t._v(" "),a("ol",[a("li",[t._v("👉 Configure the loader on the route "),a("code",[t._v("main.jsx")])])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Root"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" loader "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rootLoader "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./routes/root"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("省略代碼\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("loader")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" rootLoader"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("children")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("省略代碼"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("ol",{attrs:{start:"2"}},[a("li",[t._v("👉 Export a loader from "),a("code",[t._v("root.jsx")]),t._v(" "),a("blockquote",[a("p",[t._v("獲取聯繫人列表,這裡是異步的獲取數據,然後獲取後,放入到 return 中\n一般是異步的獲取數據,")])])])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Outlet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Link "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" getContacts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../contacts"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//異步的獲取數據")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("loader")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" contacts "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getContacts")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" contacts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//以對象的形式返回")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("省略代碼\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Root")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("省略代碼\n\n")])])]),a("ol",{attrs:{start:"3"}},[a("li",[t._v("👉 Access and render the data")])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Outlet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Link"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n useLoaderData"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" getContacts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../contacts"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* other code */")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Root")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" contacts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useLoaderData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("省略代碼\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("nav"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contacts"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ul"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contacts"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("contact")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("li key"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Link to"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token template-string"}},[a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("contacts/")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("first "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("last "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("first"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("last"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("No Name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("contact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("favorite "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("span"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("★"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("span"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Link"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("li"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("ul"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("No contacts"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("nav"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n")])])]),a("ol",{attrs:{start:"4"}},[a("li",[t._v("Creating Contacts")])]),t._v(" "),a("p",[t._v("We'll create new contacts by exporting an action in our root route, wiring it up to the route config, and changing our "),a("code",[t._v("
    ")]),t._v(" to a React Router "),a("code",[t._v(".")])]),t._v(" "),a("p",[t._v("這裡需要理解,為什麼我要把 from 改為 Form? 因為我們轉發信息的時候,Form 會攔截,然後轉發給 action,然後 action 會獲取數據,然後再轉發給組件。 而傳統的 "),a("code",[t._v("form")]),t._v(" 會直接發送請求到服務器,然後服務器會返回一個新的頁面,然後頁面會重新加載,這樣就不是單頁面應用了。")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Outlet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Link"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Form "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-router-dom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" getContacts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../contacts"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* other code */")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Form method"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"post"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button type"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"submit"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("New"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Form"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("👉 Configure the loader and action on the route and Import and set the action on the route")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//封裝了action")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Root"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n loader "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rootLoader"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n action "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rootAction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./routes/root"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//把action 綁定到這個路由上")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Root "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("errorElement")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ErrorPage "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 子路由, 應該是一個對象,裡面配置路由的路徑和組件")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("loader")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" rootLoader"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" rootAction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("children")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"contacts/:contactId"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Contact "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("思考:")]),t._v(" "),a("ol",[a("li",[t._v("那麼什麼時候用 loader, 什麼時候用 action 呢?")])]),t._v(" "),a("ul",[a("li",[t._v("當我們需要獲取數據的時候,就用 loader, 比如 get")]),t._v(" "),a("li",[t._v("當我們需要提交數據的時候,就用 action, 比如 put,post")])]),t._v(" "),a("ol",{attrs:{start:"2"}},[a("li",[t._v("這裡有一個細節,")])]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Form method"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"post"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button type"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"submit"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("New"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Form"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n")])])]),a("ol",{attrs:{start:"3"}},[a("li",[a("p",[t._v("這裡配置時,並為配置 action, 所以提交表單後,會轉發到根目錄,也就是"),a("code",[t._v("/")]),t._v(", 然後根目錄配置了 action, 所以會轉發到 action 中,然後 action 中獲取數據,然後再轉發到組件中。")])]),t._v(" "),a("li",[a("p",[t._v("官網參考\nBy convention, React Router uses this as a hint to automatically revalidate the data on the page after the action finishes.\n"),a("img",{attrs:{src:s(295),alt:"action"}})])])]),t._v(" "),a("h2",{attrs:{id:"🔶-url-params-in-loader"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔶-url-params-in-loader"}},[t._v("#")]),t._v(" 🔶 URL params in Loader")]),t._v(" "),a("p",[t._v("These params are passed to the loader with keys that match the dynamic segment. For example, our segment is named :contactId so the value will be passed as params.contactId.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//封裝loader 函數,用於獲取具體的聯繫信息")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("loader")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" params "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"params"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" params"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("contactId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//這裡每點擊new,就會打印出不同的id")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" contact "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getContact")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("params"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("contactId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" contact "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Contact")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" contact "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useLoaderData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("省略代碼\n")])])]),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createBrowserRouter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("省略代碼\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("children")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"contacts/:contactId"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Contact "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("loader")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" contactLoader"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"🔶-updating-data"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔶-updating-data"}},[t._v("#")]),t._v(" 🔶 Updating data")]),t._v(" "),a("p",[t._v("自定義的 Form 組件,意思就是還是會攔截,然後轉發給 action,然後 action 會獲取數據,然後再轉發給組件。")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Form action"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"edit"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button type"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"submit"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Edit"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Form"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n")])])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/24.fa4b7294.js b/assets/js/24.fa4b7294.js new file mode 100644 index 00000000..68539d52 --- /dev/null +++ b/assets/js/24.fa4b7294.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{300:function(e,t,n){e.exports=n.p+"assets/img/contenttypebuilder.24db04ba.png"},301:function(e,t,n){e.exports=n.p+"assets/img/contenttypebuilder2.d73df612.png"},340:function(e,t,n){"use strict";n.r(t);var a=n(14),i=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-strapi-への深い理解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-strapi-への深い理解"}},[e._v("#")]),e._v(" ⚪️ Strapi への深い理解")]),e._v(" "),t("h2",{attrs:{id:"project-structure"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#project-structure"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://docs.strapi.io/dev-docs/project-structure",target:"_blank",rel:"noopener noreferrer"}},[e._v("project structure"),t("OutboundLink")],1)]),e._v(" "),t("blockquote",[t("p",[e._v("以下の構成は、"),t("code",[e._v("strapi new")]),e._v(" で作成されるプロジェクトの構成です。")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v(". # root of the application\n├──── .strapi # auto-generated folder — do not update manually\n│ └──── client # files used by bundlers to render the application\n│ ├ index.html\n│ └ app.js\n├──── .tmp\n├──── build # build of the admin panel\n├──── config # API configurations\n│ ├ api.js\n│ ├ admin.js\n│ ├ cron-tasks.js\n│ ├ database.js\n│ ├ middlewares.js\n│ ├ plugins.js\n│ └ server.js\n├──── database\n│ └──── migrations\n├──── node_modules # npm packages used by the project\n├──── public # files accessible to the outside world\n│ └──── uploads\n├──── src\n│ ├──── admin # admin customization files\n│ ├──── extensions # files to extend the admin panel\n│ │ ├ app.js\n│ │ └ webpack.config.js\n│ ├──── api # business logic of the project split into subfolders per API\n│ │ └──── (api-name)\n│ │ ├──── content-types\n│ │ │ └──── (content-type-name)\n│ │ │ └ lifecycles.js\n│ │ │ └ schema.json\n│ │ ├──── controllers\n│ │ ├──── middlewares\n│ │ ├──── policies\n│ │ ├──── routes\n│ │ ├──── services\n│ │ └ index.js\n│ ├──── components\n│ │ └──── (category-name)\n│ │ ├ (componentA).json\n│ │ └ (componentB).json\n│ ├──── extensions # files to extend installed plugins\n│ │ └──── (plugin-to-be-extended)\n│ │ ├──── content-types\n│ │ │ └──── (content-type-name)\n│ │ │ └ schema.json\n│ │ └ strapi-server.js\n│ ├──── middlewares\n│ │ └──── (middleware-name).js\n│ ├──── plugins # local plugins files\n│ │ └──── (plugin-name)\n│ │ ├──── admin\n│ │ │ └──── src\n│ │ │ └ index.js\n│ │ ├──── server\n│ │ │ ├──── content-types\n│ │ │ ├──── controllers\n│ │ │ └──── policies\n│ │ ├ package.json\n│ │ ├ strapi-admin.js\n│ │ └ strapi-server.js\n│ ├─── policies\n│ └ index.js # include register(), bootstrap() and destroy() functions\n├ .env\n└ package.json\n")])])]),t("p",[e._v("Understand the project structure of a Strapi project.")]),e._v(" "),t("ol",[t("li",[t("p",[t("strong",[e._v("Project Root:")]),e._v(" The top-level directory of the Strapi application, containing all the files and subdirectories needed for the application to run.")])]),e._v(" "),t("li",[t("p",[t("strong",[t("code",[e._v(".strapi")]),e._v(" Directory:")]),e._v(" This is an auto-generated folder. It's created and managed by Strapi itself. You shouldn't manually update files in this directory as they are managed by the Strapi framework. It typically includes client-side files used by bundlers to render the application.")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("index.html")]),e._v(" and "),t("code",[e._v("app.js")]),e._v(" are examples of files in this directory, which are key to rendering the Strapi admin panel in a web browser.")])])]),e._v(" "),t("li",[t("p",[t("strong",[t("code",[e._v(".tmp")]),e._v(" Directory:")]),e._v(" A temporary directory used by Strapi during runtime for storing temporary files.")])]),e._v(" "),t("li",[t("p",[t("strong",[t("code",[e._v("build")]),e._v(" Directory:")]),e._v(' This is where the built version of the admin panel resides. The "build" process involves compiling and bundling all the necessary files (like JavaScript, CSS, HTML) into a format suitable for deployment. This is done so that the admin panel can be served efficiently in a production environment.')]),e._v(" "),t("ul",[t("li",[e._v('The "build" process is usually done after development when you\'re ready to deploy your application. It optimizes the application for better performance in a production environment.')])])])]),e._v(" "),t("h2",{attrs:{id:"api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#api"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://docs.strapi.io/developer-docs/latest/development/backend-customization.html#api",target:"_blank",rel:"noopener noreferrer"}},[e._v("API"),t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"headless-cms-とは"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#headless-cms-とは"}},[e._v("#")]),e._v(" headless CMS とは?")]),e._v(" "),t("p",[e._v("Headless CMS, like Strapi, represents a significant shift in how content management systems operate, particularly in the relationship between the front-end and the back-end. Let's break down what it means and how it's particularly beneficial for a React JavaScript environment:")]),e._v(" "),t("ol",[t("li",[t("p",[t("strong",[e._v("Traditional vs. Headless CMS:")])]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Traditional CMS:")]),e._v(" Systems like WordPress tightly couple the front-end (what you see) and the back-end (where content is stored and managed). This means the way content is created, stored, and displayed is predefined and linked. Customizing the front-end or integrating with different technologies can be challenging.")]),e._v(" "),t("li",[t("strong",[e._v("Headless CMS:")]),e._v(' Strapi, as a headless CMS, decouples the front-end and the back-end. It provides only the back-end (headless) part, where content is stored and managed via an API. The front-end part (the "head") is entirely separate and can be built using any technology – like React in your case.')])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("API-Driven Approach:")])]),e._v(" "),t("ul",[t("li",[e._v("In a headless CMS, content is delivered through APIs, typically RESTful or GraphQL. This approach offers greater flexibility in how content is retrieved and displayed. A front-end developer can query the API to fetch content and display it using React or any other front-end framework.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("Benefits for Front-End Developers:")])]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Flexibility:")]),e._v(" You can use your preferred front-end technology (React, Angular, Vue.js, etc.) to build your user interface.")]),e._v(" "),t("li",[t("strong",[e._v("Customization:")]),e._v(" Since the front-end is separate, you have complete control over the user experience and can build custom UIs without the constraints of traditional CMS themes or templates.")]),e._v(" "),t("li",[t("strong",[e._v("Scalability:")]),e._v(" APIs make it easier to scale your application. You can develop new features or change the front-end without altering the back-end.")]),e._v(" "),t("li",[t("strong",[e._v("Omnichannel Content Delivery:")]),e._v(" Content can be used across different platforms – web, mobile apps, IoT devices, etc., without needing to adjust the back-end for each case.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v('Why "Headless" for React Development:')])]),e._v(" "),t("ul",[t("li",[e._v("React is a powerful library for building user interfaces. Pairing React with a headless CMS like Strapi allows you to create dynamic, interactive web applications with content that's easy to manage and update.")]),e._v(" "),t("li",[e._v("You can fetch data from the Strapi API using AJAX calls (with "),t("code",[e._v("fetch")]),e._v(", "),t("code",[e._v("axios")]),e._v(", or any other HTTP client) and then render this data using React components. This setup offers a modern, efficient way to build web applications.")])])])]),e._v(" "),t("p",[e._v("Strapi 的「無頭」性質意味著它提供後端功能(例如透過 API 進行內容儲存、管理和交付),而無需規定前端應如何建置或呈現。這種分離允許前端開發人員利用 React 等現代框架的強大功能來建立豐富的互動式使用者介面,同時仍受益於 CMS 強大的內容管理功能。")]),e._v(" "),t("h2",{attrs:{id:"content-type-builder"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#content-type-builder"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://docs.strapi.io/developer-docs/latest/development/backend-customization.html#content-type-builder",target:"_blank",rel:"noopener noreferrer"}},[e._v("Content Type Builder"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("The Content Type Builder in Strapi is a powerful feature that enables you to quickly generate API endpoints for managing data through CRUD (Create, Read, Update, Delete) operations. Here's a summary of its functionalities and an example to illustrate its use:")]),e._v(" "),t("h3",{attrs:{id:"understanding-content-type-builder"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#understanding-content-type-builder"}},[e._v("#")]),e._v(" Understanding Content Type Builder:")]),e._v(" "),t("ol",[t("li",[t("p",[t("strong",[e._v("Purpose:")])]),e._v(" "),t("ul",[t("li",[e._v("Enables the creation of Content Types (data structures) in Strapi.")]),e._v(" "),t("li",[e._v("Facilitates the definition and customization of fields for these Content Types.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("Functionality:")])]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Data Structure Creation:")]),e._v(" You can define new Content Types (akin to tables in a database) directly within Strapi's admin panel. This includes specifying the fields and data types.")]),e._v(" "),t("li",[t("strong",[e._v("API Generation:")]),e._v(" Once a Content Type is created, Strapi automatically generates RESTful or GraphQL API endpoints for it. This means you can perform CRUD operations on the data associated with this Content Type.")]),e._v(" "),t("li",[t("strong",[e._v("Customization:")]),e._v(" The fields of a Content Type can be tailored to fit the data requirements of your application. You can choose from various field types like text, number, media, relational fields (to establish relationships between different Content Types), and more.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("User Interface:")])]),e._v(" "),t("ul",[t("li",[e._v("The Content Type Builder offers a user-friendly interface within the Strapi admin panel for designing and modifying Content Types without writing any code.")])])])]),e._v(" "),t("h3",{attrs:{id:"example-use-case"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-use-case"}},[e._v("#")]),e._v(" Example Use Case:")]),e._v(" "),t("ol",[t("li",[t("strong",[e._v("Creating a Blog Post Content Type:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Objective:")]),e._v(" To create a Content Type for managing blog posts.")]),e._v(" "),t("li",[t("strong",[e._v("Steps:")]),e._v(" "),t("ol",[t("li",[e._v("Access the Content Type Builder in the Strapi admin panel.")]),e._v(" "),t("li",[e._v("Create a new Content Type named "),t("code",[e._v("BlogPost")]),e._v(".")]),e._v(" "),t("li",[e._v("Define fields such as "),t("code",[e._v("title")]),e._v(" (text type), "),t("code",[e._v("content")]),e._v(" (rich text type), "),t("code",[e._v("publishedDate")]),e._v(" (date type), and "),t("code",[e._v("author")]),e._v(" (relational field linking to a "),t("code",[e._v("User")]),e._v(" Content Type).")]),e._v(" "),t("li",[e._v("Save the Content Type. Strapi then generates API endpoints for "),t("code",[e._v("BlogPost")]),e._v(".")])])]),e._v(" "),t("li",[t("strong",[e._v("Outcome:")]),e._v(" You can now use the generated API endpoints to create, retrieve, update, or delete blog posts in your application.")])])])]),e._v(" "),t("h3",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion:")]),e._v(" "),t("p",[e._v("The Content Type Builder in Strapi streamlines the process of creating data structures and corresponding APIs, making it an ideal tool for developers looking to build and manage content-driven applications efficiently. Its user-friendly interface and customization options allow for a great degree of flexibility in defining the data model according to the specific needs of your application.")]),e._v(" "),t("p",[e._v("The Content Type Builder in Strapi is a powerful feature that enables you to quickly generate API endpoints for managing data through CRUD (Create, Read, Update, Delete) operations. Here's a summary of its functionalities and an example to illustrate its use:")]),e._v(" "),t("h3",{attrs:{id:"understanding-content-type-builder-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#understanding-content-type-builder-2"}},[e._v("#")]),e._v(" Understanding Content Type Builder:")]),e._v(" "),t("ol",[t("li",[t("p",[t("strong",[e._v("Purpose:")])]),e._v(" "),t("ul",[t("li",[e._v("Enables the creation of Content Types (data structures) in Strapi.")]),e._v(" "),t("li",[e._v("Facilitates the definition and customization of fields for these Content Types.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("Functionality:")])]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Data Structure Creation:")]),e._v(" You can define new Content Types (akin to tables in a database) directly within Strapi's admin panel. This includes specifying the fields and data types.")]),e._v(" "),t("li",[t("strong",[e._v("API Generation:")]),e._v(" Once a Content Type is created, Strapi automatically generates RESTful or GraphQL API endpoints for it. This means you can perform CRUD operations on the data associated with this Content Type.")]),e._v(" "),t("li",[t("strong",[e._v("Customization:")]),e._v(" The fields of a Content Type can be tailored to fit the data requirements of your application. You can choose from various field types like text, number, media, relational fields (to establish relationships between different Content Types), and more.")])])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("User Interface:")])]),e._v(" "),t("ul",[t("li",[e._v("The Content Type Builder offers a user-friendly interface within the Strapi admin panel for designing and modifying Content Types without writing any code.")])])])]),e._v(" "),t("h3",{attrs:{id:"example-use-case-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-use-case-2"}},[e._v("#")]),e._v(" Example Use Case:")]),e._v(" "),t("p",[t("img",{attrs:{src:n(300),alt:"contenttypebuilder"}})]),e._v(" "),t("ol",[t("li",[t("strong",[e._v("Creating a Blog Post Content Type:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Objective:")]),e._v(" To create a Content Type for managing blog posts.")]),e._v(" "),t("li",[t("strong",[e._v("Steps:")]),e._v(" "),t("ol",[t("li",[e._v("Access the Content Type Builder in the Strapi admin panel.")]),e._v(" "),t("li",[e._v("Create a new Content Type named "),t("code",[e._v("BlogPost")]),e._v(".")]),e._v(" "),t("li",[e._v("Define fields such as "),t("code",[e._v("title")]),e._v(" (text type), "),t("code",[e._v("content")]),e._v(" (rich text type), "),t("code",[e._v("publishedDate")]),e._v(" (date type), and "),t("code",[e._v("author")]),e._v(" ("),t("strong",[e._v("relational")]),e._v(" field linking to a "),t("code",[e._v("User")]),e._v(" Content Type).\n"),t("img",{attrs:{src:n(301),alt:"contenttypebuilder"}})]),e._v(" "),t("li",[e._v("Save the Content Type. Strapi then generates API endpoints for "),t("code",[e._v("BlogPost")]),e._v(".")])])]),e._v(" "),t("li",[t("strong",[e._v("Outcome:")]),e._v(" You can now use the generated API endpoints to create, retrieve, update, or delete blog posts in your application.")])])])]),e._v(" "),t("h2",{attrs:{id:"content-manager"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#content-manager"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://docs.strapi.io/developer-docs/latest/development/backend-customization.html#content-manager",target:"_blank",rel:"noopener noreferrer"}},[e._v("Content Manager"),t("OutboundLink")],1)])])}),[],!1,null,null,null);t.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/25.4b75e33e.js b/assets/js/25.4b75e33e.js new file mode 100644 index 00000000..714a291e --- /dev/null +++ b/assets/js/25.4b75e33e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{239:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return s})),e.d(n,"i",(function(){return u})),e.d(n,"f",(function(){return a})),e.d(n,"g",(function(){return l})),e.d(n,"h",(function(){return c})),e.d(n,"b",(function(){return f})),e.d(n,"e",(function(){return h})),e.d(n,"k",(function(){return p})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return b})),e.d(n,"j",(function(){return m}));e(90);const r=/#.*$/,i=/\.(md|html)$/,s=/\/$/,u=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function a(t){return u.test(t)}function l(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function f(t){if(a(t))return t;const n=t.match(r),e=n?n[0]:"",i=o(t);return s.test(i)?t:i+".html"+e}function h(t,n){const e=decodeURIComponent(t.hash),i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return o(t.path)===o(n)}function p(t,n,e){if(a(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(n,e,r,i=1){if("string"==typeof n)return p(e,n,r);if(Array.isArray(n))return Object.assign(p(e,n[0],r),{title:n[1]});{const s=n.children||[];return 0===s.length&&n.path?Object.assign(p(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,initialOpenGroupIndex:n.initialOpenGroupIndex,children:s.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(t,i,e)):[]}return[]}function g(t){const n=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:n.map(n=>({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}function b(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},241:function(t,n,e){"use strict";e.r(n);var r=e(239),i={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(r.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(r.g)(this.link)||Object(r.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(r.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(r.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=e(14),u=Object(s.a)(i,(function(){var t=this,n=t._self._c;return t.isInternal?n("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(n){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):n("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?n("OutboundLink"):t._e()],1)}),[],!1,null,null,null);n.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/26.6ccb7807.js b/assets/js/26.6ccb7807.js new file mode 100644 index 00000000..7ded68cb --- /dev/null +++ b/assets/js/26.6ccb7807.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{296:function(e,t,a){e.exports=a.p+"assets/img/gitrebase.175e6a7f.png"},336:function(e,t,a){"use strict";a.r(t);var s=a(14),n=Object(s.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-git-and-github-への深い理解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-git-and-github-への深い理解"}},[e._v("#")]),e._v(" ⚪️ git and github への深い理解")]),e._v(" "),t("p",[e._v("🔺 "),t("a",{attrs:{href:"https://chodocs.cn/memo/git-command/",target:"_blank",rel:"noopener noreferrer"}},[e._v("常用一些 Git 命令"),t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"git-branch"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#git-branch"}},[e._v("#")]),e._v(" git branch")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[e._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" checkout staging/name\n"),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" pull origin staging/name "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# Ensure you have the latest changes")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" checkout "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-b")]),e._v(" branch-name staging/name\n")])])]),t("h2",{attrs:{id:"git-rebase-fix-old-commit"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#git-rebase-fix-old-commit"}},[e._v("#")]),e._v(" "),t("code",[e._v("git rebase")]),e._v(" fix old commit")]),e._v(" "),t("p",[t("img",{attrs:{src:a(296),alt:"gitrebase"}})]),e._v(" "),t("ol",[t("li",[t("p",[t("code",[e._v("git rebase -i HEAD~ 2")])])]),e._v(" "),t("li",[t("p",[e._v("change the pick to edit "),t("code",[e._v("r")])])]),e._v(" "),t("li",[t("p",[t("code",[e._v("git commit --amend")])])]),e._v(" "),t("li",[t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[e._v("wq: "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("write")]),e._v(" and quit\nq"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("!")]),e._v(": quit without saving\ni: insert mode\n")])])])])]),e._v(" "),t("h2",{attrs:{id:"fix-the-most-recent-commit-message"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#fix-the-most-recent-commit-message"}},[e._v("#")]),e._v(" Fix the most recent commit message")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" commit "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--amend")]),e._v("\n")])])]),t("p",[e._v("🔺 ### Reference:")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/6986951160619859975?from=search-suggest",target:"_blank",rel:"noopener noreferrer"}},[e._v("git は pull のデフォルト設定をリベースするように変更する。"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://juejin.cn/post/6844903618177433613?from=search-suggest",target:"_blank",rel:"noopener noreferrer"}},[e._v(" git pull vs git pull --rebase "),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://juejin.cn/post/7062315341124698119",target:"_blank",rel:"noopener noreferrer"}},[e._v("より深い理解 git pull"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"git-commit-message"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#git-commit-message"}},[e._v("#")]),e._v(" git commit message")]),e._v(" "),t("h3",{attrs:{id:"scenario"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#scenario"}},[e._v("#")]),e._v(" Scenario")]),e._v(" "),t("p",[e._v("Imagine you're developing a new feature that allows users to send feedback via email. During development, you made the following three commits:")]),e._v(" "),t("ol",[t("li",[e._v("Added a form to collect user feedback")]),e._v(" "),t("li",[e._v("Implemented logic to process the form data")]),e._v(" "),t("li",[e._v("Added functionality to send feedback via email")])]),e._v(" "),t("h3",{attrs:{id:"development-and-commits"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#development-and-commits"}},[e._v("#")]),e._v(" Development and Commits")]),e._v(" "),t("p",[e._v("In Git, you might commit these changes like so:")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" commit "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-m")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Add feedback form"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" commit "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-m")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Implement feedback processing logic"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" commit "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-m")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Add email sending functionality"')]),e._v("\n")])])]),t("h3",{attrs:{id:"squashing-commits"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#squashing-commits"}},[e._v("#")]),e._v(" Squashing Commits")]),e._v(" "),t("p",[e._v("Before merging this feature into the "),t("code",[e._v("main")]),e._v(" branch, you decide to squash these three commits into one. This can be done in a pull request or by using interactive rebase in your local branch:")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[e._v("git")]),e._v(" rebase "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-i")]),e._v(" HEAD~3\n")])])]),t("p",[e._v("This opens an editor listing the last 3 commits. You can change the "),t("code",[e._v("pick")]),e._v(" command to "),t("code",[e._v("squash")]),e._v(" (or just "),t("code",[e._v("s")]),e._v(" for short) for the second and third commits, instructing Git to squash them into the first one.")]),e._v(" "),t("h3",{attrs:{id:"commit-message-following-conventional-commits"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#commit-message-following-conventional-commits"}},[e._v("#")]),e._v(" Commit Message Following Conventional Commits")]),e._v(" "),t("p",[e._v("After squashing, you're prompted to provide a new commit message that should follow the Conventional Commits specification. For our example, the commit message could be:")]),e._v(" "),t("div",{staticClass:"language-plaintext extra-class"},[t("pre",{pre:!0,attrs:{class:"language-plaintext"}},[t("code",[e._v("feat(email): add user feedback email functionality\n\n- Add feedback form\n- Implement feedback processing logic\n- Add functionality to send feedback via email\n")])])]),t("p",[e._v("This message clearly describes the nature of the commit ("),t("code",[e._v("feat")]),e._v("), the module affected ("),t("code",[e._v("email")]),e._v("), and the specific changes made. This format helps automated tools (like those generating CHANGELOGs) to understand the intent and scope of each commit.")]),e._v(" "),t("h3",{attrs:{id:"automating-changelog-with-conventional-commits"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#automating-changelog-with-conventional-commits"}},[e._v("#")]),e._v(" Automating CHANGELOG with Conventional Commits")]),e._v(" "),t("p",[e._v("Once you start following the Conventional Commits specification, you can use tools like "),t("code",[e._v("standard-version")]),e._v(" to automate CHANGELOG generation. "),t("code",[e._v("standard-version")]),e._v(" automatically bumps the version number based on your commit history and generates or updates the CHANGELOG file.")]),e._v(" "),t("p",[e._v("To install "),t("code",[e._v("standard-version")]),e._v(":")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[e._v("npm")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" --save-dev standard-version\n")])])]),t("p",[e._v("Then, you can create a new release and CHANGELOG by running:")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[e._v("npx standard-version\n")])])]),t("p",[e._v("This command automatically determines the type of version bump (major, minor, or patch) based on your commit history (identifying "),t("code",[e._v("feat")]),e._v(", "),t("code",[e._v("fix")]),e._v(", etc.), updates the version number in "),t("code",[e._v("package.json")]),e._v(", and generates or updates the CHANGELOG based on your commits.")]),e._v(" "),t("h3",{attrs:{id:"summary"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#summary"}},[e._v("#")]),e._v(" Summary")]),e._v(" "),t("p",[e._v("Through this practical example, we explored how to keep commit history clean by using squash commits during development and how to enhance the readability and automation of commit messages by adhering to the Conventional Commits standard. These practices are highly beneficial for team collaboration, project maintenance, and automated version control.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/27.6c078df5.js b/assets/js/27.6c078df5.js new file mode 100644 index 00000000..7d0ed84e --- /dev/null +++ b/assets/js/27.6c078df5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{314:function(t,n,s){"use strict";s.r(n);var e=s(14),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/28.520f43fd.js b/assets/js/28.520f43fd.js new file mode 100644 index 00000000..1ed49b80 --- /dev/null +++ b/assets/js/28.520f43fd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{315:function(t,s,a){"use strict";a.r(s);var i=a(14),r=Object(i.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"javascript-guide"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#javascript-guide"}},[this._v("#")]),this._v(" Javascript guide")])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/29.844af673.js b/assets/js/29.844af673.js new file mode 100644 index 00000000..b54add58 --- /dev/null +++ b/assets/js/29.844af673.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{318:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-【javascript-入門】-配列の使い方と操作まとめ-初期化・追加・結合・検索・削除"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-【javascript-入門】-配列の使い方と操作まとめ-初期化・追加・結合・検索・削除"}},[t._v("#")]),t._v(" ⚪️ 【JavaScript 入門】 配列の使い方と操作まとめ(初期化・追加・結合・検索・削除)")]),t._v(" "),s("h2",{attrs:{id:"🔶-【実践】「配列」の活用技"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-【実践】「配列」の活用技"}},[t._v("#")]),t._v(" 🔶 【実践】「配列」の活用技")]),t._v(" "),s("p",[t._v("当然可以。下面是一个表格,展示了各个 JavaScript 数组方法的功能、返回值、是否改变原数组以及它们被引入的 ECMAScript 版本。")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("顺序")]),t._v(" "),s("th",[t._v("方法名")]),t._v(" "),s("th",[t._v("功能")]),t._v(" "),s("th",[t._v("返回值")]),t._v(" "),s("th",[t._v("是否改变原数组")]),t._v(" "),s("th",[t._v("版本")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("1")]),t._v(" "),s("td",[s("code",[t._v("push()")])]),t._v(" "),s("td",[t._v("向数组添加一个或多个元素(在数组尾部)")]),t._v(" "),s("td",[t._v("新数组的长度")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("2")]),t._v(" "),s("td",[s("code",[t._v("unshift()")])]),t._v(" "),s("td",[t._v("向数组添加一个或多个元素(在数组头部)")]),t._v(" "),s("td",[t._v("新数组的长度")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("3")]),t._v(" "),s("td",[s("code",[t._v("pop()")])]),t._v(" "),s("td",[t._v("删除数组的最后一个元素")]),t._v(" "),s("td",[t._v("被删除的元素")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("4")]),t._v(" "),s("td",[s("code",[t._v("shift()")])]),t._v(" "),s("td",[t._v("删除数组的第一个元素")]),t._v(" "),s("td",[t._v("被删除的元素")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("5")]),t._v(" "),s("td",[s("code",[t._v("reverse()")])]),t._v(" "),s("td",[t._v("反转数组中的元素")]),t._v(" "),s("td",[t._v("反转后的数组")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("6")]),t._v(" "),s("td",[s("code",[t._v("sort()")])]),t._v(" "),s("td",[t._v("对数组进行排序(默认按字符串 Unicode 码点)")]),t._v(" "),s("td",[t._v("排序后的数组")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("7")]),t._v(" "),s("td",[s("code",[t._v("splice()")])]),t._v(" "),s("td",[t._v("在指定位置删除或添加元素(可用于数组的增删改)")]),t._v(" "),s("td",[t._v("被删除的元素组成的数组")]),t._v(" "),s("td",[t._v("是")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("8")]),t._v(" "),s("td",[s("code",[t._v("concat()")])]),t._v(" "),s("td",[t._v("合并多个数组,返回新数组")]),t._v(" "),s("td",[t._v("合并后的数组")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("9")]),t._v(" "),s("td",[s("code",[t._v("join()")])]),t._v(" "),s("td",[t._v("将数组元素用特定字符连接成字符串")]),t._v(" "),s("td",[t._v("拼接后的字符串")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("10")]),t._v(" "),s("td",[s("code",[t._v("slice()")])]),t._v(" "),s("td",[t._v("从数组中提取一段元素,返回新数组")]),t._v(" "),s("td",[t._v("提取的元素组成的新数组")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("11")]),t._v(" "),s("td",[s("code",[t._v("toString()")])]),t._v(" "),s("td",[t._v("将数组转换为字符串")]),t._v(" "),s("td",[t._v("字符串表示的数组")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("12")]),t._v(" "),s("td",[s("code",[t._v("valueOf()")])]),t._v(" "),s("td",[t._v("返回数组的原始值")]),t._v(" "),s("td",[t._v("数组的原始值")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("13")]),t._v(" "),s("td",[s("code",[t._v("indexOf()")])]),t._v(" "),s("td",[t._v("查询数组中某元素首次出现的位置")]),t._v(" "),s("td",[t._v("元素位置,若不存在则返回-1")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("14")]),t._v(" "),s("td",[s("code",[t._v("lastIndexOf()")])]),t._v(" "),s("td",[t._v("反向查询数组中某元素首次出现的位置")]),t._v(" "),s("td",[t._v("元素位置,若不存在则返回-1")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("15")]),t._v(" "),s("td",[s("code",[t._v("forEach()")])]),t._v(" "),s("td",[t._v("遍历数组,对每个元素执行回调函数")]),t._v(" "),s("td",[t._v("无("),s("code",[t._v("undefined")]),t._v(")")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("16")]),t._v(" "),s("td",[s("code",[t._v("map()")])]),t._v(" "),s("td",[t._v("遍历数组,使用回调函数处理每个元素,并返回新数组")]),t._v(" "),s("td",[t._v("新数组")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("17")]),t._v(" "),s("td",[s("code",[t._v("filter()")])]),t._v(" "),s("td",[t._v("遍历数组,筛选符合条件的元素,返回新数组")]),t._v(" "),s("td",[t._v("符合条件的元素组成的新数组")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("18")]),t._v(" "),s("td",[s("code",[t._v("every()")])]),t._v(" "),s("td",[t._v("检测数组所有元素是否都满足条件")]),t._v(" "),s("td",[t._v("所有元素满足返回"),s("code",[t._v("true")]),t._v(",否则"),s("code",[t._v("false")])]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("19")]),t._v(" "),s("td",[s("code",[t._v("some()")])]),t._v(" "),s("td",[t._v("检测数组中是否存在满足条件的元素")]),t._v(" "),s("td",[t._v("存在满足条件的元素返回"),s("code",[t._v("true")]),t._v(",否则"),s("code",[t._v("false")])]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("20")]),t._v(" "),s("td",[s("code",[t._v("reduce()")])]),t._v(" "),s("td",[t._v("从左到右应用一个函数对数组元素进行累计/归约")]),t._v(" "),s("td",[t._v("操作结果")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("21")]),t._v(" "),s("td",[s("code",[t._v("reduceRight()")])]),t._v(" "),s("td",[t._v("从右到左应用一个函数对数组元素进行累计/归约")]),t._v(" "),s("td",[t._v("操作结果")]),t._v(" "),s("td",[t._v("否")]),t._v(" "),s("td",[t._v("ES5-")])]),t._v(" "),s("tr",[s("td",[t._v("22")]),t._v(" "),s("td",[s("code",[t._v("includes()")])]),t._v(" "),s("td"),t._v(" "),s("td"),t._v(" "),s("td"),t._v(" "),s("td")])])]),t._v(" "),s("p",[t._v("判断数组是否包含特定值 | 包含则返回"),s("code",[t._v("true")]),t._v(",否则"),s("code",[t._v("false")]),t._v(" | 否 | ES6 |\n| 23 | "),s("code",[t._v("Array.from()")]),t._v(" | 从类数组或可迭代对象创建新数组 | 新数组 | 否 | ES6 |\n| 24 | "),s("code",[t._v("find()")]),t._v(" | 查找数组中满足条件的第一个元素 | 满足条件的元素,否则"),s("code",[t._v("undefined")]),t._v(" | 否 | ES6 |\n| 25 | "),s("code",[t._v("findIndex()")]),t._v(" | 查找数组中满足条件元素的索引 | 满足条件元素的索引,否则-1 | 否 | ES6 |\n| 26 | "),s("code",[t._v("fill()")]),t._v(" | 使用给定值填充数组 | 填充后的数组 | 是 | ES6 |\n| 27 | "),s("code",[t._v("flat()")]),t._v(' | 将嵌套数组"拉平"成一维数组 | 新数组 | 否 | ES6 |\n| 28 | '),s("code",[t._v("flatMap()")]),t._v(" | 先映射每个元素,然后将结果压平成一维数组 | 新数组 | 否 | ES6 |")]),t._v(" "),s("h2",{attrs:{id:"🔶-方法详解"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-方法详解"}},[t._v("#")]),t._v(" 🔶 方法详解")]),t._v(" "),s("h3",{attrs:{id:"🔸-1-push"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-1-push"}},[t._v("#")]),t._v(" 🔸 1. "),s("code",[t._v("push()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:在数组最后一位添加一个或多个元素,并返回新数组的长度。会改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"B"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// [1, 2, "c", "A", "B"]')]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 5 (数组长度)")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-2-unshift"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-2-unshift"}},[t._v("#")]),t._v(" 🔸 2. "),s("code",[t._v("unshift()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:在数组第一位添加一个或多个元素,并返回新数组的长度。会改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unshift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"B"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["A", "B", 1, 2, "c"]')]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 5 (数组长度)")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-3-pop"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-3-pop"}},[t._v("#")]),t._v(" 🔸 3. "),s("code",[t._v("pop()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:删除数组的最后一个元素,并返回被删除的元素。会改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [1, 2]")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// c")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-4-shift"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-4-shift"}},[t._v("#")]),t._v(" 🔸 4. "),s("code",[t._v("shift()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:删除数组的第一个元素,并返回被删除的元素。会改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["b", "c"]')]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-5-reverse"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-5-reverse"}},[t._v("#")]),t._v(" 🔸 5. "),s("code",[t._v("reverse()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:反转数组中的元素。会改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["c", "b", "a", 3, 2, 1]')]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["c", "b", "a", 3, 2, 1]')]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-6-sort"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-6-sort"}},[t._v("#")]),t._v(" 🔸 6. "),s("code",[t._v("sort()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:对数组的元素进行排序。默认排序顺序是根据字符串 Unicode 码点。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\narr1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 默认排序结果")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用自定义排序函数")]),t._v("\narr1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 从小到大排序")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-7-splice"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-7-splice"}},[t._v("#")]),t._v(" 🔸 7. "),s("code",[t._v("splice()")])]),t._v(" "),s("h4",{attrs:{id:"功能"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[t._v("在指定位置添加或删除数组中的元素,或替换数组中的元素。会改变原数组。")]),t._v(" "),s("li",[s("code",[t._v("splice")]),t._v(" 方法可以用于数组的增删改操作。")]),t._v(" "),s("li",[s("code",[t._v("splice")]),t._v(" 方法的第一个参数是修改的起始位置(索引),第二个参数是删除的个数(如果是 0,则表示不删除元素),后面的参数是要添加进数组的元素。")])]),t._v(" "),s("h4",{attrs:{id:"语法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#语法"}},[t._v("#")]),t._v(" 语法:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("array.splice(start[, deleteCount[, item1[, item2[, ...]]]])")])]),t._v(" "),s("li",[s("code",[t._v("start")]),t._v(":指定修改的开始位置(从 0 计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1 计数,这意味着-n 是倒数第 n 个元素并且等价于 array.length-n),如果负数的绝对值大于数组的长度,则表示开始位置为第 0 位。")]),t._v(" "),s("li",[s("code",[t._v("deleteCount")]),t._v(":整数,表示要移除的数组元素的个数。如果"),s("code",[t._v("deleteCount")]),t._v("大于"),s("code",[t._v("start")]),t._v("之后的元素的总数,则从"),s("code",[t._v("start")]),t._v("后面的元素都将被删除(含第"),s("code",[t._v("start")]),t._v("位)。")]),t._v(" "),s("li",[s("code",[t._v("item1, item2, ...")]),t._v(":要添加进数组的元素,从"),s("code",[t._v("start")]),t._v("位置开始。如果不指定,则只删除数组元素。")]),t._v(" "),s("li",[t._v("返回值:由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。")]),t._v(" "),s("li",[t._v("注意:"),s("code",[t._v("splice")]),t._v(" 方法会改变原始数组。")])]),t._v(" "),s("h4",{attrs:{id:"示例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("splice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"add1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"add2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 修改后的数组")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 被删除的元素组成的数组")]),t._v("\n")])])]),s("h4",{attrs:{id:"使用場景"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用場景"}},[t._v("#")]),t._v(" 使用場景:")]),t._v(" "),s("p",[t._v("在 React 中,通常推荐使用不可变数据模式来更新状态,尤其是当处理数组和对象时。"),s("code",[t._v("splice")]),t._v(" 方法会直接修改原数组,这可能导致 React 的状态更新行为表现得不如预期。")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("remove")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newGoods "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("goods"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n newGoods"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("splice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 删除 splice 方法, 会改变原数组, 返回被删除的元素")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setGoods")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newGoods"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在 "),s("code",[t._v("newGoods.splice(index, 1);")]),t._v(" 这行代码中,"),s("code",[t._v("splice")]),t._v(" 被用于从 "),s("code",[t._v("newGoods")]),t._v(" 数组中移除特定索引的元素。尽管这里使用了 "),s("code",[t._v("newGoods")]),t._v(" 作为 "),s("code",[t._v("goods")]),t._v(" 数组的副本,但由于数组是引用类型,在使用 "),s("code",[t._v("splice")]),t._v(" 之前,应该创建 "),s("code",[t._v("goods")]),t._v(" 的深拷贝。")]),t._v(" "),s("h3",{attrs:{id:"为什么需要深拷贝"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#为什么需要深拷贝"}},[t._v("#")]),t._v(" 为什么需要深拷贝?")]),t._v(" "),s("p",[t._v("当你使用 "),s("code",[t._v("newGoods = [...goods]")]),t._v(" 这样的语句时,实际上创建的是原数组的浅拷贝。这意味着 "),s("code",[t._v("newGoods")]),t._v(" 和 "),s("code",[t._v("goods")]),t._v(" 都指向相同的元素对象。当你在 "),s("code",[t._v("newGoods")]),t._v(" 上使用 "),s("code",[t._v("splice")]),t._v(" 时,虽然 "),s("code",[t._v("goods")]),t._v(" 数组本身没有被直接修改,但数组中的对象可能会受到影响,这可能导致 React 的不预期行为。")]),t._v(" "),s("h3",{attrs:{id:"正确的做法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#正确的做法"}},[t._v("#")]),t._v(" 正确的做法")]),t._v(" "),s("p",[t._v("为了避免这种问题,可以使用不会改变原数组的方法来处理数组。例如,可以使用 "),s("code",[t._v("filter")]),t._v(" 方法来创建一个不包含特定索引元素的新数组,而不是使用 "),s("code",[t._v("splice")]),t._v("。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("remove")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("index")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newGoods "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" goods"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setGoods")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newGoods"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个修改后的 "),s("code",[t._v("remove")]),t._v(" 函数中,"),s("code",[t._v("filter")]),t._v(" 方法被用来创建一个新的数组,其中不包含指定索引的元素。这种方法不会修改原数组,符合 React 的不可变数据原则,能够确保状态更新的可预测性。")]),t._v(" "),s("h3",{attrs:{id:"🔸-8-concat"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-8-concat"}},[t._v("#")]),t._v(" 🔸 8. "),s("code",[t._v("concat()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:连接两个或更多数组,并返回结果。不改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arr1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("concat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arr2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 合并后的数组")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-9-join"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-9-join"}},[t._v("#")]),t._v(" 🔸 9. "),s("code",[t._v("join()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:将数组的所有元素连接成一个字符串。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "a-b-c-d"')]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-10-slice"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-10-slice"}},[t._v("#")]),t._v(" 🔸 10. "),s("code",[t._v("slice()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:返回数组的一个片段或子数组。不改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["b", "c"]')]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-11-tostring"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-11-tostring"}},[t._v("#")]),t._v(" 🔸 11. "),s("code",[t._v("toString()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:将数组转换为字符串。不改变原数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "a,b,c,d"')]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-12-valueof"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-12-valueof"}},[t._v("#")]),t._v(" 🔸 12. "),s("code",[t._v("valueOf()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:返回数组的原始值。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" rel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("valueOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [1, 2, 3, 4]")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-13-indexof"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-13-indexof"}},[t._v("#")]),t._v(" 🔸 13. "),s("code",[t._v("indexOf()")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("功能:返回指定元素在数组中"),s("strong",[t._v("首次")]),t._v("出现的索引。不存在则返回-1。")])]),t._v(" "),s("li",[s("p",[t._v("示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("indexOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-14-lastindexof"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-14-lastindexof"}},[t._v("#")]),t._v(" 🔸 14. "),s("code",[t._v("lastIndexOf()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:返回指定元素在数组中最后一次出现的索引。不存在则返回-1。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("lastIndexOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-15-foreach"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-15-foreach"}},[t._v("#")]),t._v(" 🔸 15. "),s("code",[t._v("forEach()")])]),t._v(" "),s("h4",{attrs:{id:"功能-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-2"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("对数组的每个元素执行一次提供的函数, "),s("em",[t._v("不改变原数组")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("forEach")]),t._v(" cannot directly handle asynchronous operations with "),s("code",[t._v("await")]),t._v(".("),s("code",[t._v("forEach")]),t._v(" `doesn't wait for promises to resolve before moving on to the next iteration.)")])])]),t._v(" "),s("li",[s("p",[t._v("forEach()方法需要一个回调函数(这种函数,是由我们创建但是不由我们调用的)作为参数")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[t._v("arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("回调函数中传递三个参数:")]),t._v(" "),s("ul",[s("li",[t._v("第一个参数,就是当前正在遍历的元素")]),t._v(" "),s("li",[t._v("第二个参数,就是当前正在遍历的元素的索引")]),t._v(" "),s("li",[t._v("第三个参数,就是正在遍历的数组")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("forEach")]),t._v("本身是没有中断机制的。内部是遍历执行回调的。")]),t._v(" "),s("ul",[s("li",[t._v("在回调中增加判断条件,满足条件就抛出异常。(通常是不建议这么跳出循环的)")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("for(let item in arr) {}")]),t._v("这样的遍历方式,可以提前跳出循环")]),t._v(" "),s("li",[t._v("使用"),s("code",[t._v(".some")]),t._v(" 方法,一些场景判断,满足条件可以提前结束")])])])]),t._v(" "),s("h4",{attrs:{id:"示例-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-2"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//基本for 循環支持 await, 但是效率會很低.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetaData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" arrs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" datas "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" arrs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("https://jsonplaceholder.typicode.com/todos/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("arrs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("res")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("res")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n datas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" datas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetaData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("res")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"使用場景-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用場景-2"}},[t._v("#")]),t._v(" 使用場景:")]),t._v(" "),s("p",[t._v("当您需要对数组中的每个元素执行异步操作,例如逐个上传图片,但不需要收集这些异步操作的返回值时,您可以使用 "),s("code",[t._v("forEach")]),t._v(" 方法结合 "),s("code",[t._v("async/await")]),t._v("。请注意,虽然 "),s("code",[t._v("forEach")]),t._v(" 不能直接处理 "),s("code",[t._v("await")]),t._v(",但您可以在 "),s("code",[t._v("forEach")]),t._v(" 的回调函数中定义一个立即执行的异步函数来实现这一点。")]),t._v(" "),s("p",[t._v("以下是一个例子,演示了如何使用 "),s("code",[t._v("forEach")]),t._v(" 方法逐个上传图片:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("uploadImage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里是一个假设的上传函数,实际情况下应替换为实际的上传逻辑")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 假设这个函数返回一个 Promise")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://example.com/upload"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"POST"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" image"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("uploadImages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("images")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n images"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("uploadImage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("image"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Image uploaded:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error uploading image:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 假设这个数组包含了要上传的图片")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" imageArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"image1.png"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"image2.png"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"image3.png"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("uploadImages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("imageArray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个例子中:")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("uploadImage")]),t._v(" 函数是一个异步函数,用于上传单个图片,并返回一个 Promise 对象。")]),t._v(" "),s("li",[s("code",[t._v("uploadImages")]),t._v(" 函数接受一个图片数组,使用 "),s("code",[t._v("forEach")]),t._v(" 遍历这个数组。")]),t._v(" "),s("li",[t._v("在 "),s("code",[t._v("forEach")]),t._v(" 的回调函数中,我们定义了一个立即执行的异步函数来处理图片上传。")]),t._v(" "),s("li",[t._v("每个图片上传的结果将会被打印出来,但整个 "),s("code",[t._v("uploadImages")]),t._v(" 函数本身不会返回任何结果。")])]),t._v(" "),s("p",[t._v("请注意,由于 "),s("code",[t._v("forEach")]),t._v(" 并不等待异步操作完成,所有的上传操作将会几乎同时开始,这可能会对服务器造成压力。如果需要控制上传速度,比如一次只上传一个图片,您可能需要使用基本的 "),s("code",[t._v("for")]),t._v(" 循环或其他方法来顺序执行异步操作。")]),t._v(" "),s("h4",{attrs:{id:"其他可能場景"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#其他可能場景"}},[t._v("#")]),t._v(" 其他可能場景:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("处理菜单项")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("如果您有一个菜单项数组,您可能需要使用 "),s("code",[t._v("forEach")]),t._v(" 来遍历每个菜单项,以生成展示在网页上的菜单列表。")]),t._v(" "),s("li",[t._v("对于每个菜单项,可能还需要根据特定属性(如类别、价格区间、是否为素食等)进行进一步处理或分类。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("处理顾客评论")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("如果您的网站有顾客评论功能,您可以使用 "),s("code",[t._v("forEach")]),t._v(" 遍历评论数组,展示每个顾客的评分和评论。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("订单处理")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("在订单确认页面,您可能需要遍历订单中的每个项目,计算总价或应用折扣。")]),t._v(" "),s("li",[t._v("如果需要将订单中的每个项目发送到后端处理(如库存检查、订单入库等),也可以使用 "),s("code",[t._v("forEach")]),t._v("。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("图片或媒体内容展示")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("如果餐厅网站有图库展示餐厅内部、菜品等,您可以使用 "),s("code",[t._v("forEach")]),t._v(" 来遍历图片数组,为每张图片创建相应的 HTML 元素。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("员工管理")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("在员工管理界面,"),s("code",[t._v("forEach")]),t._v(" 可用于遍历员工列表,显示员工信息,或进行特定操作,如计算工资、安排班次等。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("库存管理")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("对于库存管理,"),s("code",[t._v("forEach")]),t._v(" 可以用于遍历库存列表,更新库存状态或进行库存预警。")])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("特殊活动或促销信息展示")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("如果餐厅有特殊活动或促销,您可以使用 "),s("code",[t._v("forEach")]),t._v(" 遍历活动数组,动态生成展示这些活动的界面元素。")])])])]),t._v(" "),s("p",[t._v("在这些场景中,"),s("code",[t._v("forEach")]),t._v(" 循环提供了一种简洁的方式来处理数组中的每个元素,尤其是当您不需要返回新数组时。这有助于编写更加清晰和可维护的代码。")]),t._v(" "),s("hr"),t._v(" "),s("h3",{attrs:{id:"🔸-16-map"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-16-map"}},[t._v("#")]),t._v(" 🔸 16. "),s("code",[t._v("map()")])]),t._v(" "),s("h4",{attrs:{id:"功能-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-3"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("數組原型是一個函數,對數組遍歷"),s("strong",[t._v("不破壞原數組")]),t._v(", 返回一個新數組, "),s("strong",[t._v("按照原是數組元素順序依次執行給定的函數")]),t._v(", 並將每一次函數執行的結果"),s("strong",[t._v("作為新數組的元素返回")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("map")]),t._v(" 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个新数组。")])]),t._v(" "),s("li",[s("p",[t._v("參數: "),s("code",[t._v("map")]),t._v(" 方法的回调函数接受三个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("element")]),t._v(":就是当前正在遍历的元素")]),t._v(" "),s("li",[s("code",[t._v("index")]),t._v(", 就是当前正在遍历的元素的索引")]),t._v(" "),s("li",[s("code",[t._v("array")]),t._v(",就是正在遍历的数组, 調用了 map()的數組本身")])])]),t._v(" "),s("li",[s("p",[t._v("語法:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("arr.map(callback(currentValue[, index[, array]])[, thisArg])")])]),t._v(" "),s("li",[s("code",[t._v("arr.map(callback(currentValue[, index[, array]])")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("thisArg")]),t._v(" 可选参数。执行 "),s("code",[t._v("callback")]),t._v(" 函数时使用的 "),s("code",[t._v("this")]),t._v(" 值。")])])])])])]),t._v(" "),s("h4",{attrs:{id:"示例-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-3"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("ol",[s("li",[t._v("将数组中的每个对象都添加一个新属性,并设置为相同的值。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" users "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Charlie"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" updatedUsers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("isActive")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("updatedUsers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// [{ name: "Alice", isActive: true }, { name: "Bob", isActive: true }, { name: "Charlie", isActive: true }]')]),t._v("\n")])])]),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" doubled"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("從數組對象裡提取特定屬性")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("21")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Charlie"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" names"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[t._v("将字符串数组转换为对象数组")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fruits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"banana"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cherry"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FruitObject")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fruitObjects"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FruitObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fruits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" fruit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruitObjects"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// [{ name: "apple" }, { name: "banana" }, { name: "cherry" }]')]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[t._v("对象数组中的数字属性进行转换")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Book'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Pen'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Pencil'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" discountedProducts"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\nprice"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price \\"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.9")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"使用場景-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用場景-3"}},[t._v("#")]),t._v(" 使用場景:")]),t._v(" "),s("p",[t._v("在 TypeScript 结合 React 开发的外卖应用(Web Restaurant App)中,使用"),s("code",[t._v(".map")]),t._v("方法来渲染列表是非常常见的。这里我将提供一些示例,展示如何在 TypeScript 环境下使用"),s("code",[t._v(".map")]),t._v("方法处理和渲染餐厅应用中的数据。")]),t._v(" "),s("ol",[s("li",[t._v("渲染菜单列表: 假设你有一个菜单项的数组,你想渲染这些菜单项到页面上。")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MenuItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n description"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Burger"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.99")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" description"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A classic burger"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pizza"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7.99")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" description"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cheesy pizza"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more menu items...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" MenuList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("menuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("description"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("订单详情: 在订单详情页,你可能需要列出用户所选的菜品及其价格。")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" orderItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OrderItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 假设这些数据是用户选择的菜品")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" OrderDetails"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ul"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("orderItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("li key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quantity"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quantity "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("li"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("ul"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[t._v("评分和评论, 显示用户对菜品的评分和评论。")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Review")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n user"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rating"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n comment"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" reviews"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 用户评论数据")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ReviewsList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("reviews"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h4"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h4"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Rating"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rating"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[t._v("如果你需要同时处理多个异步操作并等待它们全部完成,你可以使用 "),s("code",[t._v("Promise.all")]),t._v(" 结合 "),s("code",[t._v("map")]),t._v(" 方法,而不是 "),s("code",[t._v("forEach")]),t._v("。当您需要同时处理多个异步操作并等待它们全部完成时,可以使用 "),s("code",[t._v("Promise.all")]),t._v(" 结合 "),s("code",[t._v("map")]),t._v(" 方法。这种方法特别适用于需要并行执行多个异步请求并等待所有请求完成的情况。")])]),t._v(" "),s("p",[t._v("示例:并行获取多个资源: 假设您有一个 URL 数组,您需要从每个 URL 获取数据。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urls"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com/data1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com/data2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com/data3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更多URLs...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定义一个异步函数来获取每个URL的数据")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Promise")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Promise.all和map来并行获取所有数据")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAllData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Promise")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 打印所有获取到的数据")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error fetching data:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAllData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,"),s("code",[t._v("urls.map(url => fetchData(url))")]),t._v(" 会为每个 URL 创建一个 fetch 请求的 Promise。然后,"),s("code",[t._v("Promise.all")]),t._v(" 接收这个 Promise 数组,并等待所有的 fetch 请求都完成。一旦所有请求完成,"),s("code",[t._v("allData")]),t._v(" 变量将包含所有 URL 返回的数据。如果任何一个请求失败,"),s("code",[t._v("catch")]),t._v(" 块将捕获错误。")]),t._v(" "),s("p",[t._v("注意事项:")]),t._v(" "),s("ul",[s("li",[t._v("当使用 "),s("code",[t._v("Promise.all")]),t._v(" 时,如果任何一个 Promise 失败,整个 "),s("code",[t._v("Promise.all")]),t._v(" 调用会立即失败。这意味着如果您有多个请求,一个请求失败,其他成功的请求的结果也会被丢弃。如果您需要不同的行为(例如,处理每个请求的单独成功或失败),您可能需要考虑使用 "),s("code",[t._v("Promise.allSettled")]),t._v(" 或单独处理每个 Promise 的错误。")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("Promise.all")]),t._v(" 可以显著提高性能,因为它允许异步操作并行执行,而不是按顺序一个接一个执行。\n当然可以。在 TypeScript 和 React 结合使用的场景中,我们可以遇到更复杂的使用 "),s("code",[t._v("map")]),t._v(" 方法的例子,特别是在处理嵌套数据结构或进行更高级的数据转换时。以下是一些复杂的使用场景示例:")])]),t._v(" "),s("ol",{attrs:{start:"5"}},[s("li",[t._v("渲染嵌套评论")])]),t._v(" "),s("p",[t._v("假设你有一个嵌套评论的数据结构,你需要递归地渲染每个评论及其子评论。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Comment")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n text"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n user"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n replies"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" comments"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 假设的评论数据,每个评论可能有回复(也是Comment类型)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" renderComments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comments"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSX")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" comments"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h4"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h4"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div className"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"replies"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("renderComments")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CommentsList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("renderComments")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comments"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"6"}},[s("li",[t._v("动态生成表格列")])]),t._v(" "),s("p",[t._v("在一个数据驱动的应用中,你可能需要根据数据对象的属性动态生成表格列。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n stock"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 产品数据")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductTable"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("table"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("thead"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("tr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("th key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toUpperCase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("th"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("tr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("thead"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("tbody"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("tr key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("values")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("td key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("td"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("tr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("tbody"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("table"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"7"}},[s("li",[t._v("使用 "),s("code",[t._v("map")]),t._v(" 处理 TypeScript 枚举")])]),t._v(" "),s("p",[t._v("当你有一个 TypeScript 枚举,并希望基于枚举的值生成一组元素时。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" OrderStatus "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Pending "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pending"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n InProgress "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_progress"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Completed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"completed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Cancelled "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cancelled"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" StatusSelector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("select"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("values")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("OrderStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("option key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("option"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("select"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"8"}},[s("li",[t._v("使用 "),s("code",[t._v("Promise.all")]),t._v(" 与类型保护")])]),t._v(" "),s("p",[t._v("在处理多个异步请求时,你可能还需要进行类型保护,以确保每个响应都符合预期的类型。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ApiResponse")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DataResponse "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ErrorResponse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataResponse")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n status"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ok"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n data"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ErrorResponse")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n status"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n message"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fetchData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Promise")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ApiResponse"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" status"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ok"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" status"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAllData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urls"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" responses "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Promise")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fetchData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n responses"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("status "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ok"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Data:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,"),s("code",[t._v("ApiResponse")]),t._v(" 类型是一个联合类型,包括 "),s("code",[t._v("DataResponse")]),t._v(" 和 "),s("code",[t._v("ErrorResponse")]),t._v("。当处理 "),s("code",[t._v("Promise.all")]),t._v(" 的结果时,使用类型保护来确定每个响应是成功的数据响应还是错误响应。")]),t._v(" "),s("p",[t._v("这些例子展示了在更复杂的场景中使用 "),s("code",[t._v(".map")]),t._v(" 方法的多样性,尤其是在 TypeScript 环境中处理类型安全和异步操作时。")]),t._v(" "),s("hr"),t._v(" "),s("h3",{attrs:{id:"🔸-17-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-17-filter"}},[t._v("#")]),t._v(" 🔸 17. "),s("code",[t._v("filter()")])]),t._v(" "),s("h4",{attrs:{id:"功能-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-4"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[s("p",[s("code",[t._v("filter")]),t._v(" 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个新数组。")])]),t._v(" "),s("li",[s("p",[t._v("在回调函数中,返回值为 "),s("code",[t._v("true")]),t._v(" 的元素将会被保留,返回值为 "),s("code",[t._v("false")]),t._v(" 的元素将会被过滤掉。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("filter")]),t._v(" 方法不会改变原数组。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("filter")]),t._v(" 方法的回调函数接受三个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("element")]),t._v(":就是当前正在遍历的元素")]),t._v(" "),s("li",[s("code",[t._v("index")]),t._v(", 就是当前正在遍历的元素的索引")]),t._v(" "),s("li",[s("code",[t._v("array")]),t._v(",就是正在遍历的数组, 調用了 filter()的數組本身")]),t._v(" "),s("li",[s("code",[t._v("thisArg")]),t._v(" 可选参数。执行 "),s("code",[t._v("callback")]),t._v(" 函数时使用的 "),s("code",[t._v("this")]),t._v(" 值。")])])]),t._v(" "),s("li",[s("p",[t._v("語法:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("arr.filter(callback(currentValue[, index[, array]])[, thisArg])")])]),t._v(" "),s("li",[s("code",[t._v("arr.filter(callback(currentValue[, index[, array]])")])])])])]),t._v(" "),s("h4",{attrs:{id:"示例-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-4"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("p",[t._v("当然可以。下面是一些使用 "),s("code",[t._v("filter")]),t._v(" 方法的 TypeScript 示例,包括处理数组对象,并在某些情况下利用索引。")]),t._v(" "),s("ol",[s("li",[t._v("过滤特定条件的对象")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n inStock"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Apple"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" inStock"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Banana"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" inStock"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cherry"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" inStock"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 过滤出库存中的产品")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inStockProducts"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inStock\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("使用索引过滤")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 只保留偶数索引的元素")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredData"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[t._v("结合对象和索引过滤")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("24")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Carol"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 过滤出年龄大于25的用户,并且只保留偶数索引的用户")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" selectedUsers"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[t._v("移除数组中的重复元素")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" uniqueNumbers"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("indexOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" index\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"5"}},[s("li",[t._v("根据多个条件过滤")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Book")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n title"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n author"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n year"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" books"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Book"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" title"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1984"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" author"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"George Orwell"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" year"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1949")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n title"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The Great Gatsby"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n author"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"F. Scott Fitzgerald"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n year"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1925")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" title"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Brave New World"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" author"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Aldous Huxley"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" year"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1932")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// 过滤出在1930年之后出版的书籍,并且作者为 "Aldous Huxley"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredBooks"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Book"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" books"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("book"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" book"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("year "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1930")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" book"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("author "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Aldous Huxley"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"6"}},[s("li",[s("code",[t._v("map")]),t._v(" 和"),s("code",[t._v("filter")]),t._v(" 鏈式調用,數組對象裡提取特定屬性")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Charlie"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newUsers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" users\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" isMember"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newUsers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// [{ id: 1, name: "Alice", isMember: true }, { id: 2, name: "Bob", isMember: true }, { id: 3, name: "Charlie", isMember: true }]')]),t._v("\n")])])]),s("h4",{attrs:{id:"其他使用場景"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#其他使用場景"}},[t._v("#")]),t._v(" 其他使用場景:")]),t._v(" "),s("p",[t._v("在一个复杂的餐厅程序中,我们可以设想几个更复杂的 "),s("code",[t._v("filter")]),t._v(" 使用场景,这些场景涉及多条件筛选、嵌套数据结构以及和其他数组方法的结合使用。以下是一些 TypeScript 示例:")]),t._v(" "),s("ol",[s("li",[t._v("根据多个条件筛选菜单项")])]),t._v(" "),s("p",[t._v("假设你的餐厅应用需要根据多个条件(如价格范围、食物类型、客户评分)筛选菜单项。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MenuItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"starter"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"main"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dessert"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n averageRating"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 菜单项数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filterCriteria "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"main"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n priceRange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" min"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" max"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n minRating"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredMenuItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" filterCriteria"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v("\n item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" filterCriteria"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("priceRange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("min "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v("\n item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" filterCriteria"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("priceRange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("max "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v("\n item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("averageRating "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" filterCriteria"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("minRating\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",[s("li",[t._v("筛选包含特定配料的菜品及其变体")])]),t._v(" "),s("p",[t._v("考虑一个复杂的场景,其中菜品可能有多个变体(如不同的调味方式或配料)。你需要找到包含或排除特定配料的所有菜品及其变体。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MenuItemVariant")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n variantId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ingredients"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MenuItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n variants"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItemVariant"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 菜单项及变体数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ingredientFilter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cheese"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemsWithIngredient "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("variants"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("variant"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n variant"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ingredients"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ingredientFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[t._v("结合 "),s("code",[t._v("filter")]),t._v(" 和 "),s("code",[t._v("map")]),t._v(" 筛选并转换数据")])]),t._v(" "),s("p",[t._v("在某些情况下,你可能需要先筛选出符合条件的数据,然后转换这些数据以用于显示。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItemsWithRatings"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 含评分的菜单项数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" highRatedDishes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" menuItemsWithRatings\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("averageRating "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n rating"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("averageRating"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n priceRange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"High"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Medium"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[t._v("复杂订单过滤")])]),t._v(" "),s("p",[t._v("考虑到餐厅可能需要处理大量的订单数据,你可能需要根据订单的多个属性来筛选它们,如订单状态、金额、下单时间等。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Order")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n totalAmount"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n status"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"new"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"processing"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"delivered"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cancelled"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n orderDate"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Date"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" orders"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 订单数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredOrders "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" orders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("status "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"delivered"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v("\n order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalAmount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v("\n order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("orderDate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Date")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2021-01-01"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"🔸-18-every"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-18-every"}},[t._v("#")]),t._v(" 🔸 18. "),s("code",[t._v("every()")])]),t._v(" "),s("h4",{attrs:{id:"功能-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-5"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[t._v("检测数组所有元素是否都满足指定条件。")]),t._v(" "),s("li",[s("code",[t._v("every")]),t._v(" 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个布尔值。")]),t._v(" "),s("li",[t._v("在回调函数中,如果"),s("strong",[t._v("所有元素都满足条件")]),t._v(","),s("code",[t._v("every")]),t._v(" 方法将返回 "),s("code",[t._v("true")]),t._v(",否则返回 "),s("code",[t._v("false")]),t._v("。")])]),t._v(" "),s("h4",{attrs:{id:"示例-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-5"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("93")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("77")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("53")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("38")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("87")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("every")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n")])])]),s("h4",{attrs:{id:"使用場景-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用場景-4"}},[t._v("#")]),t._v(" 使用場景")]),t._v(" "),s("p",[t._v("当您需要检测数组中的所有元素是否满足指定条件时,可以使用 "),s("code",[t._v("every")]),t._v(" 方法。以下是一些 TypeScript 示例:")]),t._v(" "),s("ol",[s("li",[t._v("检测订单中的所有商品是否都有库存")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" orderItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OrderItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更多商品...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allItemsInStock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" orderItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("every")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quantity "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"🔸-19-some"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-19-some"}},[t._v("#")]),t._v(" 🔸 19. "),s("code",[t._v("some()")])]),t._v(" "),s("h4",{attrs:{id:"功能-6"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-6"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[t._v("检测数组中是否有元素满足指定条件。")]),t._v(" "),s("li",[s("code",[t._v("some")]),t._v(" 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个布尔值。")]),t._v(" "),s("li",[t._v("在回调函数中,"),s("strong",[t._v("如果有一个元素满足条件")]),t._v(","),s("code",[t._v("some")]),t._v(" 方法将返回 "),s("code",[t._v("true")]),t._v(",否则返回 "),s("code",[t._v("false")]),t._v("。")])]),t._v(" "),s("h4",{attrs:{id:"示例-6"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-6"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("93")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("77")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("53")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("38")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("87")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// true")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("和 "),s("code",[t._v("every")]),t._v(" 方法类似,"),s("code",[t._v("some")]),t._v(" 方法也可以用于检测数组中是否有元素满足指定条件。但是,"),s("code",[t._v("some")]),t._v(" 方法只要有一个元素满足条件,就会返回 "),s("code",[t._v("true")]),t._v(",而不是所有元素都满足条件。")])]),t._v(" "),s("h3",{attrs:{id:"🔸-20-reduce"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-20-reduce"}},[t._v("#")]),t._v(" 🔸 20. "),s("code",[t._v("reduce()")])]),t._v(" "),s("h4",{attrs:{id:"功能-7"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-7"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("对数组中的每个元素执行一个由您提供的 "),s("code",[t._v("reducer")]),t._v(" 函数(升序执行),将其结果汇总为单个返回值。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("reduce")]),t._v(" 方法對數組中每一個元素按序執行一個指定方法, 每一次允許"),s("code",[t._v("reducer")]),t._v(" 會將先前元素的計算結果作為參數傳入, 最後返回一個累積的結果")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("reduce")]),t._v(" 方法接受两个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("reducer")]),t._v(" 函数:用于处理数组中的每个元素,并将其结果汇总为单个返回值。")]),t._v(" "),s("li",[s("code",[t._v("initialValue")]),t._v(":作为第一次调用 "),s("code",[t._v("reducer")]),t._v(" 函数时的第一个参数使用的值。第一次回調函數的初始值,如果指定初始值,則會作為第一次調用 callback 函數時的第一個參數使用。如果沒有提供初始值,則將使用數組中的第一個元素。在沒有初始值的空數組上調用 reduce 將報錯。")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("reducer")]),t._v(" 函数接受四个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("accumulator")]),t._v(":累加器累计回调的返回值; 它是上一次调用回调时返回的累积值,或 "),s("code",[t._v("initialValue")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("currentValue")]),t._v(":数组中正在处理的元素。")]),t._v(" "),s("li",[s("code",[t._v("currentIndex")]),t._v(":数组中正在处理的元素的索引。如果提供了 "),s("code",[t._v("initialValue")]),t._v(",则索引号为 0,否则索引为 1。")]),t._v(" "),s("li",[s("code",[t._v("array")]),t._v(":调用 "),s("code",[t._v("reduce")]),t._v(" 的数组。")]),t._v(" "),s("li",[s("code",[t._v("thisArg")]),t._v(" 可选参数。执行 "),s("code",[t._v("callback")]),t._v(" 函数时使用的 "),s("code",[t._v("this")]),t._v(" 值。")])])])]),t._v(" "),s("h4",{attrs:{id:"示例-7"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-7"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("ol",[s("li",[t._v("计算订单总金额: 假设你有一个表示订单中各个商品及其数量的数组,你需要计算订单的总金额。")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" orderItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OrderItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" productId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更多商品...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalAmount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" orderItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("total"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" total "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quantity "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("将数组转换为对象 使用"),s("code",[t._v("reduce")]),t._v(" 方法可以将数组转换为更复杂的数据结构,比如对象。")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更多用户...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//累加器:reduce 方法的第一个参数是一个回调函数,这个回调函数接收两个参数:当前的累加器(obj)和当前正在处理的数组元素(user)。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" usersById "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// *将用户对象添加到以用户ID为键的对象中*")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// { 1: { id: 1, name: "Alice" }, 2: { id: 2, name: "Bob" } }')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 以空对象作为初始值")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("usersById"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// { 1: { id: 1, name: "Alice" }, 2: { id: 2, name: "Bob" } }')]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("当你看到这种写法 "),s("code",[t._v("obj[user.id] = user;")]),t._v(",它是一种在 JavaScript 和 TypeScript 中常用的方式,用于将数组中的元素映射到一个对象的属性上。具体来说,这种写法是在构造一个以 "),s("code",[t._v("user.id")]),t._v(" 作为键(key),"),s("code",[t._v("user")]),t._v(" 对象本身作为值(value)的对象。")])]),t._v(" "),s("blockquote",[s("p",[t._v("在这个表达式中:")])]),t._v(" "),s("blockquote",[s("ul",[s("li",[s("code",[t._v("obj")]),t._v(" 是一个对象,通常是一个空对象 "),s("code",[t._v("{}")]),t._v(",它在 "),s("code",[t._v("reduce")]),t._v(" 函数的迭代过程中不断被更新。")]),t._v(" "),s("li",[s("code",[t._v("user")]),t._v(" 是当前正在迭代的数组元素。")]),t._v(" "),s("li",[s("code",[t._v("user.id")]),t._v(" 是 "),s("code",[t._v("user")]),t._v(" 对象的一个属性,这里用作新对象的键。")]),t._v(" "),s("li",[s("code",[t._v("obj[user.id]")]),t._v(" 表示在 "),s("code",[t._v("obj")]),t._v(" 对象中创建或更新一个以 "),s("code",[t._v("user.id")]),t._v(" 的值为键的属性。")]),t._v(" "),s("li",[s("code",[t._v("obj[user.id] = user;")]),t._v(" 表示将当前的 "),s("code",[t._v("user")]),t._v(" 对象赋值给这个键。")])])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("分类汇总数据: 对数组中的项目进行分类,并计算每个类别中的项目数量。")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n category"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" category"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Electronics"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" category"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Books"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更多产品...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" categoryCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("category"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("category"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[s("code",[t._v("{} as { [key: string]: number });")]),t._v(" 是一種 type assertion, 用來告訴編譯器, 這個空對象的類型是 "),s("code",[t._v("{ [key: string]: number }")]),t._v("。 "),s("code",[t._v("{ [key: string]: number }:")]),t._v("这是一个索引签名类型。它描述了一个对象,这个对象可以拥有任意数量的属性,但所有属性的键(key)都是字符串类型,而对应的值(value)都是数字类型。")])]),t._v(" "),s("blockquote",[s("p",[t._v("[key: string]: 表示对象的键是字符串类型。key 在这里只是一个占位符,你可以使用任何名称。\nnumber: 表示属性值的类型必须是数字。")])]),t._v(" "),s("ol",{attrs:{start:"4"}},[s("li",[t._v("创建值的累积数组: 创建一个新数组,其中每个元素是原始数组中对应元素及其之前所有元素的累积和。")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" numbers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cumulativeSum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"使用場景-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用場景-5"}},[t._v("#")]),t._v(" 使用場景:")]),t._v(" "),s("p",[t._v("在餐厅应用程序(Restaurant App)的开发中,"),s("code",[t._v("reduce")]),t._v(" 方法可以在许多场景中发挥重要作用,尤其是在处理数据汇总、统计分析以及复杂的数组转换时。以下是一些针对餐厅应用的 TypeScript 示例,展示了 "),s("code",[t._v("reduce")]),t._v(" 方法的不同用途:")]),t._v(" "),s("ol",[s("li",[t._v("统计不同类型菜品的数量")])]),t._v(" "),s("p",[t._v("假设你的餐厅应用需要对菜单中不同类型的菜品进行统计。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MenuItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"starter"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"main"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dessert"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MenuItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 菜单数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemCountByType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" menuItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("计算每日总销售额")])]),t._v(" "),s("p",[t._v("计算一天内所有订单的总销售额。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Order")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n totalAmount"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n date"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Date"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" orders"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 当日订单数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalSales "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" orders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("total"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" total "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalAmount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"3"}},[s("li",[t._v("汇总顾客反馈")])]),t._v(" "),s("p",[t._v("将所有顾客的评论汇总成一个字符串。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Review")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n comment"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" reviews"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 顾客评论数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allComments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reviews"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comments"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" comments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" review"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("comment "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"4"}},[s("li",[t._v("创建菜品成分列表")])]),t._v(" "),s("p",[t._v("假设你需要从所有菜品中创建一个包含所有独特成分的列表。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Dish")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ingredients"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dishes"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Dish"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 菜品数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allIngredients "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dishes\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ingredients"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dish"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" ingredients"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("concat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dish"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ingredients"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" self"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" self"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("indexOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 移除重复项")]),t._v("\n")])])]),s("ol",{attrs:{start:"5"}},[s("li",[t._v("分类订单并计算每类的总金额")])]),t._v(" "),s("p",[t._v("假设你需要按顾客类型(比如会员和非会员)分类订单,并计算每一类的总金额。")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomerOrder")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n customerId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n totalAmount"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n isMember"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" customerOrders"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CustomerOrder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 顾客订单数据...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalAmountByCustomerType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" customerOrders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("totals"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isMember "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"members"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"nonMembers"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n totals"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("totals"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalAmount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" totals"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" members"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" nonMembers"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("hr"),t._v(" "),s("h3",{attrs:{id:"🔸-21-reduceright"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-21-reduceright"}},[t._v("#")]),t._v(" 🔸 21. "),s("code",[t._v("reduceRight()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:类似于"),s("code",[t._v("reduce()")]),t._v(",但从右到左执行。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 示例与`reduce()`类似,仅改变迭代方向")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"🔸-22-includes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-22-includes"}},[t._v("#")]),t._v(" 🔸 22. "),s("code",[t._v("includes()")])]),t._v(" "),s("h4",{attrs:{id:"功能-8"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#功能-8"}},[t._v("#")]),t._v(" 功能:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("判断数组是否包含指定的值, 返回布尔值。")])]),t._v(" "),s("li",[s("p",[t._v("只能檢測基本類型的值, 不能檢測引用類型的值")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("includes")]),t._v(" 方法接受两个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("searchElement")]),t._v(":要查找的元素。")]),t._v(" "),s("li",[s("code",[t._v("fromIndex")]),t._v(":可选参数。开始查找的位置。如果省略,则从数组的第一个元素(索引位置 0)开始查找。如果该值为负数,则按升序从 "),s("code",[t._v("array.length + fromIndex")]),t._v(" 的索引开始搜索。如果 "),s("code",[t._v("fromIndex")]),t._v(" 大于或等于数组的长度,则 "),s("code",[t._v("includes")]),t._v(" 不会查找数组,返回 "),s("code",[t._v("false")]),t._v("。")])])])]),t._v(" "),s("h4",{attrs:{id:"示例-8"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例-8"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" site "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"facebook"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"google"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"youtube"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("site"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"youtube"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// true")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("site"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"yahoo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n")])])]),s("h3",{attrs:{id:"_23-🔸-from"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_23-🔸-from"}},[t._v("#")]),t._v(" 23.🔸 "),s("code",[t._v("from()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:从类数组或可迭代对象创建一个新数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" all "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"张飞"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"28"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"男"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"率土"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"鸿图"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"三战"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("all"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"_24-🔸-find"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_24-🔸-find"}},[t._v("#")]),t._v(" 24. 🔸 "),s("code",[t._v("find()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:返回数组中满足提供的测试函数的第一个元素的值。否则返回"),s("code",[t._v("undefined")]),t._v("。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("66")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("77")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("88")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("99")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 66")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"_25-🔸-findindex"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_25-🔸-findindex"}},[t._v("#")]),t._v(" 25. 🔸 "),s("code",[t._v("findIndex()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("66")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("77")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("88")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("99")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" index "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"_26-🔸-fill"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_26-🔸-fill"}},[t._v("#")]),t._v(" 26. 🔸 "),s("code",[t._v("fill()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:用一个固定值填充数组中从起始索引到终止索引内的全部元素。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"填充"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["a", "填充", "c"]')]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"_27-🔸-flat"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_27-🔸-flat"}},[t._v("#")]),t._v(" 27. 🔸 "),s("code",[t._v("flat()")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("功能:创建一个新数组,其中所有子数组元素递归地连接到指定深度。")])]),t._v(" "),s("li",[s("p",[t._v("示例:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"拉平一次"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [1, 2, 3, 4, [5]]")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" arr2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 拉平两次")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"拉平两次"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arr2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [1, 2, 3, 4, 5]")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"_28-🔸-flatmap"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_28-🔸-flatmap"}},[t._v("#")]),t._v(" 28. 🔸 "),s("code",[t._v("flatMap()")])]),t._v(" "),s("ul",[s("li",[t._v("功能:首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。")]),t._v(" "),s("li",[t._v("示例:"),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("66")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("77")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("88")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("99")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" newArr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flatMap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"flatMap方法:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" newArr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 结果: [[55, 0], [66, 1], [77, 2], [88, 3], [99, 4], [100, 5]]")]),t._v("\n")])])])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/3.f8c28e7e.js b/assets/js/3.f8c28e7e.js new file mode 100644 index 00000000..3d7232bd --- /dev/null +++ b/assets/js/3.f8c28e7e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3,18,21],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return d})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(90);const r=/#.*$/,i=/\.(md|html)$/,s=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(r),n=e?e[0]:"",i=o(t);return s.test(i)?t:i+".html"+n}function d(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return o(t.path)===o(e)}function h(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,r,i=1){if("string"==typeof e)return h(n,e,r);if(Array.isArray(e))return Object.assign(h(n,e[0],r),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function b(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},242:function(t,e,n){"use strict";n.r(e);var r={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(243),n(14)),s=Object(i.a)(r,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},243:function(t,e,n){"use strict";n(240)},245:function(t,e,n){},250:function(t,e,n){},252:function(t,e,n){"use strict";n(245)},253:function(t,e,n){"use strict";n.r(e);var r=n(266),i=n(255),s=n(239);function a(t,e){if("group"===e.type){const n=e.path&&Object(s.e)(t,e.path),r=e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(s.e)(t,e.path));return n||r}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:r.default,SidebarLink:i.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(s.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,r){return e("li",{key:r},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:r===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(r)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},255:function(t,e,n){"use strict";n.r(e);var r=n(239);function i(t,e,n,r,i){const s={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}};return i>2&&(s.style={"padding-left":i+"rem"}),t("RouterLink",s,n)}function s(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(r.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,u,e.level-1),s(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(r.e)(a,u.path),d="auto"===u.type?p||u.children.some(t=>Object(r.e)(a,u.basePath+"#"+t.slug)):p,h="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):i(t,u.path,u.title||u.path,d),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[h,s(t,u.children,u.basePath,a,f)];if((d||b)&&u.headers&&!r.d.test(u.path)){return[h,s(t,Object(r.c)(u.headers),u.path,a,f)]}return h}},o=(n(252),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);e.default=l.exports},263:function(t,e,n){"use strict";n(250)},266:function(t,e,n){"use strict";n.r(e);var r=n(239),i={name:"SidebarGroup",components:{DropdownTransition:n(242).default},props:["item","open","collapsable","depth"],beforeCreate(){this.$options.components.SidebarLinks=n(253).default},methods:{isActive:r.e}},s=(n(263),n(14)),a=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("RouterLink",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/30.b352e55d.js b/assets/js/30.b352e55d.js new file mode 100644 index 00000000..2ebc16d8 --- /dev/null +++ b/assets/js/30.b352e55d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{319:function(t,s,a){"use strict";a.r(s);var r=a(14),i=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-javascript-articles-の研究例をいくつか"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-javascript-articles-の研究例をいくつか"}},[this._v("#")]),this._v(" ⚪️ Javascript -"),t("em",[this._v("articles")]),this._v(" の研究例をいくつか")])])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/31.c2296a43.js b/assets/js/31.c2296a43.js new file mode 100644 index 00000000..ee471e75 --- /dev/null +++ b/assets/js/31.c2296a43.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{320:function(t,e,r){"use strict";r.r(e);var n=r(14),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"next-js"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#next-js"}},[t._v("#")]),t._v(" Next.js")]),t._v(" "),e("p",[t._v("Reading lists:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://juejin.cn/post/7270331043234791458",target:"_blank",rel:"noopener noreferrer"}},[t._v("梳理 NextJS13 两种路由下的不同渲染方式:SSG,ISR,SSR,RSC"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://juejin.cn/post/7204085076504920119",target:"_blank",rel:"noopener noreferrer"}},[t._v("理解前端基础渲染模式| CSR、SSR、同构、静态化"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://juejin.cn/post/7160279477690466335",target:"_blank",rel:"noopener noreferrer"}},[t._v("Next.js 之前端渲染模式"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://malik11217.medium.com/%E7%90%86%E8%A7%A3-next-js-app-router-%E7%9A%84-data-fetching-%E8%88%87-server-components-%E4%B8%8D%E5%86%8D%E7%82%BA-ssr-ssg-isr-%E7%AD%89%E5%90%8D%E8%A9%9E%E7%85%A9%25E",target:"_blank",rel:"noopener noreferrer"}},[t._v("理解 Next.js App Router 的 Data Fetching 與 Server Components — 不再為 SSR/SSG/ISR 等名詞煩惱"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/32.f990ea1b.js b/assets/js/32.f990ea1b.js new file mode 100644 index 00000000..ac22407b --- /dev/null +++ b/assets/js/32.f990ea1b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{317:function(t,e,a){"use strict";a.r(e);var s=a(14),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"_1-what-is-getstaticprops-getstaticpaths"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-what-is-getstaticprops-getstaticpaths"}},[t._v("#")]),t._v(" 1. What is getStaticProps && getStaticPaths")]),t._v(" "),e("h3",{attrs:{id:"getstaticprops"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#getstaticprops"}},[t._v("#")]),t._v(" getStaticProps")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Purpose")]),t._v(": Primarily used for fetching static data at build time, which is then pre-rendered into HTML.")]),t._v(" "),e("li",[e("strong",[t._v("Execution Timing")]),t._v(": By default, getStaticProps runs only once at build time, with subsequent requests serving the data fetched during this build.")]),t._v(" "),e("li",[e("strong",[t._v("Application Scenarios")]),t._v(":\n"),e("ul",[e("li",[e("strong",[t._v("SSG")]),t._v(": In static site generation, getStaticProps provides necessary data for each page, optimizing SEO and load performance.")]),t._v(" "),e("li",[e("strong",[t._v("ISR")]),t._v(": By specifying a revalidate option, getStaticProps supports incremental static regeneration, allowing pages to be updated periodically after deployment without rebuilding the entire site.")])])])]),t._v(" "),e("h3",{attrs:{id:"getstaticpaths"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#getstaticpaths"}},[t._v("#")]),t._v(" getStaticPaths")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Purpose")]),t._v(": Used for dynamic route pages, guiding Next.js on how to generate static pages for dynamic routes at build time.")]),t._v(" "),e("li",[e("strong",[t._v("Execution Timing")]),t._v(": Runs at build time to pre-generate pages based on the returned paths.")]),t._v(" "),e("li",[e("strong",[t._v("Application Scenarios")]),t._v(":\n"),e("ul",[e("li",[e("strong",[t._v("Dynamic Routes")]),t._v(": For pages with dynamic routes (e.g., pages/posts/[id].js), getStaticPaths determines which ids should be pre-rendered into static pages.")]),t._v(" "),e("li",[e("strong",[t._v("Integration with")]),t._v(" getStaticProps: Once getStaticPaths specifies certain paths, each path is then pre-rendered using getStaticProps to fetch the corresponding data.")])])])]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-considerations"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-considerations"}},[t._v("#")]),t._v(" :light_bulb_on: Considerations")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Difference from")]),t._v(" getServerSideProps: getStaticProps fetches data at build time, suitable for data that changes infrequently; getServerSideProps, on the other hand, fetches data on every request, suitable for scenarios requiring real-time data.")]),t._v(" "),e("li",[e("strong",[t._v("Data Updates")]),t._v(": To update data on pages pre-rendered with getStaticProps, you can trigger a site rebuild or utilize ISR for updates.")]),t._v(" "),e("li",[e("strong",[t._v("Page-Level Only")]),t._v(": Both getStaticProps and getStaticPaths can only be used in page components, not within child components.")])]),t._v(" "),e("h2",{attrs:{id:"_2-deep-understanding-getstaticprops"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-deep-understanding-getstaticprops"}},[t._v("#")]),t._v(" 2. Deep understanding getStaticProps")]),t._v(" "),e("div",{staticClass:"language-tsx extra-class"},[e("pre",{pre:!0,attrs:{class:"language-tsx"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// pages/products.tsx")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n description"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductsPageProps")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n products"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductsPage"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ProductsPageProps"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" products "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("header")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Our Products")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("main")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("ul")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("products"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("key")]),e("span",{pre:!0,attrs:{class:"token script language-javascript"}},[e("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("description"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("strong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("$")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getStaticProps")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Simulating fetching data from an external API")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" res "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" products"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Product"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Fetched products at build time with getStaticProps"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n props"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n products"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" ProductsPage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("**Page Component (**ProductsPage): This component is responsible for rendering the products page. It receives an array of products as a prop, iterating over the array to display each product's name, description, and price.")]),t._v(" "),e("li",[e("strong",[t._v("Data Fetching with")]),t._v(" getStaticProps: The getStaticProps function fetches data from an external API, in this case, a list of products. This function runs at build time, pre-fetching the data needed to render the products page.")]),t._v(" "),e("li",[e("strong",[t._v("Props Structure")]),t._v(": The fetched data is structured under the props key and passed to the ProductsPage component. This approach ensures that the component has access to the product data when it's rendered.")]),t._v(" "),e("li",[e("strong",[t._v("Static Generation")]),t._v(": By utilizing getStaticProps, Next.js pre-renders the products page with the fetched data at build time. The resulting static page includes all product information, ready to be served immediately to users, enhancing the page's load time and SEO.")])]),t._v(" "),e("h3",{attrs:{id:"benefits"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#benefits"}},[t._v("#")]),t._v(" Benefits")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Improved Load Time")]),t._v(": Since the data is fetched at build time and the page is pre-rendered, users experience faster page loads.")]),t._v(" "),e("li",[e("strong",[t._v("SEO Optimization")]),t._v(": The pre-rendered page includes all product information in the HTML, making it easily indexable by search engines.")]),t._v(" "),e("li",[e("strong",[t._v("Build-time Data Fetching")]),t._v(": Fetching data at build time is efficient for data that doesn't change frequently, reducing the need for real-time API calls on each request.")])]),t._v(" "),e("h2",{attrs:{id:"invocation-timing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#invocation-timing"}},[t._v("#")]),t._v(" Invocation Timing")]),t._v(" "),e("ol",[e("li",[e("p",[e("strong",[t._v("During")]),t._v(" next build Execution:")]),t._v(" "),e("ul",[e("li",[t._v("getStaticProps is called once during the build process (next build). This means that for each page, getStaticProps fetches data and generates static HTML and a corresponding JSON file. These files can then be directly deployed to a CDN.")])])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("When")]),t._v(" getStaticPaths Returns fallback as Not false:")]),t._v(" "),e("ul",[e("li",[t._v("For dynamic route pages, getStaticProps is used alongside getStaticPaths. If getStaticPaths sets fallback to true or 'blocking', getStaticProps will be invoked to generate static pages for new path requests that were not generated at build time.")])])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("When Using")]),t._v(" revalidate:")]),t._v(" "),e("ul",[e("li",[t._v("When the object returned by getStaticProps includes a revalidate property, Incremental Static Regeneration (ISR) is enabled. The revalidate property specifies the interval at which the page data should be updated. Within this interval, the page will not be regenerated. Once surpassed, the next page request will trigger a re-generation of the page.")])])])]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-json-file-and-data-access"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-json-file-and-data-access"}},[t._v("#")]),t._v(" :light_bulb_on:JSON File and Data Access")]),t._v(" "),e("p",[t._v("At build time, Next.js generates not only static HTML files but also corresponding JSON files for pages using getStaticProps. This JSON file contains the return value of getStaticProps. It enables Next.js to quickly load data from the JSON file during client-side navigation (e.g., through next/link or next/router), instead of reloading the entire page, thus achieving fast client-side route transitions.")]),t._v(" "),e("p",[t._v("Example of a JSON file:")]),t._v(" "),e("div",{staticClass:"language-tsx extra-class"},[e("pre",{pre:!0,attrs:{class:"language-tsx"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"pageProps"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"content"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"__N_SSG"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Here, the **N_SSG flag indicates that this is a page generated through static generation, distinct from the **N_SSP flag used for pages generated through Server-Side Rendering (SSR), to differentiate between the data fetching methods.")]),t._v(" "),e("h3",{attrs:{id:"key-takeaways"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#key-takeaways"}},[t._v("#")]),t._v(" "),e("strong",[t._v("Key Takeaways:")])]),t._v(" "),e("p",[t._v("getStaticProps offers an efficient method for data fetching and page pre-rendering, particularly suited for scenarios where content updates infrequently. By leveraging static generation, incremental generation for dynamic routes, and ISR, Next.js applications can combine the high performance of static files with the flexibility of dynamic content, optimizing both user experience and SEO.")]),t._v(" "),e("ol",[e("li",[e("strong",[t._v("Server-Side Execution")]),t._v(": getStaticProps operates exclusively on the server, ensuring no part of its code ends up in the client-side JavaScript bundle.")]),t._v(" "),e("li",[e("strong",[t._v("Direct Server-Side Code")]),t._v(": Within getStaticProps, you can write server-side code to access the file system via the fs module, query databases, or include sensitive information like API keys, all securely without exposing any of it to the client-side browser.")]),t._v(" "),e("li",[e("strong",[t._v("Page-Specific and Pre-rendering Only")]),t._v(": getStaticProps is exclusive to page components and cannot be used in regular presentation components. It's designed for pre-rendering pages at build time, not for client-side data fetching.")]),t._v(" "),e("li",[e("strong",[t._v("Return Object Structure")]),t._v(": getStaticProps must return an object containing a props key, which itself is an object. This structure ensures the returned data can be passed as props to the page component.")]),t._v(" "),e("li",[e("strong",[t._v("Build Time and Development Mode Execution")]),t._v(": getStaticProps runs at build time for static generation. In development mode (npm run dev), getStaticProps executes on every request, ensuring developers have up-to-date data while working on the application.")])]),t._v(" "),e("h2",{attrs:{id:"_3-deep-understanding-getstaticpaths"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-deep-understanding-getstaticpaths"}},[t._v("#")]),t._v(" 3. Deep understanding `getStaticPaths")]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-using-getstaticpaths"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-using-getstaticpaths"}},[t._v("#")]),t._v(" :light_bulb_on: Using getStaticPaths")]),t._v(" "),e("p",[t._v("getStaticPaths is mainly used to build static pages in dynamic routes, which simply means that a dynamic route can be converted to multiple static pages by getStaticPaths.")]),t._v(" "),e("ul",[e("li",[t._v("pages/get-static-paths/[id].tsx")])]),t._v(" "),e("div",{staticClass:"language-tsx extra-class"},[e("pre",{pre:!0,attrs:{class:"language-tsx"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetStaticPaths")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" post "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" post"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Post: ")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("post"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStaticPaths")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://jsonplaceholder.typicode.com/posts"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" paths "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n params"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generated paths:"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" paths"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" paths"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" fallback"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStaticProps")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" params "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" params"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Fetching data for post:"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" params"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" props"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" post"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("Post content for ")]),e("span",{pre:!0,attrs:{class:"token interpolation"}},[e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("params"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" GetStaticPaths"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Here is a simple dynamic route, with getStaticPaths we can define the matching route values for this dynamic route, matching the parameters in the dynamic route with the params parameter in paths[number]. "),e("em",[t._v("Here are the")]),t._v(" getStaticPaths "),e("em",[t._v("and")]),t._v(" getStaticProps "),e("em",[t._v("related parts of the next.js steps to convert it to a static page.")])]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Invoke")]),t._v(" next build: Initiates the page data collection process in Next.js.")]),t._v(" "),e("li",[e("strong",[t._v("Detect Dynamic Routes")]),t._v(": Next.js calls getStaticPaths for pages with dynamic routes to obtain paths for static generation.")]),t._v(" "),e("li",[e("strong",[t._v("Iterate")]),t._v(" paths: Each path from the getStaticPaths return value is matched with its corresponding dynamic route.")]),t._v(" "),e("li",[e("strong",[t._v("Generate Static Pages")]),t._v(": Matches lead to the static generation process for each route.")]),t._v(" "),e("li",[e("strong",[t._v("Execute")]),t._v(" getStaticProps: The params from each path are passed to getStaticProps, which fetches data for the page.")]),t._v(" "),e("li",[e("strong",[t._v("Create HTML and JSON")]),t._v(": The data returned from getStaticProps is used to produce HTML and JSON files for each static page.")])]),t._v(" "),e("p",[t._v("So the above code will generate 10 static pages [1-10].html and 10 JSON files [1-10].json in next build, the generated files can be viewed under .next/server/pages/.")]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-understanding-getstaticpaths-operation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-understanding-getstaticpaths-operation"}},[t._v("#")]),t._v(" :light_bulb_on: "),e("strong",[t._v("Understanding")]),t._v(" getStaticPaths Operation:")]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("Static Resources")]),t._v(": The posts document, along with associated JavaScript files (e.g., _app, framework, main, and webpack runtime), are downloaded. These scripts include the code for the entire application and are essential for the page to function correctly.")])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("JSON Data Fetching")]),t._v(": Alongside the static resources, there are JSON files named 1.json, 2.json, 3.json, etc. These files are fetched dynamically and correspond to the data for each post.")])]),t._v(" "),e("li",[e("p",[t._v("When using getStaticPaths, Next.js statically pre-renders pages at build time based on the paths returned from this function.")])]),t._v(" "),e("li",[e("p",[t._v("Each path corresponds to a page that can be accessed by a user, and for dynamic routes (like posts), Next.js generates a JSON file for each path.")])]),t._v(" "),e("li",[e("p",[t._v("These JSON files contain the data needed to hydrate the page with content on the client side after the initial HTML has been loaded.")])]),t._v(" "),e("li",[e("p",[t._v("The presence of 1.json, 2.json, and 3.json indicates that three posts have been pre-rendered, and their data is available for the application to use when rendering the pages client-side.")])]),t._v(" "),e("li",[e("p",[t._v("When a user navigates to a specific post, the corresponding JSON file is fetched, which provides the data necessary to render the page fully with all the post details.")])])]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-understanding-the-fallback-parameter-in-next-js"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-understanding-the-fallback-parameter-in-next-js"}},[t._v("#")]),t._v(" :light_bulb_on: Understanding the fallback Parameter in Next.js")]),t._v(" "),e("p",[t._v("The fallback parameter in getStaticPaths is a crucial feature for handling dynamic routes in Next.js applications. "),e("em",[t._v("It determines the behavior of the application when a user accesses a route that hasn't been pre-rendered into a static page.")]),t._v(" There are three possible values for fallback: false, true, and blocking, each affecting the page access differently:")]),t._v(" "),e("h4",{attrs:{id:"fallback-false"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fallback-false"}},[t._v("#")]),t._v(" fallback: false")]),t._v(" "),e("ul",[e("li",[t._v("This is the default behavior where only the paths specified in getStaticPaths are pre-rendered at build time.")]),t._v(" "),e("li",[t._v("Accessing a non-existent page, such as /get-static-paths/11 when it's not defined in getStaticPaths, results in a 404 error page.")]),t._v(" "),e("li",[t._v("Suitable for applications where the set of valid paths is known and static.")]),t._v(" "),e("li",[t._v("使用場景:\n"),e("ul",[e("li",[t._v("需要預渲染的路徑較少")]),t._v(" "),e("li",[t._v("不經常添加新頁面")])])])]),t._v(" "),e("h4",{attrs:{id:"fallback-true"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fallback-true"}},[t._v("#")]),t._v(" fallback: true")]),t._v(" "),e("ul",[e("li",[t._v("The path returned by getStaticProps will be rendered to html by getStaticProps at build time.")]),t._v(" "),e("li",[t._v("When a user navigates to a page that doesn't exist within the pre-rendered paths, instead of immediately presenting a 404 error, Next.js will render a fallback version of the page. This is especially relevant when the fallback key in getStaticPaths is set to true. During this time, if you want to display a loading state, you can use router.isFallback to check if the fallback is currently being displayed. Here's how you can integrate this into your component:")])]),t._v(" "),e("div",{staticClass:"language-tsx extra-class"},[e("pre",{pre:!0,attrs:{class:"language-tsx"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRouter "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"next/router"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("MyComponent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" router "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRouter")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("router"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isFallback"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Render a loading state while the page is being statically generated")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),e("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Loading...")]),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Render your page's content")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("In the background, Next.js uses the page parameters to fetch data with getStaticProps, generates the static page and a JSON file, and then dynamically updates the page with the fetched data.")]),t._v(" "),e("li",[t._v("On subsequent visits to the same path, the pre-rendered static page is served directly, mirroring the behavior of existing pages.")]),t._v(" "),e("li",[t._v("This can be seen as a "),e("em",[t._v("lazy build")]),t._v(" strategy, enabling on-demand static generation for paths not pre-rendered at build time.")])]),t._v(" "),e("h4",{attrs:{id:"fallback-blocking"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fallback-blocking"}},[t._v("#")]),t._v(" fallback: 'blocking'")]),t._v(" "),e("ul",[e("li",[t._v("Similar to fallback: true, but with a critical difference: when accessing a non-existent page, the request waits for getStaticProps to finish fetching data and generating the static page before it is returned to the user.")]),t._v(" "),e("li",[t._v("This eliminates the need for a second data request and ensures that users get a consistent, pre-rendered page on the first access, whether asynchronously (with true) or synchronously (with blocking).")])]),t._v(" "),e("p",[t._v("Each fallback mode offers different advantages, depending on the specific needs of your application. fallback: false ensures fast performance and is suitable for known, unchanging routes. fallback: true offers flexibility and efficiency for applications with potentially infinite paths by generating pages on-demand. fallback: 'blocking' provides a seamless user experience by ensuring all users receive statically generated content, even if it means a slight delay on the first request to a non-pre-rendered path.")]),t._v(" "),e("p",[t._v("📌 Here there is a need to pay attention to the problem is getStaticPaths params in the parameter needs to be a string, otherwise it will lead to a failure to match, "),e("em",[t._v("guess for next.js in the type judgment or map operation, this in the follow-up source code to understand in the learning.")])]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-understanding-getstaticprops-and-getserversideprops-in-next-js"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-understanding-getstaticprops-and-getserversideprops-in-next-js"}},[t._v("#")]),t._v(" :light_bulb_on: Understanding getStaticProps and getServerSideProps in Next.js")]),t._v(" "),e("p",[t._v("It's crucial to recognize that getStaticProps and getServerSideProps are not interchangeable within the same page in Next.js. getStaticProps is tailored for Static Site Generation (SSG) scenarios, while getServerSideProps is designed for Server-Side Rendering (SSR) scenarios. Attempting to use both in a single page will trigger a Next.js warning: "),e("em",[t._v("You cannot use")]),t._v(" getStaticProps "),e("em",[t._v("or")]),t._v(" getStaticPaths "),e("em",[t._v("with")]),t._v(" getServerSideProps "),e("em",[t._v("To use SSG, please remove getServerSideProps")]),t._v(".")]),t._v(" "),e("p",[t._v("From a design perspective, mixing them might seem logical: getStaticProps for fetching static data and getServerSideProps for dynamic data, with dynamic potentially overriding static. However, Next.js enforces a function singularity principle, advocating for clear separation of static and dynamic data fetching mechanisms to ensure optimal performance and predictability.")]),t._v(" "),e("h3",{attrs:{id:"light-bulb-on-when-to-use-getstaticprops"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#light-bulb-on-when-to-use-getstaticprops"}},[t._v("#")]),t._v(" :light_bulb_on: When to Use getStaticProps")]),t._v(" "),e("p",[t._v("The decision on when to utilize getStaticProps can be guided by the nature of the data on your page:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Static Data Updates")]),t._v(": If your page content updates are triggered by publishing actions, getStaticProps is the ideal choice. It's essential, however, to be mindful of data security and privacy concerns.")]),t._v(" "),e("li",[e("strong",[t._v("Mix of Static and Dynamic Data")]),t._v(": For pages containing both static and dynamic data, it's recommended to stick with getServerSideProps. This ensures that dynamic content is accurately rendered based on each request, maintaining up-to-date information and interaction.")])]),t._v(" "),e("p",[t._v("In summary, while getStaticProps offers significant benefits for pages with data that doesn't change frequently, scenarios requiring real-time data should leverage getServerSideProps for its ability to fetch and render content server-side on each request. The choice between these data fetching methods hinges on the specific requirements of your Next.js application and the data it needs to present.")]),t._v(" "),e("h2",{attrs:{id:"pre-rendering"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#pre-rendering"}},[t._v("#")]),t._v(" Pre-rendering")]),t._v(" "),e("ul",[e("li",[t._v("Nextjs will pre-generate the HTML for each page, instead of letting client-side Javascript generate the HTML. "),e("strong",[t._v("Each HTML generated is associated with the minimum JavaScript code required for that page.")]),t._v(" When the browser loads the page, its JavaScript code works and makes the page fully interactive. "),e("em",[t._v("(This process is called hydration.)")])])]),t._v(" "),e("h2",{attrs:{id:"two-forms-of-pre-rendering"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#two-forms-of-pre-rendering"}},[t._v("#")]),t._v(" Two Forms of Pre-rendering")]),t._v(" "),e("h3",{attrs:{id:"static-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#static-generation"}},[t._v("#")]),t._v(" "),e("strong",[t._v("Static generation")]),t._v(":")]),t._v(" "),e("ul",[e("li",[t._v("Static generation is the "),e("code",[t._v("pre-rendering")]),t._v(" method where the "),e("code",[t._v("HTML")]),t._v(" pages are generated at build time. It offers excellent performance since the HTML is generated once and reused for each request. There are two scenarios in "),e("code",[t._v("Static Generation")]),t._v(":\n"),e("ul",[e("li",[e("strong",[t._v("Without Data")]),t._v(": This is suitable for pages that "),e("em",[t._v("do not require external data")]),t._v(" to be rendered. The "),e("code",[t._v("HTML")]),t._v(" is generated at build time and can be cached and served by a CDN.")]),t._v(" "),e("li",[e("strong",[t._v("With Data")]),t._v(": When the page content depends on external data (e.g., from a headless CMS), you can fetch this data at build time and generate the "),e("code",[t._v("HTML")]),t._v(" based on that data. This approach is "),e("em",[t._v("still "),e("strong",[t._v("static")]),t._v(" since the data fetching and")]),t._v(" "),e("code",[t._v("HTML")]),t._v(" "),e("em",[t._v("generation happen once during the build process.")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Incremental Static Regeneration (ISR)")]),t._v(": An enhancement to static generation with data, ISR allows pages to be regenerated on a per-request basis, at a defined interval, without needing to rebuild the entire site. "),e("em",[t._v("This makes it possible to have updated data without sacrificing the benefits of static generation")])])])])])])]),t._v(" "),e("h3",{attrs:{id:"server-side-rendering-ssr"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#server-side-rendering-ssr"}},[t._v("#")]),t._v(" "),e("strong",[t._v("Server-Side Rendering (SSR)")])]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Data Fetching")]),t._v(": SSR dynamically "),e("em",[t._v("generates the HTML for each page")]),t._v(" on every request, which means it can always serve the most up-to-date content. It's particularly useful for pages that fetch data that changes frequently, ensuring that users always get the latest information.")]),t._v(" "),e("li",[e("strong",[t._v("Dynamic Parameters Support")]),t._v(": SSR is ideal for handling dynamic routes where the content of the page depends on parameters passed in the URL. The server can use these parameters to fetch specific data and render the page accordingly.")])]),t._v(" "),e("table",[e("thead",[e("tr",[e("th"),t._v(" "),e("th"),t._v(" "),e("th")])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("strong",[t._v("Use Cases")])]),t._v(" "),e("td",[e("strong",[t._v("Static Generation")])]),t._v(" "),e("td",[e("strong",[t._v("Server-Side Rendering")])])]),t._v(" "),e("tr",[e("td"),t._v(" "),e("td",[e("strong",[t._v("Blogging Sites")]),t._v(":"),e("br"),e("br"),t._v("- Content updates infrequently."),e("br"),t._v(" "),e("br"),t._v("- At build time, articles are fetched from a headless CMS to generate static pages for fast access.")]),t._v(" "),e("td",[e("strong",[t._v("E-commerce Sites")]),t._v(":"),e("br"),e("br"),t._v("- Product information, prices, and stock levels change frequently."),e("br"),t._v(" "),e("br"),t._v("- SSR ensures that users see the most up-to-date product information.")])]),t._v(" "),e("tr",[e("td"),t._v(" "),e("td",[e("strong",[t._v("Documentation Sites")]),t._v(":"),e("br"),e("br"),t._v("- Technical documentation with relatively low update frequency."),e("br"),t._v(" "),e("br"),t._v("- Static pages are easy to cache and distribute, speeding up access.")]),t._v(" "),e("td",[e("strong",[t._v("Social Media Platforms")]),t._v(":"),e("br"),e("br"),t._v("- User posts, comments, and other content are constantly updated."),e("br"),t._v(" "),e("br"),t._v("- SSR dynamically generates pages with the latest content, enhancing real-time interaction.")])])])]),t._v(" "),e("h2",{attrs:{id:"how-to-enabling-static-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#how-to-enabling-static-generation"}},[t._v("#")]),t._v(" How to Enabling Static Generation")]),t._v(" "),e("p",[t._v("Static Generation is a pre-rendering technique in Next.js that allows for the generation of HTML pages at build time. The most straightforward way to enable Static Generation is by using "),e("code",[t._v("getStaticProps")]),t._v(" (for fetching page data) and "),e("code",[t._v("getStaticPaths")]),t._v(" (for pages with dynamic routes) within your pages.")]),t._v(" "),e("h3",{attrs:{id:"production-server-vs-development-server"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#production-server-vs-development-server"}},[t._v("#")]),t._v(" Production Server vs. Development Server")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Production Server")]),t._v(": When you run the "),e("code",[t._v("next build")]),t._v(" command to build your application, Next.js generates static HTML for every page that utilizes "),e("code",[t._v("getStaticProps")]),t._v(". These pages are rendered at build time and subsequently, each request serves these pre-rendered static pages without regenerating them. This means that once the build is complete, the page content will not change unless a rebuild is executed.")]),t._v(" "),e("li",[e("strong",[t._v("Development Server")]),t._v(": In development mode (usually initiated with "),e("code",[t._v("npm run dev")]),t._v(" or "),e("code",[t._v("yarn dev")]),t._v("), "),e("code",[t._v("getStaticProps")]),t._v(" is executed on every request for the sake of convenience in development. This ensures that you see the most up-to-date data and page changes while developing. The development mode simulates the static generation of the production mode but ensures hot reloading after each file change, offering a smoother development experience.")])]),t._v(" "),e("h2",{attrs:{id:"fetching-data-at-request-time"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fetching-data-at-request-time"}},[t._v("#")]),t._v(" Fetching Data at Request Time")]),t._v(" "),e("h3",{attrs:{id:"data-fetching-with-dynamic-parameters-and-client-side-data-fetching"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#data-fetching-with-dynamic-parameters-and-client-side-data-fetching"}},[t._v("#")]),t._v(" Data Fetching with Dynamic Parameters and Client-Side Data Fetching")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Dynamic Parameter Support in Server-Side Rendering")]),t._v(": Server-side rendering allows for dynamic data fetching based on request parameters, making it ideal for pages with dynamic routes. This flexibility enables the server to generate page content that specifically matches the parameters of each request.")]),t._v(" "),e("li",[e("strong",[t._v("Client-Side Data Fetching")]),t._v(": Data can also be fetched on the client-side using JavaScript, which is suitable for scenarios where page content needs to be updated in real-time based on user interactions. This approach allows web applications to fetch and render data reactively, enhancing the user experience with dynamic content.")])]),t._v(" "),e("h3",{attrs:{id:"combining-pre-rendering-with-client-side-data-fetching"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#combining-pre-rendering-with-client-side-data-fetching"}},[t._v("#")]),t._v(" Combining Pre-rendering with Client-Side Data Fetching")]),t._v(" "),e("p",[t._v("By integrating pre-rendering techniques with client-side data fetching, developers can create applications that are both fast to load and highly interactive. Static content is pre-rendered at build time for quick initial display to users, while dynamic content is fetched and updated on the client-side as users interact with the application. This combination offers the best of both worlds: the performance benefits of static generation and the flexibility of dynamic, client-side data updates.")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/33.e2f64269.js b/assets/js/33.e2f64269.js new file mode 100644 index 00000000..f2a6bb8c --- /dev/null +++ b/assets/js/33.e2f64269.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{316:function(t,s,e){"use strict";e.r(s);var r=e(14),a=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-next-js-articles-の研究例をいくつか"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-next-js-articles-の研究例をいくつか"}},[this._v("#")]),this._v(" ⚪️ Next.js-"),t("em",[this._v("articles")]),this._v(" の研究例をいくつか")])])}),[],!1,null,null,null);s.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/34.b9fe4fba.js b/assets/js/34.b9fe4fba.js new file mode 100644 index 00000000..bd2ae24e --- /dev/null +++ b/assets/js/34.b9fe4fba.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{322:function(e,t,r){"use strict";r.r(t);var a=r(14),o=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"react"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#react"}},[e._v("#")]),e._v(" React")]),e._v(" "),t("blockquote",[t("p",[e._v("React は、インタラクティブなユーザインターフェイスの作成にともなう苦痛を取り除きます。アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。")])]),e._v(" "),t("blockquote",[t("p",[e._v("宣言的な View を用いてアプリケーションを構築することで、コードはより見通しが立ちやすく、デバッグのしやすいものになります。")])]),e._v(" "),t("h2",{attrs:{id:"references"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[e._v("#")]),e._v(" References")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://react.dev/reference/react",target:"_blank",rel:"noopener noreferrer"}},[e._v("React 公式文書"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("a",{attrs:{href:"https://ja.legacy.reactjs.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("ユーザインターフェース構築のための JavaScript ライブラリ"),t("OutboundLink")],1),e._v(" React を学びましょう。")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://alexkondov.com/tao-of-react/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Tao of React - Software Design, Architecture & Best Practices"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("a",{attrs:{href:"https://frontendmastery.com/posts/the-new-wave-of-react-state-management/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("The new wave of React state management"),t("OutboundLink")],1),e._v(" (Excellent read!)")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://alexsidorenko.com/blog/react-render-usememo?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("A Visual Guide to React Rendering - useMemo"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("a",{attrs:{href:"https://overreacted.io/react-as-a-ui-runtime/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("React as a UI Runtime"),t("OutboundLink")],1),e._v(" (By Dan Abramov from the React team)\n"),t("a",{attrs:{href:"https://react.dev/learn/you-might-not-need-an-effect?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("You Might Not Need an Effect"),t("OutboundLink")],1),e._v(" (Official React docs)")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://overreacted.io/a-complete-guide-to-useeffect/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("A Complete Guide to useEffect"),t("OutboundLink")],1),e._v(" (By Dan Abramov)\n"),t("a",{attrs:{href:"https://blog.thoughtspile.tech/2021/11/15/unintentional-layout-effect/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("useEffect sometimes fires before paint"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("a",{attrs:{href:"https://overreacted.io/making-setinterval-declarative-with-react-hooks/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Making setInterval Declarative with React Hooks"),t("OutboundLink")],1),e._v(" (By Dan Abramov)")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/?ref=jonas.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Redux - Not Dead Yet!"),t("OutboundLink")],1),e._v(" (By Mark Erikson from the Redux team)")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://blog.isquaredsoftware.com/2021/01/context-redux-differences/",target:"_blank",rel:"noopener noreferrer"}},[e._v('Why React Context is Not a "State Management" Tool'),t("OutboundLink")],1),e._v(" (By Mark Erikson)")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/35.6015d88a.js b/assets/js/35.6015d88a.js new file mode 100644 index 00000000..33e53548 --- /dev/null +++ b/assets/js/35.6015d88a.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[35],{321:function(t,r,e){"use strict";e.r(r);var a=e(14),s=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"⚪️-react-js-articles-の研究例をいくつか"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-react-js-articles-の研究例をいくつか"}},[t._v("#")]),t._v(" ⚪️ React.js -"),r("em",[t._v("articles")]),t._v(" の研究例をいくつか")]),t._v(" "),r("h2",{attrs:{id:"🔸-react-ssr-原理解析和实践"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#🔸-react-ssr-原理解析和实践"}},[t._v("#")]),t._v(" 🔸 "),r("a",{attrs:{href:"https://juejin.cn/post/7144905013016395783",target:"_blank",rel:"noopener noreferrer"}},[t._v("React SSR 原理解析和实践"),r("OutboundLink")],1)]),t._v(" "),r("h2",{attrs:{id:"🔸-从零开始-react-服务器渲染-ssr-同构-😏-基于-koa"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#🔸-从零开始-react-服务器渲染-ssr-同构-😏-基于-koa"}},[t._v("#")]),t._v(" 🔸 "),r("a",{attrs:{href:"https://juejin.cn/post/6844903777766473742",target:"_blank",rel:"noopener noreferrer"}},[t._v("从零开始 React 服务器渲染(SSR)同构 😏(基于 Koa"),r("OutboundLink")],1)]),t._v(" "),r("h2",{attrs:{id:"🔸-react-服务端渲染从入门到精通"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#🔸-react-服务端渲染从入门到精通"}},[t._v("#")]),t._v(" 🔸 "),r("a",{attrs:{href:"https://juejin.cn/post/6844903807994822669",target:"_blank",rel:"noopener noreferrer"}},[t._v("React 服务端渲染从入门到精通"),r("OutboundLink")],1)])])}),[],!1,null,null,null);r.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/36.2ee99065.js b/assets/js/36.2ee99065.js new file mode 100644 index 00000000..72bd9b81 --- /dev/null +++ b/assets/js/36.2ee99065.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{323:function(t,e,a){"use strict";a.r(e);var s=a(14),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"⚪️react-を基礎から理解する"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#⚪️react-を基礎から理解する"}},[t._v("#")]),t._v(" ⚪️React を基礎から理解する")]),t._v(" "),e("h2",{attrs:{id:"🔶-react-api-とは"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#🔶-react-api-とは"}},[t._v("#")]),t._v(" 🔶 React API とは")]),t._v(" "),e("p",[t._v("React API とは、React が提供する機能のことです。React API は、React のコンポーネントを作成するために必要な機能を提供します。")]),t._v(" "),e("h2",{attrs:{id:"🔶-react-api-の種類"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#🔶-react-api-の種類"}},[t._v("#")]),t._v(" 🔶 React API の種類")]),t._v(" "),e("p",[t._v("React API には、以下の種類があります。")]),t._v(" "),e("ul",[e("li",[e("p",[t._v("React.createElement()\n"),e("code",[t._v("React.createElement(type, [props], [...children])")])]),t._v(" "),e("ul",[e("li",[t._v("用来创建 React 元素")]),t._v(" "),e("li",[t._v("React の要素は、一度作成すると変更することができず、新しい要素を作成してレンダリングすることしかできない。")])])]),t._v(" "),e("li",[e("p",[t._v("ReactDOM.createRoot()\n"),e("code",[t._v("createRoot(container[, options])")])]),t._v(" "),e("ul",[e("li",[t._v("用来创建 React 的根容器,容器用来放置 React 元素")])])]),t._v(" "),e("li",[e("p",[t._v("ReactDOM.render()\n"),e("code",[t._v("root.render(element)")])]),t._v(" "),e("ul",[e("li",[t._v("用来将 React 元素渲染到根元素中")]),t._v(" "),e("li",[t._v("根元素中所有的内容都会被删除,被 React 元素所替换")]),t._v(" "),e("li",[t._v("当重复调用 render()时,React 会将两次的渲染结果进行比较,")]),t._v(" "),e("li",[t._v("它会确保只修改那些发生变化的元素,对 DOM 做最少的修改")])])])]),t._v(" "),e("h3",{attrs:{id:"▫️-react-createelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#▫️-react-createelement"}},[t._v("#")]),t._v(" ▫️ "),e("code",[t._v("React.createElement")])]),t._v(" "),e("ul",[e("li",[e("p",[t._v("React 要素を作成するためのメソッドで、DOM 要素ではなく React 要素を生成します。")])]),t._v(" "),e("li",[e("p",[t._v("DOM 要素は最終的にページに表示される要素であり、React 要素は実際に操作する要素です。")])]),t._v(" "),e("li",[e("p",[t._v("両者は仮想 DOM を介して操作され、相互に関連しています。")])]),t._v(" "),e("li",[e("p",[t._v("原則として、React 要素を操作する際には、原生の DOM 要素を直接操作せず、React の仮想 DOM 構造を壊さないように心がけるべきです。")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("React.createElement")]),t._v(" 関数の戻り値は React 要素であり、React 内の仮想 DOM 構造において操作されます。")])]),t._v(" "),e("li",[e("p",[t._v("React でのイベントはキャメルケースで表記されるべきであり、例えば、onClick、onMouseOver、onMouseOut などがあります。")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("React")]),t._v(" 要素は、type、props、children の 3 つのプロパティを持つオブジェクトである。")]),t._v(" "),e("ul",[e("li",[t._v("type: string | function")]),t._v(" "),e("li",[t._v("props: object")]),t._v(" "),e("li",[t._v("children: ReactElement | string | number")]),t._v(" "),e("li",[t._v("return: ReactElement")])])]),t._v(" "),e("li",[e("p",[t._v("要素の命名規則:")]),t._v(" "),e("ul",[e("li",[t._v("要素の名前: HTML タグは小文字である必要があり、React では大文字はコンポーネントとして解釈されます。")]),t._v(" "),e("li",[t._v("要素のプロパティ: オブジェクトで、キーがプロパティの名前、値がプロパティの値です。")]),t._v(" "),e("li",[t._v("要素の子要素: 1 つ以上の子要素で、テキスト、または要素、または要素の配列が可能です。")])]),t._v(" "),e("blockquote",[e("p",[t._v("注意:React において、イベントの設定と属性の設定は異なります。イベントの設定時には、属性名をキャメルケースに変更する必要があります。例えば、"),e("code",[t._v("onClick")]),t._v("は"),e("code",[t._v("onclick")]),t._v("ではなく"),e("code",[t._v("onClick")]),t._v("となります。これは、ネイティブイベントと React イベントを区別するためであり、そのため React イベントの属性名はキャメルケースである必要があります。")])]),t._v(" "),e("blockquote",[e("p",[t._v("React において、"),e("code",[t._v("onClick")]),t._v("はコードを受け取るのではなく、関数を受け取ります。これは、"),e("code",[t._v("onClick")]),t._v("がトリガーされたときに関数が実行されることを意味します。"),e("code",[t._v('onClick={() => alert("click me")}')]),t._v("のように書くと、レンダリング時に即座に実行されず、クリック時にのみ実行されます。"),e("code",[t._v('onClick={() => alert("click me")}')]),t._v("のように直接書くと、"),e("code",[t._v("onClick")]),t._v("には"),e("code",[t._v('alert("click me")')]),t._v("の戻り値が代入され、レンダリング時に実行されてしまいます。これを避け、クリック時に実行されるようにするためには、アロー関数を使用することが適切です。")])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("const div = React.createElement('div', {}, button)")]),t._v(" 可以在子元素裡直接放 button 進去")])])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div id"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//create a react element")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" button "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"button"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"btn"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("className")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'btn'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onClick")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("alert")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'clicked'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Click me"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//get the root element, 就是把dom元素轉換成react裏的根元素, 這樣才能render, 這裏的rootElement就是一個dom元素")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" rootElement "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" document"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//render the react element into the root element")]),t._v("\nReactDOM"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("button"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rootElement"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"▫️reactdom-createroot"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#▫️reactdom-createroot"}},[t._v("#")]),t._v(" ▫️"),e("code",[t._v("ReactDOM.createRoot")])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("ReactDOM.createRoot")]),t._v(" 関数は、React の根要素を作成するための関数です。")])]),t._v(" "),e("h3",{attrs:{id:"▫️reactdom-render"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#▫️reactdom-render"}},[t._v("#")]),t._v(" ▫️"),e("code",[t._v("ReactDOM.render")])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("ReactDOM.render")]),t._v(" 関数は、React 要素をレンダリングするための関数です。")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/37.9bd0a687.js b/assets/js/37.9bd0a687.js new file mode 100644 index 00000000..ea54a680 --- /dev/null +++ b/assets/js/37.9bd0a687.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{325:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-react-hooks-を基礎から理解する"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-react-hooks-を基礎から理解する"}},[t._v("#")]),t._v(" ⚪️ React Hooks を基礎から理解する")]),t._v(" "),s("h2",{attrs:{id:"🔷-usestate-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-usestate-とは"}},[t._v("#")]),t._v(" 🔷 useState とは")]),t._v(" "),s("p",[t._v("useState()は、関数コンポーネントで state を管理(state の保持と更新)するための React フックであり、最も利用されるフックです。")]),t._v(" "),s("p",[t._v("state とはコンポーネントが内部で保持する「状態」のことで、画面上に表示されるデータ等、アプリケーションが保持している状態を指しています。state は props と違い後から変更することができます")]),t._v(" "),s("h3",{attrs:{id:"▫️-usestate-の注意点"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usestate-の注意点"}},[t._v("#")]),t._v(" ▫️ useState の注意点")]),t._v(" "),s("p",[s("strong",[t._v("1. Accepts a single parameter, the initial state value, which can be any data type:")])]),t._v(" "),s("blockquote",[s("p",[t._v("唯一のパラメータを受け取り、それが状態の初期値であり、初期値は任意のデータ型であることができます。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with a string initial state")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setText"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with a number initial state")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with an object initial state")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setPerson"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setText")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bye"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Change Text"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("2. Returns an array containing the state value and a method to update the state:")])]),t._v(" "),s("blockquote",[s("p",[t._v('戻り値は、状態値と状態を更新するためのメソッドが含まれた配列で、メソッド名は "set" で始まり、後に状態名が続きます。')])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example using a boolean state")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("isActive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setIsActive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("3. "),s("code",[t._v("useState()")]),t._v(" can be used multiple times to store multiple states:")])]),t._v(" "),s("blockquote",[s("p",[t._v("useState()は複数回使用でき、異なる状態値を保存できます。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with two different states")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAge"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("4. Parameter can be a function, and the initial state is determined by the function's return value. The function is only called once, it used when the initial value is dynamic.:")])]),t._v(" "),s("blockquote",[s("p",[t._v("パラメータは関数であることができ、関数が返すものが初期状態になります。関数は一度だけ呼び出され、初期の動的値の場合に使用されます。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with a function as the initial state")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 從外部 props 中取得 count 的值,如果不存在,預設為 0")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" propsCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 useState,將初始值設置為一個函數,這個函數會在初始化時被調用一次")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 這裡可以進行一些邏輯處理,例如動態計算初始值")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" propsCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//這樣寫是有錯誤的 ❌,因為每次渲染都會調用 useState,這樣會導致每次渲染都會調用函數,這樣就不是只調用一次了。 正確寫法如下:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//這樣,這個函數就只會在渲染的時候執行。")]),t._v("\n\n")])])]),s("p",[s("strong",[t._v("5.状態の設定メソッドの引数は値または関数にすることができます(つまり、値を渡すことも、関数を渡すこともできます。関数の戻り値によって新しい状態が設定されます。")])]),t._v(" "),s("p",[s("code",[t._v("setCount()")]),t._v(" の引数は値であるか、あるいは関数であるか選択できます。関数の場合、その関数の引数は現在の状態値であり、関数の戻り値が新しい状態値となります。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 値を渡す")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("新しい値"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 関数を渡す")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("現在のCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここで計算やロジックを行います")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 戻り値が新しい状態値になります")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("何らかの計算")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("現在のCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example with a function as the parameter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleCountChange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setCount(count + 1);")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("prevCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" prevCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleCountChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Change Count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("strong",[t._v("6. 状態の設定メソッド自体が非同期です")])]),t._v(" "),s("p",[t._v("状態の更新は非同期で行われるため、"),s("code",[t._v("setCount")]),t._v(" を即座に呼び出しても、React はすぐに状態を更新しません。状態更新後に何らかの操作を実行する必要がある場合は、"),s("code",[t._v("useEffect")]),t._v(" を使用するか、関数式の更新で前の状態値を使用します。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// useEffect を使用する例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここで何らかの操作を実行します。これは状態が更新された後に実行されます")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Count updated:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// count を useEffect の依存リストに追加することを忘れずに")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// あるいは関数式の更新で前の状態値を使用する例")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("前のCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここで前の状態値(前のCount)を使用します")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" 前のCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("strong",[t._v("7. "),s("code",[t._v("useState()")]),t._v(" can be used in a custom hook:")])]),t._v(" "),s("blockquote",[s("p",[t._v("useState()はカスタムフックで使用できます。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom hook")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCounter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("initialCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("increment")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("prevCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" prevCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decrement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("prevCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" prevCount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" increment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" decrement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Component using the custom hook")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" increment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" decrement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCounter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("increment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Increment"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("decrement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Decrement"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("hr"),t._v(" "),s("h2",{attrs:{id:"🔶-usereducer-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-usereducer-とは"}},[t._v("#")]),t._v(" 🔶 useReducer とは")]),t._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"https://qiita.com/seira/items/2fbad56e84bda885c84c",target:"_blank",rel:"noopener noreferrer"}},[t._v("React hooks を基礎から理解する (useReducer 編)"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("状態管理のためのフックで、"),s("code",[t._v("useState")]),t._v(" と似たような機能。"),s("code",[t._v("useState")]),t._v(" は "),s("code",[t._v("useReducer")]),t._v(" に内部実装されています。")]),t._v(" "),s("p",[s("code",[t._v("(state, action) => newState")]),t._v(" という型の "),s("code",[t._v("reducer")]),t._v(" を受け取り、現在の "),s("code",[t._v("state")]),t._v(" と "),s("code",[t._v("dispatch")]),t._v(" 関数の両方を返します。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"初期値"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("reducer")]),t._v(" は "),s("code",[t._v("state")]),t._v(" を更新するための関数で、"),s("code",[t._v("dispatch")]),t._v(" は、"),s("code",[t._v("reducer")]),t._v(" を実行するための呼び出し関数です。 (変数を宣言するときに、state の更新方法をあらかじめ設定しておくことが出来る。)\n"),s("code",[t._v("dispatch(action)")]),t._v("で実行\n"),s("code",[t._v("action")]),t._v(" は何をするのかを示すオブジェクト \n"),s("code",[t._v("{type: increment, payload: 0}")]),t._v("のように、type プロパティ("),s("code",[t._v("action")]),t._v(" の識別子)と値のプロパティで構成されている。")]),t._v(" "),s("h3",{attrs:{id:"▫️-usereducer-の注意点"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usereducer-の注意点"}},[t._v("#")]),t._v(" ▫️ useReducer の注意点")]),t._v(" "),s("p",[s("strong",[t._v("1. "),s("code",[t._v("useReducer")]),t._v(" は "),s("code",[t._v("useState")]),t._v(" の代替ではない")])]),t._v(" "),s("blockquote",[s("p",[t._v("useState と useReducer の比較")])]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("特性")]),t._v(" "),s("th",[s("code",[t._v("useState")])]),t._v(" "),s("th",[s("code",[t._v("useReducer")])])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("扱える state 的 type")]),t._v(" "),s("td",[t._v("数値、文字列、オブジェクト、論理値")]),t._v(" "),s("td",[t._v("オブジェクト、配列")])]),t._v(" "),s("tr",[s("td",[t._v("関連する state 的取り扱い")]),t._v(" "),s("td",[t._v("☓")]),t._v(" "),s("td",[t._v("複数を同時に取り扱うことが出来る")])]),t._v(" "),s("tr",[s("td",[t._v("ローカル or グローバル")]),t._v(" "),s("td",[t._v("ローカル")]),t._v(" "),s("td",[t._v("グローバル "),s("code",[t._v("useContext()")]),t._v(" と一緒に取り扱う")])])])]),t._v(" "),s("hr"),t._v(" "),s("h2",{attrs:{id:"🔷-usecontext-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-usecontext-とは"}},[t._v("#")]),t._v(" 🔷 useContext とは")]),t._v(" "),s("p",[t._v("React コンポーネントのツリーに対して「グローバル」とみなすデータについて利用するように設計されています。\nコンポーネントの再利用をより難しくする為、慎重に利用しなくてはなりません。")]),t._v(" "),s("p",[t._v("Context によってコンポーネントツリー間におけるデータの橋渡しについて、すべての階層ごとに渡す必要性がなくなり、props バケツリレーをしなくても下の階層で Context に収容されているデータにアクセスできるようになりました。")]),t._v(" "),s("p",[t._v("useContext とは、Context 機能をよりシンプルに使えるようになった機能。\n親から Props で渡されていないのに、Context に収容されているデータへよりシンプルにアクセスできるというものです。")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://camo.qiitausercontent.com/d85d663b26e6c050651d65ac61d80a50ab125eb5/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3231383635362f31353330363034392d653661652d666439352d653035312d3133623633363365626636352e676966",alt:""}})]),t._v(" "),s("p",[s("img",{attrs:{src:"https://dev.classmethod.jp/articles/react-i-checked-again-how-to-use-usecontext/",alt:"[React] useContextの使い方を改めて確認してみた"}})]),t._v(" "),s("hr"),t._v(" "),s("ul",[s("li",[t._v("without useReducer")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Child")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Child "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("add"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Parent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Parent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Child count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MyApp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Parent count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReactDOM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createRoot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nroot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("MyApp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("The above code leads to the problem that the more nested levels are, the more props are passed, and the more difficult the code is to maintain.")])]),t._v(" "),s("ul",[s("li",[t._v("useReducer 使わない場合")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" createContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useContext "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1. Create a context object")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" MyContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Child")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3. Retrieve values from the context object using useContext and destructure the object")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Child "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("add"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Parent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// const { count, setCount } = props;")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4. Retrieve values from the context object using useContext and destructure the object")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Parent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* \n Child component can access context values directly */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Child"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Child"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MyApp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 2. Configure the context provider and pass the value.\n The 'value' prop contains the data to be passed, and all child components,\n including nested ones, can access it using useContext. */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Provider value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Parent component can access context values directly */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Parent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Provider"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReactDOM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createRoot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nroot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("MyApp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("useReducer と useContext を使わない場合")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" createContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useReducer "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Define the initial state and reducer function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"increment"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a context object")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" MyContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Child")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve values from the context object using useContext and destructure the object")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Child "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"increment"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("add"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Parent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve values from the context object using useContext and destructure the object")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Parent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Child component can access context values directly */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Child "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MyApp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use useReducer to manage state")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initialState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Configure the context provider and pass the value */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Provider value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("Root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("h2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Parent component can access context values directly */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Parent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("MyContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Provider"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReactDOM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createRoot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nroot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("render")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("MyApp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔷-useeffect-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-useeffect-とは"}},[t._v("#")]),t._v(" 🔷 useEffect とは")]),t._v(" "),s("p",[t._v("'useEffect' を使うと、'useEffect' に渡された関数はレンダーの結果が画面に反映された後に動作します。\nつまり 'useEffect' とは、「関数の実行タイミングを React のレンダリング後まで遅らせる 'hook'」です。")]),t._v(" "),s("p",[t._v("副作用の処理(DOM の書き換え、変数代入、API 通信など UI 構築以外の処理)を関数コンポーネントで扱えます。\nクラスコンポーネントでのライフサイクルメソッドに当たります。")]),t._v(" "),s("p",[t._v("'componentDidMount'\n'componentDidUpdate'\n'componentWillUnmount'")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://ja.legacy.reactjs.org/docs/hooks-effect.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("副作用フックの利用法\n"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"▫️-副作用を実行、制御するために-useeffect-を利用する"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-副作用を実行、制御するために-useeffect-を利用する"}},[t._v("#")]),t._v(" ▫️ 副作用を実行、制御するために useEffect を利用する")]),t._v(" "),s("p",[t._v("useEffect()の基本構文は以下の通りです。関数コンポーネントのトップレベルで宣言します。")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("_ 第 1 引数には実行させたい副作用関数を記述_")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"副作用関数が実行されました!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("依存する変数の配列"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 第 2 引数には副作用関数の実行タイミングを制御する依存データを記述")]),t._v("\n")])])]),s("p",[t._v("第 2 引数を指定することにより、第 1 引数に渡された副作用関数の実行タイミングを制御することができます。React は第 2 引数の依存配列の中身の値を比較して、副作用関数をスキップするかどうかを判断します。")]),t._v(" "),s("h3",{attrs:{id:"▫️-執行時機"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-執行時機"}},[t._v("#")]),t._v(" ▫️ 執行時機")]),t._v(" "),s("p",[t._v("可以把"),s("code",[t._v("useEffect")]),t._v(" 函數卡奴走 componentDidiMount、componentDidUpdate、componentWillUnmount 三個生命週期函數的組合體。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("useEffect(() => {}); componentDidMount + componentDidUpdate;")])]),t._v(" "),s("li",[s("code",[t._v("useEffect(() => {}, []); componentDidMount;")])]),t._v(" "),s("li",[s("code",[t._v("useEffect(() => () => {}); componentWillUnmount;")])])]),t._v(" "),s("p",[t._v("以下是 "),s("code",[t._v("useEffect")]),t._v(" 的理解:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[s("code",[t._v("useEffect(() => {});")]),t._v(" - "),s("code",[t._v("componentDidMount")]),t._v(" + "),s("code",[t._v("componentDidUpdate")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("この形式の "),s("code",[t._v("useEffect")]),t._v(" は、コンポーネントのレンダリング後に実行され、コンポーネントが更新されるたびにも実行されます。")]),t._v(" "),s("li",[s("code",[t._v("componentDidMount")]),t._v(" と "),s("code",[t._v("componentDidUpdate")]),t._v(" の組み合わせに相当します。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここにあるコードはコンポーネントのレンダリング後および更新時に実行されます")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("useEffect(() => {}, []);")]),t._v(" - "),s("code",[t._v("componentDidMount")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("この形式の "),s("code",[t._v("useEffect")]),t._v(" は、コンポーネントのレンダリング後にのみ実行され、コンポーネントの更新時には実行されません。")]),t._v(" "),s("li",[s("code",[t._v("componentDidMount")]),t._v(" だけが実行された場合と同じです。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここにあるコードはコンポーネントのレンダリング後に一度だけ実行されます")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("useEffect(() => () => {});")]),t._v(" - "),s("code",[t._v("componentWillUnmount")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("この形式の "),s("code",[t._v("useEffect")]),t._v(" では、返り値として返された関数はコンポーネントがアンマウント(消える)される際に実行され、"),s("code",[t._v("componentWillUnmount")]),t._v(" に相当します。")]),t._v(" "),s("li",[t._v("返り値として返された関数はコンポーネントがアンマウントされる前に実行され、リソースのクリーンアップや購読の解除に使用できます。")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ここにあるコードはコンポーネントのレンダリング後に実行されます")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返り値として返された関数はコンポーネントがアンマウントされる前に実行されます")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// リソースのクリーンアップや購読の解除などのコード")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])]),t._v(" "),s("h3",{attrs:{id:"▫️-useeffect-の使い方"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-useeffect-の使い方"}},[t._v("#")]),t._v(" ▫️ useEffect の使い方")]),t._v(" "),s("ol",[s("li",[t._v("為 window 對象添加滾動事件 - "),s("code",[t._v("componentDidMount")]),t._v(" + "),s("code",[t._v("componentDidUpdate")])])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onScroll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"onScroll"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 組件渲染後,添加滾動事件")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addEventListener")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"scroll"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" onScroll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 組件卸載時,移除滾動事件")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("removeEventListener")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"scroll"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" onScroll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("App"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("定時器:掛載定時器,要在組件渲染後才能掛載,所以要在 useEffect 中掛載定時器")])]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useEffect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" ReactDom "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react-dom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" timerId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("timerId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("span"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("span"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" ReactDOM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unmountComponentAtNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n 卸載組件\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"▫️-useeffect-依賴項"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-useeffect-依賴項"}},[t._v("#")]),t._v(" ▫️ useEffect 依賴項")]),t._v(" "),s("blockquote",[s("p",[t._v("依存配列の値が変化した場合のみ副作用関数を実行させる\nuseEffect()の第2引数に[count]を渡すと、count に変化があったときだけ副作用関数を実行します。")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" makeStyles "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@material-ui/core/styles"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" ButtonGroup "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@material-ui/core/ButtonGroup"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Button "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@material-ui/core/Button"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Input "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@material-ui/core/Input"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" useStyles "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeStyles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("theme")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("root")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"& > *"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("margin")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" theme"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("spacing")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("EffectFunc")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" classes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useStyles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("lastName")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("firstName")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("title "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("回クリックされました")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("回クリックされました")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ButtonGroup color"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"primary"')]),t._v(" aria"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("label"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"outlined primary button group"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("prev")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("ボタン"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Button onClick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("リセット"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("Button"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("ButtonGroup"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("私の名前は")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lastName"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("firstName"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("です")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("form className"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("classes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" noValidate autoComplete"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"off"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Input\n placeholder"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"姓"')]),t._v("\n value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lastName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n onChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("lastName")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Input\n placeholder"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"名"')]),t._v("\n value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("firstName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n onChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("firstName")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("form"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" EffectFunc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔷-useref-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-useref-とは"}},[t._v("#")]),t._v(" 🔷 useRef とは")]),t._v(" "),s("p",[s("code",[t._v("useRef")]),t._v(" 是 React 提供的一个 Hook,其主要特点是用于在函数组件中保存和访问可变的引用。以下是 "),s("code",[t._v("useRef")]),t._v(" 的主要特点:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("保存可变的引用:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" 创建一个对象,该对象的 "),s("code",[t._v("current")]),t._v(" 属性可以被赋值为任何可变的值。这使得在整个组件的生命周期内都可以访问和修改该值,而不引发组件重新渲染。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("不触发重新渲染:")]),t._v(" 当 "),s("code",[t._v("useRef")]),t._v(" 的 "),s("code",[t._v("current")]),t._v(" 属性被修改时,不会触发组件的重新渲染。这使得它非常适合存储不需要引起视图更新的数据,例如 DOM 元素引用、定时器 ID、或其他持久性数据。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("持久性数据存储:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" 创建的引用是持久的,即使组件重新渲染,引用仍然保持不变。这与 "),s("code",[t._v("useState")]),t._v(" 不同,后者在重新渲染时会创建新的状态。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("访问 DOM 元素:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" 常用于引用 DOM 元素。当 "),s("code",[t._v("ref")]),t._v(" 属性附加到 JSX 元素上时,"),s("code",[t._v("useRef")]),t._v(" 的 "),s("code",[t._v("current")]),t._v(" 属性将持有该元素的引用。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("适用于保存上一个值:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" 也常用于保存上一个状态值,因为它不会引发重新渲染,可以在渲染期间保留其值。")])])]),t._v(" "),s("p",[t._v("下面是一个简单的示例,演示了 "),s("code",[t._v("useRef")]),t._v(" 保存 DOM 元素引用的情况:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("ExampleComponent")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inputRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" HTMLInputElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在组件挂载后,通过 inputRef.current 访问 input 元素")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("focus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("input ref"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,"),s("code",[t._v("inputRef")]),t._v(" 用于引用 "),s("code",[t._v("input")]),t._v(" 元素,而不需要通过 "),s("code",[t._v("document.getElementById")]),t._v(" 或其他方式获取。")]),t._v(" "),s("blockquote",[s("p",[t._v("key characteristics of the "),s("code",[t._v("useRef")]),t._v(" hook:")])]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Mutable Reference:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" creates a mutable object that persists across renders.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Preservation of Value:")]),t._v(" The value assigned to "),s("code",[t._v("current")]),t._v(" property of the "),s("code",[t._v("useRef")]),t._v(" object persists between renders.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Doesn't Trigger Re-renders:")]),t._v(" Updating the "),s("code",[t._v("current")]),t._v(" property of a "),s("code",[t._v("useRef")]),t._v(" does not trigger a re-render of the component.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Preserving Values Without Re-renders:")]),t._v(" It's useful for holding values that need to be preserved between renders but don't require triggering a re-render.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Common Use Cases:")])])])]),t._v(" "),s("ul",[s("li",[t._v("Managing and maintaining references to DOM elements.")]),t._v(" "),s("li",[t._v("Holding values that should persist without causing re-renders.")]),t._v(" "),s("li",[t._v("Storing mutable values without triggering component updates.")])]),t._v(" "),s("ol",{attrs:{start:"6"}},[s("li",[s("p",[s("strong",[t._v("When to Use:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" is useful for managing and maintaining references to DOM elements, storing mutable values that don't trigger re-renders, and storing mutable values that you want to persist across renders.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("When Not to Use:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" should not be used to manage state or trigger re-renders.")])])]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("Note:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" is not a replacement for "),s("code",[t._v("useState")]),t._v(". Always use "),s("code",[t._v("useState")]),t._v(" when you need to manage state that changes over time. "),s("code",[t._v("useRef")]),t._v(" is useful for storing mutable values that don't change over time, such as a reference to a DOM node or a value computed in a previous render.")])]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("Note:")]),t._v(" "),s("code",[t._v("useRef")]),t._v(" returns a mutable ref object whose "),s("code",[t._v(".current")]),t._v(" property is initialized to the passed argument ("),s("code",[t._v("initialValue")]),t._v("). The returned object will persist for the full lifetime of the component.")])]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("Note:")]),t._v(" "),s("code",[t._v("useRef()")]),t._v(" is useful for more than the "),s("code",[t._v("ref")]),t._v(" attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.")])]),t._v(" "),s("h2",{attrs:{id:"🔷-usecallback-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-usecallback-とは"}},[t._v("#")]),t._v(" 🔷 useCallback とは")]),t._v(" "),s("h3",{attrs:{id:"🔺-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔺-example"}},[t._v("#")]),t._v(" 🔺 Example")]),t._v(" "),s("p",[t._v("在實際應用中,"),s("code",[t._v("useCallback")]),t._v(" 的使用場景通常涉及到優化性能,特別是在 React 應用中傳遞回調函數給子組件的情況。以下是一個實際應用的例子:")]),t._v(" "),s("p",[t._v('假設你有一個點餐應用(類似 SkipTheDishes),你有一個頁面顯示用戶的訂單列表。每個訂單都有一個狀態,比如"已下單"、"準備中"、"配送中"等。你的應用可能會有一個組件來顯示單個訂單的詳細信息,並且你希望在點擊"更新狀態"按鈕時觸發一個回調函數來更新訂單的狀態。')]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useCallback "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("OrderDetails")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" onUpdateStatus "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleUpdateStatus "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在這裡處理更新訂單狀態的邏輯")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("onUpdateStatus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" newStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("onUpdateStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" newStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 顯示訂單詳細信息 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Order ID: ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Status: ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 更新狀態按鈕 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleUpdateStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Update Status")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("OrderList")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" orders "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleUpdateStatus "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("orderId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" newStatus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在這裡處理更新訂單狀態的邏輯")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 這個函數可能會在 OrderDetails 組件中使用,因此使用 useCallback 進行優化")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Updating status of order ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("orderId"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" to ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("newStatus"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Order List")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 顯示訂單列表 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("orders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderDetails")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("order")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onUpdateStatus")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleUpdateStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("SkipTheDishesApp")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("orders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setOrders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 初始訂單數據 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OrderList")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("orders")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("orders"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("在這個例子中,"),s("code",[t._v("handleUpdateStatus")]),t._v(' 函數是一個回調函數,當你點擊"Update Status"按鈕時,這個函數會被觸發。由於它被傳遞給 '),s("code",[t._v("OrderDetails")]),t._v(" 組件,我們使用 "),s("code",[t._v("useCallback")]),t._v(" 來確保它只在 "),s("code",[t._v("onUpdateStatus")]),t._v("、"),s("code",[t._v("order.id")]),t._v(" 或 "),s("code",[t._v("newStatus")]),t._v(" 改變時才重新創建。這樣可以避免不必要的組件重新渲染,提高應用性能。")])]),t._v(" "),s("hr"),t._v(" "),s("h2",{attrs:{id:"🔷-usememo-とは"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-usememo-とは"}},[t._v("#")]),t._v(" 🔷 useMemo とは")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://www.joshwcomeau.com/react/usememo-and-usecallback/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Understanding useMemo and useCallback-Josh"),s("OutboundLink")],1)]),t._v(" "),s("h2",{attrs:{id:"🔶-hooks-compare"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-hooks-compare"}},[t._v("#")]),t._v(" 🔶 Hooks compare")]),t._v(" "),s("h3",{attrs:{id:"▫️-usecallback-vs-usememo"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usecallback-vs-usememo"}},[t._v("#")]),t._v(" ▫️ useCallback vs useMemo")]),t._v(" "),s("blockquote",[s("p",[s("code",[t._v("useMemo")]),t._v(" 和 "),s("code",[t._v("useCallback")]),t._v("接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于 "),s("code",[t._v("useMemo")]),t._v(" 返回的是函数运行的结果,"),s("code",[t._v("useCallback")]),t._v(" 返回的是函数,这个回调函数是经过处理后的也就是说父组件传递一个函数给子组件的时候,由于是无状态组件每一次都会重新生成新的 "),s("code",[t._v("props")]),t._v(" 函数,这样就使得每一次传递给子组件的函数都发生了变化,这时候就会触发子组件的更新,这些更新是没有必要的,此时我们就可以通过 "),s("code",[t._v("useCallback")]),t._v(" 来处理此函数,然后作为 props 传递给子组件。")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 用react.memo */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" DemoChildren "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 只有初始化的时候打印了 子组件更新 */")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"子组件更新"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getInfo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"子组件"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("子组件")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("DemoUseCallback")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("number"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setNumber"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 此时usecallback的第一参数 (sonName)=>{ console.log(sonName) }\n 经过处理赋值给 getInfo */")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" getInfo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("sonName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sonName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 点击按钮触发父组件更新 ,但是子组件没有更新 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("number "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("增加")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DemoChildren")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("getInfo")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getInfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/38.04db86c7.js b/assets/js/38.04db86c7.js new file mode 100644 index 00000000..f980d7c9 --- /dev/null +++ b/assets/js/38.04db86c7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{327:function(t,e,s){"use strict";s.r(e);var r=s(14),a=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"react-redux-を基礎から理解する"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#react-redux-を基礎から理解する"}},[this._v("#")]),this._v(" React Redux を基礎から理解する")])])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/39.1fe91b86.js b/assets/js/39.1fe91b86.js new file mode 100644 index 00000000..7e40b42e --- /dev/null +++ b/assets/js/39.1fe91b86.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{326:function(e,t,r){"use strict";r.r(t);var a=r(14),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"typescript-reference-guide"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#typescript-reference-guide"}},[e._v("#")]),e._v(" Typescript Reference Guide")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/intro.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("TypeScript Handbook"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("a",{attrs:{href:"https://qiita.com/kamenaris/items/8393c08dde3584d5e6ba",target:"_blank",rel:"noopener noreferrer"}},[e._v("TypeScript で型をご安全に メモ"),t("OutboundLink")],1),e._v(" "),t("a",{attrs:{href:"https://chodocs.cn/ts/ch4.html",target:"_blank",rel:"noopener noreferrer"}},[t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"shortcut-reference"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#shortcut-reference"}},[e._v("#")]),e._v(" Shortcut Reference")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/basic-types.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Basic Types"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/interfaces.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Interfaces"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/classes.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Classes"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/functions.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Functions"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/generics.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Generics"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/enums.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Enums"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/type-inference.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Type Inference"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/type-compatibility.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Type Compatibility"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/advanced-types.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Advanced Types"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/symbols.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Symbols"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Iterators and Generators"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/modules.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Modules"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/namespaces.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Namespaces"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"table-of-contents"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#table-of-contents"}},[e._v("#")]),e._v(" Table of Contents")]),e._v(" "),t("ul",[t("li",[t("p",[t("a",{attrs:{href:"#basic-types"}},[e._v("Basic Types")])]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#boolean"}},[e._v("Boolean")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#number"}},[e._v("Number")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#string"}},[e._v("String")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#array"}},[e._v("Array")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#tuple"}},[e._v("Tuple")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#enum"}},[e._v("Enum")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#any"}},[e._v("Any")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#void"}},[e._v("Void")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#null-and-undefined"}},[e._v("Null and Undefined")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#never"}},[e._v("Never")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#object"}},[e._v("Object")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#type-assertions"}},[e._v("Type Assertions")])])])]),e._v(" "),t("li",[t("p",[t("a",{attrs:{href:"#advanced-types"}},[e._v("advanced-types")])]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#intersection-types"}},[e._v("Intersection Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#union-types"}},[e._v("Union Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#type-guards-and-differentiating-types"}},[e._v("Type Guards and Differentiating Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#type-aliases"}},[e._v("Type Aliases")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#string-literal-types"}},[e._v("String Literal Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#numeric-literal-types"}},[e._v("Numeric Literal Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#enum-member-types"}},[e._v("Enum Member Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#discriminated-unions"}},[e._v("Discriminated Unions")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#polymorphic-this-types"}},[e._v("Polymorphic this types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#index-types"}},[e._v("Index types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#mapped-types"}},[e._v("Mapped types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#key-remapping-via-as"}},[e._v("Key Remapping via as")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#conditional-types"}},[e._v("Conditional Types")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#predefined-conditional-types"}},[e._v("Predefined conditional types")])])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/4.9eb8282d.js b/assets/js/4.9eb8282d.js new file mode 100644 index 00000000..7e6e4f57 --- /dev/null +++ b/assets/js/4.9eb8282d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{277:function(t,e,n){},291:function(t,e,n){"use strict";n(277)},313:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:(t,{props:e,slots:n})=>t("span",{class:["badge",e.type],style:{verticalAlign:e.vertical}},e.text||n().default)},p=(n(291),n(14)),l=Object(p.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/40.43f0acc3.js b/assets/js/40.43f0acc3.js new file mode 100644 index 00000000..7b4c3982 --- /dev/null +++ b/assets/js/40.43f0acc3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{328:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-typescript-advanced-knowledge"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-typescript-advanced-knowledge"}},[t._v("#")]),t._v(" ⚪️ TypeScript Advanced Knowledge")]),t._v(" "),s("h2",{attrs:{id:"type-aliases"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-aliases"}},[t._v("#")]),t._v(" Type Aliases")]),t._v(" "),s("p",[t._v("Type aliases are used to give a new name to a type, often used with union types.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//Type Alias Name: This creates a type alias NameResolver for a function that takes no parameters and returns a string. It represents a function that resolves a name.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NameResolver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//Type Alias NameOrResolver: NameOrResolver is a union type alias that can be either a Name (string) or a NameResolver (function returning string). This allows flexibility in accepting different types for the getName function.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NameOrResolver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" NameResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//Function getName: The getName function takes a parameter x of type NameOrResolver. If x is a string, it's returned directly. If it's a function, the function is invoked to get the name. This function illustrates the flexibility provided by type aliases.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" NameOrResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"string"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("x")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h4",{attrs:{id:"advantages"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#advantages"}},[t._v("#")]),t._v(" Advantages:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("Readability:")]),t._v(" "),s("ul",[s("li",[t._v("Type aliases allow you to give meaningful names to types, improving code readability.\nIn this example, Name, NameResolver, and NameOrResolver make the code more self-explanatory.")])])]),t._v(" "),s("li",[s("p",[t._v("Reusability:")]),t._v(" "),s("ul",[s("li",[t._v("Type aliases promote the reuse of types throughout your codebase.\nIf you need to represent a name or a function that resolves a name in multiple places, using type aliases avoids redundancy.")])])]),t._v(" "),s("li",[s("p",[t._v("Flexibility:")]),t._v(" "),s("ul",[s("li",[t._v("By combining different types into a union (NameOrResolver), you gain flexibility in function parameters.\nThis flexibility allows the getName function to accept either a name or a name resolver function.")])])])]),t._v(" "),s("h2",{attrs:{id:"string-literal-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#string-literal-types"}},[t._v("#")]),t._v(" String Literal Types")]),t._v(" "),s("p",[t._v("Restrict values to a specific set of string literals.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EventNames")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"click"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"scroll"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mousemove"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleEvent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("el"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" event"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" EventNames"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do something")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleEvent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"scroll"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleEvent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"jump"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// error")]),t._v("\n")])])]),s("h2",{attrs:{id:"tuples"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tuples"}},[t._v("#")]),t._v(" Tuples")]),t._v(" "),s("blockquote",[s("p",[t._v("Arrays store elements of the same type, while tuples store elements of different types.")])]),t._v(" "),s("ol",[s("li",[t._v("Tuple types allow you to express an array with a fixed number of elements whose types are known, but need not be the same.")]),t._v(" "),s("li",[t._v("When accessing or modifying elements with a known index, the correct type is returned.")]),t._v(" "),s("li",[t._v('During initialization, all internal elements must be included unless the element is marked as "optional."')])]),t._v(" "),s("h3",{attrs:{id:"accessing-tuple-elements"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-tuple-elements"}},[t._v("#")]),t._v(" Accessing Tuple Elements")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" john"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" kevin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.")]),t._v("\njohn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"johnny dept"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\njohn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"100"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// error")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.")]),t._v("\nkevin "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Kevin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initializing with missing elements will result in an error unless the element is optional.")]),t._v("\n")])])]),s("h3",{attrs:{id:"tuple-overflow"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tuple-overflow"}},[t._v("#")]),t._v(" Tuple Overflow")]),t._v(" "),s("p",[t._v("When adding elements beyond the original tuple limit, the type is restricted to the union type of each type in the tuple.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tom"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"male"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type 'boolean' is not assignable to type 'string | number'. ts(2345)")]),t._v("\n")])])]),s("h2",{attrs:{id:"enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#enum"}},[t._v("#")]),t._v(" Enum")]),t._v(" "),s("p",[t._v("Enums are used to define a set of named constants, making it easier to document or identify code.\nSure, here are the explanations in English:")]),t._v(" "),s("h3",{attrs:{id:"incremental-enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#incremental-enum"}},[t._v("#")]),t._v(" Incremental Enum:")]),t._v(" "),s("p",[t._v("In TypeScript, an incremental enum refers to a numeric enum where each member's value automatically increases. Here's an example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Numeric Enum (increases by default)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Weekday "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Monday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 0")]),t._v("\n Tuesday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n Wednesday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2")]),t._v("\n Thursday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n Friday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4")]),t._v("\n Saturday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 5")]),t._v("\n Sunday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 6")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Usage")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" today "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Weekday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Wednesday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("today"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Outputs: 2")]),t._v("\n")])])]),s("p",[t._v("In this example, "),s("code",[t._v("Weekday")]),t._v(" is a numeric enum, and its members automatically increase starting from 0. If no value is specified for a member, TypeScript increments it based on the value of the preceding member.")]),t._v(" "),s("p",[t._v("If you manually set a value for a member and want subsequent members to increment automatically, you can do it like this:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Weekday "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Monday "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n Tuesday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2")]),t._v("\n Wednesday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n Thursday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4")]),t._v("\n Friday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 5")]),t._v("\n Saturday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 6")]),t._v("\n Sunday"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 7")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here, "),s("code",[t._v("Monday")]),t._v(" is manually set to 1, and the following members will increment accordingly. This kind of enum can enhance code clarity and readability in certain situations.")]),t._v(" "),s("h3",{attrs:{id:"string-enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#string-enum"}},[t._v("#")]),t._v(" String Enum:")]),t._v(" "),s("p",[t._v("String enums in TypeScript are enums where each member has an associated string value. They are beneficial for serialization and debugging because the runtime values are meaningful and readable. Here's an example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// String Enum")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Direction "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Up "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"UP"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Down "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"DOWN"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LEFT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RIGHT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Usage")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" myDirection "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Direction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("myDirection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Outputs: "LEFT"')]),t._v("\n")])])]),s("h3",{attrs:{id:"heterogeneous-enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#heterogeneous-enum"}},[t._v("#")]),t._v(" heterogeneous enum")]),t._v(" "),s("p",[t._v("In this example, "),s("code",[t._v("Direction")]),t._v(" is a string enum where each member has an associated string value. This allows for more meaningful representations during runtime, especially when debugging or serializing enum values.\nHeterogeneous Enums refer to enums where the member values have different data types. This situation typically occurs in enums that mix numeric and string members. Here's an example of a heterogeneous enum:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Status "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Success "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n NotFound "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Not Found"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Error "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Internal Server Error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Usage")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" successStatus"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Status "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Success"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" notFoundStatus"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Status "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("NotFound"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" errorStatus"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Status "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("successStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Outputs: 200")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("notFoundStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Outputs: "Not Found"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("errorStatus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Outputs: "Internal Server Error"')]),t._v("\n")])])]),s("p",[t._v("In this example, the "),s("code",[t._v("Status")]),t._v(" enum has three members, each with a different data type for its value. One member has a numeric value ("),s("code",[t._v("Success")]),t._v("), and the other two have string values ("),s("code",[t._v("NotFound")]),t._v(" and "),s("code",[t._v("Error")]),t._v("). This allows the enum to represent status codes or messages with different data types, and you can choose the appropriate member based on the context. The usage of heterogeneous enums is relatively less common and is typically employed when handling data of different types simultaneously.")]),t._v(" "),s("h3",{attrs:{id:"interface-enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#interface-enum"}},[t._v("#")]),t._v(" interface enum")]),t._v(" "),s("p",[t._v("In TypeScript, "),s("code",[t._v("enum")]),t._v(" is commonly used to define a set of named numeric constants, while "),s("code",[t._v("interface")]),t._v(" is used to define the structure of objects. These two concepts are typically used for different purposes, where one represents a group of related constants, and the other represents the shape of objects.")]),t._v(" "),s("p",[t._v("Here is an example using both "),s("code",[t._v("enum")]),t._v(" and "),s("code",[t._v("interface")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Define a set of direction constants using enum")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Direction "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Up "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"UP"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Down "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"DOWN"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LEFT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RIGHT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Define the structure of an object with coordinates and direction using interface")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")])]),t._v(" Point "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n direction"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Direction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Using constants from the enum")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create an object adhering to the Point interface using the defined enum")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" point"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Point "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n direction"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Direction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("point"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"const-enum"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#const-enum"}},[t._v("#")]),t._v(" const enum")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://www.konosumi.net/entry/2021/05/09/130648",alt:"TypeScriptにおけるenumとconst enumの違いを、tscのコンパイル結果から確認してみる"}})]),t._v(" "),s("p",[s("img",{attrs:{src:"https://qiita.com/kat0/items/d8e6f9f5eda1e17caa50",alt:"enumとconstsの使い分け"}})]),t._v(" "),s("h3",{attrs:{id:"reverse-mapping"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#reverse-mapping"}},[t._v("#")]),t._v(" Reverse mapping")]),t._v(" "),s("p",[t._v("Reverse mapping refers to the capability in an enum type where, in addition to the normal mapping from names to values, there is also a mapping from enum values back to their names. This feature provides more flexibility in certain programming scenarios.")]),t._v(" "),s("p",[t._v("In TypeScript, when you assign initial values to enum members, TypeScript automatically generates both forward mapping (from enum names to values) and reverse mapping (from enum values to names). Here's an example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("enum")]),t._v(" Direction "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Up "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"UP"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Down "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"DOWN"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LEFT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RIGHT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Forward mapping")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Direction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output: UP")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Reverse mapping")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Direction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"UP"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output: Up")]),t._v("\n")])])]),s("p",[t._v("In this example, the value of the enum member "),s("code",[t._v("Direction.Up")]),t._v(" is the string "),s("code",[t._v('"UP"')]),t._v(". Through "),s("code",[t._v('Direction["UP"]')]),t._v(", you can retrieve the name of this member, which is "),s("code",[t._v('"Up"')]),t._v(". This illustrates the concept of reverse mapping, where you find the corresponding name based on the enum value.")]),t._v(" "),s("p",[t._v("Reverse mapping can be useful in various scenarios, such as generating labels on the user interface based on enum values or determining enum values based on user-inputted strings.")]),t._v(" "),s("p",[t._v("In this example, "),s("code",[t._v("enum Direction")]),t._v(" defines four constants representing different directions, and then "),s("code",[t._v("interface Point")]),t._v(" defines the structure of an object with "),s("code",[t._v("x")]),t._v(", "),s("code",[t._v("y")]),t._v(", and "),s("code",[t._v("direction")]),t._v(" properties, where "),s("code",[t._v("direction")]),t._v(" uses constants from the "),s("code",[t._v("Direction")]),t._v(" enum. Finally, an object "),s("code",[t._v("point")]),t._v(" is created that conforms to the structure defined by the "),s("code",[t._v("Point")]),t._v(" interface.")]),t._v(" "),s("h2",{attrs:{id:"classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#classes"}},[t._v("#")]),t._v(" Classes")]),t._v(" "),s("blockquote",[s("p",[t._v("While JavaScript has the concept of classes, many JavaScript programmers may not be very familiar with classes. Here's a brief introduction to class-related concepts:")])]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("Class")]),t._v(": Defines the abstract characteristics of a thing, including its properties and methods.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Object")]),t._v(": An instance of a class, created through the "),s("code",[t._v("new")]),t._v(" keyword.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Object-Oriented Programming (OOP) Three Pillars")]),t._v(": Encapsulation, Inheritance, and Polymorphism.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Encapsulation")]),t._v(": Hides the details of data operations, exposing only the necessary interfaces. It ensures that external callers can interact with the object through provided interfaces without knowing the internal details.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Inheritance")]),t._v(": A mechanism where a subclass inherits properties and behaviors from a superclass. The subclass retains the characteristics of the superclass and may have additional features.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Polymorphism")]),t._v(": Different classes related through inheritance can respond to the same method in different ways. For example, a "),s("code",[t._v("Cat")]),t._v(" and a "),s("code",[t._v("Dog")]),t._v(" both inheriting from an "),s("code",[t._v("Animal")]),t._v(" class may have different implementations of the "),s("code",[t._v("eat")]),t._v(" method.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Accessors (Getter & Setter)")]),t._v(": Methods to change the reading and assigning behavior of properties.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Modifiers (Access Modifiers)")]),t._v(": Keywords that limit the nature of members or types, such as "),s("code",[t._v("public")]),t._v(" indicating a public property or method.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Abstract Class")]),t._v(": A base class meant for other classes to inherit from. Instances of an abstract class cannot be created, and abstract methods within it must be implemented by its subclasses.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Interfaces")]),t._v(": Common properties or methods shared among different classes, abstracted into an interface. Classes can implement (or adhere to) multiple interfaces.")])])]),t._v(" "),s("h3",{attrs:{id:"readonly"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#readonly"}},[t._v("#")]),t._v(" "),s("code",[t._v("readonly")])]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("readonly")]),t._v(" keyword is used to declare read-only properties and can only appear in property declarations or index signatures.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n readonly name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Jack'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Jack")]),t._v("\na"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Tom'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property.")]),t._v("\n")])])]),s("p",[t._v("Note that if "),s("code",[t._v("readonly")]),t._v(" is used along with other access modifiers, it should come after them.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// public readonly name;")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" readonly name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"instance-properties"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#instance-properties"}},[t._v("#")]),t._v(" Instance Properties")]),t._v(" "),s("p",[t._v("In ES7 proposals, instance properties can be defined directly inside the class.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Jack"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"static-properties"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#static-properties"}},[t._v("#")]),t._v(" Static Properties")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" num "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"access-modifiers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#access-modifiers"}},[t._v("#")]),t._v(" Access Modifiers")]),t._v(" "),s("p",[t._v("In TypeScript, access modifiers include "),s("code",[t._v("public")]),t._v(", "),s("code",[t._v("private")]),t._v(", and "),s("code",[t._v("protected")]),t._v(".")]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[s("code",[t._v("public")])]),t._v(": Accessible anywhere (default). The modified property or method is public, meaning it can be accessed from any part of the code. All properties and methods are public by default.")])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("private")])]),t._v(": Cannot be accessed outside the declaring class. The modified property or method is private, and it cannot be accessed from outside the class where it is declared.")])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("protected")])]),t._v(": Accessible within the declaring class and its subclasses. The modified property or method is protected, similar to private. However, it can be accessed within the declaring class and its subclasses.")])])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" dog "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cute"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'name' is a private property and can only be accessed within class 'Animal'.")]),t._v("\ndog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'name' is a private property and can only be accessed within class 'Animal'.")]),t._v("\n")])])]),s("p",[t._v("Note: "),s("code",[t._v("private")]),t._v(" does not restrict access in the compiled code; it provides compile-time checking only.")]),t._v(" "),s("h3",{attrs:{id:"getters-and-setters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getters-and-setters"}},[t._v("#")]),t._v(" Getters and Setters")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Private property to store the password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" _password"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"******"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Getter method to retrieve the password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("get")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("password")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Setter method to update the password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("set")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("password")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newPass"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" newPass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// When printing the password in the setter, use this.password instead of u-password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example usage")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" u "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get the current password")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" currentPassword "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" u"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("currentPassword"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output: ******")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set a new password")]),t._v("\nu"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"newPassword"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"abstract-classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#abstract-classes"}},[t._v("#")]),t._v(" Abstract Classes")]),t._v(" "),s("p",[s("code",[t._v("abstract")]),t._v(" is used to define abstract classes and abstract methods, and instances cannot be created from them.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sayHi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Jack"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// index.ts(9,11): error TS2511: Cannot create an instance of the abstract class 'Animal'.")]),t._v("\n")])])]),s("p",[t._v("In the example above, we define an abstract class "),s("code",[t._v("Animal")]),t._v(" and an abstract method "),s("code",[t._v("sayHi")]),t._v(". Attempting to instantiate an abstract class directly results in an error.")]),t._v(" "),s("h4",{attrs:{id:"implementing-abstract-methods"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#implementing-abstract-methods"}},[t._v("#")]),t._v(" Implementing Abstract Methods")]),t._v(" "),s("p",[t._v("Secondly, abstract methods within an abstract class must be implemented by subclasses:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sayHi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("eat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" is eating.")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// index.ts(9,7): error TS2515: Non-abstract class 'Cat' does not implement inherited abstract member 'sayHi' from class 'Animal'.")]),t._v("\n")])])]),s("p",[t._v("In this example, the "),s("code",[t._v("Cat")]),t._v(" class inherits from "),s("code",[t._v("Animal")]),t._v(" but fails to implement the abstract method "),s("code",[t._v("sayHi")]),t._v(", resulting in a compilation error.")]),t._v(" "),s("p",[t._v("Here's a correct usage example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sayHi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sayHi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Meow, My name is ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In this corrected example, we implement the "),s("code",[t._v("sayHi")]),t._v(" method in the "),s("code",[t._v("Cat")]),t._v(" class, making it a valid subclass of the abstract "),s("code",[t._v("Animal")]),t._v(" class.")]),t._v(" "),s("p",[t._v("It's important to note that even though it's an abstract method, TypeScript still generates the corresponding class in the compiled result, as seen in the generated JavaScript code.")]),t._v(" "),s("p",[t._v("Note: Abstract classes are present in the compiled code.")]),t._v(" "),s("h3",{attrs:{id:"here-are-a-few-common-scenarios-where-abstract-classes-are-beneficial-in-typescript"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#here-are-a-few-common-scenarios-where-abstract-classes-are-beneficial-in-typescript"}},[t._v("#")]),t._v(" Here are a few common scenarios where abstract classes are beneficial in TypeScript:")]),t._v(" "),s("p",[t._v("Abstract classes in TypeScript serve the primary purpose of providing a base class for deriving other classes. They can include both concrete implementations and abstract members, which must be implemented in derived classes. Abstract classes cannot be instantiated on their own; they are meant to be used as base classes for other classes.")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Sharing Implementation Logic:")]),t._v("\nAbstract classes can contain shared implementation logic that may be common across derived classes. By placing this logic in the abstract class, redundancy in code can be avoided.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Shape")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculateArea")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("displayArea")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Area: ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculateArea")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Circle")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Shape")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" radius"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculateArea")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("PI")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("radius "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" circle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Circle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncircle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("displayArea")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Outputs: Area: 78.54")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Enforcing Specific Interface Implementation:")]),t._v("\nAbstract members in an abstract class must be implemented in derived classes. This helps ensure that derived classes have specific behavior or properties.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Printer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printDocument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LaserPrinter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Printer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printDocument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Printing document (laser): ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InkjetPrinter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Printer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printDocument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Printing document (inkjet): ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Providing a Common Interface:")]),t._v("\nAbstract classes can define a set of common methods or properties to ensure a consistent interface across derived classes.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeSound")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("move")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Moving..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Dog")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeSound")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Woof! Woof!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bird")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Animal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeSound")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Chirp! Chirp!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])]),t._v(" "),s("p",[t._v("In summary, abstract classes in TypeScript are a tool for building class hierarchies and providing a consistent interface. They help establish stricter relationships between classes and ensure certain behaviors remain consistent throughout the class hierarchy.")]),t._v(" "),s("h2",{attrs:{id:"class-and-interface-interactions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#class-and-interface-interactions"}},[t._v("#")]),t._v(" Class and Interface Interactions")]),t._v(" "),s("h3",{attrs:{id:"class-implements-interface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#class-implements-interface"}},[t._v("#")]),t._v(" Class Implements Interface")]),t._v(" "),s("p",[t._v("When different classes share common features, interfaces can be used, and classes implement them.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Chatroom")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Customer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomA")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Customer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implements")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Chatroom")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"welcome to A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CustomB")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Customer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implements")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Chatroom")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"welcome to B"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("A class can implement multiple interfaces:")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Chatroom")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Shop")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Customer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Customer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implements")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Chatroom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Shop "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"welcome~"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"buy successful"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("For more interface and class interaction patterns, "),s("a",{attrs:{href:"https://willh.gitbook.io/typescript-tutorial/advanced/class-and-interfaces#jie-mian-ji-cheng-jie-mian",target:"_blank",rel:"noopener noreferrer"}},[t._v("check here"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"generators-and-iterators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generators-and-iterators"}},[t._v("#")]),t._v(" generators and iterators")]),t._v(" "),s("blockquote",[s("p",[t._v("In TypeScript, generators and iterators are often used together to provide a convenient way to implement iterable objects. Let's discuss generators, iterators, and how to use them in TypeScript.")])]),t._v(" "),s("h3",{attrs:{id:"iterators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iterators"}},[t._v("#")]),t._v(" Iterators")]),t._v(" "),s("p",[t._v("In TypeScript, an iterator is an object with a "),s("code",[t._v("next")]),t._v(" method. The "),s("code",[t._v("next")]),t._v(" method returns an object with "),s("code",[t._v("value")]),t._v(" and "),s("code",[t._v("done")]),t._v(" properties, indicating the current value of the iteration and whether it is done.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Iterator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" done"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example: Iterator for a range of numbers")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeIterator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n start"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n end"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Iterator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" done"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" done"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" end "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" numberIterator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeIterator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberIterator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 1, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberIterator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 2, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberIterator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 3, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberIterator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: undefined, done: true }")]),t._v("\n")])])]),s("h3",{attrs:{id:"generators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generators"}},[t._v("#")]),t._v(" Generators")]),t._v(" "),s("p",[t._v("Generators are a special type of function declared using "),s("code",[t._v("function*")]),t._v(". They can pause execution using "),s("code",[t._v("yield")]),t._v(" to return a value and can later resume execution. Generator functions return an iterator.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example: Generator for a range of numbers")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeGenerator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n start"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n end"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Generator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" numberGenerator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeGenerator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 1, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 2, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: 3, done: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { value: undefined, done: true }")]),t._v("\n")])])]),s("h3",{attrs:{id:"using-generators-and-iterators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#using-generators-and-iterators"}},[t._v("#")]),t._v(" Using Generators and Iterators")]),t._v(" "),s("p",[t._v("Generators offer a more concise and readable syntax. You can use the "),s("code",[t._v("for...of")]),t._v(" loop to iterate over the values generated by the generator.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Using a generator to create a number range")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeGenerator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n start"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n end"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Generator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Iterating over the generator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" num "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNumberRangeGenerator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("num"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n")])])]),s("p",[t._v("Generators and iterators provide a flexible and clear way to handle a sequence of values, especially when dealing with large datasets or asynchronous operations.")]),t._v(" "),s("h2",{attrs:{id:"generics"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generics"}},[t._v("#")]),t._v(" Generics")]),t._v(" "),s("blockquote",[s("p",[t._v("Generics allow you to define functions, interfaces, or classes without specifying the exact type, and instead, determine the type during usage.")])]),t._v(" "),s("h3",{attrs:{id:"basic-usage"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#basic-usage"}},[t._v("#")]),t._v(" Basic Usage")]),t._v(" "),s("p",[t._v("Let's start with a function, "),s("code",[t._v("createArray")]),t._v(", that creates an array of a specified length and fills each element with a default value:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Result: ['x', 'x', 'x']")]),t._v("\n")])])]),s("p",[t._v("The issue here is that the return type ("),s("code",[t._v("Array")]),t._v(") allows any type in the array. To address this, we introduce generics:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Result: ['x', 'x', 'x']")]),t._v("\n")])])]),s("p",[t._v("Now, the function is generic, and you can specify the type (e.g., "),s("code",[t._v("string")]),t._v(") when calling it.")]),t._v(" "),s("h3",{attrs:{id:"multiple-type-parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#multiple-type-parameters"}},[t._v("#")]),t._v(" Multiple Type Parameters")]),t._v(" "),s("p",[t._v("Define multiple type parameters in a generic function, like in the "),s("code",[t._v("swap")]),t._v(" function:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swap")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tuple"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("tuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"seven"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Result: ['seven', 7]")]),t._v("\n")])])]),s("p",[t._v("Here, "),s("code",[t._v("swap")]),t._v(" takes a tuple and swaps its elements.")]),t._v(" "),s("h3",{attrs:{id:"generic-constraints"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generic-constraints"}},[t._v("#")]),t._v(" Generic Constraints")]),t._v(" "),s("p",[t._v("When using generic variables inside a function, you might need to constrain them. For example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Lengthwise")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("loggingIdentity")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Lengthwise"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("loggingIdentity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Prints the length of the object")]),t._v("\n")])])]),s("p",[t._v("Here, "),s("code",[t._v("loggingIdentity")]),t._v(" has a generic constraint to ensure that the type "),s("code",[t._v("T")]),t._v(" extends the "),s("code",[t._v("Lengthwise")]),t._v(" interface, which has a "),s("code",[t._v("length")]),t._v(" property.")]),t._v(" "),s("h3",{attrs:{id:"generic-interface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generic-interface"}},[t._v("#")]),t._v(" Generic Interface")]),t._v(" "),s("p",[t._v("Interfaces can also be generic. Here's an example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CreateArrayFunc")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" createArray"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CreateArrayFunc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createArray")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Result: ['x', 'x', 'x']")]),t._v("\n")])])]),s("p",[t._v("You can also move the generic type parameter to the interface level.")]),t._v(" "),s("h3",{attrs:{id:"generic-class"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generic-class"}},[t._v("#")]),t._v(" Generic Class")]),t._v(" "),s("p",[t._v("Like interfaces, classes can also use generics:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GenericNumber"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n zeroValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" myGenericNumber "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GenericNumber"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmyGenericNumber"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zeroValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmyGenericNumber"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("add")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This "),s("code",[t._v("GenericNumber")]),t._v(" class can work with various numeric types.")]),t._v(" "),s("h3",{attrs:{id:"default-generic-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#default-generic-types"}},[t._v("#")]),t._v(" Default Generic Types")]),t._v(" "),s("p",[t._v("Starting TypeScript 2.3, you can specify default types for generic parameters:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createArray")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("This allows you to provide a default type ("),s("code",[t._v("string")]),t._v(" in this case) when a specific type is not explicitly provided.")]),t._v(" "),s("p",[t._v("Generics enhance the flexibility and type safety of your code, allowing you to create reusable and type-agnostic components. They are particularly useful when you want to create functions or classes that can work with a variety of data types.")]),t._v(" "),s("h3",{attrs:{id:"more-generics"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#more-generics"}},[t._v("#")]),t._v(" More Generics")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" echo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" isObj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" arg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"object"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" arg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// false")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("////////////////////////////////////")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" isTrue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("arg "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("arg "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//{ arg: false, is: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//{ arg: 0, is: false }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//{ arg: true, is: true }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//{ arg: 1, is: true }")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Dave"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modified")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Dave"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modified")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("NaN")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isTrue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("////////////////////////////////////")]),t._v("\n")])])]),s("h2",{attrs:{id:"common-techniques"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#common-techniques"}},[t._v("#")]),t._v(" Common Techniques")]),t._v(" "),s("h3",{attrs:{id:"extracting-variable-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extracting-variable-types"}},[t._v("#")]),t._v(" Extracting Variable Types")]),t._v(" "),s("p",[t._v("Use "),s("code",[t._v("typeof")]),t._v(" to extract variable types:")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("123")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("A")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("B")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { x: number, y: number }")]),t._v("\n")])])]),s("h3",{attrs:{id:"binding-function-this"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#binding-function-this"}},[t._v("#")]),t._v(" Binding Function "),s("code",[t._v("this")])]),t._v(" "),s("p",[t._v("Bind "),s("code",[t._v("this")]),t._v(" on the first parameter. "),s("a",{attrs:{href:"https://www.typescriptlang.org/docs/handbook/functions.html#this",target:"_blank",rel:"noopener noreferrer"}},[t._v("See reference"),s("OutboundLink")],1)]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" obj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello: "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" obj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"index-variables"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#index-variables"}},[t._v("#")]),t._v(" Index Variables")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("A")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'in' iterates over sub-properties, resulting in the type: string")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("B")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"built-in-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#built-in-types"}},[t._v("#")]),t._v(" Built-in Types")]),t._v(" "),s("p",[t._v("TypeScript provides built-in utility types:")]),t._v(" "),s("h4",{attrs:{id:"record"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#record"}},[t._v("#")]),t._v(" Record")]),t._v(" "),s("p",[t._v("Generates an object type with keys of type K and values of type T.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("K")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bar"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"y"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"partial"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#partial"}},[t._v("#")]),t._v(" Partial")]),t._v(" "),s("p",[t._v("Makes all properties of T optional.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Partial"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Partial"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'a' is optional")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"required"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#required"}},[t._v("#")]),t._v(" Required")]),t._v(" "),s("p",[t._v("Opposite of "),s("code",[t._v("Partial")]),t._v(", makes all properties of T required.")]),t._v(" "),s("h4",{attrs:{id:"readonly-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#readonly-2"}},[t._v("#")]),t._v(" Readonly")]),t._v(" "),s("p",[t._v("Makes all properties of T readonly.")]),t._v(" "),s("h4",{attrs:{id:"pick"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#pick"}},[t._v("#")]),t._v(" Pick")]),t._v(" "),s("p",[t._v("Selects properties from T specified by K.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Pick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("K")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Pick"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Foo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"exclude"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exclude"}},[t._v("#")]),t._v(" Exclude")]),t._v(" "),s("p",[t._v("Exclude from T those types that are assignable to U.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exclude"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("never")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Exclude"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nfoo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"extract"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extract"}},[t._v("#")]),t._v(" Extract")]),t._v(" "),s("p",[t._v("Extract from T those types that are assignable to U.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Extract"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("U")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("never")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Extract"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("p",[t._v("Returns a tuple type based on the parameters of a function.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Parameters"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("infer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("P")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("never")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Parameters"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [string, number]")]),t._v("\n")])])]),s("h4",{attrs:{id:"returntype"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#returntype"}},[t._v("#")]),t._v(" ReturnType")]),t._v(" "),s("p",[t._v("Returns the return type of a function.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ReturnType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("T")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("infer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("R")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("R")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Foo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReturnType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Foo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Returns boolean type")]),t._v("\n")])])]),s("h3",{attrs:{id:"🔹-index-signature"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔹-index-signature"}},[t._v("#")]),t._v(" 🔹 index signature")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Index Signatures")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interface TransactionObj {")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// readonly [index: string]: number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TransactionObj")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n Pizza"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n Books"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n Job"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" todaysTransactions"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" TransactionObj "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Pizza"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Books"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Job"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todaysTransactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Pizza"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todaysTransactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pizza"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" prop"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pizza"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todaysTransactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("prop"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" todaysNet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("transactions"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" TransactionObj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" total "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" transaction "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" transactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n total "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" transactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("transaction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" total"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("todaysNet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todaysTransactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//todaysTransactions.Pizza = 40")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todaysTransactions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Dave"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// undefined")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("///////////////////////////////////")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Student")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("GPA")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n classes"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Student "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Doug"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("GPA")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n classes"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//because of the index signature, this is allowed")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(": ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" Student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//'name: Doug' ,'GPA: 3.5' ​​​​​, 'classes: 100,200' ​​​​​, 'test: undefined'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'Doug' , 3.5 , [ 100, 200 ]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" logStudentKey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" Student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Student ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(": ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//'Student name: Doug'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("logStudentKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/////////////////////////////////")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interface Incomes {")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [key: string]: number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Streams")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"salary"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bonus"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sidehustle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Incomes")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Streams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" monthlyIncomes"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Incomes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n salary"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n bonus"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n sidehustle"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("250")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" revenue "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" monthlyIncomes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("monthlyIncomes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("revenue "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" Incomes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 500 , 100 , 250")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("🔺 "),s("strong",[s("code",[t._v("student[key as keyof typeof student]")])]),t._v(":")]),t._v(" "),s("p",[t._v("Inside the function passed to "),s("code",[t._v("map")]),t._v(", each key is used to access the corresponding value in the "),s("code",[t._v("student")]),t._v(" object. - "),s("code",[t._v("key")]),t._v(" is a variable holding the current property name being iterated over. - "),s("code",[t._v("key as keyof typeof student")]),t._v(" is a TypeScript type assertion. It tells TypeScript to treat "),s("code",[t._v("key")]),t._v(" as one of the keys of the type of "),s("code",[t._v("student")]),t._v(". This is necessary because, by default, the type of "),s("code",[t._v("key")]),t._v(" would be just "),s("code",[t._v("string")]),t._v(", which is too general. The "),s("code",[t._v("keyof typeof student")]),t._v(" type is more specific, representing the union of all literal types of the keys in the "),s("code",[t._v("student")]),t._v(" object.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[t._v("Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" student"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("🔺 補充理解在 JavaScript 和 TypeScript 中,对象属性可以通过两种方式访问")]),t._v(" "),s("blockquote",[s("p",[t._v("点符号("),s("code",[t._v(".")]),t._v(")和方括号符号("),s("code",[t._v("[]")]),t._v(")。在您提供的代码中,"),s("code",[t._v("todaysTransactions")]),t._v(" 是一个对象,其中包含了不同的属性(如 "),s("code",[t._v("Pizza")]),t._v("、"),s("code",[t._v("Books")]),t._v(" 和 "),s("code",[t._v("Job")]),t._v("),每个属性都有对应的值。")])]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("点符号")]),t._v(": "),s("code",[t._v("todaysTransactions.Pizza")]),t._v("。这种方式是直接访问对象的属性,其中 "),s("code",[t._v("Pizza")]),t._v(" 是属性的字面量名称。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("方括号符号")]),t._v(": "),s("code",[t._v("todaysTransactions['Pizza']")]),t._v(" 和 "),s("code",[t._v("todaysTransactions[prop]")]),t._v("。这种方式用于当属性名是动态的或者是一个变量时。在这种情况下,属性名需要作为字符串传递。")])])]),t._v(" "),s("p",[t._v("在代码中,"),s("code",[t._v("prop")]),t._v(" 是一个字符串类型的变量,其值为 "),s("code",[t._v("'Pizza'")]),t._v("。因此,当你使用 "),s("code",[t._v("todaysTransactions[prop]")]),t._v(" 时,它实际上是 "),s("code",[t._v("todaysTransactions['Pizza']")]),t._v(" 的简写。由于 "),s("code",[t._v("prop")]),t._v(" 变量的值是 "),s("code",[t._v("'Pizza'")]),t._v(",所以这个表达式最终访问的是 "),s("code",[t._v("todaysTransactions")]),t._v(" 对象中 "),s("code",[t._v("Pizza")]),t._v(" 这个属性的值。")]),t._v(" "),s("h3",{attrs:{id:"accessing-object-properties-dynamically-in-typescript"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-object-properties-dynamically-in-typescript"}},[t._v("#")]),t._v(" Accessing object properties dynamically in TypeScript")]),t._v(" "),s("p",[t._v("Accessing object properties dynamically in TypeScript can be achieved through various methods, including dot notation, square brackets, and the "),s("code",[t._v("keyof")]),t._v(" operator. Each method has its specific use cases and benefits depending on the requirements of your application.")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("Using Square Brackets")]),t._v(": This method is particularly useful when the property name is dynamic, such as in the case of user input or other runtime conditions. For example, you might have a TypeScript React component where you need to access properties of an object based on user interactions or input. Here's a simple example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n email"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n email"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"alice@example.com"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" propertyName "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" propertyValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("propertyName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("propertyValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Outputs: alice@example.com")]),t._v("\n")])])]),s("p",[t._v("In this example, "),s("code",[t._v("propertyName")]),t._v(" is a variable that holds the name of the property you want to access. This approach is useful in scenarios like handling form inputs dynamically.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Using "),s("code",[t._v("keyof")]),t._v(" with TypeScript")]),t._v(": The "),s("code",[t._v("keyof")]),t._v(" operator is another powerful feature in TypeScript, which you can use to create a union type of all the keys in an object. This is particularly useful for ensuring type safety when accessing properties dynamically. Here's an example:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n email"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserKeys")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" User"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" User "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bob"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n email"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bob@example.com"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" propertyName"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UserKeys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" propertyValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("propertyName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("propertyValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Outputs: Bob")]),t._v("\n")])])]),s("p",[t._v("In this example, "),s("code",[t._v("propertyName")]),t._v(" is a variable of type "),s("code",[t._v("UserKeys")]),t._v(", which is a union of all keys in the "),s("code",[t._v("User")]),t._v(" interface. This ensures that only valid property names can be assigned to "),s("code",[t._v("propertyName")]),t._v(".")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Dynamic Property Access in React Components")]),t._v(": In React components, you might encounter scenarios where you need to dynamically access or update the state based on user input or interaction. For example, if you are building a form with multiple fields, you can use the square bracket notation to update the state for each field dynamically:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" FormComponent"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("formState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setFormState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("handleChange")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ChangeEvent"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("HTMLInputElement"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setFormState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("formState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("form"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("input name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),t._v(" onChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("input name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),t._v(" onChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* ... other form fields ... */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("form"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In this React component, "),s("code",[t._v("handleChange")]),t._v(" function updates the "),s("code",[t._v("formState")]),t._v(" dynamically based on the input field's "),s("code",[t._v("name")]),t._v(" attribute.")])])]),t._v(" "),s("p",[t._v("🔺 For more detailed information, you can refer to these resources:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.typescriptsos.com/faqs/how-to-dynamically-access-object-property-in-typescript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Typescript SOS - How to dynamically access object property in typescript"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://www.squash.io/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Squash.io - How to Get an Object Value by Dynamic Keys in TypeScript"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://www.bennadel.com/go/3126",target:"_blank",rel:"noopener noreferrer"}},[t._v("Ben Nadel - Object Access: Bracket-Notation vs. Dot-Notation With TypeScript In Angular 2 RC 4"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"reference-articles"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#reference-articles"}},[t._v("#")]),t._v(" Reference Articles")]),t._v(" "),s("ol",[s("li",[s("a",{attrs:{href:"https://willh.gitbook.io/typescript-tutorial/",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript for Beginners"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://juejin.cn/post/6873080212675166215#heading-15",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript Practical Tips and Tricks"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/41.7bcb3391.js b/assets/js/41.7bcb3391.js new file mode 100644 index 00000000..fb5a4966 --- /dev/null +++ b/assets/js/41.7bcb3391.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{330:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"🔶-typescript-basic-knowledge"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔶-typescript-basic-knowledge"}},[t._v("#")]),t._v(" 🔶 TypeScript Basic Knowledge")]),t._v(" "),s("h2",{attrs:{id:"🔸-primitive-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-primitive-types"}},[t._v("#")]),t._v(" 🔸 Primitive Types")]),t._v(" "),s("p",[s("code",[t._v("string")]),t._v(", "),s("code",[t._v("number")]),t._v(", "),s("code",[t._v("boolean")]),t._v(", "),s("code",[t._v("null")]),t._v(", "),s("code",[t._v("undefined")]),t._v(", "),s("code",[t._v("Symbol")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Known type")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Unknown with expectation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" num "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("unknown")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Known expectation")]),t._v("\nnum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Function returning a number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Void function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"any-type"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#any-type"}},[t._v("#")]),t._v(" Any Type")]),t._v(" "),s("p",[t._v("A variable of any type cannot change its type during operations.")]),t._v(" "),s("ol",[s("li",[t._v("Any type allows any operation, and the return type is of any.")]),t._v(" "),s("li",[t._v("When a variable is declared without specifying a type and no value is assigned, it defaults to any.")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" someText"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Will cause an error if set to number")]),t._v("\nsomeText "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"someText"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Error")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔸-never"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔸-never"}},[t._v("#")]),t._v(" 🔸 Never")]),t._v(" "),s("p",[t._v("A function that never returns, or a function that always throws an error.")]),t._v(" "),s("ul",[s("li",[t._v("bottom level type")]),t._v(" "),s("li",[t._v("can be assigned to any type")])]),t._v(" "),s("p",[t._v("In TypeScript, the "),s("code",[t._v("never")]),t._v(" type is often used in the context of exhaustiveness checking, particularly in situations like "),s("code",[t._v("switch")]),t._v(" statements. The "),s("code",[t._v("never")]),t._v(" type represents the type of values that never occur. It is used to indicate that a function will not return normally (e.g., it throws an error or has an infinite loop).")]),t._v(" "),s("p",[t._v("Let's discuss how "),s("code",[t._v("never")]),t._v(" is commonly used with "),s("code",[t._v("switch")]),t._v(" statements and the "),s("code",[t._v("default")]),t._v(" case:")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fruit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Apple"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Banana"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Orange"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getFruitColor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Fruit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fruit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Apple"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Red"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Banana"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Yellow"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Orange"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Orange"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The default case is marked as unreachable, and its return type is 'never'.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This is because TypeScript can infer that the switch is exhaustive, covering all possible values of 'Fruit'.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" exhaustiveCheck"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("never")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fruit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" exhaustiveCheck"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This line will never be reached.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Explanation:")]),t._v(" "),s("ol",[s("li",[t._v("The "),s("code",[t._v("Fruit")]),t._v(" type is defined as a union of string literals representing different fruit names.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("getFruitColor")]),t._v(" function takes a "),s("code",[t._v("fruit")]),t._v(" argument of type "),s("code",[t._v("Fruit")]),t._v(" and returns a string representing the color.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("switch")]),t._v(" statement is used to handle different cases based on the value of "),s("code",[t._v("fruit")]),t._v(".")]),t._v(" "),s("li",[t._v("For each known fruit case ("),s("code",[t._v("'Apple'")]),t._v(", "),s("code",[t._v("'Banana'")]),t._v(", "),s("code",[t._v("'Orange'")]),t._v("), the function returns the corresponding color.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("default")]),t._v(" case is marked with "),s("code",[t._v("never")]),t._v(". This indicates to TypeScript that this case should never be reached because we've covered all possible values of "),s("code",[t._v("Fruit")]),t._v(".")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("exhaustiveCheck")]),t._v(" variable is of type "),s("code",[t._v("never")]),t._v(", which means TypeScript understands that it can never have a value, and this line will never be executed.")])]),t._v(" "),s("p",[t._v("This pattern helps TypeScript catch situations where you might forget to handle a specific case in a "),s("code",[t._v("switch")]),t._v(" statement, providing better safety and avoiding unintentional bugs.")]),t._v(" "),s("h2",{attrs:{id:"型アノテーション-type-annotation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#型アノテーション-type-annotation"}},[t._v("#")]),t._v(" 型アノテーション(Type Annotation)")]),t._v(" "),s("p",[t._v("TypeScript では value: Type というフォーマットで宣言時の変数 に型の注釈がつけられる\nアノテー ションによって静的に型付けされた情報はコンパイル時のチェックに用いられ、書かれたコード中 に型の不整合があるとコンパイルエラーになる")]),t._v(" "),s("h2",{attrs:{id:"型推論-type-inference"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#型推論-type-inference"}},[t._v("#")]),t._v(" 型推論(Type Inference)")]),t._v(" "),s("p",[t._v("When the type is not explicitly specified, TypeScript infers the type based on the assigned value.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" typeS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"seven"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntypeS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Inferred as string due to the initial value being a string")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" typeA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntypeA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"six"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntypeA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Inferred as any since no initial value is given")]),t._v("\n")])])]),s("h2",{attrs:{id:"union-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#union-types"}},[t._v("#")]),t._v(" Union Types")]),t._v(" "),s("p",[t._v("Represents a value that can be one of multiple types, using "),s("code",[t._v("|")]),t._v(" to separate types.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" unionC"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Ray"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nunionC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getLength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("something"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" something"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Can only access properties common to both types, error")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"object-types-interface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#object-types-interface"}},[t._v("#")]),t._v(" Object Types - Interface")]),t._v(" "),s("p",[t._v("Commonly used to describe the shape of objects.")]),t._v(" "),s("ol",[s("li",[t._v("Interface names typically start with a capital letter.")]),t._v(" "),s("li",[t._v("Optional properties are denoted with "),s("code",[t._v("?")]),t._v(" to enhance flexibility.")]),t._v(" "),s("li",[t._v("Index signatures allow any property of a certain type.")]),t._v(" "),s("li",[t._v("Use "),s("code",[t._v("readonly")]),t._v(" to mark properties as read-only.")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("readonly")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Optional property")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("prop"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Any property of type any")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// [prop: string]: string; // Uncommenting restricts any property to string type")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tom"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3387")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// age: 30,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Constraints Tom to have the same shape as Person (no more, no less)")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Cannot modify readonly property after initialization, error")]),t._v("\ntom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4069")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Function interfaces or interfaces with function properties are also possible:")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFunction")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyObject")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("jump")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"array-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#array-types"}},[t._v("#")]),t._v(" Array Types")]),t._v(" "),s("p",[t._v("Several ways to define array types:")]),t._v(" "),s("ol",[s("li",[t._v("Type + square brackets")]),t._v(" "),s("li",[t._v("Array generics (Array)")]),t._v(" "),s("li",[t._v("Interface for arrays")]),t._v(" "),s("li",[t._v("Tuple types (IArguments, NodeList, HTMLCollection, Element...)")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myArr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmyArr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"4"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Method calls are type-checked, error")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myArr2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmyArr2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Error")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NumberArray")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myArr3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" NumberArray "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4. Built-in array interfaces")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IArguments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arguments"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("For more built-in objects, refer to "),s("a",{attrs:{href:"https://willh.gitbook.io/typescript-tutorial/basics/built-in-objects",target:"_blank",rel:"noopener noreferrer"}},[t._v("this link"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"function-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#function-types"}},[t._v("#")]),t._v(" Function Types")]),t._v(" "),s("blockquote",[s("p",[t._v("Functions have input and output types, considering both is crucial.")])]),t._v(" "),s("ol",[s("li",[s("p",[t._v("Declaration")])]),t._v(" "),s("li",[s("p",[t._v("Expression")]),t._v(" "),s("ul",[s("li",[t._v("Be cautious when using the => syntax; it might be confusing and is recommended to use the declaration syntax.")])])]),t._v(" "),s("li",[s("p",[t._v("Interface definition")])]),t._v(" "),s("li",[s("p",[t._v("Optional parameters marked with ?, which cannot follow required parameters.")])]),t._v(" "),s("li",[s("p",[t._v("Default parameter values make parameters optional.")])]),t._v(" "),s("li",[s("p",[t._v("Rest parameters can be defined using an array type (any[]).")])]),t._v(" "),s("li",[s("p",[t._v("Overloads allow a function to accept different numbers or types of parameters.")])])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sumFn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sumFn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Error")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sumFn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Error")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sumFnEx")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Isum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mySum"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Isum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4. & 5.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n firstName"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n lastName"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("firstName"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("lastName"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", now age ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("age"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"johnny"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 6.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("items"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 7.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Define precise input and output types for numbers, then implement logic")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"number"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("split")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"string"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("split")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"type-assertion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-assertion"}},[t._v("#")]),t._v(" Type Assertion")]),t._v(" "),s("p",[t._v("Manually specify a value's type, commonly used in React's TSX (TS for JSX) to distinguish between TypeScript and ES6 arrow functions.")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("When dealing with union types, sometimes a specific type's property needs to be accessed.")]),t._v(" "),s("ul",[s("li",[t._v("Caution is needed to avoid runtime errors when accessing properties immediately after assertion.")])])]),t._v(" "),s("li",[s("p",[t._v("Parent class inheritance assertion")])]),t._v(" "),s("li",[s("p",[t._v('"XXX as any" should be a last resort for solving type issues, use sparingly.')])]),t._v(" "),s("li",[s("p",[t._v("Type assertion reinforcement (for old code returning any, explicitly assert its type after calling)")])]),t._v(" "),s("li",[s("p",[t._v("Type assertions are only effective during compilation, having no impact on the compiled code.")])]),t._v(" "),s("li",[s("p",[t._v("Type declarations are stricter; prefer using them whenever possible.")])])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fish")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swim")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("animal"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Cat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" Fish"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Accessing swim directly after assertion may cause runtime errors")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if (typeof animal.swim === 'function') {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("animal "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Fish"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("swim "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"function"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Is a fish"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ApiError")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n code"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HttpError")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n statusCode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isApiError")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" ApiError"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("code "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"number"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Accessing any property is legal, but this is a last resort")]),t._v("\nwindow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Error")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Cat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type assertion")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" tomCat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tom"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Cat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type declaration (more strict)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// const tomCat: Cat = getCache('tom');")]),t._v("\ntomCat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"declaration-files"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#declaration-files"}},[t._v("#")]),t._v(" Declaration Files")]),t._v(" "),s("p",[t._v("When using third-party libraries, include their declaration files to enable type checking.")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://ts.xcatliu.com/basics/declaration-files.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Declaration Syntax Reference"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://microsoft.github.io/TypeSearch/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Declaration File Search"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("Usually, declaration statements are placed in separate files, e.g., jQuery.d.ts.")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("declare var/let/const")])]),t._v(" "),s("li",[s("code",[t._v("declare namespace")]),t._v(" creates a namespace to avoid global pollution; use the namespace when accessing its interfaces.")]),t._v(" "),s("li",[t._v("For library declaration files, it is recommended to use "),s("code",[t._v("@types")]),t._v(" for centralized management. Install with "),s("code",[t._v("npm install @types/library --save-dev")]),t._v(". No further configuration is needed for global declarations.")]),t._v(" "),s("li",[t._v("For NPM declaration files, export and import are required to use types within modules.")])]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1. Using jQuery as an example")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("jQuery")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("selector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2. Example (illustrative purposes only)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("namespace")]),t._v(" Vue "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("component")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mixin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"declaration-merging"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#declaration-merging"}},[t._v("#")]),t._v(" Declaration Merging")]),t._v(" "),s("p",[t._v("Taking jQuery as an example, it is both a function and an object with properties. Multiple declaration statements that do not conflict will be merged.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("jQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("selector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("declare")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("namespace")]),t._v(" jQuery "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ajax")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" settings"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/42.d64e546e.js b/assets/js/42.d64e546e.js new file mode 100644 index 00000000..86c72765 --- /dev/null +++ b/assets/js/42.d64e546e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{329:function(e,t,r){"use strict";r.r(t);var a=r(14),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"🔺-memo-メモ"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔺-memo-メモ"}},[e._v("#")]),e._v(" 🔺 MEMO メモ")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://qiita.com/e99h2121/items/833b34ed6c34020af8f9",target:"_blank",rel:"noopener noreferrer"}},[e._v("「ファインマンテクニック」を使って複雑な概念をよりよく理解する"),t("OutboundLink")],1)]),e._v(" "),t("h3",{attrs:{id:"🔺-react"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔺-react"}},[e._v("#")]),e._v(" 🔺 react")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/7080888443865137188",target:"_blank",rel:"noopener noreferrer"}},[e._v("function component vs class component"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://react.dev/learn/conditional-rendering",target:"_blank",rel:"noopener noreferrer"}},[e._v("conditional rendering"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://react.dev/learn/rendering-lists",target:"_blank",rel:"noopener noreferrer"}},[e._v("list and key"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.freecodecamp.org/news/how-to-build-forms-in-react/#:~:text=Controlled%20Components%20in%20React,immediately%20reflected%20in%20the%20state.",target:"_blank",rel:"noopener noreferrer"}},[e._v("How to Build Forms in React - Controlled Components in React"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://react.dev/reference/react-dom/components/form#noun-labs-1201738-(2)",target:"_blank",rel:"noopener noreferrer"}},[e._v("form"),t("OutboundLink")],1)])]),e._v(" "),t("h3",{attrs:{id:"🔺-reacthooks"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔺-reacthooks"}},[e._v("#")]),e._v(" 🔺 reactHooks")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://react.dev/learn/passing-data-deeply-with-context#before-you-use-context",target:"_blank",rel:"noopener noreferrer"}},[e._v("passing-data-deeply-with-context"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://react.dev/learn/scaling-up-with-reducer-and-context",target:"_blank",rel:"noopener noreferrer"}},[e._v("scaling-up-with-reducer-and-context"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://juejin.cn/post/7118937685653192735?searchId=20231203144532DC30BB5CFA5FD3A1A5A7#heading-16",target:"_blank",rel:"noopener noreferrer"}},[e._v("React hooks を基本からまとめてみた "),t("OutboundLink")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useState 編)")])]),e._v(" "),t("li",[t("a",{attrs:{href:"https://qiita.com/seira/items/e62890f11e91f6b9653f",target:"_blank",rel:"noopener noreferrer"}},[e._v("React hooks を基礎から理解する (useEffect 編)"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useContext 編)")])]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useReducer 編)")])]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useCallback 編)")])]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useMemo 編)")])]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("React hooks を基礎から理解する (useRef 編)")])])])])]),e._v(" "),t("h3",{attrs:{id:"🔺-typescript"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔺-typescript"}},[e._v("#")]),e._v(" 🔺 typescript")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase",target:"_blank",rel:"noopener noreferrer"}},[e._v("React TypeScript Cheatsheet"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.reactandtypescript.dev/examples/functional-components",target:"_blank",rel:"noopener noreferrer"}},[e._v("Use TypeScript with React Components"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.youtube.com/watch?v=9lUN3sqAjQQ",target:"_blank",rel:"noopener noreferrer"}},[e._v("Use TypeScript with React Components Video"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/43.a2cbbfc3.js b/assets/js/43.a2cbbfc3.js new file mode 100644 index 00000000..f17daa2f --- /dev/null +++ b/assets/js/43.a2cbbfc3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{331:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:""}},[s("a",{staticClass:"header-anchor",attrs:{href:"#"}},[t._v("#")])]),t._v(" "),s("h2",{attrs:{id:"backend-for-frontend"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#backend-for-frontend"}},[t._v("#")]),t._v(" Backend for Frontend")]),t._v(" "),s("p",[t._v("学习 BFF(Backend for Frontend)并不要求专门学习 Java 的某个特定部分。BFF 是一种架构模式,可以在多种后端编程语言中实现,包括 Java。要学习 BFF,你需要掌握以下关键概念和技能:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("后端开发基础:你需要了解后端开发的基本原理,包括处理 HTTP 请求和响应、路由、数据存储等。这些原理在不同的后端编程语言中都是通用的。")])]),t._v(" "),s("li",[s("p",[t._v("Java 编程语言:如果你选择在 Java 中实现 BFF,那么你需要掌握 Java 编程语言的基础知识,包括语法、数据结构、面向对象编程等。")])]),t._v(" "),s("li",[s("p",[t._v("Spring Framework:Spring 是一个流行的 Java 开发框架,它提供了一套丰富的工具和库,用于构建后端应用程序。学习 Spring 框架可以帮助你更轻松地实现 BFF。")])]),t._v(" "),s("li",[s("p",[t._v("RESTful API 设计:BFF 通常是为前端应用程序提供 RESTful API 的一部分。你需要了解如何设计和实现 RESTful API,包括资源的表示、HTTP 方法的使用等。")])]),t._v(" "),s("li",[s("p",[t._v("安全性:了解如何保护后端服务和 API 的安全性是非常重要的。学习关于身份验证、授权、数据验证和防止安全漏洞的最佳实践。")])]),t._v(" "),s("li",[s("p",[t._v("前端开发基础:虽然 BFF 是后端的一部分,但它的目标是为前端应用程序提供服务。因此,了解前端开发的基本原理和技能也是有益的,以更好地理解前后端之间的交互。")])])]),t._v(" "),s("p",[t._v("总之,学习 BFF 需要你掌握后端开发的基础知识,以及如果选择 Java 作为实现语言,那么需要学习 Java 编程和 Spring 框架。同时,了解前端开发基础也有助于更好地满足前端应用程序的需求。")]),t._v(" "),s("h2",{attrs:{id:"graphql-来实现-bff-需要掌握哪些技能"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#graphql-来实现-bff-需要掌握哪些技能"}},[t._v("#")]),t._v(" GraphQL 来实现 BFF,需要掌握哪些技能?")]),t._v(" "),s("p",[t._v("如果你打算使用 GraphQL 来实现 BFF,那么你需要学习以下关键概念和技能:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("GraphQL 基础知识:首先,你需要理解 GraphQL 的基本概念,包括如何定义和查询数据模型,以及 GraphQL 查询语言的语法和结构。")])]),t._v(" "),s("li",[s("p",[t._v("后端开发:BFF 通常是作为后端服务的一部分,用于处理前端应用程序的数据需求。你需要具备后端开发的基础知识,包括如何编写 GraphQL 服务、处理查询和变异等。")])]),t._v(" "),s("li",[s("p",[t._v("GraphQL 服务器:选择适合你的编程语言的 GraphQL 服务器。在 Java 中,你可以使用一些库和框架来构建 GraphQL 服务器,如 Apollo Server、GraphQL-Java、Spring GraphQL 等。")])]),t._v(" "),s("li",[s("p",[t._v("数据模型和解析器:定义你的数据模型,并创建相应的解析器来处理 GraphQL 查询。你需要了解如何映射数据模型到 GraphQL 类型,以及如何编写解析器来获取和转换数据。")])]),t._v(" "),s("li",[s("p",[t._v("查询优化:GraphQL 允许客户端指定其需要的数据,因此查询的优化非常重要。学习如何优化查询以减少数据传输和提高性能。")])]),t._v(" "),s("li",[s("p",[t._v("安全性:了解如何在 GraphQL 服务中实现安全性措施,包括身份验证和授权,以确保只有授权的用户能够访问特定的数据。")])]),t._v(" "),s("li",[s("p",[t._v("前端开发基础:虽然 BFF 是后端的一部分,但了解前端开发基础也有助于更好地满足前端应用程序的需求,特别是在设计 GraphQL 查询时。")])])]),t._v(" "),s("p",[t._v("总之,学习如何使用 GraphQL 来实现 BFF 需要你掌握 GraphQL 的基础知识,后端开发技能,以及选择适合你的编程语言的 GraphQL 服务器和工具。同时,了解如何优化查询、确保安全性和理解前端开发基础也是有帮助的。")]),t._v(" "),s("p",[t._v("BFF 筆記:")]),t._v(" "),s("blockquote",[s("p",[t._v("這時候就需要一個統一的接口, 這個接口就是 BFF . 就可以做到真正的前後端分離")])]),t._v(" "),s("p",[t._v("BFF 的背景:")]),t._v(" "),s("ul",[s("li",[t._v("应用程序通常有多个平台,如 PC WebApp、iOS、Android、微信小程序等,它们直接向后端服务发送请求。")]),t._v(" "),s("li",[t._v("每个平台的请求可能不同,导致后端需要为每个平台构建一个服务器,这会增加开发成本和服务器负担。")]),t._v(" "),s("li",[t._v("单个请求可能需要多个接口,这会增加网络开销和降低性能。")])]),t._v(" "),s("p",[t._v("BFF 的作用:")]),t._v(" "),s("ul",[s("li",[t._v("BFF 是一种统一的接口,用于解决不同平台请求的问题,实现前后端分离。")]),t._v(" "),s("li",[t._v("BFF 可以根据请求的平台返回相应的数据,避免了后端的复杂判断逻辑。")])]),t._v(" "),s("p",[t._v("BFF 的实现方式:")]),t._v(" "),s("ul",[s("li",[t._v("BFF 可以通过代理(Proxy)来实现,而不需要安装额外的服务器,只需要配置代理即可。")]),t._v(" "),s("li",[t._v("BFF 可以生成一个用于前端服务器的分发包(dist),使前端服务器能够找到接口。")]),t._v(" "),s("li",[t._v("BFF 还可以支持同构化,允许在服务器端和客户端共享代码,提高性能。")])]),t._v(" "),s("p",[t._v("总结:\nBFF 是一种解决多平台应用请求管理和性能优化的重要工具,它可以通过统一接口、代理和分发包来实现。 BFF 的使用可以简化后端逻辑,降低开发成本,提高性能。")]),t._v(" "),s("p",[t._v("Certainly! Below is a simple example of how a React frontend might interact with a Backend for Frontend (BFF) which is then communicating with a set of Java-based microservices.")]),t._v(" "),s("h3",{attrs:{id:"react-frontend-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#react-frontend-example"}},[t._v("#")]),t._v(" React Frontend Example")]),t._v(" "),s("p",[t._v("Here's a basic React component that interacts with a BFF to get the details of a product for display:")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProductDetails")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" productId "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("loading"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setLoading"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setError"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fetchProduct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setLoading")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/bff/products/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("productId"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Product not found"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setProduct")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setError")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("finally")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setLoading")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchProduct")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("productId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("loading"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Loading...")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Error: ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("No product details available.")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Price: ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("img")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("src")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("thumbnailUrl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("alt")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* ... other product details */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" ProductDetails"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"backend-for-frontend-bff-example-with-java-spring-boot"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#backend-for-frontend-bff-example-with-java-spring-boot"}},[t._v("#")]),t._v(" Backend for Frontend (BFF) Example with Java/Spring Boot")]),t._v(" "),s("p",[t._v("Your BFF might be a Spring Boot application that routes requests to different microservices:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RestController")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequestMapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/bff/products"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductBFFController")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductService")]),t._v(" productService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductBFFController")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductService")]),t._v(" productService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("productService "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" productService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@GetMapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/{id}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseEntity")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getProduct")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@PathVariable")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),t._v(" product "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" productService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getProductById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseEntity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductNotFoundException")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseEntity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("notFound")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here's the "),s("code",[t._v("ProductService")]),t._v(" that the BFF controller might use to communicate with the product microservice:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Service")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductService")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RestTemplate")]),t._v(" restTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductService")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RestTemplate")]),t._v(" restTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("restTemplate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" restTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getProductById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" productMicroserviceUrl "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://product-microservice/api/products/"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseEntity")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" restTemplate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getForEntity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("productMicroserviceUrl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getStatusCode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HttpStatus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OK")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBody")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductNotFoundException")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Product not found with ID: "')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("And the "),s("code",[t._v("ProductDTO")]),t._v(" might look like this:")]),t._v(" "),s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductDTO")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" description"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BigDecimal")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" thumbnailUrl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Getters and setters...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example, when the React component makes a request to the BFF ("),s("code",[t._v("/bff/products/{productId}")]),t._v("), the BFF controller in the Spring Boot application receives the request, uses the "),s("code",[t._v("ProductService")]),t._v(" to make a call to the product microservice, gets the product information, and returns it to the frontend formatted as needed.")]),t._v(" "),s("p",[t._v("Remember, for a real-world application, you'd need to handle cross-origin resource sharing (CORS) in the BFF, have proper error handling, use environment variables for service URLs, implement security, and consider using asynchronous communication patterns where appropriate.")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/44.0492f992.js b/assets/js/44.0492f992.js new file mode 100644 index 00000000..aed6d0f6 --- /dev/null +++ b/assets/js/44.0492f992.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{333:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"🔻-使用される場面"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔻-使用される場面"}},[t._v("#")]),t._v(" 🔻 使用される場面")]),t._v(" "),a("h3",{attrs:{id:"例子-1-javascript-data-transformation-using-object-values-and-map"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#例子-1-javascript-data-transformation-using-object-values-and-map"}},[t._v("#")]),t._v(" "),a("strong",[t._v("例子 1: JavaScript Data Transformation Using "),a("code",[t._v("Object.values")]),t._v(" and "),a("code",[t._v("map")])])]),t._v(" "),a("div",{staticClass:"language-ts extra-class"},[a("pre",{pre:!0,attrs:{class:"language-ts"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" animals"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" colors "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../constants"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ANIMAL_OPTIONS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectOption"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("values")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("animals"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("animal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n value"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" animal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n label"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" animal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("charAt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" animal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLowerCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("COLOR_OPTIONS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectOption"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("values")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("colors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("color"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n value"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" color"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n label"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" color"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("charAt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" color"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLowerCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("ol",[a("li",[a("p",[a("strong",[t._v("Extracting Object Values with "),a("code",[t._v("Object.values")])]),t._v(":")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("Object.values")]),t._v(" is a method that takes an object as an argument and returns an array containing all the values of that object's properties.")]),t._v(" "),a("li",[t._v("Example Usage: In the context of a "),a("code",[t._v("countries")]),t._v(" object, "),a("code",[t._v("Object.values(countries)")]),t._v(" would extract all country names and create an array of these names, such as "),a("code",[t._v("['CANADA', 'UNITED KINGDOM', 'AUSTRALIA']")]),t._v(".")])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Transforming Array Elements with "),a("code",[t._v("map")])]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("The "),a("code",[t._v("map")]),t._v(" method creates a new array by performing a specified operation on each element of an array.")]),t._v(" "),a("li",[t._v("In the given example, "),a("code",[t._v("map")]),t._v(" is used to transform each country name into an object with two properties: "),a("code",[t._v("value")]),t._v(" and "),a("code",[t._v("label")]),t._v(".\n"),a("ul",[a("li",[a("code",[t._v("value")]),t._v(": The original country name.")]),t._v(" "),a("li",[a("code",[t._v("label")]),t._v(": The country name formatted with the first letter in uppercase and the rest in lowercase, achieved through "),a("code",[t._v("country.charAt(0)")]),t._v(" (first character) and "),a("code",[t._v("country.slice(1).toLowerCase()")]),t._v(" (remaining characters in lowercase).")])])])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Resulting Data Structure")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("The combination of "),a("code",[t._v("Object.values")]),t._v(" and "),a("code",[t._v("map")]),t._v(" results in an array of objects, each representing a country option. Each object has a "),a("code",[t._v("value")]),t._v(" (the original uppercase country name) and a "),a("code",[t._v("label")]),t._v(" (formatted with only the first letter capitalized).")]),t._v(" "),a("li",[t._v("Example Output: An array of objects like "),a("code",[t._v("{ canada: 'Canada', unitedkingdom: 'United Kingdom', australia: 'Australia' }")]),t._v(", where the keys are lowercase versions of the country names and the values are formatted as specified.")])])])]),t._v(" "),a("p",[a("strong",[t._v("Key Takeaways")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("These methods are effective for converting and preparing data from objects into a specific format, such as options for a dropdown menu.")]),t._v(" "),a("li",[a("code",[t._v("Object.values")]),t._v(" and "),a("code",[t._v("map")]),t._v(" offer a common and powerful pattern for data handling and transformation in JavaScript, ensuring consistency and readability in your code.")])]),t._v(" "),a("hr"),t._v(" "),a("h3",{attrs:{id:"例子-2-用array-prototype-reduce-把-array-轉換成-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#例子-2-用array-prototype-reduce-把-array-轉換成-object"}},[t._v("#")]),t._v(" **例子 2: 用"),a("code",[t._v("Array.prototype.reduce")]),t._v(" 把 "),a("code",[t._v("array")]),t._v(" 轉換成 "),a("code",[t._v("object")]),t._v(" **")]),t._v(" "),a("ol",[a("li",[a("p",[a("strong",[t._v("Defining the Array")]),t._v(":\nFirst, define an array containing country names. For example:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" countries "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Canada"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"United Kingdom"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Australia"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Using "),a("code",[t._v("reduce")]),t._v(" to Transform into an Object")]),t._v(":\nUse the "),a("code",[t._v("reduce")]),t._v(" method to iterate over the array, transforming each array element (country name) into both key and value of the object.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" countriesObject "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" countries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("obj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" country")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" country"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLowerCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("replace")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token regex"}},[a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v(" ")]),a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token regex-flags"}},[t._v("g")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n obj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" country"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" obj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("In this example, the "),a("code",[t._v("reduce")]),t._v(" method takes two parameters: an accumulator ("),a("code",[t._v("obj")]),t._v(") and the current element ("),a("code",[t._v("country")]),t._v("). We first convert the country name to lowercase and remove all spaces to create the key, then assign the original country name ("),a("code",[t._v("country")]),t._v(") as the value.")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Accessing Country Names Using the Object")]),t._v(":\nOnce the object is created, you can use it as Cameron described:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("country "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" countriesObject"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("canada"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Logic to handle the scenario")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("blockquote",[a("p",[t._v("在您提供的代码示例中,使用 "),a("code",[t._v("reduce")]),t._v(" 方法创建对象时,指定了键(key)和值(value)的过程如下:")])]),t._v(" "),a("ul",[a("li",[a("p",[a("strong",[t._v("键(Key)的创建")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("键是通过将国家名转换为小写并移除所有空格来创建的。在代码中,这是通过 "),a("code",[t._v("country.toLowerCase().replace(/ /g, '')")]),t._v(" 实现的。")]),t._v(" "),a("li",[t._v("这里,"),a("code",[t._v("country")]),t._v(" 是数组中的当前元素(即国家名)。"),a("code",[t._v("toLowerCase()")]),t._v(" 方法将国家名转换为小写,"),a("code",[t._v("replace(/ /g, '')")]),t._v(" 方法则移除所有空格。")]),t._v(" "),a("li",[t._v("这个转换后的字符串(国家名的小写无空格版本)被用作对象的键。")])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("值(Value)的指定")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("值直接使用原始的国家名(即数组中的当前元素 "),a("code",[t._v("country")]),t._v(")。")]),t._v(" "),a("li",[t._v("在 "),a("code",[t._v("obj[key] = country;")]),t._v(" 这行代码中,"),a("code",[t._v("obj")]),t._v(" 是累加器对象,"),a("code",[t._v("key")]),t._v(" 是经过处理的国家名,"),a("code",[t._v("country")]),t._v("是原始的国家名。")]),t._v(" "),a("li",[t._v("因此,每次迭代时,都会在"),a("code",[t._v("obj")]),t._v(" 对象中添加一个新属性,其属性名为处理后的国家名,属性值为原始国家名。")])])])]),t._v(" "),a("p",[t._v("这种方式确保了在生成的对象中,每个键(处理后的国家名)都对应一个值(原始的国家名)。例如,如果 "),a("code",[t._v("countries")]),t._v(" 数组包含 "),a("code",[t._v("'Canada'")]),t._v(",则生成的对象会有一个属性,其键为 "),a("code",[t._v("'canada'")]),t._v(",值为 "),a("code",[t._v("'Canada'")]),t._v("。")])])]),t._v(" "),a("h3",{attrs:{id:"称为-属性访问器语法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#称为-属性访问器语法"}},[t._v("#")]),t._v(" 称为“属性访问器语法”")]),t._v(" "),a("p",[t._v("在 Javascript 中, 使用 "),a("code",[t._v("obj[key] = country;")]),t._v(" 这种使用方括号 ("),a("code",[t._v("[]")]),t._v(") 的语法是访问或设置对象属性的一种方式,称为“属性访问器语法”。在这个特定的上下文中,它用于动态地设置对象的属性。当您需要动态地将变量的值用作对象键(key)时,使用方括号 ("),a("code",[t._v("[]")]),t._v(") 语法是非常重要和实用的。这种语法使您可以根据变量的值来动态设置或访问对象的属性。")]),t._v(" "),a("p",[a("strong",[t._v("使用方括号语法动态处理对象属性:")])]),t._v(" "),a("ol",[a("li",[a("p",[a("strong",[t._v("动态属性名")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("使用 "),a("code",[t._v("obj[key]")]),t._v(" 时,"),a("code",[t._v("key")]),t._v(" 是一个变量,其值可以在每次迭代或函数调用中改变。方括号允许使用变量的值作为属性名。")]),t._v(" "),a("li",[t._v("相比之下,点语法(如 "),a("code",[t._v("obj.key")]),t._v(')用于访问名为 "key" 的固定属性,而不是变量 '),a("code",[t._v("key")]),t._v(" 的值。")])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("设置对象属性")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("表达式 "),a("code",[t._v("obj[key] = country")]),t._v(" 表示在对象 "),a("code",[t._v("obj")]),t._v(" 上设置一个属性,其属性名为变量 "),a("code",[t._v("key")]),t._v(" 的值,属性值为 "),a("code",[t._v("country")]),t._v("。")]),t._v(" "),a("li",[t._v("在迭代过程中,根据每个 "),a("code",[t._v("country")]),t._v(" 的值动态创建或更新 "),a("code",[t._v("obj")]),t._v(" 的属性。")])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("灵活性和实用性")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("方括号语法在运行时动态确定属性名,特别适用于处理变量属性名或由表达式计算得到的属性名。")]),t._v(" "),a("li",[t._v("这种方法提高了灵活性,允许根据不同情况和数据设置不同的属性名。")])])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("应用场景")]),t._v(":")]),t._v(" "),a("ul",[a("li",[t._v("当处理需要根据运行时数据动态创建或访问对象属性的场景(如用户输入、结果计算或数组迭代)时,方括号语法是必需的。")])])])]),t._v(" "),a("p",[a("strong",[t._v("结论")]),t._v(":\n使用方括号 ("),a("code",[t._v("obj[key]")]),t._v(") 语法是 JavaScript 中一种强大的特性,允许您的代码根据不同情况动态地处理对象属性。它在如 "),a("code",[t._v("reduce")]),t._v(" 方法这样的场景中特别有用,因为它允许根据数组中的每个元素动态构建对象的属性,确保代码的灵活性和一致性。")]),t._v(" "),a("h2",{attrs:{id:"🔻-dan-tutorial-チュートリアル"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔻-dan-tutorial-チュートリアル"}},[t._v("#")]),t._v(" 🔻 Dan tutorial チュートリアル")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" people "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bob'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("position")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'developer'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'peter'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("position")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'designer'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'susy'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("position")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'the boss'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// without using map method")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" person "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" People"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n names"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("person"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toUpperCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("names"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// ["BOB", "PETER", "SUSY"]')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//with map method")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" names "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" people"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("person")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" person"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toUpperCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//with map method")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" names"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" people"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("person")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("person"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toUpperCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//with map method")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newPeople "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" people"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("person")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("firstName")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" person"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toUpperCase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("oldAge")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" person"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("age "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/45.af66bbe7.js b/assets/js/45.af66bbe7.js new file mode 100644 index 00000000..5c3083a4 --- /dev/null +++ b/assets/js/45.af66bbe7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{332:function(s,a,t){"use strict";t.r(a);var n=t(14),e=Object(n.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"⚪️-コンフィギュレーション"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-コンフィギュレーション"}},[s._v("#")]),s._v(" ⚪️ コンフィギュレーション")]),s._v(" "),a("h2",{attrs:{id:"install-update-nvm"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#install-update-nvm"}},[s._v("#")]),s._v(" Install & Update nvm")]),s._v(" "),a("p",[s._v("To install or update Node Version Manager (nvm), you can use the following commands:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("curl")]),s._v(" -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bash")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("export")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("NVM_DIR")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-z")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${XDG_CONFIG_HOME-}")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("printf")]),s._v(" %s "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${"),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("HOME")]),s._v("}")]),s._v('/.nvm"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("||")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("printf")]),s._v(" %s "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${XDG_CONFIG_HOME}")]),s._v('/nvm"')]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$NVM_DIR")]),s._v('/nvm.sh"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v(". "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$NVM_DIR")]),s._v('/nvm.sh"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# This loads nvm")]),s._v("\n")])])]),a("p",[s._v("Don't forget to source your shell configuration file after the installation:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("source")]),s._v(" ~/.bashrc\n")])])]),a("p",[s._v("For zsh users, you can modify your "),a("code",[s._v(".zshrc")]),s._v(" file using the following steps:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nano")]),s._v(" .zshrc\n")])])]),a("p",[s._v("To automatically call "),a("code",[s._v("nvm use")]),s._v(" if "),a("code",[s._v(".nvmrc")]),s._v(" is present, you can add the following snippet to your "),a("code",[s._v(".zshrc")]),s._v(":")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("export")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("NVM_DIR")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-z")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${XDG_CONFIG_HOME-}")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("printf")]),s._v(" %s "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${"),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("HOME")]),s._v("}")]),s._v('/.nvm"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("||")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("printf")]),s._v(" %s "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${XDG_CONFIG_HOME}")]),s._v('/nvm"')]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$NVM_DIR")]),s._v('/nvm.sh"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v(". "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$NVM_DIR")]),s._v('/nvm.sh"')]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Place this after nvm initialization!")]),s._v("\nautoload "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-U")]),s._v(" add-zsh-hook\n\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("load-nvmrc")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("local")]),s._v(" nvmrc_path\n "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("nvmrc_path")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("nvm_find_nvmrc"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$nvmrc_path")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("local")]),s._v(" nvmrc_node_version\n "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("nvmrc_node_version")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("nvm version "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${nvmrc_path}")]),s._v('"')]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$nvmrc_node_version")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"N/A"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n nvm "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("install")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("elif")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$nvmrc_node_version")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("nvm version"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n nvm use\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("elif")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("PWD")])]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("$OLDPWD")]),s._v(" nvm_find_nvmrc"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("nvm version"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("nvm version default"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Reverting to nvm default version"')]),s._v("\n nvm use default\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\nadd-zsh-hook chpwd load-nvmrc\nload-nvmrc\n")])])]),a("p",[s._v("This configuration will ensure that "),a("code",[s._v("nvm use")]),s._v(" is called automatically based on the presence of a "),a("code",[s._v(".nvmrc")]),s._v(" file in your project directory.")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/46.c1c9a53c.js b/assets/js/46.c1c9a53c.js new file mode 100644 index 00000000..dd360677 --- /dev/null +++ b/assets/js/46.c1c9a53c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{334:function(t,s,r){"use strict";r.r(s);var e=r(14),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-dockers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-dockers"}},[this._v("#")]),this._v(" ⚪️ dockers")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/47.7a2bd268.js b/assets/js/47.7a2bd268.js new file mode 100644 index 00000000..12862a7c --- /dev/null +++ b/assets/js/47.7a2bd268.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{335:function(t,s,r){"use strict";r.r(s);var e=r(14),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-dockers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-dockers"}},[this._v("#")]),this._v(" ⚪️ dockers")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/48.0376d3a5.js b/assets/js/48.0376d3a5.js new file mode 100644 index 00000000..b648658f --- /dev/null +++ b/assets/js/48.0376d3a5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{337:function(t,s,r){"use strict";r.r(s);var a=r(14),n=Object(a.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-graphql"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-graphql"}},[this._v("#")]),this._v(" ⚪️ graphql")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/49.60535624.js b/assets/js/49.60535624.js new file mode 100644 index 00000000..4902a71e --- /dev/null +++ b/assets/js/49.60535624.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{338:function(t,s,n){"use strict";n.r(s);var e=n(14),i=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-jinkens"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-jinkens"}},[this._v("#")]),this._v(" ⚪️ jinkens")])])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/5.4ceb5601.js b/assets/js/5.4ceb5601.js new file mode 100644 index 00000000..dc9c9e50 --- /dev/null +++ b/assets/js/5.4ceb5601.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{278:function(t,e,a){},292:function(t,e,a){"use strict";a(278)},309:function(t,e,a){"use strict";a.r(e);var s={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(292),a(14)),n=Object(i.a)(s,(function(){return(0,this._self._c)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/50.88e721ab.js b/assets/js/50.88e721ab.js new file mode 100644 index 00000000..91d13976 --- /dev/null +++ b/assets/js/50.88e721ab.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{346:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"⚪️-reacthooks-を深く理解する"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-reacthooks-を深く理解する"}},[t._v("#")]),t._v(" ⚪️ ReactHooks を深く理解する")]),t._v(" "),s("h2",{attrs:{id:"🔷-useeffect"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-useeffect"}},[t._v("#")]),t._v(" 🔷 useEffect")]),t._v(" "),s("h3",{attrs:{id:"▫️-what-is-useeffect"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-what-is-useeffect"}},[t._v("#")]),t._v(" ▫️ what is "),s("code",[t._v("useEffect")])]),t._v(" "),s("p",[s("code",[t._v("useEffect")]),t._v(" 是 React 中的一個 Hook,它主要用於處理副作用操作,例如異步數據的獲取、對已渲染的結果進行更新渲染等。")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("第二個參數:依賴數組")]),t._v(" "),s("p",[s("code",[t._v("useEffect")]),t._v(" 的第二個參數,通常是一個依賴數組,決定了 "),s("code",[t._v("useEffect")]),t._v(" 何時執行。這個參數的作用有以下幾種情況:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("空數組 "),s("code",[t._v("[]")]),t._v(":當依賴數組為空時,"),s("code",[t._v("useEffect")]),t._v(" 只會在組件挂載時運行一次,就像 "),s("code",[t._v("componentDidMount")]),t._v("。這對於僅在組件挂載和卸載時執行一次的操作非常有用,例如初始化資料")])]),t._v(" "),s("li",[s("p",[t._v("非空數組 "),s("code",[t._v("[依賴1, 依賴2, ...]")]),t._v(":當依賴數組中的任何一個依賴發生變化時,"),s("code",[t._v("useEffect")]),t._v(" 會運行。這對於需要根據特定狀態或 prop 執行操作的情況非常有用。如果你希望 "),s("code",[t._v("useEffect")]),t._v(" 在每次渲染時都運行,則不傳入第二個參數即可。")])])]),t._v(" "),s("p",[t._v("簡而言之,"),s("code",[t._v("useEffect")]),t._v(" 的第二個參數決定了該 hook 何時執行,它提供了對 hook 執行的細粒度控制。")])]),t._v(" "),s("li",[s("p",[t._v("side effect(外部影響內部): 從外部獲取數據,對內部渲染的結果產生了作用")])])]),t._v(" "),s("h3",{attrs:{id:"▫️-basic-purpose"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-basic-purpose"}},[t._v("#")]),t._v(" ▫️ Basic Purpose")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MyComponent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---回调中---"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("querySelector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"h1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"當前的值: "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里的空数组表示只在组件挂载时运行一次")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"***组件中***"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Hello World! ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" container "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getElementById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"root"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// 这里假设你的根 DOM 元素的 id 是 "root"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" MyComponent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("輸出結果")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("如果组件首次挂载(加载),那么输出将如下所示:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***组件中***\n---回调中---\nnull\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("***组件中***")]),t._v("会在每次组件函数被调用时输出。")]),t._v(" "),s("li",[s("code",[t._v("---回调中---")]),t._v("会在"),s("code",[t._v("useEffect")]),t._v("的回调函数内部输出,只有在组件挂载时才会执行一次。")]),t._v(" "),s("li",[s("code",[t._v("null")]),t._v("是因为在组件挂载时,"),s("code",[t._v("

    ")]),t._v("元素还没有被渲染到 DOM 中,所以"),s("code",[t._v('document.querySelector("h1")')]),t._v("返回"),s("code",[t._v("null")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("當前的值: 0")]),t._v("表示"),s("code",[t._v("count")]),t._v("的初始值为 0。")])])]),t._v(" "),s("li",[s("p",[t._v("如果用户点击"),s("code",[t._v("

    ")]),t._v("元素以增加"),s("code",[t._v("count")]),t._v("的值,那么每次点击后的输出将如下所示,以点击两次为例:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("2")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("***组件中***")]),t._v("会在每次组件函数被调用时输出。")]),t._v(" "),s("li",[s("code",[t._v("---回调中---")]),t._v("会在"),s("code",[t._v("useEffect")]),t._v("的回调函数内部输出,但它只在组件挂载时执行一次,所以之后点击"),s("code",[t._v("

    ")]),t._v("元素不会再次触发该输出。")]),t._v(" "),s("li",[s("code",[t._v("

    Hello World! 1

    ")]),t._v("和"),s("code",[t._v("

    Hello World! 2

    ")]),t._v("是每次点击后,React 重新渲染组件后生成的"),s("code",[t._v("

    ")]),t._v("元素。")]),t._v(" "),s("li",[s("code",[t._v("當前的值: 1")]),t._v("和"),s("code",[t._v("當前的值: 2")]),t._v("表示"),s("code",[t._v("count")]),t._v("的值在每次点击后更新。")])])])]),t._v(" "),s("h3",{attrs:{id:"▫️-second-argument-dependency-array"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-second-argument-dependency-array"}},[t._v("#")]),t._v(" ▫️ Second Argument - Dependency Array")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setPage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---回调中---"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("document"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("querySelector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"h1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"當前的值: "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里的空数组表示只在组件挂载时运行一次")]),t._v("\n\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"***组件中***"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Hello World! ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("page "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Next Page ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v('如果同时点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(' 元素和 "Next Page" 按钮,会同时触发'),s("code",[t._v("count")]),t._v("和"),s("code",[t._v("page")]),t._v("的更新,因此"),s("code",[t._v("useEffect")]),t._v("将在两者之间交替触发。以下是可能的打印结果示例:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v('初始渲染(挂载)后,点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(' 元素和 "Next Page" 按钮:')]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("0")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("0")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n")])])]),s("ul",[s("li",[t._v("初始渲染时,"),s("code",[t._v("count")]),t._v(" 的值为 0,"),s("code",[t._v("page")]),t._v(" 的值为 1。")]),t._v(" "),s("li",[t._v('同时点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(' 元素和 "Next Page" 按钮,'),s("code",[t._v("count")]),t._v(" 和 "),s("code",[t._v("page")]),t._v(" 的值会同时更新,但是由于"),s("code",[t._v("useEffect")]),t._v("的依赖数组包含了这两者,它会在其中任何一个发生变化时触发。所以 "),s("code",[t._v("useEffect")]),t._v(" 打印了新的 "),s("code",[t._v("count")]),t._v(" 值为 0 和新的 "),s("code",[t._v("page")]),t._v(" 值为 2,以及其他信息。")])])]),t._v(" "),s("li",[s("p",[t._v('点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(' 元素后再点击 "Next Page" 按钮:')]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("0")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("0")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("0")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n***组件中***\n---回调中---\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("Hello World"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v("<")]),t._v("/h"),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("1")]),t._v(">")]),t._v("\n當前的值: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n")])])]),s("ul",[s("li",[t._v('首先点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(" 元素,"),s("code",[t._v("count")]),t._v(" 的值递增到 1,但 "),s("code",[t._v("page")]),t._v(" 仍然是 1,所以 "),s("code",[t._v("useEffect")]),t._v(" 不会触发。")]),t._v(" "),s("li",[t._v('然后点击 "Next Page" 按钮,'),s("code",[t._v("page")]),t._v(" 的值从 1 增加到 2,同时 "),s("code",[t._v("count")]),t._v(" 仍然是 1,这次 "),s("code",[t._v("useEffect")]),t._v(" 会触发,并打印新的 "),s("code",[t._v("page")]),t._v(" 值为 2,以及其他信息。")])])])]),t._v(" "),s("p",[t._v('总结:同时点击 "Hello World!" '),s("code",[t._v("

    ")]),t._v(' 元素和 "Next Page" 按钮会导致'),s("code",[t._v("count")]),t._v("和"),s("code",[t._v("page")]),t._v("的值同时更新,但是由于"),s("code",[t._v("useEffect")]),t._v("的依赖数组包含了这两者,它会在其中任何一个发生变化时触发,从而打印出相应的信息。"),s("code",[t._v("***组件中***")]),t._v(" 在每次组件函数被调用时都会输出,但它与这两个值无关。")]),t._v(" "),s("h3",{attrs:{id:"▫️-return-of-cleanup-function"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-return-of-cleanup-function"}},[t._v("#")]),t._v(" ▫️ Return of Cleanup Function")]),t._v(" "),s("p",[t._v("理解清除函数 ("),s("code",[t._v("return")]),t._v(" 函数) 在 "),s("code",[t._v("useEffect")]),t._v(" 中的作用非常重要,它用于处理副作用的清理和资源释放。以下是关于为什么需要清除函数以及一些常见用例的优化笔记:")]),t._v(" "),s("blockquote",[s("p",[t._v("为什么需要清除函数?")])]),t._v(" "),s("ol",[s("li",[s("p",[t._v("因為 "),s("code",[t._v("useEffect")]),t._v(" 會反覆執行")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("资源释放")]),t._v(":"),s("code",[t._v("useEffect")]),t._v(" 可以用于处理需要清理的操作,比如关闭数据库连接、取消网络请求、清除定时器等。这是因为在组件卸载或下一次 "),s("code",[t._v("useEffect")]),t._v(" 触发之前,React 会调用清除函数,以确保资源被正确释放,避免内存泄漏和不必要的资源占用。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("防止副作用的重复执行")]),t._v(":在某些情况下,组件的重新渲染可能会导致 "),s("code",[t._v("useEffect")]),t._v(" 多次触发。通过清除函数,你可以在每次 "),s("code",[t._v("useEffect")]),t._v(" 触发前清理之前的副作用,以确保只执行最新的操作,而不重复执行。")])])]),t._v(" "),s("p",[t._v("🔻 シナリオ")]),t._v(" "),s("ul",[s("li",[t._v("清除定时器")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" timerId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 执行一些操作")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清除定时器")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("timerId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("上述代码示例创建了一个定时器,并且通过返回的清除函数来清除定时器。这样可以确保在组件卸载或下一次 "),s("code",[t._v("useEffect")]),t._v(" 触发之前,定时器会被正确清除,防止内存泄漏和不必要的执行。")]),t._v(" "),s("ul",[s("li",[t._v("断开数据库连接")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 连接到数据库")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清理数据库连接")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 断开数据库连接")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,"),s("code",[t._v("useEffect")]),t._v(" 用于连接数据库,并通过返回的清除函数来断开数据库连接。这确保了在组件卸载或下一次 "),s("code",[t._v("useEffect")]),t._v(" 触发之前,数据库连接会被正确关闭。")]),t._v(" "),s("ul",[s("li",[t._v("取消网络请求")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" controller "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AbortController")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com/data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("signal")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controller"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signal "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 处理响应数据")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("catch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"AbortError"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 请求被取消")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 处理其他错误")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清除控制器以取消网络请求")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" controller"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("abort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,我们使用 "),s("code",[t._v("AbortController")]),t._v(" 来控制网络请求,并通过返回的清除函数来取消网络请求。这样可以确保在组件卸载或下一次 "),s("code",[t._v("useEffect")]),t._v(" 触发之前,网络请求会被正确取消。")]),t._v(" "),s("p",[t._v("总之,清除函数在处理副作用的清理和资源释放时非常重要。它允许你在组件生命周期中管理资源,确保它们被正确释放,从而避免潜在的问题。")]),t._v(" "),s("h3",{attrs:{id:"▫️-execution-timing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-execution-timing"}},[t._v("#")]),t._v(" ▫️ Execution Timing")]),t._v(" "),s("blockquote",[s("p",[t._v("在 useEffect 的回调函数中,当依赖数组中的某些依赖发生变化或者组件被卸载时,React 会执行回调函数中的返回值函数(清除函数)。这是确保在重新运行 useEffect 之前,清理之前副作用的机制。")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("組件被銷毀時")])]),t._v(" "),s("li",[s("p",[t._v("第二次執行回調時,會先執行上一次回調中的返回值函數")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---回调中---"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"~~~回調中返回值函數~~~"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"***組件中***"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("打印結果:")])])]),t._v(" "),s("ol",[s("li",[s("p",[t._v("第一次打印:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***組件中***\n---回调中---\n")])])])]),t._v(" "),s("li",[s("p",[t._v("第二次打印:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("***組件中***\n~~~回調中返回值函數~~~ "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n---回调中---\n")])])])])]),t._v(" "),s("p",[t._v("從第二次打印中,可以看出,如果 "),s("code",[t._v("page")]),t._v(" 的值发生了变化,那么 "),s("code",[t._v("useEffect")]),t._v("的回调函数将会再次执行。但在执行新的回调函数之前,React 会先执行上一次回调函数中的返回值函数(清除函数),然后再执行新的回调函数。这确保了在重新运行 useEffect 之前,可以清理之前的副作用。")]),t._v(" "),s("h3",{attrs:{id:"▫️-usage-limitation-cannot-use-async-functions-directly"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usage-limitation-cannot-use-async-functions-directly"}},[t._v("#")]),t._v(" ▫️ Usage Limitation - Cannot Use "),s("code",[t._v("async")]),t._v(" Functions Directly")]),t._v(" "),s("blockquote",[s("p",[t._v("因为 "),s("code",[t._v("async")]),t._v(" 函数返回的是一个 Promise 对象。这是因为 "),s("code",[t._v("useEffect")]),t._v(" 的回调函数应该是同步的,而不应该返回一个 Promise 对象。")])]),t._v(" "),s("blockquote",[s("p",[t._v("如果你需要在 "),s("code",[t._v("useEffect")]),t._v(" 中执行异步操作,可以在回调函数内部创建一个 async 函数,然后在这个 async 函数内部执行异步操作。以下是一个示例:")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.example.com/data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 执行其他操作,例如更新 state")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"发生错误:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,我们在 "),s("code",[t._v("useEffect")]),t._v(" 的回调函数内部创建了一个名为 "),s("code",[t._v("fetchData")]),t._v(" 的 async 函数,然后在其中执行异步操作。这种方式可以让你在 "),s("code",[t._v("useEffect")]),t._v(" 中处理异步逻辑,但依然保持了回调函数的同步性质。")]),t._v(" "),s("p",[t._v("需要注意的是,虽然 async 函数内部可以使用 "),s("code",[t._v("await")]),t._v(" 关键字等待异步操作完成,但整个回调函数仍然是同步执行的,不会等待异步操作的完成。因此,在使用 async 函数时,要确保正确处理异步操作的结果和错误。")]),t._v(" "),s("h2",{attrs:{id:"🔷-useref"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-useref"}},[t._v("#")]),t._v(" 🔷 useRef")]),t._v(" "),s("h3",{attrs:{id:"▫️-what-is-useref"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-what-is-useref"}},[t._v("#")]),t._v(" ▫️ what is "),s("code",[t._v("useRef")])]),t._v(" "),s("p",[s("code",[t._v("useRef")]),t._v(" 是 React 中的一个 Hook,它可以用于获取或存储组件的引用。它类似于 class 组件中的 "),s("code",[t._v("ref")]),t._v(" 属性,但是它可以用于函数组件。 "),s("code",[t._v("useRef")]),t._v(" 返回一个可变的 ref 对象,其 "),s("code",[t._v(".current")]),t._v(" 属性被初始化为传入的参数("),s("code",[t._v("initialValue")]),t._v(")。返回的 ref 对象在组件的整个生命周期内保持不变。")]),t._v(" "),s("h3",{attrs:{id:"▫️-basic-purpose-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-basic-purpose-2"}},[t._v("#")]),t._v(" ▫️ Basic Purpose")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inputRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleClick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("focus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleClick"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("聚焦输入框")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个示例中,我们使用 "),s("code",[t._v("useRef")]),t._v(" 创建了一个名为 "),s("code",[t._v("inputRef")]),t._v(" 的 ref 对象,并将其传递给 "),s("code",[t._v("")]),t._v(" 元素的 "),s("code",[t._v("ref")]),t._v(" 属性。这样,我们就可以通过 "),s("code",[t._v("inputRef.current")]),t._v(" 来获取 "),s("code",[t._v("")]),t._v(" 元素的引用。")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("handleClick")]),t._v(" 函数中,我们使用 "),s("code",[t._v("inputRef.current.focus()")]),t._v(" 来聚焦 "),s("code",[t._v("")]),t._v(' 元素。这样,当用户点击 "Focus the input" 按钮时,'),s("code",[t._v("")]),t._v(" 元素就会被聚焦。")]),t._v(" "),s("h3",{attrs:{id:"▫️-usage-limitation-cannot-use-useref-to-update-state"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usage-limitation-cannot-use-useref-to-update-state"}},[t._v("#")]),t._v(" ▫️ Usage Limitation - Cannot Use "),s("code",[t._v("useRef")]),t._v(" to Update State")]),t._v(" "),s("blockquote",[s("p",[s("code",[t._v("useRef")]),t._v(" 不能用于更新组件的 state。这是因为 "),s("code",[t._v("useRef")]),t._v(" 返回的 ref 对象在组件的整个生命周期内保持不变,而 "),s("code",[t._v("useState")]),t._v(" 会在每次渲染时返回一个新的 state 值。")])]),t._v(" "),s("blockquote",[s("p",[t._v("如果你需要在 "),s("code",[t._v("useRef")]),t._v(" 中更新 state,可以使用 "),s("code",[t._v("useRef")]),t._v(" 的 "),s("code",[t._v(".current")]),t._v(" 属性来存储 state 的值。以下是一个示例:")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" countRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleAlertClick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTimeout")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("alert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You clicked on: "')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" countRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Increment-useState")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleAlertClick"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Show alert-useRef")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在這個示例中, 我們使用 "),s("code",[t._v("useRef")]),t._v(" 創建了一個名為 "),s("code",[t._v("countRef")]),t._v(" 的 ref 對象,並將其初始化為 0。然後,我們在 "),s("code",[t._v("handleAlertClick")]),t._v(" 函數中使用 "),s("code",[t._v("countRef.current")]),t._v(" 來獲取 "),s("code",[t._v("count")]),t._v(' 的值。這樣,當用戶點擊 "Show alert" 按鈕時,我們就可以獲取 '),s("code",[t._v("count")]),t._v(" 的值。")]),t._v(" "),s("p",[t._v("當點擊 "),s("code",[t._v("Increment")]),t._v(" 後, "),s("code",[t._v("count")]),t._v(" 的值會增加,但是 "),s("code",[t._v("countRef.current")]),t._v(" 的值仍然是 0。這是因為 "),s("code",[t._v("useRef")]),t._v(" 返回的 ref 對象在組件的"),s("strong",[t._v("整個生命周期")]),t._v("內保持不變,而 "),s("code",[t._v("useState")]),t._v(" 會在每次渲染時返回一個新的 state 值。")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th"),t._v(" "),s("th",[s("code",[t._v("useState")])]),t._v(" "),s("th",[s("code",[t._v("useRef")])])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("修改值的時候")]),t._v(" "),s("td",[t._v("觸發重新渲染")]),t._v(" "),s("td",[s("strong",[t._v("不")]),t._v("觸發重新渲染")])]),t._v(" "),s("tr",[s("td",[t._v("組件重新渲染時")]),t._v(" "),s("td",[t._v("獲取之前的值")]),t._v(" "),s("td",[t._v("獲取之前值")])])])]),t._v(" "),s("p",[t._v("🔺 シナリオ:")]),t._v(" "),s("ul",[s("li",[t._v("定時器案例:當我們不需要它渲染後的值,而是需要它渲染前的值時,就可以使用 "),s("code",[t._v("useRef")]),t._v("。")])]),t._v(" "),s("blockquote",[s("p",[t._v("不使用 "),s("code",[t._v("useRef")]),t._v(" 的情況, 以下: 每次點擊,都清除之前的定時器,看上去沒有問題。 但其實如果組件重新渲染,是不會清除之前定時器的, 本次的 timer 與上一次的 timer 不一樣")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("handleClick")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("timer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n timer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"timer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("使用"),s("code",[t._v("useRef")]),t._v(" 之後")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" timer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("handleClick")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("timer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n timer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setInterval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"timer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在這個示例中, 我們使用 "),s("code",[t._v("useRef")]),t._v(" 創建了一個名為 "),s("code",[t._v("countRef")]),t._v(" 的 ref 對象,並將其初始化為 0。然後,我們在 "),s("code",[t._v("handleAlertClick")]),t._v(" 函數中使用 "),s("code",[t._v("countRef.current")]),t._v(" 來獲取 "),s("code",[t._v("count")]),t._v(' 的值。這樣,當用戶點擊 "Show alert" 按鈕時,我們就可以獲取 '),s("code",[t._v("count")]),t._v(" 的值。")]),t._v(" "),s("p",[t._v("當點擊 "),s("code",[t._v("Increment")]),t._v(" 後, "),s("code",[t._v("count")]),t._v(" 的值會增加,但是 "),s("code",[t._v("countRef.current")]),t._v(" 的值仍然是 0。這是因為 "),s("code",[t._v("useRef")]),t._v(" 返回的 ref 對象在組件的"),s("strong",[t._v("整個生命周期")]),t._v("內保持不變,而 "),s("code",[t._v("useState")]),t._v(" 會在每次渲染時返回一個新的 state 值。")]),t._v(" "),s("ul",[s("li",[t._v("修改"),s("code",[t._v("dom")]),t._v("的值")])]),t._v(" "),s("ol",[s("li",[t._v("變量引用的方式 - 在"),s("code",[t._v("

    ")]),t._v("元素上使用 ref 属性,将 h1Ref 引用对象与该 DOM 元素关联。这样,"),s("code",[t._v("h1Ref.current")]),t._v(" 就可以访问到这个 DOM 元素。")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" h1Ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleClick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n h1Ref"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("innerHTML "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("h1Ref"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Hello React!")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleClick"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Change the h1")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[t._v("在这个 React 函数组件中,要注意渲染和拿到值的顺序如下:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("在组件渲染之初,会创建一个"),s("code",[t._v("h1Ref")]),t._v("引用对象,并初始化为"),s("code",[t._v("null")]),t._v("。在元素上使用 ref 属性,将"),s("code",[t._v("h1Ref")]),t._v("引用对象与该 DOM 元素关联。这样,"),s("code",[t._v("h1Ref.current")]),t._v("就可以访问到这个 DOM 元素。")])]),t._v(" "),s("li",[s("p",[t._v("渲染阶段:React 会首先渲染组件的 UI,包括 元素和按钮。此时,"),s("code",[t._v("h1Ref")]),t._v("仍然是"),s("code",[t._v("null")]),t._v('。当页面首次渲染时, 元素的内容显示为"Hello React!"。')])]),t._v(" "),s("li",[s("p",[t._v("用户点击按钮后,触发"),s("code",[t._v("handleClick")]),t._v("函数。")])]),t._v(" "),s("li",[s("p",[t._v("在"),s("code",[t._v("handleClick")]),t._v("函数内部,通过"),s("code",[t._v("h1Ref.current")]),t._v("来访问引用的 DOM 元素,尝试修改其"),s("code",[t._v("innerHTML")]),t._v("属性为"),s("code",[t._v('"Hello World!"。')])])]),t._v(" "),s("li",[s("p",[t._v("由于 React 的生命周期,上述 DOM 修改是在组件的渲染完成后才执行的。这是因为 React 会在渲染阶段记录下需要进行的 DOM 更新操作,并在渲染完成后才执行这些操作,以确保性能和一致性。")])])]),t._v(" "),s("p",[t._v("所以,虽然在"),s("code",[t._v("handleClick")]),t._v("函数中访问了"),s("code",[t._v("h1Ref.current")]),t._v(',但实际的 DOM 操作是在渲染完成后才进行的。因此,当用户点击按钮时,页面上的 元素会被修改为"Hello World!"。这就是 React 的渲染和 DOM 更新机制的基本工作原理。')])])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("回調函數的方式")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("App")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" h1Ref "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleClick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n h1Ref"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("innerHTML "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("thisDom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("thisDom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n thisDom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("style"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("background "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"green"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n h1Ref"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" thisDom"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Update the reference of h1Ref")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n Hello React!\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleClick"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Change the h1")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("code",[t._v("useRef")]),t._v("的回调函数方式来引用 DOM 元素并修改其样式。")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("在"),s("code",[t._v("

    ")]),t._v("元素上使用"),s("code",[t._v("ref")]),t._v("属性,传递一个回调函数。这个回调函数接收一个参数"),s("code",[t._v("thisDom")]),t._v(",它代表了"),s("code",[t._v("

    ")]),t._v("元素的 DOM 对象。")])]),t._v(" "),s("li",[s("p",[t._v("在回调函数中,首先检查"),s("code",[t._v("thisDom")]),t._v("是否存在,以防止在某些情况下为"),s("code",[t._v("null")]),t._v("。如果"),s("code",[t._v("thisDom")]),t._v("存在,就在其中设置样式"),s("code",[t._v("background")]),t._v("为'green'。")])]),t._v(" "),s("li",[s("p",[t._v("然后,通过"),s("code",[t._v("h1Ref.current = thisDom")]),t._v("来更新"),s("code",[t._v("h1Ref")]),t._v("的引用,以确保"),s("code",[t._v("h1Ref")]),t._v("引用的始终是当前的 DOM 元素。")])])]),t._v(" "),s("p",[t._v("现在,当组件渲染时,"),s("code",[t._v("

    ")]),t._v("元素的背景颜色会被设置为绿色,并且你仍然可以使用"),s("code",[t._v("h1Ref.current")]),t._v("来访问它以进行其他操作。")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/51.a1a8ca8d.js b/assets/js/51.a1a8ca8d.js new file mode 100644 index 00000000..2910a214 --- /dev/null +++ b/assets/js/51.a1a8ca8d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{341:function(t,a,r){"use strict";r.r(a);var s=r(14),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"⚪️-typescript-深い理解と実践"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-typescript-深い理解と実践"}},[t._v("#")]),t._v(" ⚪️ Typescript 深い理解と実践")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-1-start-here"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-1-start-here"}},[t._v("#")]),t._v(" 🔸 Chapter 1: Start Here")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-2-basic-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-2-basic-types"}},[t._v("#")]),t._v(" 🔸 Chapter 2: Basic Types")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-3-arrays-objects"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-3-arrays-objects"}},[t._v("#")]),t._v(" 🔸 Chapter 3: Arrays & Objects")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-4-functions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-4-functions"}},[t._v("#")]),t._v(" 🔸 Chapter 4: Functions")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-5-assertions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-5-assertions"}},[t._v("#")]),t._v(" 🔸 Chapter 5: Assertions")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-6-classes"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-6-classes"}},[t._v("#")]),t._v(" 🔸 Chapter 6: Classes")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-7-index-signatures-keyof-assertions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-7-index-signatures-keyof-assertions"}},[t._v("#")]),t._v(" 🔸 Chapter 7: Index Signatures & keyof Assertions")]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-8-generics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-8-generics"}},[t._v("#")]),t._v(" 🔸 Chapter 8: Generics")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://chodocs.cn/ts/ch4.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("泛型-chocolate blog"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:""}},[t._v("dave gray")])]),t._v(" "),a("h2",{attrs:{id:"🔸-chapter-9-utility-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#🔸-chapter-9-utility-types"}},[t._v("#")]),t._v(" 🔸 Chapter 9: Utility Types")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/52.19d2519d.js b/assets/js/52.19d2519d.js new file mode 100644 index 00000000..f6ae2756 --- /dev/null +++ b/assets/js/52.19d2519d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{343:function(e,t,a){"use strict";a.r(t);var s=a(14),n=Object(s.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"⚪️-webpack-深い理解と実践"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#⚪️-webpack-深い理解と実践"}},[e._v("#")]),e._v(" ⚪️ Webpack 深い理解と実践")]),e._v(" "),t("h2",{attrs:{id:"🔶-webpack-とは"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔶-webpack-とは"}},[e._v("#")]),e._v(" 🔶 Webpack とは?")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("Webpack は複数の JavaScript ファイルを一つのファイルにまとめて出力するツールです。この「一つのファイルにまとめる」ことをバンドル(bundle)と言い、また「モジュールを一つのファイルにまとめて出力するツール」のことをモジュールバンドラー(module bundler)と呼びます。")])]),e._v(" "),t("li",[t("p",[e._v("公式 Document で Webpack は、👇 のように静的モジュールバンドラーと紹介されています。")])]),e._v(" "),t("li",[t("p",[e._v("webpack is a static module bundler for modern JavaScript applications")])]),e._v(" "),t("li",[t("p",[e._v("公式には 👇 のような図が記載されています。バンドルの雰囲気がわかりやすいですね。\n"),t("a",{attrs:{href:"https://webpack.js.org/concepts/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Concepts | webpack"),t("OutboundLink")],1)])])]),e._v(" "),t("h2",{attrs:{id:"🔶-なぜ-webpack-を使うのか"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔶-なぜ-webpack-を使うのか"}},[e._v("#")]),e._v(" 🔶 なぜ Webpack を使うのか?")]),e._v(" "),t("p",[e._v("複数の JavaScript ファイルを一つにまとめることで、ブラウザからのリクエスト数を減らし、ファイル転送の最適化が可能です。これが Webpack などのモジュールバンドラーを使う大きな理由です。")]),e._v(" "),t("p",[e._v("JavaScript ファイルが複数存在することでリクエスト回数が増えて転送効率が落ちるのであれは、最初から一つのファイルに記載することも可能ですが、可読性や保守性などの観点から現実的でありません。また、機能を複数ファイルに分割したままだと、ブラウザからのリクエスト回数が増えてファイル転送効率が落ちます。こういったつらみに対して、Webpack を利用することで機能をファイルごとに分割しながら開発し、実行時は一つのファイルとしてブラウザに提供することが可能となります。")]),e._v(" "),t("p",[e._v("👇 の記事では、dev ツールで実際のファイルサイズを細かく見ながら、Webpack のメリットについて言及されていますので、参考までに。\n"),t("a",{attrs:{href:"https://dev.to/bruno8moura/why-am-i-using-the-webpack-tool-4h14",target:"_blank",rel:"noopener noreferrer"}},[e._v("Why am'I using the webpack tool?"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://webpack.js.org/api/cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn more about the CLI!"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://webpack.js.org/api/module-methods",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn more about modules!"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://webpack.js.org/api/node",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn more about the Node API!"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://webpack.js.org/api/loaders",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn more about loaders!"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://webpack.js.org/api/plugins",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn more about plugins!"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"🔶-webpack-の詳細"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#🔶-webpack-の詳細"}},[e._v("#")]),e._v(" 🔶 Webpack の詳細?")]),e._v(" "),t("h3",{attrs:{id:"▫️-loader-for-different-resource-types"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-loader-for-different-resource-types"}},[e._v("#")]),e._v(" ▫️ Loader for Different Resource Types")]),e._v(" "),t("p",[e._v("Webpack uses loaders for different resource types, such as:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("CSS:")]),e._v(" "),t("code",[e._v("css-loader")]),e._v(", "),t("code",[e._v("style-loader")])]),e._v(" "),t("li",[t("strong",[e._v("Less:")]),e._v(" "),t("code",[e._v("less-loader")])]),e._v(" "),t("li",[t("strong",[e._v("Sass:")]),e._v(" "),t("code",[e._v("sass-loader")])]),e._v(" "),t("li",[t("strong",[e._v("JavaScript:")]),e._v(" "),t("code",[e._v("ts-loader")]),e._v(", "),t("code",[e._v("babel-loader")])]),e._v(" "),t("li",[t("strong",[e._v("Vue:")]),e._v(" "),t("code",[e._v("vue-loader")])]),e._v(" "),t("li",[t("strong",[e._v("Static Resources:")]),e._v(" "),t("code",[e._v("url-loader")]),e._v(" (images, audio, video), "),t("code",[e._v("file-loader")]),e._v(" (files), "),t("code",[e._v("json-loader")]),e._v(" (JSON)")])]),e._v(" "),t("h3",{attrs:{id:"▫️-basic-functions-of-webpack-using-loaders"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-basic-functions-of-webpack-using-loaders"}},[e._v("#")]),e._v(" ▫️ Basic Functions of Webpack (Using Loaders)")]),e._v(" "),t("ol",[t("li",[t("strong",[e._v("Code Transformation:")]),e._v(" TypeScript to JavaScript, ES6 to ES5, SCSS to CSS, etc.")]),e._v(" "),t("li",[t("strong",[e._v("Code Syntax Checking:")]),e._v(" Automatic code syntax checking using "),t("code",[e._v("eslint-loader")]),e._v(".")]),e._v(" "),t("li",[t("strong",[e._v("Code Splitting:")]),e._v(" Splitting code into chunks for on-demand loading, reducing initialization time, and improving first-screen rendering efficiency.")]),e._v(" "),t("li",[t("strong",[e._v("Automatic Compilation and Page Refresh:")]),e._v(" Automatically compile and refresh the page on local source code changes.")]),e._v(" "),t("li",[t("strong",[e._v("Automatic Deployment (Not commonly used):")]),e._v(" Automatically build and deploy code to the production system.")]),e._v(" "),t("li",[t("strong",[e._v("File Compression:")]),e._v(" Compress JavaScript, CSS, and HTML files to reduce file size.")]),e._v(" "),t("li",[t("strong",[e._v("Module Concatenation:")]),e._v(" Merge modules into a single file during compilation.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-two-key-features-of-webpack"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-two-key-features-of-webpack"}},[e._v("#")]),e._v(" ▫️ Two Key Features of Webpack")]),e._v(" "),t("ol",[t("li",[t("strong",[e._v("Code Splitting:")]),e._v(" Breaks down code into chunks for on-demand loading, reducing initialization time.")]),e._v(" "),t("li",[t("strong",[e._v("Loader:")]),e._v(" Handles various types of static files and supports chaining operations.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-webpack-configuration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-webpack-configuration"}},[e._v("#")]),e._v(" ▫️ Webpack Configuration")]),e._v(" "),t("p",[e._v("Webpack runs in the Node.js environment, and its configuration file ("),t("code",[e._v("webpack.config.js")]),e._v(") follows the CommonJS pattern. It exports a JSON object with the following basic configuration options:")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("entry")]),e._v(": Specifies the entry point of the modules.")]),e._v(" "),t("li",[t("code",[e._v("output")]),e._v(": Configures output file locations, names, and base paths.")]),e._v(" "),t("li",[t("code",[e._v("module")]),e._v(": Configures rules for different file types.")]),e._v(" "),t("li",[t("code",[e._v("resolve")]),e._v(": Configures aliases or module resolution rules.")]),e._v(" "),t("li",[t("code",[e._v("plugins")]),e._v(": Configures additional plugins to extend Webpack's functionality.")]),e._v(" "),t("li",[t("code",[e._v("devServer")]),e._v(": Implements local HTTP server features.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-webpack-build-process"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-webpack-build-process"}},[e._v("#")]),e._v(" ▫️ Webpack Build Process")]),e._v(" "),t("ol",[t("li",[e._v("Start from the entry point and recursively transform dependent modules.")]),e._v(" "),t("li",[e._v("For each module found, use the corresponding loader to transform it.")]),e._v(" "),t("li",[e._v("Continue transforming the dependencies of the current module until there are no more dependencies.")]),e._v(" "),t("li",[e._v("Group modules by entry point, creating chunks.")]),e._v(" "),t("li",[e._v("Convert all chunks into output files.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-common-plugins"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-common-plugins"}},[e._v("#")]),e._v(" ▫️ Common Plugins")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("html-webpack-plugin:")]),e._v(" Generates HTML pages based on a template.")]),e._v(" "),t("li",[t("strong",[e._v("clean-webpack-plugin:")]),e._v(" Cleans specified directories.")]),e._v(" "),t("li",[t("strong",[e._v("copy-webpack-plugin:")]),e._v(" Copies files.")]),e._v(" "),t("li",[t("strong",[e._v("uglifyjs-webpack-plugin:")]),e._v(" Minifies JavaScript code.")]),e._v(" "),t("li",[t("strong",[e._v("mini-css-extract-plugin:")]),e._v(" Extracts CSS into separate files.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-difference-between-loader-and-plugin"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-difference-between-loader-and-plugin"}},[e._v("#")]),e._v(" ▫️ Difference Between Loader and Plugin")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Loader:")]),e._v(" Acts as a translator, transforming non-JavaScript resources during the build process.")]),e._v(" "),t("li",[t("strong",[e._v("Plugin:")]),e._v(" Extends Webpack's functionality by listening to events and altering the output.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-webpack-hot-module-replacement-hmr-principle"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-webpack-hot-module-replacement-hmr-principle"}},[e._v("#")]),e._v(" ▫️ Webpack Hot Module Replacement (HMR) Principle")]),e._v(" "),t("p",[e._v("HMR allows modules to be replaced without refreshing the entire page. The key steps include establishing a WebSocket connection, monitoring file changes, and notifying the client about the changes.")]),e._v(" "),t("h3",{attrs:{id:"▫️-webpack-build-speed-optimization"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-webpack-build-speed-optimization"}},[e._v("#")]),e._v(" ▫️ Webpack Build Speed Optimization")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("Use the latest Webpack and Node.js versions.")])]),e._v(" "),t("li",[t("p",[e._v("Minify code using plugins like "),t("code",[e._v("uglifyjs-webpack-plugin")]),e._v(".")])]),e._v(" "),t("li",[t("p",[e._v("Utilize multiple threads or processes for building (e.g., "),t("code",[e._v("thread-loader")]),e._v(" or "),t("code",[e._v("HappyPack")]),e._v(").")])]),e._v(" "),t("li",[t("p",[e._v("Narrow down the scope of file resolution.")])]),e._v(" "),t("li",[t("p",[e._v("Leverage caching for faster secondary builds.")])]),e._v(" "),t("li",[t("p",[e._v("Implement Tree Shaking to eliminate unused code.")])]),e._v(" "),t("li",[t("p",[e._v("Optimize module dependencies using Scope Hoisting.")])]),e._v(" "),t("li",[t("p",[e._v("Use CDN for basic packages to reduce bundle size.")])]),e._v(" "),t("li",[t("p",[e._v("Separate CSS from JavaScript using "),t("code",[e._v("mini-css-extract-plugin")]),e._v(".")])]),e._v(" "),t("li",[t("p",[t("a",{attrs:{href:"https://loadable-components.com/docs/getting-started/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Loadable Components"),t("OutboundLink")],1)])])]),e._v(" "),t("h3",{attrs:{id:"▫️-webpack-bundle-analyzer"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-webpack-bundle-analyzer"}},[e._v("#")]),e._v(" ▫️ webpack-bundle-analyzer")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://qiita.com/kurosame/items/9e7092cdf08ff2ba7500",target:"_blank",rel:"noopener noreferrer"}},[e._v("webpack を可視化するツールを紹介"),t("OutboundLink")],1)]),e._v(" "),t("h3",{attrs:{id:"basic-steps-for-configuring-and-using-webpack-bundle-analyzer"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#basic-steps-for-configuring-and-using-webpack-bundle-analyzer"}},[e._v("#")]),e._v(" Basic Steps for Configuring and Using webpack-bundle-analyzer:")]),e._v(" "),t("ol",[t("li",[t("p",[e._v("Install the webpack-bundle-analyzer plugin using the following command in your project directory:")]),e._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[e._v("npm")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" --save-dev webpack-bundle-analyzer\n")])])])]),e._v(" "),t("li",[t("p",[e._v("In your webpack configuration file (e.g., webpack.config.js), import the webpack-bundle-analyzer plugin:")]),e._v(" "),t("div",{staticClass:"language-javascript extra-class"},[t("pre",{pre:!0,attrs:{class:"language-javascript"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("const")]),e._v(" BundleAnalyzerPlugin "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("require")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"webpack-bundle-analyzer"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("BundleAnalyzerPlugin"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])])]),e._v(" "),t("li",[t("p",[e._v("Add a new instance of BundleAnalyzerPlugin to the "),t("code",[e._v("plugins")]),e._v(" property in your webpack configuration file:")]),e._v(" "),t("div",{staticClass:"language-javascript extra-class"},[t("pre",{pre:!0,attrs:{class:"language-javascript"}},[t("code",[e._v("module"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("exports "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// ...")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("plugins")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("new")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BundleAnalyzerPlugin")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// ...")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])])]),e._v(" "),t("li",[t("p",[e._v("Save your webpack configuration file and run your webpack build command. After the build is complete, webpack-bundle-analyzer will open a page on a server where you can view detailed analysis results.")])])]),e._v(" "),t("h3",{attrs:{id:"▫️-conditional-usage-in-development-environment"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-conditional-usage-in-development-environment"}},[e._v("#")]),e._v(" ▫️ Conditional Usage in Development Environment:")]),e._v(" "),t("div",{staticClass:"language-javascript extra-class"},[t("pre",{pre:!0,attrs:{class:"language-javascript"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("const")]),e._v(" BundleAnalyzerPlugin "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("require")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"webpack-bundle-analyzer"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("BundleAnalyzerPlugin"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("let")]),e._v(" plugins "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("if")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("process"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("env"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("NODE_ENV")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("===")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"development"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n plugins"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("push")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("new")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BundleAnalyzerPlugin")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\nmodule"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("exports "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("//...")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("plugins")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" plugins"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("//...")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])]),t("p",[e._v("In this code, the "),t("code",[e._v("BundleAnalyzerPlugin")]),e._v(" is added to the "),t("code",[e._v("plugins")]),e._v(" array only when the "),t("code",[e._v("NODE_ENV")]),e._v(" is set to 'development'. This helps in avoiding the generation of additional data in the production environment.")]),e._v(" "),t("h3",{attrs:{id:"▫️-detailed-configuration-options-for-bundleanalyzerplugin"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-detailed-configuration-options-for-bundleanalyzerplugin"}},[e._v("#")]),e._v(" ▫️ Detailed Configuration Options for BundleAnalyzerPlugin:")]),e._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("new")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BundleAnalyzerPlugin")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Accepts a string to specify the format and channel of the generated report. It can be 'server', 'static', or 'disabled'.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'server' starts an HTTP server to provide an interactive report view, defaulting to localhost:8888.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'static' generates a single HTML file to describe the report.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'disabled' can be useful in some scenarios to temporarily disable the plugin while keeping the configuration code.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("analyzerMode")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"server"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// In 'server' mode, defines the hostname for the HTTP server.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("analyzerHost")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"127.0.0.1"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// In 'server' mode, defines the port number for the HTTP server.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("analyzerPort")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("8888")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// In 'static' mode, defines the filename for the generated report.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("reportFilename")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"report.html"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Defines the method for calculating module sizes. Can be 'stat', 'parsed', or 'gzip'.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'stat' describes the size before any code is parsed (size between modules).")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'parsed' describes the size of all parsed code (code that has been processed and parsed by loaders).")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// 'gzip' describes the gzip size of all parsed code (if this value is defined).")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("defaultSizes")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"parsed"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Specifies whether a module should be shown. You can use this option to hide unnecessary modules.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// You can pass a function that takes a module as a parameter and returns a boolean value.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("filterModules")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// If you want the content of the generated report file to be a custom data structure, you can pass a function.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// This function receives stats data as a parameter and should return a serialized JSON object or a Promise.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("generateStatsFile")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// If you want to customize the filename of the generated stats file, you can modify this option.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("statsFilename")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"stats.json"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Defines whether to generate a report when generating stats files.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("statsOptions")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Defines a logging function.")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("logLevel")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"info"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])]),t("ul",[t("li",[t("code",[e._v("analyzerMode")]),e._v(": Specifies the format and channel for report generation ('server', 'static', or 'disabled').")]),e._v(" "),t("li",[t("code",[e._v("analyzerHost")]),e._v(" and "),t("code",[e._v("analyzerPort")]),e._v(": Define the hostname and port for the HTTP server in 'server' mode.")]),e._v(" "),t("li",[t("code",[e._v("reportFilename")]),e._v(": Specifies the filename for the generated report in 'static' mode.")]),e._v(" "),t("li",[t("code",[e._v("defaultSizes")]),e._v(": Defines how module sizes should be calculated ('stat', 'parsed', or 'gzip').")]),e._v(" "),t("li",[t("code",[e._v("filterModules")]),e._v(": A function to determine whether a module should be displayed in the report.")]),e._v(" "),t("li",[t("code",[e._v("generateStatsFile")]),e._v(": Allows customization of the generated stats file content using a function.")]),e._v(" "),t("li",[t("code",[e._v("statsFilename")]),e._v(": Specifies the filename for the generated stats file.")]),e._v(" "),t("li",[t("code",[e._v("statsOptions")]),e._v(": Defines options for generating stats files.")]),e._v(" "),t("li",[t("code",[e._v("logLevel")]),e._v(": Defines the log level for the plugin.")])]),e._v(" "),t("h3",{attrs:{id:"▫️-reference-links"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#▫️-reference-links"}},[e._v("#")]),e._v(" ▫️ Reference Links:")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://qiita.com/wataru86/items/7d0804a5651b1777691b",target:"_blank",rel:"noopener noreferrer"}},[e._v("webpack-bundle-analyzer から始めるフロントエンドのパフォーマンス改善入門"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://webpack.js.org/guides/getting-started/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Getting Started"),t("OutboundLink")],1),e._v(" -"),t("a",{attrs:{href:"https://zenn.dev/antez/articles/58307946cf4f3e",target:"_blank",rel:"noopener noreferrer"}},[e._v("やっぱり webpack がわからない(エピソード 1)"),t("OutboundLink")],1),e._v(" -"),t("a",{attrs:{href:"https://qiita.com/tanimoto-hikari/items/c718476294480330f929",target:"_blank",rel:"noopener noreferrer"}},[e._v("webpack はちゃんと理解しておいたほうがいい(導入時の Tips 付き"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/53.891befed.js b/assets/js/53.891befed.js new file mode 100644 index 00000000..0bfb4df0 --- /dev/null +++ b/assets/js/53.891befed.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{342:function(t,s,n){"use strict";n.r(s);var r=n(14),a=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"プラクティス"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#プラクティス"}},[this._v("#")]),this._v(" プラクティス")])])}),[],!1,null,null,null);s.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/54.b3d8b254.js b/assets/js/54.b3d8b254.js new file mode 100644 index 00000000..7ddb801a --- /dev/null +++ b/assets/js/54.b3d8b254.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{345:function(t,n,s){"use strict";s.r(n);var e=s(14),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/55.a4b8b234.js b/assets/js/55.a4b8b234.js new file mode 100644 index 00000000..17e61386 --- /dev/null +++ b/assets/js/55.a4b8b234.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{348:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"react-and-typescript-shopping-cart-application"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#react-and-typescript-shopping-cart-application"}},[t._v("#")]),t._v(" React and TypeScript Shopping Cart Application")]),t._v(" "),s("h2",{attrs:{id:"🔷-cartprovider-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-cartprovider-component"}},[t._v("#")]),t._v(" 🔷 CartProvider Component")]),t._v(" "),s("blockquote",[s("p",[t._v("path: "),s("code",[t._v("src/Context/CartProvider.tsx")])])]),t._v(" "),s("h3",{attrs:{id:"_1-type-definitions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-type-definitions"}},[t._v("#")]),t._v(" 1. Type Definitions")]),t._v(" "),s("blockquote",[s("p",[t._v("CartItemType")])]),t._v(" "),s("p",[t._v("Defines the structure of a single shopping cart item.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CartItemType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sku"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n qty"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("CartStateType")])]),t._v(" "),s("p",[t._v("Defines the type for the shopping cart state.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CartStateType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-action-types-definition"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-action-types-definition"}},[t._v("#")]),t._v(" 2. Action Types Definition")]),t._v(" "),s("blockquote",[s("p",[t._v("REDUCER_ACTION_TYPE")])]),t._v(" "),s("p",[t._v("An object defining various action types for updating the state.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ADD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REMOVE")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"REMOVE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("QUANTITY")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"QUANTITY"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SUBMIT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUBMIT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ReducerActionType")])]),t._v(" "),s("p",[t._v("Extracts the type of "),s("code",[t._v("REDUCER_ACTION_TYPE")]),t._v(" object.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ReducerActionType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ReducerAction")])]),t._v(" "),s("p",[t._v("Defines the structure of the action object expected by the reducer function.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ReducerAction")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n payload"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_3-reducer-function"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-reducer-function"}},[t._v("#")]),t._v(" 3. Reducer Function")]),t._v(" "),s("blockquote",[s("p",[t._v("reducer")])]),t._v(" "),s("p",[t._v("A core function that handles changes in the shopping cart state.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("reducer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReducerAction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...switch case statements")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_4-custom-hook-usecartcontext"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-custom-hook-usecartcontext"}},[t._v("#")]),t._v(" 4. Custom Hook: useCartContext")]),t._v(" "),s("blockquote",[s("p",[t._v("useCartContext")])]),t._v(" "),s("p",[t._v("A custom React Hook providing a context related to the shopping cart.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("useCartContext")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialCartState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...hook implementation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_5-react-context-and-provider"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-react-context-and-provider"}},[t._v("#")]),t._v(" 5. React Context and Provider")]),t._v(" "),s("blockquote",[s("p",[t._v("CartContext")])]),t._v(" "),s("p",[t._v("Creates a React Context to share the shopping cart state across components.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CartContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("UseCartContextType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n initalCartContextState\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("CartProvider")])]),t._v(" "),s("p",[t._v("A React component using "),s("code",[t._v("useCartContext")]),t._v(" Hook and "),s("code",[t._v("CartContext.Provider")]),t._v(" to provide the shopping cart context to the application.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CartProvider "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" children "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChildrenType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...provider implementation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"usage-instructions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usage-instructions"}},[t._v("#")]),t._v(" Usage Instructions")]),t._v(" "),s("p",[t._v("Use "),s("code",[t._v("useContext(CartContext)")]),t._v(" in components that need to access or modify the shopping cart state.\nExample: To add an item to the cart, use "),s("code",[t._v("dispatch({ type: 'ADD', payload: newItem })")]),t._v(".")]),t._v(" "),s("h3",{attrs:{id:"🔻-cartprovider-code-review"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔻-cartprovider-code-review"}},[t._v("#")]),t._v(" 🔻 CartProvider Code review")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//path: src/context/CartProvider.tsx")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" createContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useMemo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useReducer "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//用於描述單個購物車項目的結構。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CartItemType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\nsku"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nname"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nprice"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nqty"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//1. 定義購物車相關的 TypeScript 類型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//定義購物車狀態類型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//它是一個包含單個屬性 cart 的對象,而 cart 是一個 CartItemType[] 類型的數組。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CartStateType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialCartState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//2. 定義用於更新購物車狀態的 Action 類型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//2.1 這是一個對象,其中定義了用於更新狀態的各種 action 的類型。如 ADD,REMOVE,QUANTITY,SUBMIT。 這些是你將在應用中用來描述發生的事件的常量。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ADD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REMOVE")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"REMOVE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("QUANTITY")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"QUANTITY"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SUBMIT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUBMIT"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//2.2 通過 typeof 獲取 REDUCER_ACTION_TYPE 的對象的類型,並將這個類型導出為 ReducerActionType。 這樣做的好處是你獲得了一個精確的類型,代表 REDUCER_ACTION_TYPE 的結構,而不僅僅是一個簡單的對象。這在 TypeScript 中有助於提高類型安全性和自動完成。")]),t._v("\n\n\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ReducerActionType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//2.3 定義了傳遞給 reducer 函數的 action 對象的結構。 包含 type(動作類型)和 payload(附加數據,可選)。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//這是另一個 TypeScript 類型定義,用於描述 reducer 函數期望接收的 action 對象的結構。每個 action 都有一個 type 屬性,它是一個字符串,應對應於 REDUCER_ACTION_TYPE 中定義的一個值。payload 是一個可選屬性,包含了任何附加的數據(在這種情況下是 CartItemType)。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ReducerAction")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\ntype"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\npayload"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//3. Reducer 函數")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//3.1 Reducer Function (reducer): 這是核心功能之一,用於處理購物車狀態的變化。它根據不同的動作(添加、移除、修改數量、提交)來更新狀態。這種方式能夠集中管理狀態的變更,是 Redux 架構中的一部分。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("reducer")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReducerAction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"action.payload missing in ADD action"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//如果 sku 不等于给定的值,这个元素就会被保留在新数组 filteredCart 中,否则将被排除。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" sku\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemExisted"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" sku\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" qty"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" itemExisted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" itemExisted"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("filteredCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" qty "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REMOVE")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"action.payload missing in REMOVE action"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" sku "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" sku\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("filteredCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//然后,它创建一个名为 updatedItem 的对象,该对象是购物车中现有商品的副本,但具有更新的 qty。最后,它创建一个名为 filteredCart 的新数组,其中包含所有其他商品,但不包括要更新的商品。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("QUANTITY")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"action.payload missing in QUANTITY action"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" qty "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemExists"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("undefined")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" sku\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("itemExists"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"item must exist in order to update quantity"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建一个更新后的商品对象")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" updatedItem"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("itemExists"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" qty "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建一个新的购物车数组,其中包括更新后的商品")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" filteredCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartItemType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" sku\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("filteredCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updatedItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// map 方法 : 创建一个新的购物车数组,其中包括更新后的商品")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// const filteredCart: CartItemType[] = state.cart.map((item) =>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// item.sku === sku ? updatedItem : item")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// );")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回更新后的购物车状态")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return { ...state, cart: filteredCart };")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SUBMIT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unidentified reducer action type"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4. 自定義 Hook:useCartContext")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\\"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\\"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("使用 useReducer 來管理購物車狀態。\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("用 useMemo 來緩存計算結果("),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),t._v(")。\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("計算購物車的總數量和總價格。\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("對購物車中的商品進行排序。\\"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//useCartContext 是一个自定义的 React Hook,它的作用是为你的应用程序提供一个与购物车相关的上下文。这个上下文包含了购物车的状态以及与购物车操作相关的函数,例如添加商品、删除商品、更新商品数量等。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//自定義 Hook 如 useCartContext 被用來封裝和共享邏輯,相同的邏輯可以在應用中的多個地方使用,而不必重複相同的代碼。 useCartContext 接受一个参数 initialCartState,它是购物车的初始状态,包含一个空的购物车数组。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("useCartContext")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialCartState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initialCartState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//useMemo 主要用于缓存计算结果,并在依赖项(dependencies)发生变化时重新计算。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useMemo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalPrice "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Intl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("NumberFormat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en-US"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\nstyle"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"currency"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\ncurrency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\nstate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty \\"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这段代码的作用是对购物车中的商品进行排序,排序的规则是按照商品的 sku 属性的后四位数字进行升序排序。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//分别提取了商品 a 和 b 的 sku 属性的后四位数字部分。这些数字会被转换成数值类型。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//表示根据提取出的数字进行升序排序,即如果 itemA 小于 itemB,返回负数;如果 itemA 等于 itemB,返回零;如果 itemA 大于 itemB,返回正数。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" itemB"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalPrice"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//这里使用了 TypeScript 的 ReturnType 工具类型,它用于获取一个函数返回值的类型 。typeof useCartContext 表示获取 useCartContext 函数的类型,ReturnType 则是这个函数返回值的类型。这个类型被用作下面 CartContext 的类型参数。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//返回值是什么 : useCartContext Hook 的返回值是一个对象,包含了与购物车相关的数据和函数。这通常包括购物车的状态(如商品列表、总价等)以及用于更新这些状态的方法(如 dispatch 方法)。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UseCartContextType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReturnType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" useCartContext"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//Context and Provider (CartContext 和 CartProvider): 這個部分創建了一個 React Context 來跨組件共享購物車的狀態和操作。CartProvider 組件則將這個上下文應用於應用程序的根組件。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//这里定义了初始的上下文状态。initalCartContextState 符合 UseCartContextType 类型,包含了 dispatch 函数、REDUCER_ACTIONS 常量、以及一些购物车相关的状态如 totalItems、totalPrice 和 cart。dispatch 函数是一个空函数,表示在默认情况下不执行任何操作。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initalCartContextState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UseCartContextType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\ntotalItems"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\ntotalPrice"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\ncart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//5. React Context 和 Provider")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 創建一個 React Context,允許跨組件共享購物車狀態。 用於在應用程序中提供購物車的狀態和操作。其他組件可以使用這個 Context 來訪問購物車的狀態。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//const SomeContext = createContext(defaultValue)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CartContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("UseCartContextType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\ninitalCartContextState\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChildrenType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\nchildren"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//使用 CartContext.Provider 來將 useCartContext 的返回值作為上下文值提供給其子組件。 CartProvider 組件:這是一個 React 組件,它使用 useCartContext Hook 並通過 CartContext.Provider 提供購物車上下文給應用程序。它包裝了應用程序的根組件,使購物車上下文對整個應用程序可用。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CartProvider "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" children "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChildrenType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CartContext.Provider")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCartContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialCartState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("children"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//使用 Custom Hook 和 Context:")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//在需要訪問或修改購物車狀態的組件中,使用 useContext(CartContext) 來獲取購物車的狀態和 dispatch 函數。例如,如果需要向購物車中添加一個商品,可以使用 dispatch({ type: 'ADD', payload: newItem })。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" CartContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("_ 使用說明\n在需要訪問或修改購物車狀態的組件中,使用 "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CartContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" 來獲取購物車的狀態和 dispatch 函數。\n例如,添加商品到購物車可以使用 "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ADD'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" newItem "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("。 _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n\n")])])]),s("h2",{attrs:{id:"🔷-productsprovider-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-productsprovider-component"}},[t._v("#")]),t._v(" 🔷 ProductsProvider Component")]),t._v(" "),s("blockquote",[s("p",[t._v("path: "),s("code",[t._v("src/Context/ProductsProvider.tsx")])])]),t._v(" "),s("h3",{attrs:{id:"_1-type-definitions-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-type-definitions-2"}},[t._v("#")]),t._v(" 1. Type Definitions")]),t._v(" "),s("blockquote",[s("p",[t._v("ProductType")])]),t._v(" "),s("p",[t._v("Defines the structure of a product.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sku"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-initial-state"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-initial-state"}},[t._v("#")]),t._v(" 2. Initial State")]),t._v(" "),s("blockquote",[s("p",[t._v("initialState")])]),t._v(" "),s("p",[t._v("An array that holds the initial state of the product list.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_3-context-type-definition"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-context-type-definition"}},[t._v("#")]),t._v(" 3. Context Type Definition")]),t._v(" "),s("blockquote",[s("p",[t._v("UseProductsContextType")])]),t._v(" "),s("p",[t._v("Defines the shape of the context used for managing product information.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UseProductsContextType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_4-react-context-and-provider"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-react-context-and-provider"}},[t._v("#")]),t._v(" 4. React Context and Provider")]),t._v(" "),s("blockquote",[s("p",[t._v("ProductsContext")])]),t._v(" "),s("p",[t._v("Creates a React Context for sharing and managing product information globally.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductsContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("UseProductsContextType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialContextState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ProductsProvider")])]),t._v(" "),s("p",[t._v("A React component that provides the product context to the application using the "),s("code",[t._v("ProductsContext.Provider")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductsProvider "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" children "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChildrenType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...provider implementation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_5-fetching-and-updating-product-data"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-fetching-and-updating-product-data"}},[t._v("#")]),t._v(" 5. Fetching and Updating Product Data")]),t._v(" "),s("blockquote",[s("p",[t._v("useEffect Hook")])]),t._v(" "),s("p",[t._v("Fetches product data from an external source and updates the state.")]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Function to fetch products and error handling")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"usage-instructions-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usage-instructions-2"}},[t._v("#")]),t._v(" Usage Instructions")]),t._v(" "),s("p",[t._v("Use "),s("code",[t._v("useContext(ProductsContext)")]),t._v(" in components that need to access or modify the product information.\nExample: To access the list of products, use "),s("code",[t._v("const { products } = useContext(ProductsContext)")]),t._v(".")]),t._v(" "),s("p",[t._v("This Markdown note provides a structured overview of your React and TypeScript product management application, outlining type definitions, initial state, context and provider, along with instructions for fetching and updating product data.")]),t._v(" "),s("h3",{attrs:{id:"🔻-productsprovider-code-review"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔻-productsprovider-code-review"}},[t._v("#")]),t._v(" 🔻 ProductsProvider Code review")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("////这里定义了一个名为 ProductType 的 TypeScript")]),t._v("\n类型,该类型描述了产品的结构,包括sku(库存单位)、name(名称)和price(价格)等属性。\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" createContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useEffect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sku"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n price"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//const initState: ProductType[] = []")]),t._v("\n\n\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//这里定义了一个名为 initState的常量,它是一个数组,包含了一些产品对象。这个数组通常用于初始化应用程序的状态,可以在React的上下文中使用。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// export const initialState: ProductType[] = [")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// sku: "item0001",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// name: "Widget",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// price: 9.99,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// },")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// sku: "item0002",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// name: "Premium Widget",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// price: 19.99,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// },")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// sku: "item0003",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// name: "Deluxe Widget",')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// price: 29.99,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// },")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ];")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//它描述了一个用于管理产品信息的上下文的形状。具体来说,它包含一个属性(object) products,其值是一个 ProductType 类型的数组,用于存储产品信息。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UseProductsContextType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" initialContextState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UseProductsContextType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//最后,它创建了一个名为 ProductsContext 的上下文对象,使用了之前定义的 UseProductsContextType 类型作为泛型参数,并将初始状態initialContextState传递给createContext函数。这个上下文对象可以在应用程序中使用,用于共享和管理产品信息的全局状态。")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChildrenType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" children"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductsContext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createContext")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("UseProductsContextType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialContextState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ProductsProvider "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" children "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChildrenType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setProducts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fetchProducts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Promise")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost:3500/products"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Network response was not ok"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回产品数据")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用类型断言将 error 标记为 Error 类型")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 抛出错误,使外部可以捕获")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchProducts")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setProducts")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// eslint-disable-next-line @typescript-eslint/no-unused-vars")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("catch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在此处可以进一步处理错误,例如显示错误消息")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProductsContext.Provider")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" products "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("children"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" ProductsContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("ProductType[]")]),t._v("是一个表示产品数组的类型定义。而 "),s("code",[t._v("UseProductContextType")]),t._v("是另一个类型定义,它定义了一个对象,这个对象包含了一个名为"),s("code",[t._v("products")]),t._v("的字段,其类型为 "),s("code",[t._v("ProductType[]")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"🔷-hooks-useproducts-hook"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-hooks-useproducts-hook"}},[t._v("#")]),t._v(" 🔷 Hooks/useProducts Hook")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useContext "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" ProductsContext "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/ProductsProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" UseProductsContextType "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/ProductsProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" useProducts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UseProductsContextType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ProductsContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" useProducts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔷-hooks-usecart-hook"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-hooks-usecart-hook"}},[t._v("#")]),t._v(" 🔷 Hooks/useCart Hook")]),t._v(" "),s("blockquote",[s("p",[t._v("它的作用是简化了在组件中使用购物车上下文(CartContext)的过程。这个 Hook 返回了 CartContext 的值,使得在组件中访问购物车数据和操作更加直观和便捷。这种模式非常适用于将上下文的逻辑封装起来,以便在多个组件中重用。")])]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useContext "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" CartContext "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/CartProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" UseCartContextType "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/CartProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//通过指定返回类型为 UseCartContextType,这个 Hook 的使用者可以得到关于返回值的类型提示和校验。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" useCart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UseCartContextType "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useContext")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CartContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" useCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("hr"),t._v(" "),s("h2",{attrs:{id:"🔷-components-productlist"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-components-productlist"}},[t._v("#")]),t._v(" 🔷 components/ProductList")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" useCart "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../hooks/useCart"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" useProdudcts "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../hooks/useProducts"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Product "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Product"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("ProductList")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCart")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" products "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useProdudcts")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//使用 some 方法檢查:具體地,inCart 的值是通過檢查購物車(cart)中是否存在具有相同 sku 值的產品來確定的。這通過使用 Array.prototype.some 方法實現,這個方法會測試陣列中是否至少有一個元素滿足提供的函數。如果滿足條件(即購物車中已有相同 sku 的產品),則 inCart 為 true;否則,為 false。")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" pageContent"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Loading...")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("products"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pageContent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Product")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("product")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("inCart")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("main")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("main main--products"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("pageContent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" ProductList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"🔷-components-product"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🔷-components-product"}},[t._v("#")]),t._v(" 🔷 components/Product")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 引入所需的依賴和類型")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ProductType "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/ProductsProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ReducerActionType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ReducerAction "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../context/CartProvider"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" memo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定義 PropsType,用於描述 Product 組件的屬性")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PropsType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n product"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 產品信息")]),t._v("\n dispatch"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Dispatch"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ReducerAction"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 購物車操作的 dispatch 函數")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReducerActionType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 購物車操作的行為類型")]),t._v("\n inCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 產品是否已在購物車中的標記")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Product 組件定義")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Product "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n inCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" PropsType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 產品圖片的路徑")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" img"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("URL")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("../images/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(".jpg")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("meta"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("href"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("console")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("img"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加產品到購物車的事件處理函數")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onAddToCart")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" qty"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 如果產品已在購物車中,顯示標記")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemInCart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" inCart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" → Item in Cart: ✔️"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 產品的展示內容")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("article")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("h3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("img")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("src")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("img"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("alt")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("product__img"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Intl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("NumberFormat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en-US"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n style"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"currency"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("itemInCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("onAddToCart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Add to Cart")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 比較函數,用於優化性能,避免不必要的重新渲染")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("areProductsEqual")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" prevProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" inCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" prevInCart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" PropsType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" product"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" nextProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" inCart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" nextInCart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" PropsType\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("prevProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("every")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n prevProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v("\n nextProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("keyof")]),t._v(" ProductType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" prevInCart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" nextInCart\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 memo 包裝 Product 組件,優化渲染性能")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" MemoizedProduct "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memo")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" Product"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Product"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" areProductsEqual"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" MemoizedProduct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"トラブルシューティング"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#トラブルシューティング"}},[t._v("#")]),t._v(" トラブルシューティング")]),t._v(" "),s("h3",{attrs:{id:"▫️-usecartcontext-hooks"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usecartcontext-hooks"}},[t._v("#")]),t._v(" ▫️ useCartContext hooks")]),t._v(" "),s("blockquote",[s("p",[t._v("這段代碼定义了一个名为 "),s("code",[t._v("useCartContext")]),t._v(" 的自定义 React Hook。这个 Hook 使用了 React 的几个内置功能,如 "),s("code",[t._v("useReducer")]),t._v(" 和 "),s("code",[t._v("useMemo")]),t._v(",来管理和优化购物车应用的状态。下面是对每个部分的详细解释:")])]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("useCartContext")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("initialCartState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CartStateType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initialCartState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//useMemo 主要用于缓存计算结果,并在依赖项(dependencies)发生变化时重新计算。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useMemo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalPrice "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Intl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("NumberFormat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en-US"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n style"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"currency"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这段代码的作用是对购物车中的商品进行排序,排序的规则是按照商品的 sku 属性的后四位数字进行升序排序。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//分别提取了商品 a 和 b 的 sku 属性的后四位数字部分。这些数字会被转换成数值类型。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//表示根据提取出的数字进行升序排序,即如果 itemA 小于 itemB,返回负数;如果 itemA 等于 itemB,返回零;如果 itemA 大于 itemB,返回正数。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" itemB"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalPrice"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("useReducer")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initialCartState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("这里使用了 "),s("code",[t._v("useReducer")]),t._v(" Hook 来管理购物车的状态。"),s("code",[t._v("useReducer")]),t._v(" 是一个替代 "),s("code",[t._v("useState")]),t._v(" 的 Hook,适用于复杂的状态逻辑,可以让你根据 action 更新状态。")]),t._v(" "),s("li",[s("code",[t._v("reducer")]),t._v(" 是一个函数,定义了状态如何响应不同的 action 类型。")]),t._v(" "),s("li",[s("code",[t._v("initialCartState")]),t._v(" 是购物车的初始状态。")]),t._v(" "),s("li",[s("code",[t._v("state")]),t._v(" 代表当前的状态,"),s("code",[t._v("dispatch")]),t._v(" 是一个函数,用来发送 action 到 reducer。")])]),t._v(" "),s("blockquote",[s("p",[t._v("useMemo")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useMemo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("useMemo")]),t._v(" 用于缓存计算的结果。这里它被用来缓存 "),s("code",[t._v("REDUCER_ACTION_TYPE")]),t._v(" 对象。")]),t._v(" "),s("li",[t._v("依赖项数组("),s("code",[t._v("[]")]),t._v(")为空,这意味着 "),s("code",[t._v("REDUCER_ACTIONS")]),t._v(" 只会在组件首次渲染时计算一次。")])]),t._v(" "),s("blockquote",[s("p",[t._v("计算总数和总价")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalItems "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" totalPrice "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Intl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("NumberFormat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en-US"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n style"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"currency"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USD"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reduce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("previousValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" previousValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("qty "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" cartItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("这两个变量使用 "),s("code",[t._v("reduce")]),t._v(" 方法来计算购物车中商品的总数量 ("),s("code",[t._v("totalItems")]),t._v(") 和总价 ("),s("code",[t._v("totalPrice")]),t._v(")。")])]),t._v(" "),s("blockquote",[s("p",[t._v("对购物车商品进行排序")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" itemB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sku"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" itemA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" itemB"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("这段代码对购物车中的商品根据 "),s("code",[t._v("sku")]),t._v(" 的后四位数字进行升序排序。")])]),t._v(" "),s("blockquote",[s("p",[t._v("返回值")])]),t._v(" "),s("div",{staticClass:"language-typescript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-typescript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REDUCER_ACTIONS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalPrice"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" totalItems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cart "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("useCartContext")]),t._v(" 返回一个包含 "),s("code",[t._v("dispatch")]),t._v(" 函数、动作类型 ("),s("code",[t._v("REDUCER_ACTIONS")]),t._v(")、购物车总价 ("),s("code",[t._v("totalPrice")]),t._v(")、总数量 ("),s("code",[t._v("totalItems")]),t._v(") 和排序后的购物车商品列表 ("),s("code",[t._v("cart")]),t._v(") 的对象。")]),t._v(" "),s("li",[t._v("这个 Hook 可以被用于组件中,以便于访问和操作购物车的状态。")])]),t._v(" "),s("p",[t._v("总的来说,"),s("code",[t._v("useCartContext")]),t._v(" Hook 为购物车应用提供了一个集中的状态管理方案,使得状态的读取和更新更加方便和高效。")]),t._v(" "),s("h3",{attrs:{id:"▫️-usecartcontexttype"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#▫️-usecartcontexttype"}},[t._v("#")]),t._v(" ▫️ UseCartContextType")]),t._v(" "),s("blockquote",[s("p",[t._v("在 TypeScript 中定义 "),s("code",[t._v("UseCartContextType")]),t._v(" 类型作为 "),s("code",[t._v("ReturnType")]),t._v(" 的原因是为了确保类型安全和代码的清晰性。这里解释一下具体原因和用途:")])]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UseCartContextType")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ReturnType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typeof")]),t._v(" useCartContext"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("为什么要确定返回值的类型")])]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("类型安全")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("TypeScript 强类型系统的一个主要优点是它提供了类型安全。通过明确指定函数返回值的类型,你可以在编译时捕捉潜在的错误,而不是在运行时。")]),t._v(" "),s("li",[t._v("在这个案例中,"),s("code",[t._v("useCartContext")]),t._v(" 是一个自定义 Hook,它可能返回一个复杂的对象,包含多个属性和方法。使用 "),s("code",[t._v("ReturnType")]),t._v(" 可以确保你完全理解并正确处理这个 Hook 返回的数据结构。")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("自动推断")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("ReturnType")]),t._v(" 自动推断 "),s("code",[t._v("useCartContext")]),t._v(" Hook 的返回值类型。这意味着如果 "),s("code",[t._v("useCartContext")]),t._v(" 的实现更改了返回值的结构,"),s("code",[t._v("UseCartContextType")]),t._v(" 也会相应地更新,无需手动更改。")])]),t._v(" "),s("blockquote",[s("p",[t._v("返回值是什么")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("返回值")]),t._v(":")]),t._v(" "),s("li",[s("code",[t._v("useCartContext")]),t._v(" Hook 的返回值是一个对象,包含了与购物车相关的数据和函数。这通常包括购物车的状态(如商品列表、总价等)以及用于更新这些状态的方法(如 dispatch 方法)。")])]),t._v(" "),s("blockquote",[s("p",[t._v("在什么地方用")])]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("在 Context 提供者中")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("当你创建一个 Context 并且想要在整个应用中共享 "),s("code",[t._v("useCartContext")]),t._v(" 提供的数据和函数时,可以使用这个类型。例如,在 "),s("code",[t._v("CartProvider")]),t._v(" 组件中,你可能会将 "),s("code",[t._v("useCartContext")]),t._v(" 的返回值作为 Context 的值。")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("在消费者组件中")]),t._v(":")])]),t._v(" "),s("ul",[s("li",[t._v("组件可以通过 "),s("code",[t._v("useContext(CartContext)")]),t._v(" 使用这个类型来访问购物车的数据和操作函数。这样可以确保组件正确地使用了 Context 提供的数据,同时也享受到了 TypeScript 的类型检查和自动完成的好处。")])]),t._v(" "),s("p",[t._v("总之,"),s("code",[t._v("UseCartContextType")]),t._v(" 的定义和使用使得你的 React 组件可以高效且安全地与购物车相关的状态和操作进行交互,同时保持代码的清晰和可维护性。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/56.710acef5.js b/assets/js/56.710acef5.js new file mode 100644 index 00000000..156e06c7 --- /dev/null +++ b/assets/js/56.710acef5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{347:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"todolist-app"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#todolist-app"}},[t._v("#")]),t._v(" TodoList App")]),t._v(" "),s("h2",{attrs:{id:"プロジェクトの構成"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#プロジェクトの構成"}},[t._v("#")]),t._v(" プロジェクトの構成")]),t._v(" "),s("ul",[s("li",[s("p",[s("code",[t._v("TodoList")])]),t._v(" "),s("ul",[s("li",[t._v("Manages the overall state of the todo list.")]),t._v(" "),s("li",[t._v("Provides the "),s("code",[t._v("addTodo")]),t._v(" function to add new todos.")]),t._v(" "),s("li",[t._v("Logs the current state of the todo list.")]),t._v(" "),s("li",[s("code",[t._v("index")]),t._v(":"),s("code",[t._v("TdList")]),t._v(" & "),s("code",[t._v("TdInput")])])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("Input(TdInput)")]),t._v(": Responsible for the input field")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("index:")]),t._v(" Main view with the input field")]),t._v(" "),s("li",[t._v("Handles user input for adding new todos.")]),t._v(" "),s("li",[t._v("Validates input and prevents the addition of duplicate todos.")]),t._v(" "),s("li",[t._v("Calls the parent's "),s("code",[t._v("TodoList")]),t._v(" addTodo function to update the todo list.")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("List(TdList)")]),t._v(": Responsible for displaying the list of todos")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("index(TdList)")]),t._v(":Manages and displays all items in the list (including all TdItems)")]),t._v(" "),s("li",[s("code",[t._v("Item(TdItem)")]),t._v(": Responsible for displaying a single item")])])])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" TdInput "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Input"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" TdList "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./List"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("TodoList")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdInput")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdList")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TodoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"tdinput-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tdinput-component"}},[t._v("#")]),t._v(" TdInput Component")]),t._v(" "),s("ol",[s("li",[t._v("Input Handling:")])]),t._v(" "),s("ul",[s("li",[t._v("Utilizes the "),s("code",[t._v("useRef")]),t._v(" hook to create a reference ("),s("code",[t._v("inputRef")]),t._v(") to the input element. This reference is used to access the input element's value imperatively.")]),t._v(" "),s("li",[t._v("Defines a function ("),s("code",[t._v("handleAddTodoItem")]),t._v(") to handle the addition of new todo items based on user input.")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("Validation and Interaction:")])]),t._v(" "),s("ul",[s("li",[t._v("Ensures that the input value is trimmed and not empty. Displays an alert if a todo with the same content already exists.")]),t._v(" "),s("li",[t._v("Calls the "),s("code",[t._v("addTodo")]),t._v(" function passed as a prop from the parent component (TodoList) to add a new todo item.")])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("User Interface:")])]),t._v(" "),s("ul",[s("li",[t._v('Renders an input field and a button within a div with the class "todo-input."')]),t._v(" "),s("li",[t._v("The button triggers the "),s("code",[t._v("handleAddTodoItem")]),t._v(" function when clicked.")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("TdInput")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("form")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Enter your todo here"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("submit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Add")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TdInput"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"tdlist-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tdlist-component"}},[t._v("#")]),t._v(" TdList Component")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" TdItem "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Item"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("TdList")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("td-list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdItem")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TdList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"tditem-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tditem-component"}},[t._v("#")]),t._v(" TdItem Component")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Each item")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("TdItem")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("ul")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("checkbox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("span")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("Placeholder text here")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TdItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("strong",[t._v("Props:")]),t._v(" Every functional component ("),s("code",[t._v("FC")]),t._v(") has a collection of external properties ("),s("code",[t._v("props")]),t._v(") that it can receive. However, in the provided "),s("code",[t._v("TdItem")]),t._v(" component, no props are explicitly defined or used.")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Return Value:")]),t._v(" Every functional component returns a "),s("code",[t._v("ReactElement")]),t._v(", which is an object containing properties such as "),s("code",[t._v("type")]),t._v(", "),s("code",[t._v("props")]),t._v(", "),s("code",[t._v("ref")]),t._v(", "),s("code",[t._v("key")]),t._v(", etc.")])])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// IProps is a generic parameter, indicating the expected type of properties (props) this component should receive.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The component (TdInput) is declared with the FC (FunctionComponent) type, as it uses ref, and for that, generics are needed.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("TdInput")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" = (")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("): ReactElement => ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(";\n")])])])]),s("blockquote",[s("p",[t._v("Takeaways:")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Prop")]),t._v(": In functional components, external properties are received through the props collection. 每一個函數組件都有一個外部傳入的 props 屬性集合。")]),t._v(" "),s("li",[t._v("Every functional component has a return value, which is a ReactElement object, representing JSX. 每一個函數組件是有一個返回值的,返回的是 ReactElement 對象,即 jsx")]),t._v(" "),s("li",[s("strong",[t._v("ReactElement Object")]),t._v(": A comprehensive object containing properties like type, props, ref, key, etc.")])]),t._v(" "),s("blockquote",[s("p",[t._v("Explanation:")])]),t._v(" "),s("ul",[s("li",[t._v("Props, short for properties, are external attributes passed to functional components.")]),t._v(" "),s("li",[t._v("Functional components, unlike class components, inherently produce ReactElement objects as their output.")]),t._v(" "),s("li",[t._v("A ReactElement is an object encapsulating information such as the component type, its properties (props),\nreferences (ref), keys, and more, making it a fundamental unit in React's rendering process.")])]),t._v(" "),s("p",[t._v("In summary, functional components receive external attributes through props and, in turn, generate ReactElement objects, forming the basis of JSX rendering in React applications.")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// IProps is a generic parameter, indicating the expected type of properties (props) this component should receive.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The component (TdInput) is declared with the FC (FunctionComponent) type, as it uses ref, and for that, generics are needed.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("TdInput")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" = (")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("): ReactElement => ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(";\n")])])])]),s("blockquote",[s("p",[s("strong",[t._v("Explanation")]),t._v(": The TdInput component is a functional component that is expected to receive props conforming to the IProps interface. It uses the FC (FunctionComponent) type, a generic type provided by React for defining functional components. The function returns a React element (ReactElement), indicating that this component will render JSX. The empty object ({}) in the parameter list represents the expected props, and it can be adjusted based on the actual props needed by the component. This component is defined to handle input functionality within the TodoList app.")])]),t._v(" "),s("h3",{attrs:{id:"定義-inputref"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#定義-inputref"}},[t._v("#")]),t._v(" 定義 inputRef")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inputRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" useRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" HTMLInputElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"定義-itodo-接口"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#定義-itodo-接口"}},[t._v("#")]),t._v(" 定義 Itodo 接口")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Itodo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" number"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("description")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" boolean"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"定義-iprops-src-components-todolist-input-index-tsx"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#定義-iprops-src-components-todolist-input-index-tsx"}},[t._v("#")]),t._v(" 定義 Iprops "),s("code",[t._v("src/components/TodoList/Input/index.tsx")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//為什麼沒有返回值? 因為這裡是一個函數組件,不是一個函數。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里 addTodo 是一个属性,其类型为一个函数,这个函数接受一个 ITodo 类型的参数 todo,并且没有返回值(void)。在使用这个组件时,你需要从父组件传递一个满足这个函数签名的函数给 addTodo 属性。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("思考")]),t._v(" "),s("ul",[s("li",[t._v("onClick 中應該放什麼?")]),t._v(" "),s("li",[t._v("useRef 的使用方式: 使用了 useRef"),s("HTMLInputElement",[t._v("(null),但您在代碼中沒有使用這個 inputRef。如果您希望在按鈕點擊時獲取輸入的值,您需要使用 inputRef.current.value。")])],1)])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ITodo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../../types"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("TdInput")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" = (")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" addTodo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("): ReactElement => ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//inputRef 是一個對象,裡面有一個current屬性,current屬性指向input元素,用於獲取input元素的值。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inputRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" useRef"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HTMLInputElement")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("(null);\n\n return (\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 这里,inputRef是一个useRef具有current属性的对象。该current属性最初设置为,但在安装组件时null将更新为指向DOM 元素。input之后,您可以使用inputRef.current来引用实际的inputDOM 元素。 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("please input to do list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n );\n};\n\nexport default TdInput;\n\n")])])])]),s("blockquote",[s("p",[t._v("接下來,應該是對 input 取值, 那麼就需要一個 "),s("code",[t._v("handleAddTodoItem")]),t._v("的方法, 並且在 "),s("code",[t._v("onClick")]),t._v(" 中調用它。")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// IProps interface representing the properties (props) expected by the component.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// addTodo is a function that takes a todo (of type ITodo) and returns void.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// todoList is an array of ITodo objects, representing the list of to-do items.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleAddTodoItem "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//inputRef.current用于获取输入元素(用户输入的文本)的当前值。这允许您直接访问输入字段的值,而无需使用 React 状态。当您需要在通常的 React 状态和事件处理机制之外强制访问输入字段的当前值时,这种模式很常见。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("val")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("trim")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Check if the trimmed value is not empty")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Check if a todo with the same content already exists in the todoList")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" isExist "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If a todo with the same content exists, show an alert and return from the function")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isExist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("alert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"To-do list item already exists"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//執行父類的addTodo方法, 把子類的val 傳給父類。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Date")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a unique id (using timestamp)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("completed")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Clear the input field by setting its value to an empty string")]),t._v("\n inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 这里,inputRef是一个useRef具有current属性的对象。该current属性最初设置为,但在安装组件时null将更新为指向DOM 元素。input之后,您可以使用inputRef.current来引用实际的inputDOM 元素。 */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("please input to do list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleAddTodoItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n")])])]),s("h2",{attrs:{id:"todolist-父組件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#todolist-父組件"}},[t._v("#")]),t._v(" TodoList 父組件")]),t._v(" "),s("ol",[s("li",[t._v("State Management:")])]),t._v(" "),s("ul",[s("li",[t._v("Manages the state of the todo list using the "),s("code",[t._v("useState")]),t._v(" hook. The state is initialized as an empty array.")]),t._v(" "),s("li",[t._v("Logs the current state of todoList using the "),s("code",[t._v("useEffect")]),t._v(" hook whenever "),s("code",[t._v("todoList")]),t._v(" changes.")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("addTodo Function:")])]),t._v(" "),s("ul",[s("li",[t._v("Defines an addTodo function using "),s("code",[t._v("useCallback")]),t._v(". This function takes a todo item as a parameter and updates the todoList state by appending the new todo.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("useCallback")]),t._v(" hook ensures that the addTodo function maintains a stable reference across renders, optimizing performance by preventing unnecessary re-renders.")])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("Rendering Child Components:")])]),t._v(" "),s("ul",[s("li",[t._v("Renders two child components, "),s("code",[t._v("TdInput")]),t._v(" and "),s("code",[t._v("TdList")]),t._v(", within a "),s("code",[t._v("div")]),t._v(' with the class "todo-list."')]),t._v(" "),s("li",[t._v("Passes the "),s("code",[t._v("addTodo")]),t._v(" function and the current "),s("code",[t._v("todoList")]),t._v(" state as props to "),s("code",[t._v("TdInput")]),t._v(".")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定義一個狀態,用 useState,為了讓子組件能夠獲取到父組件的狀態,所以要用 useState")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setTodoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" useState"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//當 useEffect 被觸發時,它內部的回調函數就會執行。即當新的代辦事項被添加到 todoList 時,useEffect 的回調函數就會執行。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//addTodo 函數的目的: addTodo 函數的目的是將代表待辦事項的物件添加到 todoList 狀態中。這是透過使用 setTodoList 更新 todoList 狀態實現的。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" addTodo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在實際應用中,你應該使用 setTodoList 更新 todoList 狀態")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setTodoList((prevTodoList) => [...prevTodoList, todo]);")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTodoList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//將 addTodo 作為 prop 傳遞給 TdInput 子組件: 在 return 語句中,addTodo 函數作為 prop 傳遞給了 TdInput 子組件,這樣子組件就能夠使用父組件中的這個函數。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* 將 addTodo 函數作為 prop 傳遞給子組件 TdInput */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdInput")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("addTodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdList")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[s("code",[t._v("useCallback")]),t._v(" 是 React 中的一個 Hook,用於優化函數引用,特別是在子組件的 props 中使用。在這個特定的代碼中,"),s("code",[t._v("useCallback")]),t._v(" 用於優化 "),s("code",[t._v("addTodo")]),t._v(" 函數的引用,以防止不必要的重新渲染。")])]),t._v(" "),s("ol",[s("li",[s("code",[t._v("useCallback")]),t._v(" 用途:")])]),t._v(" "),s("p",[t._v("在 React 中,每次父組件渲染時,內聯函數都會被重新創建。為了避免不必要的函數重新創建,特別是在子組件的 props 中使用函數時,可以使用 "),s("code",[t._v("useCallback")]),t._v(" 進行優化。在這裡,"),s("code",[t._v("useCallback")]),t._v(" 用於優化 "),s("code",[t._v("addTodo")]),t._v(" 函數的引用,以防止不必要的重新渲染。")]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("code",[t._v("useCallback")]),t._v(" 的作用:")])]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("避免不必要的函數重新創建:")]),t._v(" 使用 "),s("code",[t._v("useCallback")]),t._v(" 可以緩存函數的實例,只有當 "),s("code",[t._v("useCallback")]),t._v(" 的依賴項發生變化時才會創建一個新的函數實例。這減少了子組件的不必要重新渲染,提高了應用程序性能。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("子組件性能優化:")]),t._v(" 如果子組件使用了 "),s("code",[t._v("React.memo")]),t._v(" 進行性能優化(防止不必要的重新渲染),"),s("code",[t._v("useCallback")]),t._v(" 的使用能夠確保即使父組件重新渲染,子組件不會因 "),s("code",[t._v("addTodo")]),t._v(" 函數的實際邏輯未改變而重新渲染。")])])]),t._v(" "),s("blockquote",[s("p",[s("code",[t._v("useEffect")]),t._v(": 簡單來說,當使用者在 "),s("code",[t._v("TdInput")]),t._v(' 組件中點擊 "add" 按鈕時,'),s("code",[t._v("handleAddTodoItem")]),t._v(" 函數被觸發,並且它內部調用了由父組件 "),s("code",[t._v("TodoList")]),t._v(" 提供的 "),s("code",[t._v("addTodo")]),t._v(" 函數。這樣做的目的是將新的待辦事項添加到父組件的 "),s("code",[t._v("todoList")]),t._v(" 狀態中,從而觸發 "),s("code",[t._v("useEffect")]),t._v(" 並在控制台中輸出新的 "),s("code",[t._v("todoList")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"使用-usereducer-替代-usestate"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用-usereducer-替代-usestate"}},[t._v("#")]),t._v(" 使用 useReducer 替代 useState")]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//path: todo-list-app/src/components/TodoList/reducer.ts")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" IAction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" IState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ITodo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./types"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//todoReducer 是一個純函數,用於處理有關待辦事項應用程序狀態的變化。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("todoReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("state")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IAction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//返回一個IState,todoList: []的集合")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//action包含兩個值:一個是payload, 另一個是type。 payload 其實就是我們要傳遞的參數,也就是todo的內容,就是const addTodo = useCallback((todo: ITodo) => 裡面的todo,另一個是type則是我們要做的事情")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD_TODO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" todoReducer "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])]),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//path: src/components/TodoList/index.tsx")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ReactElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n useCallback"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n useEffect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n useReducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" TdInput "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Input"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" TdList "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./List"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" IState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./types"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" todoReducer "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./reducer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("initialState")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("TodoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("ReactElement")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dispatch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todoReducer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initialState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//當 useEffect 被觸發時,它內部的回調函數就會執行。,即當新的代辦事項被添加到 todoList 時,useEffect 的回調函數就會執行。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useEffect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//可理解為redux裡的action creator, 用來創建action,是純粹的函數, 它們返回一個action對象,而這個對象然後被傳遞給 dispatch()方法。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" addTodo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setTodoList((todoList) => [...todoList, todo]);")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD_TODO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("payload")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdInput")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("addTodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TdList")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TodoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"分析-1-親コンポーネントが子コンポーネントに提供する-addtodo-関数を理解するには"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#分析-1-親コンポーネントが子コンポーネントに提供する-addtodo-関数を理解するには"}},[t._v("#")]),t._v(" 分析 1:親コンポーネントが子コンポーネントに提供する addTodo 関数を理解するには?")]),t._v(" "),s("p",[t._v("在提供給 "),s("code",[t._v("TdInput")]),t._v(" 子組件的 "),s("code",[t._v("addTodo")]),t._v(" 函數和 "),s("code",[t._v("handleAddTodoItem")]),t._v(" 函數之間有一個簡單的對應關係:")]),t._v(" "),s("ol",[s("li",[s("strong",[s("code",[t._v("addTodo")]),t._v(" 函數:")]),t._v(" "),s("ul",[s("li",[t._v("定義在父組件 "),s("code",[t._v("TodoList")]),t._v(" 中。")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("useCallback")]),t._v(" 優化函數引用。")]),t._v(" "),s("li",[t._v("負責將新的待辦事項("),s("code",[t._v("todo")]),t._v(" 物件)添加到 "),s("code",[t._v("todoList")]),t._v(" 狀態中。")])])])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" addTodo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD_TODO")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("payload")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[s("code",[t._v("handleAddTodoItem")]),t._v(" 函數:")]),t._v(" "),s("ul",[s("li",[t._v("定義在子組件 "),s("code",[t._v("TdInput")]),t._v(" 中。")]),t._v(" "),s("li",[t._v("負責處理使用者輸入的待辦事項,並通過呼叫父組件提供的 "),s("code",[t._v("addTodo")]),t._v(" 函數將新的待辦事項添加到 "),s("code",[t._v("todoList")]),t._v(" 中。")])])])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleAddTodoItem "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...(省略其他處理邏輯)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Date")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("completed")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...(省略其他處理邏輯)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:"/docs/guide/images/react/todolist.png",alt:"todolist"}})]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[s("code",[t._v("TodoList")]),t._v(" 組件:")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("TodoList")]),t._v(" 組件是一個 React 函數組件,負責渲染待辦事項應用的主要 UI。")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("useReducer")]),t._v(" Hook 管理狀態,並將狀態和派發函數 "),s("code",[t._v("dispatch")]),t._v(" 作為 "),s("code",[t._v("todoReducer")]),t._v(" 的參數。")])])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("TdInput")]),t._v(" 組件:")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("TdInput")]),t._v(" 組件是 "),s("code",[t._v("TodoList")]),t._v(" 組件的子組件,負責處理待辦事項的輸入部分。")]),t._v(" "),s("li",[t._v("接收 "),s("code",[t._v("addTodo")]),t._v(" 函數作為 prop,用來添加新的待辦事項。")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("inputRef")]),t._v(' 來獲取用戶輸入的值,並在點擊 "add" 按鈕時調用 '),s("code",[t._v("handleAddTodoItem")]),t._v(" 函數。")])])]),t._v(" "),s("li",[s("p",[s("strong",[s("code",[t._v("todoReducer")]),t._v(" 函數:")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("todoReducer")]),t._v(" 是一個純函數,用於處理與待辦事項應用的狀態相關的操作。")]),t._v(" "),s("li",[t._v("接收當前應用程序的狀態 ("),s("code",[t._v("state")]),t._v(") 和一個描述操作的對象 ("),s("code",[t._v("action")]),t._v(")。")]),t._v(" "),s("li",[t._v("在這個特定的應用中,只處理一種操作類型 "),s("code",[t._v("ACTION_TYPE.ADD_TODO")]),t._v(",用來將新的待辦事項添加到 "),s("code",[t._v("todoList")]),t._v(" 中。")])])])]),t._v(" "),s("p",[t._v("這三個組件/函數之間的關係是通過 React 的層級組件結構和 props 傳遞建立的。主要的工作流程是:")]),t._v(" "),s("ul",[s("li",[t._v("在 "),s("code",[t._v("TodoList")]),t._v(" 組件中使用 "),s("code",[t._v("useReducer")]),t._v(" 來初始化應用的狀態並獲取 "),s("code",[t._v("dispatch")]),t._v(" 函數。")]),t._v(" "),s("li",[s("code",[t._v("TodoList")]),t._v(" 將狀態和 "),s("code",[t._v("addTodo")]),t._v(" 函數作為 prop 傳遞給 "),s("code",[t._v("TdInput")]),t._v(" 子組件。")]),t._v(" "),s("li",[t._v("在 "),s("code",[t._v("TdInput")]),t._v(" 中,使用 "),s("code",[t._v("inputRef")]),t._v(' 獲取用戶輸入的值,並在點擊 "add" 按鈕時調用 '),s("code",[t._v("addTodo")]),t._v(" 函數。")]),t._v(" "),s("li",[s("code",[t._v("addTodo")]),t._v(" 函數內部調用 "),s("code",[t._v("dispatch")]),t._v(" 並傳遞一個描述添加待辦事項操作的 action 對象。")]),t._v(" "),s("li",[s("code",[t._v("dispatch")]),t._v(" 調用 "),s("code",[t._v("todoReducer")]),t._v(" 函數來修改應用的狀態。")]),t._v(" "),s("li",[s("code",[t._v("useEffect")]),t._v(" Hook 監聽 "),s("code",[t._v("state.todoList")]),t._v(" 的變化,並在變化時輸出日誌。")])]),t._v(" "),s("div",{staticClass:"language-jsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//path: todo-list-app/src/components/TodoList/reducer.ts")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * Redux 中 reducer 函數內的 switch case,用於處理不同的 action types。\n\n * 在 todoReducer 中,這些 case 實際上是 action types 的不同分支,用於決定根據不同的 action type 如何更新應用的狀態。\n\n * Reducer 是一個純函數,它接收先前的狀態和一個 action 物件,然後根據 action 的類型執行相應的操作,返回新的狀態。\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" IAction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" IState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ITodo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./types"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("todoReducer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("state")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IAction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IState "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ADD_TODO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payload "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * 這裡的目的是從 todoList 中移除指定 id 的待辦事項。具體步驟如下:\n\n 1. 使用 filter 方法遍歷 state.todoList 中的每個待辦事項 (todo)。\n 2. 對於每個待辦事項,檢查其 id 是否等於 payload(payload 是從 action 中傳入的待辦事項的 id)。\n 3. 如果待辦事項的 id 與 payload 不相等,則保留該待辦事項;如果相等,則過濾掉該待辦事項。\n 4. 將過濾後的待辦事項列表更新到新的 state 中。\n */")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REMOVE_TODO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" payload"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * 這裡的目的是切換指定 `id` 的待辦事項的完成狀態(`completed`)。具體步驟如下:\n\n 1. 使用 `map` 方法遍歷 `state.todoList` 中的每個待辦事項 (`todo`)。\n 2. 對於每個待辦事項,檢查其 `id` 是否等於 `payload`(`payload` 是從 `action` 中傳入的待辦事項的 `id`)。\n 3. 如果待辦事項的 `id` 與 `payload` 相等,則將該待辦事項的 `completed` 狀態取反(切換完成狀態)。\n 4. 將修改後的待辦事項列表更新到新的 `state` 中。\n */")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ACTION_TYPE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("TOGGLE_TODO")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("todoList")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" payload\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("completed")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("completed "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("todo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" todoReducer "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"分析-3-什麼是-action-creator-返回純函數的意思是"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#分析-3-什麼是-action-creator-返回純函數的意思是"}},[t._v("#")]),t._v(" 分析 3 什麼是 action creator? 返回純函數的意思是?")]),t._v(" "),s("p",[t._v("在 Redux 中,一個 action creator 是一個返回 action 物件的函數。這個 action 物件包含了描述 action 類型(type)和相關數據(payload)的信息。一個典型的 action creator 純函數如下:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// action creator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("text")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ADD_TODO"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("payload")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("completed")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 action creator 來創建一個 action 物件")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" newTodoAction "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Buy groceries"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在這個例子中,"),s("code",[t._v("addTodo")]),t._v(" 是一個 action creator 函數。當你調用它時,它返回一個包含 action 信息的物件。這個 action 物件至少包含 "),s("code",[t._v("type")]),t._v(" 屬性,用來指定 action 的類型,以及 "),s("code",[t._v("payload")]),t._v(" 屬性,用來包含相關的數據。")]),t._v(" "),s("p",[t._v("Redux 的 reducer 函數則根據這些 action 物件的 "),s("code",[t._v("type")]),t._v(" 屬性,來決定如何更新應用的狀態。在 reducer 內部,通常使用一個 switch case 來處理不同的 action types。這就是為什麼在 Redux 中的 action creators 是純函數的原因,因為它們返回一個描述 action 的純函數,而不執行對應的非純操作。")]),t._v(" "),s("p",[t._v("簡而言之,Redux 中的 action creators 是純函數,因為它們只返回描述 action 的物件,而不執行其他可能引起副作用的操作。這有助於保持 Redux 應用的可預測性和可測試性。")]),t._v(" "),s("h3",{attrs:{id:"分析-4-iprops"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#分析-4-iprops"}},[t._v("#")]),t._v(" 分析 4: Iprops")]),t._v(" "),s("p",[t._v("//IProps 具有属性 todoList、toggleTodo 和 的接口 removeTodo 用于 TdItem(item) 和 TdList(list) 组件,以定义这些组件应接收的预期 props。")]),t._v(" "),s("h3",{attrs:{id:"iprops-interface-for-tdinput-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iprops-interface-for-tdinput-component"}},[t._v("#")]),t._v(" "),s("code",[t._v("IProps")]),t._v(" Interface for "),s("code",[t._v("TdInput")]),t._v(" Component:")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n todoList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("code",[t._v("addTodo")]),t._v(": This property is a function that takes an "),s("code",[t._v("ITodo")]),t._v(" parameter and returns "),s("code",[t._v("void")]),t._v(". It suggests that the "),s("code",[t._v("TdInput")]),t._v(" component expects a function to be passed down that will handle the addition of a new todo item to the list.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("todoList")]),t._v(": This property is an array of "),s("code",[t._v("ITodo")]),t._v(" items. It represents the list of todos that the "),s("code",[t._v("TdInput")]),t._v(" component needs access to, possibly for checking if a todo already exists before adding a new one.")])])]),t._v(" "),s("h3",{attrs:{id:"iprops-interface-for-tdlist-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iprops-interface-for-tdlist-component"}},[t._v("#")]),t._v(" "),s("code",[t._v("IProps")]),t._v(" Interface for "),s("code",[t._v("TdList")]),t._v(" Component:")]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n todoList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("toggleTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("removeTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("number")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("code",[t._v("todoList")]),t._v(": This property is an array of "),s("code",[t._v("ITodo")]),t._v(" items. It represents the list of todos that the "),s("code",[t._v("TdList")]),t._v(" component will render.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("toggleTodo")]),t._v(": This property is a function that takes a "),s("code",[t._v("number")]),t._v(" (presumably the id of a todo item) and returns "),s("code",[t._v("void")]),t._v(". It suggests that the "),s("code",[t._v("TdList")]),t._v(" component expects a function to be passed down that will handle toggling the completion status of a todo item.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("removeTodo")]),t._v(": This property is a function that takes a "),s("code",[t._v("number")]),t._v(" (presumably the id of a todo item) and returns "),s("code",[t._v("void")]),t._v(". It suggests that the "),s("code",[t._v("TdList")]),t._v(" component expects a function to be passed down that will handle removing a todo item from the list.")])])]),t._v(" "),s("h3",{attrs:{id:"common-aspects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#common-aspects"}},[t._v("#")]),t._v(" Common Aspects:")]),t._v(" "),s("ul",[s("li",[t._v("Both interfaces include a "),s("code",[t._v("todoList")]),t._v(" property, indicating that both components need access to the list of todos.")]),t._v(" "),s("li",[t._v("The "),s("code",[t._v("ITodo")]),t._v(" type is referenced in both interfaces, suggesting that it defines the structure of a todo item.")])]),t._v(" "),s("p",[t._v("Understanding these interfaces helps clarify what kind of props each component expects and how they interact with the rest of the application.")]),t._v(" "),s("h3",{attrs:{id:"iprops-in-the-todolist-input-index-tsx"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iprops-in-the-todolist-input-index-tsx"}},[t._v("#")]),t._v(" "),s("code",[t._v("IProps")]),t._v(" in the "),s("code",[t._v("TodoList>input>index.tsx")])]),t._v(" "),s("div",{staticClass:"language-tsx extra-class"},[s("pre",{pre:!0,attrs:{class:"language-tsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//path: src/components/TodoList/Input/index.tsx")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" useRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"react"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" ITodo "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../types"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//addTodo接口中属性的存在IProps表明TdInput组件期望将函数作为 prop 传递,并且该函数应该具有签名(todo: ITodo) => void。这表明该函数的目的可能是处理添加新的待办事项。")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("IProps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//addTodo:它是一个以ITodo对象作为参数并返回的函数void。该函数预计可以处理添加新的待办事项。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//todoList:它是一个对象数组ITodo。该数组表示组件将与之交互的待办事项列表TdInput,专门用于检查列表中是否已存在新的待办事项。")]),t._v("\n todoList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ITodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * addTodoProp: 是一个向下传递给TdInput组件的函数。在函数内部handleAddTodoItem,当即将添加新的待办事项时,将调用此函数。该addTodo函数负责将新的待办事项添加到整个待办事项列表中。\n\n * todoListProp: 是待办事项的数组。它在handleAddTodoItem函数中用于检查列表中是否已存在具有相同内容的新待办事项。如果是,则会显示警报,并且不会添加新的待办事项。\n */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" TdInput"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FC")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("IProps"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" addTodo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" todoList "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" inputRef "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generic-function"}},[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useRef")]),s("span",{pre:!0,attrs:{class:"token generic class-name"}},[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("HTMLInputElement"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleAddTodoItem "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("trim")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" isExist "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" todoList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" todo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isExist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("alert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"to do list has existed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//在该函数中,addTodo使用新的 todo 对象作为参数来调用该函数。addTodo这与界面中的属性设置的期望一致IProps。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Date")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n content"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n completed"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("className")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("todo-input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("please input to do list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("inputRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("button")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onClick")]),s("span",{pre:!0,attrs:{class:"token script language-javascript"}},[s("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("handleAddTodoItem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" TdInput"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/6.cb88f024.js b/assets/js/6.cb88f024.js new file mode 100644 index 00000000..112c0ef5 --- /dev/null +++ b/assets/js/6.cb88f024.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{279:function(e,t,a){},293:function(e,t,a){"use strict";a(279)},310:function(e,t,a){"use strict";a.r(t);var o={name:"CodeGroup",data:()=>({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.activateCodeTab(e)}},mounted(){this.loadTabs()},methods:{changeCodeTab(e){this.activeCodeTabIndex=e},loadTabs(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab(e){this.codeTabs.forEach(e=>{e.elm&&e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},s=(a(293),a(14)),c=Object(s.a)(o,(function(){var e=this,t=e._self._c;return t("ClientOnly",[t("div",{staticClass:"theme-code-group"},[t("div",{staticClass:"theme-code-group__nav"},[t("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(a,o){return t("li",{key:a.title,staticClass:"theme-code-group__li"},[t("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(a.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?t("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/7.0f51d652.js b/assets/js/7.0f51d652.js new file mode 100644 index 00000000..7ac1c130 --- /dev/null +++ b/assets/js/7.0f51d652.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{311:function(t,e,s){"use strict";s.r(e);const o=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."];var n={methods:{getMsg:()=>o[Math.floor(Math.random()*o.length)]}},h=s(14),i=Object(h.a)(n,(function(){var t=this._self._c;return t("div",{staticClass:"theme-container"},[t("div",{staticClass:"theme-default-content"},[t("h1",[this._v("404")]),this._v(" "),t("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),t("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/app.204ed3d4.js b/assets/js/app.204ed3d4.js new file mode 100644 index 00000000..d4ced85d --- /dev/null +++ b/assets/js/app.204ed3d4.js @@ -0,0 +1,16 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var r,a,s=e[0],c=e[1],u=e[2],f=0,p=[];f

    '};function o(t,e,n){return tn?n:t}function i(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(r[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=o(t,r.minimum,1),n.status=1===t?null:t;var c=n.render(!e),u=c.querySelector(r.barSelector),l=r.speed,f=r.easing;return c.offsetWidth,a((function(e){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,function(t,e,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(t)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(t)+"%,0)"}:{"margin-left":i(t)+"%"}).transition="all "+e+"ms "+n,o}(t,l,f)),1===t?(s(c,{transition:"none",opacity:1}),c.offsetWidth,setTimeout((function(){s(c,{transition:"all "+l+"ms linear",opacity:0}),setTimeout((function(){n.remove(),e()}),l)}),l)):setTimeout(e,l)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var t=function(){setTimeout((function(){n.status&&(n.trickle(),t())}),r.trickleSpeed)};return r.trickle&&t(),this},n.done=function(t){return t||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(t){var e=n.status;return e?("number"!=typeof t&&(t=(1-e)*o(Math.random()*e,.1,.95)),e=o(e+t,0,.994),n.set(e)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},t=0,e=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===e&&n.start(),t++,e++,r.always((function(){0==--e?(t=0,n.done()):n.set((t-e)/t)})),this):this},n.render=function(t){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=r.template;var o,a=e.querySelector(r.barSelector),c=t?"-100":i(n.status||0),l=document.querySelector(r.parent);return s(a,{transition:"all 0 linear",transform:"translate3d("+c+"%,0,0)"}),r.showSpinner||(o=e.querySelector(r.spinnerSelector))&&p(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(e),e},n.remove=function(){l(document.documentElement,"nprogress-busy"),l(document.querySelector(r.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&p(t)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var a=function(){var t=[];function e(){var n=t.shift();n&&n(e)}return function(n){t.push(n),1==t.length&&e()}}(),s=function(){var t=["Webkit","O","Moz","ms"],e={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(t,e){return e.toUpperCase()})),e[n]||(e[n]=function(e){var n=document.body.style;if(e in n)return e;for(var r,o=t.length,i=e.charAt(0).toUpperCase()+e.slice(1);o--;)if((r=t[o]+i)in n)return r;return e}(n))}function r(t,e,r){e=n(e),t.style[e]=r}return function(t,e){var n,o,i=arguments;if(2==i.length)for(n in e)void 0!==(o=e[n])&&e.hasOwnProperty(n)&&r(t,n,o);else r(t,i[1],i[2])}}();function c(t,e){return("string"==typeof t?t:f(t)).indexOf(" "+e+" ")>=0}function u(t,e){var n=f(t),r=n+e;c(n,e)||(t.className=r.substring(1))}function l(t,e){var n,r=f(t);c(t,e)&&(n=r.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function f(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function p(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?r.call(e,n,e,t):r)||(t.exports=o)},function(t,e,n){"use strict";var r=n(1),o=n(45).f,i=n(12),a=n(92),s=n(32),c=n(61),u=n(120);t.exports=function(t,e){var n,l,f,p,d,h=t.target,v=t.global,m=t.stat;if(n=v?r:m?r[h]||s(h,{}):(r[h]||{}).prototype)for(l in e){if(p=e[l],f=t.dontCallGetSet?(d=o(n,l))&&d.value:n[l],!u(v?l:h+(m?".":"#")+l,t.forced)&&void 0!==f){if(typeof p==typeof f)continue;c(p,f)}(t.sham||f&&f.sham)&&i(p,"sham",!0),a(n,l,p,t)}}},function(t,e,n){"use strict";var r=n(25),o=Function.prototype.call;t.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},function(t,e,n){"use strict";var r=n(3);t.exports=!r((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},function(t,e,n){"use strict";t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){"use strict";var r=n(46),o=n(47);t.exports=function(t){return r(o(t))}},function(t,e,n){"use strict";var r=n(1),o=n(0),i=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?i(r[t]):r[t]&&r[t][e]}},function(t,e,n){"use strict";var r=n(0),o=n(102),i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not a function")}},function(t,e,n){"use strict";var r=n(1),o=n(56),i=n(7),a=n(58),s=n(54),c=n(53),u=r.Symbol,l=o("wks"),f=c?u.for||u:u&&u.withoutSetter||a;t.exports=function(t){return i(l,t)||(l[t]=s&&i(u,t)?u[t]:f("Symbol."+t)),l[t]}},function(t,e,n){"use strict";var r=n(1),o=n(32),i=r["__core-js_shared__"]||o("__core-js_shared__",{});t.exports=i},function(t,e,n){"use strict";var r=n(1),o=Object.defineProperty;t.exports=function(t,e){try{o(r,t,{value:e,configurable:!0,writable:!0})}catch(n){r[t]=e}return e}},function(t,e,n){"use strict";var r=n(47),o=Object;t.exports=function(t){return o(r(t))}},function(t,e,n){"use strict";var r=n(8),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not an object")}},function(t,e,n){"use strict";var r=n(117);t.exports=function(t){return r(t.length)}},function(t,e,n){var r=n(143),o=n(10),i=Object.prototype,a=i.hasOwnProperty,s=i.propertyIsEnumerable,c=r(function(){return arguments}())?r:function(t){return o(t)&&a.call(t,"callee")&&!s.call(t,"callee")};t.exports=c},function(t,e,n){var r=n(9)(n(6),"Map");t.exports=r},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,n){var r=n(163),o=n(170),i=n(172),a=n(173),s=n(174);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){var r=n(4),o=n(43),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(r(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!o(t))||(a.test(t)||!i.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var r=n(11),o=n(10);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==r(t)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){"use strict";var r=n(5),o=n(24),i=n(98),a=n(26),s=n(27),c=n(49),u=n(7),l=n(59),f=Object.getOwnPropertyDescriptor;e.f=r?f:function(t,e){if(t=s(t),e=c(e),l)try{return f(t,e)}catch(t){}if(u(t,e))return a(!o(i.f,t,e),t[e])}},function(t,e,n){"use strict";var r=n(2),o=n(3),i=n(16),a=Object,s=r("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===i(t)?s(t,""):a(t)}:a},function(t,e,n){"use strict";var r=n(48),o=TypeError;t.exports=function(t){if(r(t))throw new o("Can't call method on "+t);return t}},function(t,e,n){"use strict";t.exports=function(t){return null==t}},function(t,e,n){"use strict";var r=n(99),o=n(51);t.exports=function(t){var e=r(t,"string");return o(e)?e:e+""}},function(t,e,n){"use strict";var r="object"==typeof document&&document.all,o=void 0===r&&void 0!==r;t.exports={all:r,IS_HTMLDDA:o}},function(t,e,n){"use strict";var r=n(28),o=n(0),i=n(52),a=n(53),s=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=r("Symbol");return o(e)&&i(e.prototype,s(t))}},function(t,e,n){"use strict";var r=n(2);t.exports=r({}.isPrototypeOf)},function(t,e,n){"use strict";var r=n(54);t.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){"use strict";var r=n(55),o=n(3),i=n(1).String;t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol("symbol detection");return!i(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},function(t,e,n){"use strict";var r,o,i=n(1),a=n(100),s=i.process,c=i.Deno,u=s&&s.versions||c&&c.version,l=u&&u.v8;l&&(o=(r=l.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(o=+r[1]),t.exports=o},function(t,e,n){"use strict";var r=n(57),o=n(31);(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.33.3",mode:r?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.33.3/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e,n){"use strict";t.exports=!1},function(t,e,n){"use strict";var r=n(2),o=0,i=Math.random(),a=r(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++o+i,36)}},function(t,e,n){"use strict";var r=n(5),o=n(3),i=n(104);t.exports=!r&&!o((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){"use strict";t.exports={}},function(t,e,n){"use strict";var r=n(7),o=n(111),i=n(45),a=n(15);t.exports=function(t,e,n){for(var s=o(e),c=a.f,u=i.f,l=0;ll))return!1;var p=c.get(t),d=c.get(e);if(p&&d)return p==e&&d==t;var h=-1,v=!0,m=2&n?new r:void 0;for(c.set(t,e),c.set(e,t);++h-1&&t%1==0&&t]/;t.exports=function(t){var e,n=""+t,o=r.exec(n);if(!o)return n;var i="",a=0,s=0;for(a=o.index;a=e||n<0||m&&t-u>=i}function x(){var t=d();if(_(t))return w(t);s=setTimeout(x,function(t){var n=e-(t-c);return m?p(n,i-(t-u)):n}(t))}function w(t){return s=void 0,g&&r?y(t):(r=o=void 0,a)}function k(){var t=d(),n=_(t);if(r=arguments,o=this,c=t,n){if(void 0===s)return b(c);if(m)return s=setTimeout(x,e),y(c)}return void 0===s&&(s=setTimeout(x,e)),a}return e=v(e)||0,h(n)&&(l=!!n.leading,i=(m="maxWait"in n)?f(v(n.maxWait)||0,e):i,g="trailing"in n?!!n.trailing:g),k.cancel=function(){void 0!==s&&clearTimeout(s),u=0,r=c=o=s=void 0},k.flush=function(){return void 0===s?a:w(d())},k}},function(t,e,n){"use strict";var r=n(23),o=n(33),i=n(35),a=n(124),s=n(126);r({target:"Array",proto:!0,arity:1,forced:n(3)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(t){return t instanceof TypeError}}()},{push:function(t){var e=o(this),n=i(e),r=arguments.length;s(n+r);for(var c=0;c79&&a<83||!i("reduce")},{reduce:function(t){var e=arguments.length;return o(this,t,e,e>1?arguments[1]:void 0)}})},function(t,e,n){"use strict";var r={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!r.call({1:2},1);e.f=i?function(t){var e=o(this,t);return!!e&&e.enumerable}:r},function(t,e,n){"use strict";var r=n(24),o=n(8),i=n(51),a=n(101),s=n(103),c=n(30),u=TypeError,l=c("toPrimitive");t.exports=function(t,e){if(!o(t)||i(t))return t;var n,c=a(t,l);if(c){if(void 0===e&&(e="default"),n=r(c,t,e),!o(n)||i(n))return n;throw new u("Can't convert object to primitive value")}return void 0===e&&(e="number"),s(t,e)}},function(t,e,n){"use strict";t.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},function(t,e,n){"use strict";var r=n(29),o=n(48);t.exports=function(t,e){var n=t[e];return o(n)?void 0:r(n)}},function(t,e,n){"use strict";var r=String;t.exports=function(t){try{return r(t)}catch(t){return"Object"}}},function(t,e,n){"use strict";var r=n(24),o=n(0),i=n(8),a=TypeError;t.exports=function(t,e){var n,s;if("string"===e&&o(n=t.toString)&&!i(s=r(n,t)))return s;if(o(n=t.valueOf)&&!i(s=r(n,t)))return s;if("string"!==e&&o(n=t.toString)&&!i(s=r(n,t)))return s;throw new a("Can't convert object to primitive value")}},function(t,e,n){"use strict";var r=n(1),o=n(8),i=r.document,a=o(i)&&o(i.createElement);t.exports=function(t){return a?i.createElement(t):{}}},function(t,e,n){"use strict";var r=n(5),o=n(3);t.exports=r&&o((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},function(t,e,n){"use strict";var r=n(5),o=n(7),i=Function.prototype,a=r&&Object.getOwnPropertyDescriptor,s=o(i,"name"),c=s&&"something"===function(){}.name,u=s&&(!r||r&&a(i,"name").configurable);t.exports={EXISTS:s,PROPER:c,CONFIGURABLE:u}},function(t,e,n){"use strict";var r=n(2),o=n(0),i=n(31),a=r(Function.toString);o(i.inspectSource)||(i.inspectSource=function(t){return a(t)}),t.exports=i.inspectSource},function(t,e,n){"use strict";var r,o,i,a=n(109),s=n(1),c=n(8),u=n(12),l=n(7),f=n(31),p=n(110),d=n(60),h=s.TypeError,v=s.WeakMap;if(a||f.state){var m=f.state||(f.state=new v);m.get=m.get,m.has=m.has,m.set=m.set,r=function(t,e){if(m.has(t))throw new h("Object already initialized");return e.facade=t,m.set(t,e),e},o=function(t){return m.get(t)||{}},i=function(t){return m.has(t)}}else{var g=p("state");d[g]=!0,r=function(t,e){if(l(t,g))throw new h("Object already initialized");return e.facade=t,u(t,g,e),e},o=function(t){return l(t,g)?t[g]:{}},i=function(t){return l(t,g)}}t.exports={set:r,get:o,has:i,enforce:function(t){return i(t)?o(t):r(t,{})},getterFor:function(t){return function(e){var n;if(!c(e)||(n=o(e)).type!==t)throw new h("Incompatible receiver, "+t+" required");return n}}}},function(t,e,n){"use strict";var r=n(1),o=n(0),i=r.WeakMap;t.exports=o(i)&&/native code/.test(String(i))},function(t,e,n){"use strict";var r=n(56),o=n(58),i=r("keys");t.exports=function(t){return i[t]||(i[t]=o(t))}},function(t,e,n){"use strict";var r=n(28),o=n(2),i=n(112),a=n(119),s=n(34),c=o([].concat);t.exports=r("Reflect","ownKeys")||function(t){var e=i.f(s(t)),n=a.f;return n?c(e,n(t)):e}},function(t,e,n){"use strict";var r=n(113),o=n(118).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,o)}},function(t,e,n){"use strict";var r=n(2),o=n(7),i=n(27),a=n(114).indexOf,s=n(60),c=r([].push);t.exports=function(t,e){var n,r=i(t),u=0,l=[];for(n in r)!o(s,n)&&o(r,n)&&c(l,n);for(;e.length>u;)o(r,n=e[u++])&&(~a(l,n)||c(l,n));return l}},function(t,e,n){"use strict";var r=n(27),o=n(115),i=n(35),a=function(t){return function(e,n,a){var s,c=r(e),u=i(c),l=o(a,u);if(t&&n!=n){for(;u>l;)if((s=c[l++])!=s)return!0}else for(;u>l;l++)if((t||l in c)&&c[l]===n)return t||l||0;return!t&&-1}};t.exports={includes:a(!0),indexOf:a(!1)}},function(t,e,n){"use strict";var r=n(62),o=Math.max,i=Math.min;t.exports=function(t,e){var n=r(t);return n<0?o(n+e,0):i(n,e)}},function(t,e,n){"use strict";var r=Math.ceil,o=Math.floor;t.exports=Math.trunc||function(t){var e=+t;return(e>0?o:r)(e)}},function(t,e,n){"use strict";var r=n(62),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){"use strict";t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(t,e,n){"use strict";e.f=Object.getOwnPropertySymbols},function(t,e,n){"use strict";var r=n(3),o=n(0),i=/#|\.prototype\./,a=function(t,e){var n=c[s(t)];return n===l||n!==u&&(o(e)?r(e):!!e)},s=a.normalize=function(t){return String(t).replace(i,".").toLowerCase()},c=a.data={},u=a.NATIVE="N",l=a.POLYFILL="P";t.exports=a},function(t,e,n){"use strict";var r=n(29),o=n(33),i=n(46),a=n(35),s=TypeError,c=function(t){return function(e,n,c,u){r(n);var l=o(e),f=i(l),p=a(l),d=t?p-1:0,h=t?-1:1;if(c<2)for(;;){if(d in f){u=f[d],d+=h;break}if(d+=h,t?d<0:p<=d)throw new s("Reduce of empty array with no initial value")}for(;t?d>=0:p>d;d+=h)d in f&&(u=n(u,f[d],d,l));return u}};t.exports={left:c(!1),right:c(!0)}},function(t,e,n){"use strict";var r=n(3);t.exports=function(t,e){var n=[][t];return!!n&&r((function(){n.call(null,e||function(){return 1},1)}))}},function(t,e,n){"use strict";var r=n(1),o=n(16);t.exports="process"===o(r.process)},function(t,e,n){"use strict";var r=n(5),o=n(125),i=TypeError,a=Object.getOwnPropertyDescriptor,s=r&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(t){return t instanceof TypeError}}();t.exports=s?function(t,e){if(o(t)&&!a(t,"length").writable)throw new i("Cannot set read only .length");return t.length=e}:function(t,e){return t.length=e}},function(t,e,n){"use strict";var r=n(16);t.exports=Array.isArray||function(t){return"Array"===r(t)}},function(t,e,n){"use strict";var r=TypeError;t.exports=function(t){if(t>9007199254740991)throw r("Maximum allowed index exceeded");return t}},function(t,e,n){"use strict";var r=n(23),o=n(1),i=n(128),a=n(129),s=o.WebAssembly,c=7!==new Error("e",{cause:7}).cause,u=function(t,e){var n={};n[t]=a(t,e,c),r({global:!0,constructor:!0,arity:1,forced:c},n)},l=function(t,e){if(s&&s[t]){var n={};n[t]=a("WebAssembly."+t,e,c),r({target:"WebAssembly",stat:!0,constructor:!0,arity:1,forced:c},n)}};u("Error",(function(t){return function(e){return i(t,this,arguments)}})),u("EvalError",(function(t){return function(e){return i(t,this,arguments)}})),u("RangeError",(function(t){return function(e){return i(t,this,arguments)}})),u("ReferenceError",(function(t){return function(e){return i(t,this,arguments)}})),u("SyntaxError",(function(t){return function(e){return i(t,this,arguments)}})),u("TypeError",(function(t){return function(e){return i(t,this,arguments)}})),u("URIError",(function(t){return function(e){return i(t,this,arguments)}})),l("CompileError",(function(t){return function(e){return i(t,this,arguments)}})),l("LinkError",(function(t){return function(e){return i(t,this,arguments)}})),l("RuntimeError",(function(t){return function(e){return i(t,this,arguments)}}))},function(t,e,n){"use strict";var r=n(25),o=Function.prototype,i=o.apply,a=o.call;t.exports="object"==typeof Reflect&&Reflect.apply||(r?a.bind(i):function(){return a.apply(i,arguments)})},function(t,e,n){"use strict";var r=n(28),o=n(7),i=n(12),a=n(52),s=n(63),c=n(61),u=n(132),l=n(133),f=n(134),p=n(137),d=n(138),h=n(5),v=n(57);t.exports=function(t,e,n,m){var g=m?2:1,y=t.split("."),b=y[y.length-1],_=r.apply(null,y);if(_){var x=_.prototype;if(!v&&o(x,"cause")&&delete x.cause,!n)return _;var w=r("Error"),k=e((function(t,e){var n=f(m?e:t,void 0),r=m?new _(t):new _;return void 0!==n&&i(r,"message",n),d(r,k,r.stack,2),this&&a(x,this)&&l(r,this,k),arguments.length>g&&p(r,arguments[g]),r}));if(k.prototype=x,"Error"!==b?s?s(k,w):c(k,w,{name:!0}):h&&"stackTraceLimit"in _&&(u(k,_,"stackTraceLimit"),u(k,_,"prepareStackTrace")),c(k,_),!v)try{x.name!==b&&i(x,"name",b),x.constructor=k}catch(t){}return k}}},function(t,e,n){"use strict";var r=n(2),o=n(29);t.exports=function(t,e,n){try{return r(o(Object.getOwnPropertyDescriptor(t,e)[n]))}catch(t){}}},function(t,e,n){"use strict";var r=n(0),o=String,i=TypeError;t.exports=function(t){if("object"==typeof t||r(t))return t;throw new i("Can't set "+o(t)+" as a prototype")}},function(t,e,n){"use strict";var r=n(15).f;t.exports=function(t,e,n){n in t||r(t,n,{configurable:!0,get:function(){return e[n]},set:function(t){e[n]=t}})}},function(t,e,n){"use strict";var r=n(0),o=n(8),i=n(63);t.exports=function(t,e,n){var a,s;return i&&r(a=e.constructor)&&a!==n&&o(s=a.prototype)&&s!==n.prototype&&i(t,s),t}},function(t,e,n){"use strict";var r=n(93);t.exports=function(t,e){return void 0===t?arguments.length<2?"":e:r(t)}},function(t,e,n){"use strict";var r=n(136),o=n(0),i=n(16),a=n(30)("toStringTag"),s=Object,c="Arguments"===i(function(){return arguments}());t.exports=r?i:function(t){var e,n,r;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=s(t),a))?n:c?i(e):"Object"===(r=i(e))&&o(e.callee)?"Arguments":r}},function(t,e,n){"use strict";var r={};r[n(30)("toStringTag")]="z",t.exports="[object z]"===String(r)},function(t,e,n){"use strict";var r=n(8),o=n(12);t.exports=function(t,e){r(e)&&"cause"in e&&o(t,"cause",e.cause)}},function(t,e,n){"use strict";var r=n(12),o=n(139),i=n(140),a=Error.captureStackTrace;t.exports=function(t,e,n,s){i&&(a?a(t,e):r(t,"stack",o(n,s)))}},function(t,e,n){"use strict";var r=n(2),o=Error,i=r("".replace),a=String(new o("zxcasd").stack),s=/\n\s*at [^:]*:[^\n]*/,c=s.test(a);t.exports=function(t,e){if(c&&"string"==typeof t&&!o.prepareStackTrace)for(;e--;)t=i(t,s,"");return t}},function(t,e,n){"use strict";var r=n(3),o=n(26);t.exports=!r((function(){var t=new Error("a");return!("stack"in t)||(Object.defineProperty(t,"stack",o(1,7)),7!==t.stack)}))},function(t,e,n){var r=n(64),o=n(142);t.exports=function t(e,n,i,a,s){var c=-1,u=e.length;for(i||(i=o),s||(s=[]);++c0&&i(l)?n>1?t(l,n-1,i,a,s):r(s,l):a||(s[s.length]=l)}return s}},function(t,e,n){var r=n(13),o=n(36),i=n(4),a=r?r.isConcatSpreadable:void 0;t.exports=function(t){return i(t)||o(t)||!!(a&&t&&t[a])}},function(t,e,n){var r=n(11),o=n(10);t.exports=function(t){return o(t)&&"[object Arguments]"==r(t)}},function(t,e,n){var r=n(13),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,s=r?r.toStringTag:void 0;t.exports=function(t){var e=i.call(t,s),n=t[s];try{t[s]=void 0;var r=!0}catch(t){}var o=a.call(t);return r&&(e?t[s]=n:delete t[s]),o}},function(t,e){var n=Object.prototype.toString;t.exports=function(t){return n.call(t)}},function(t,e,n){var r=n(147),o=n(203),i=n(44),a=n(4),s=n(213);t.exports=function(t){return"function"==typeof t?t:null==t?i:"object"==typeof t?a(t)?o(t[0],t[1]):r(t):s(t)}},function(t,e,n){var r=n(148),o=n(202),i=n(82);t.exports=function(t){var e=o(t);return 1==e.length&&e[0][2]?i(e[0][0],e[0][1]):function(n){return n===t||r(n,t,e)}}},function(t,e,n){var r=n(66),o=n(70);t.exports=function(t,e,n,i){var a=n.length,s=a,c=!i;if(null==t)return!s;for(t=Object(t);a--;){var u=n[a];if(c&&u[2]?u[1]!==t[u[0]]:!(u[0]in t))return!1}for(;++a-1}},function(t,e,n){var r=n(18);t.exports=function(t,e){var n=this.__data__,o=r(n,t);return o<0?(++this.size,n.push([t,e])):n[o][1]=e,this}},function(t,e,n){var r=n(17);t.exports=function(){this.__data__=new r,this.size=0}},function(t,e){t.exports=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n}},function(t,e){t.exports=function(t){return this.__data__.get(t)}},function(t,e){t.exports=function(t){return this.__data__.has(t)}},function(t,e,n){var r=n(17),o=n(37),i=n(39);t.exports=function(t,e){var n=this.__data__;if(n instanceof r){var a=n.__data__;if(!o||a.length<199)return a.push([t,e]),this.size=++n.size,this;n=this.__data__=new i(a)}return n.set(t,e),this.size=n.size,this}},function(t,e,n){var r=n(68),o=n(160),i=n(38),a=n(69),s=/^\[object .+?Constructor\]$/,c=Function.prototype,u=Object.prototype,l=c.toString,f=u.hasOwnProperty,p=RegExp("^"+l.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=function(t){return!(!i(t)||o(t))&&(r(t)?p:s).test(a(t))}},function(t,e,n){var r,o=n(161),i=(r=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";t.exports=function(t){return!!i&&i in t}},function(t,e,n){var r=n(6)["__core-js_shared__"];t.exports=r},function(t,e){t.exports=function(t,e){return null==t?void 0:t[e]}},function(t,e,n){var r=n(164),o=n(17),i=n(37);t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},function(t,e,n){var r=n(165),o=n(166),i=n(167),a=n(168),s=n(169);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}},function(t,e,n){var r=n(72),o=n(225),i=n(230),a=n(73),s=n(231),c=n(40);t.exports=function(t,e,n){var u=-1,l=o,f=t.length,p=!0,d=[],h=d;if(n)p=!1,l=i;else if(f>=200){var v=e?null:s(t);if(v)return c(v);p=!1,l=a,h=new r}else h=e?[]:d;t:for(;++u-1}},function(t,e,n){var r=n(227),o=n(228),i=n(229);t.exports=function(t,e,n){return e==e?i(t,e,n):r(t,o,n)}},function(t,e){t.exports=function(t,e,n,r){for(var o=t.length,i=n+(r?1:-1);r?i--:++i=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||p(t)&&t.toString===f?JSON.stringify(t,null,2):String(t)}function g(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var x=Object.prototype.hasOwnProperty;function w(t,e){return x.call(t,e)}function k(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var j=/-(\w)/g,C=k((function(t){return t.replace(j,(function(t,e){return e?e.toUpperCase():""}))})),S=k((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),O=/\B([A-Z])/g,P=k((function(t){return t.replace(O,"-$1").toLowerCase()}));var $=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function E(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function T(t,e){for(var n in e)t[n]=e[n];return t}function A(t){for(var e={},n=0;n0,Q=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var Z=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var tt,et=J&&J.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(K)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!K&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=K&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function st(t){return"function"==typeof t&&/native code/.test(t.toString())}var ct,ut="undefined"!=typeof Symbol&&st(Symbol)&&"undefined"!=typeof Reflect&&st(Reflect.ownKeys);ct="undefined"!=typeof Set&&st(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var lt=null;function ft(t){void 0===t&&(t=null),t||lt&<._scope.off(),lt=t,t&&t._scope.on()}var pt=function(){function t(t,e,n,r,o,i,a,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),dt=function(t){void 0===t&&(t="");var e=new pt;return e.text=t,e.isComment=!0,e};function ht(t){return new pt(void 0,void 0,void 0,String(t))}function vt(t){var e=new pt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,gt=[],yt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,gt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,r=e.length;n0&&(Jt((u=t(u,"".concat(n||"","_").concat(r)))[0])&&Jt(f)&&(p[l]=ht(f.text+u[0].text),u.shift()),p.push.apply(p,u)):c(u)?Jt(f)?p[l]=ht(f.text+u):""!==u&&p.push(ht(u)):Jt(u)&&Jt(f)?p[l]=ht(f.text+u.text):(s(e._isVList)&&a(u.tag)&&i(u.key)&&a(n)&&(u.key="__vlist".concat(n,"_").concat(r,"__")),p.push(u)));return p}(t):void 0}function Jt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,r,i,s,c=null;if(o(t)||"string"==typeof t)for(c=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!a,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&o&&o!==r&&c===o.$key&&!a&&!o.$hasNormal)return o;for(var u in i={},e)e[u]&&"$"!==u[0]&&(i[u]=ve(t,n,u,e[u]))}else i={};for(var l in n)l in i||(i[l]=me(n,l));return e&&Object.isExtensible(e)&&(e._normalized=i),V(i,"$stable",s),V(i,"$key",c),V(i,"$hasNormal",a),i}function ve(t,e,n,r){var i=function(){var e=lt;ft(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Kt(n))&&n[0];return ft(e),n&&(!i||1===n.length&&i.isComment&&!de(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function me(t,e){return function(){return t[e]}}function ge(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};V(e,"_v_attr_proxy",!0),ye(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ye(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||_e(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:$(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Ut(t,e,n)}))}}}function ye(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,be(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function be(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function _e(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var xe=null;function we(t,e){return(t.__esModule||ut&&"Module"===t[Symbol.toStringTag])&&(t=t.default),l(t)?e.extend(t):t}function ke(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(cn=function(){return un.now()})}var ln=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function fn(){var t,e;for(sn=cn(),on=!0,tn.sort(ln),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Ne(fn))}}function dn(t,e){if(t){for(var n=Object.create(null),r=ut?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!w(o,"default"))a=!1;else if(""===a||a===P(t)){var c=Dn(String,o.type);(c<0||s-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!d(t)&&t.test(e)}function Xn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Yn(n,i,r,o)}}}function Yn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,_(n,e)}Wn.prototype._init=function(t){var e=this;e._uid=qn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Bt(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=$n(Vn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ke(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=fe(e._renderChildren,o),t.$scopedSlots=n?he(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return je(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return je(t,e,n,r,o,!0)};var i=n&&n.data;Tt(t,"$attrs",i&&i.attrs||r,null,!0),Tt(t,"$listeners",e._parentListeners||r,null,!0)}(e),Ze(e,"beforeCreate",void 0,!1),function(t){var e=dn(t.$options.inject,t);e&&(Ot(!1),Object.keys(e).forEach((function(n){Tt(t,n,e[n])})),Ot(!0))}(e),Nn(e),function(t){var e=t.$options.provide;if(e){var n=u(e)?e.call(t):e;if(!l(n))return;for(var r=zt(t),o=ut?Reflect.ownKeys(n):Object.keys(n),i=0;i1?E(n):n;for(var r=E(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Yn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Jn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Jn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=ke(t),n=e&&e.componentOptions;if(n){var r=Kn(n),o=this.include,i=this.exclude;if(o&&(!r||!Jn(o,r))||i&&r&&Jn(i,r))return e;var a=this.cache,s=this.keys,c=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[c]?(e.componentInstance=a[c].componentInstance,_(s,c),s.push(c)):(this.vnodeToCache=e,this.keyToCache=c),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return z}};Object.defineProperty(t,"config",e),t.util={warn:wn,extend:T,mergeOptions:$n,defineReactive:Tt},t.set=At,t.delete=Rt,t.nextTick=Ne,t.observable=function(t){return Et(t),t},t.options=Object.create(null),F.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,T(t.options.components,Zn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=E(arguments,1);return n.unshift(this),u(t.install)?t.install.apply(t,n):u(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=$n(this.options,t),this}}(t),Gn(t),function(t){F.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&p(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&u(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:it}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:hn}),Wn.version="2.7.15";var tr=y("style,class"),er=y("input,textarea,option,select,progress"),nr=y("contenteditable,draggable,spellcheck"),rr=y("events,caret,typing,plaintext-only"),or=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},sr=function(t){return ar(t)?t.slice(6,t.length):""},cr=function(t){return null==t||!1===t};function ur(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=lr(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=lr(e,n.data));return function(t,e){if(a(t)||a(e))return fr(t,pr(e));return""}(e.staticClass,e.class)}function lr(t,e){return{staticClass:fr(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function fr(t,e){return t?e?t+" "+e:t:e||""}function pr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?Ir(t,e,n):or(e)?cr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return cr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?cr(n)?t.removeAttributeNS(ir,sr(e)):t.setAttributeNS(ir,e,n):Ir(t,e,n)}function Ir(t,e,n){if(cr(n))t.removeAttribute(e);else{if(X&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Mr={create:Lr,update:Lr};function Nr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var s=ur(e),c=n._transitionClasses;a(c)&&(s=fr(s,pr(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var Ur,Fr={create:Nr,update:Nr};function Br(t,e,n){var r=Ur;return function o(){var i=e.apply(null,arguments);null!==i&&qr(t,o,n,r)}}var zr=Ee&&!(et&&Number(et[1])<=53);function Hr(t,e,n,r){if(zr){var o=sn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ur.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function qr(t,e,n,r){(r||Ur).removeEventListener(t,e._wrapper||e,n)}function Vr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Ur=e.elm||t.elm,function(t){if(a(t.__r)){var e=X?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Vt(n,r,Hr,qr,Br,e.context),Ur=void 0}}var Wr,Gr={create:Vr,update:Vr,destroy:function(t){return Vr(t,kr)}};function Kr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,o=e.elm,c=t.data.domProps||{},u=e.data.domProps||{};for(n in(a(u.__ob__)||s(u._v_attr_proxy))&&(u=e.data.domProps=T({},u)),c)n in u||(o[n]="");for(n in u){if(r=u[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===c[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var l=i(r)?"":String(r);Jr(o,l)&&(o.value=l)}else if("innerHTML"===n&&vr(o.tagName)&&i(o.innerHTML)){(Wr=Wr||document.createElement("div")).innerHTML="".concat(r,"");for(var f=Wr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;f.firstChild;)o.appendChild(f.firstChild)}else if(r!==c[n])try{o[n]=r}catch(t){}}}}function Jr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(a(r)){if(r.number)return g(n)!==g(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xr={create:Kr,update:Kr},Yr=k((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Qr(t){var e=Zr(t.style);return t.staticStyle?T(t.staticStyle,e):e}function Zr(t){return Array.isArray(t)?A(t):"string"==typeof t?Yr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(P(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(co).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function lo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(co).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function fo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&T(e,po(t.name||"v")),T(e,t),e}return"string"==typeof t?po(t):void 0}}var po=k((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ho=K&&!Y,vo="transition",mo="transitionend",go="animation",yo="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(vo="WebkitTransition",mo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(go="WebkitAnimation",yo="webkitAnimationEnd"));var bo=K?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function _o(t){bo((function(){bo(t)}))}function xo(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),uo(t,e))}function wo(t,e){t._transitionClasses&&_(t._transitionClasses,e),lo(t,e)}function ko(t,e,n){var r=Co(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s="transition"===o?mo:yo,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n="transition",l=a,f=i.length):"animation"===e?u>0&&(n="animation",l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?"transition":"animation":null)?"transition"===n?i.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:"transition"===n&&jo.test(r[vo+"Property"])}}function So(t,e){for(;t.length1}function Ao(t,e){!0!==e.data.show&&Po(e)}var Ro=function(t){var e,n,r={},u=t.modules,l=t.nodeOps;for(e=0;eh?_(t,i(n[g+1])?null:n[g+1].elm,n,d,g,r):d>g&&w(e,f,h)}(f,v,g,n,u):a(g)?(a(t.text)&&l.setTextContent(f,""),_(f,null,g,0,g.length-1,n)):a(v)?w(v,0,v.length-1):a(t.text)&&l.setTextContent(f,""):t.text!==e.text&&l.setTextContent(f,e.text),a(h)&&a(d=h.hook)&&a(d=d.postpatch)&&d(t,e)}}}function S(t,e,n){if(s(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(I(No(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Mo(t,e){return e.every((function(e){return!I(e,t)}))}function No(t){return"_value"in t?t._value:t.value}function Uo(t){t.target.composing=!0}function Fo(t){t.target.composing&&(t.target.composing=!1,Bo(t.target,"input"))}function Bo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function zo(t){return!t.componentInstance||t.data&&t.data.transition?t:zo(t.componentInstance._vnode)}var Ho={model:Lo,show:{bind:function(t,e,n){var r=e.value,o=(n=zo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,Po(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=zo(n)).data&&n.data.transition?(n.data.show=!0,r?Po(n,(function(){t.style.display=t.__vOriginalDisplay})):$o(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},qo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Vo(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Vo(ke(e.children)):t}function Wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[C(r)]=o[r];return e}function Go(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Ko=function(t){return t.tag||de(t)},Jo=function(t){return"show"===t.name},Xo={name:"transition",props:qo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Ko)).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=Vo(o);if(!i)return o;if(this._leaving)return Go(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=Wo(this),u=this._vnode,l=Vo(u);if(i.data.directives&&i.data.directives.some(Jo)&&(i.data.show=!0),l&&l.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,l)&&!de(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=T({},s);if("out-in"===r)return this._leaving=!0,Wt(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Go(t,o);if("in-out"===r){if(de(i))return u;var p,d=function(){p()};Wt(s,"afterEnter",d),Wt(s,"enterCancelled",d),Wt(f,"delayLeave",(function(t){p=t}))}}return o}}},Yo=T({tag:String,moveClass:String},qo);function Qo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Zo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Yo.mode;var ei={Transition:Xo,TransitionGroup:{props:Yo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Wo(this),s=0;s-1?gr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:gr[t]=/HTMLUnknownElement/.test(e.toString())},T(Wn.options.directives,Ho),T(Wn.options.components,ei),Wn.prototype.__patch__=K?Ro:R,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=dt),Ze(t,"beforeMount"),r=function(){t._update(t._render(),n)},new qe(t,r,R,{before:function(){t._isMounted&&!t._isDestroyed&&Ze(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),u=e&&e.path||"/",l=c.path?wi(c.path,u,n||o.append):u,f=function(t,e,n){void 0===e&&(e={});var r,o=n||ui;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(ci):ci(a)}return r}(c.query,o.query,r&&r.options.parseQuery),p=o.hash||c.hash;return p&&"#"!==p.charAt(0)&&(p="#"+p),{_normalized:!0,path:l,query:f,hash:p}}var Hi,qi=function(){},Vi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,s=o.href,c={},u=n.options.linkActiveClass,l=n.options.linkExactActiveClass,f=null==u?"router-link-active":u,p=null==l?"router-link-exact-active":l,d=null==this.activeClass?f:this.activeClass,h=null==this.exactActiveClass?p:this.exactActiveClass,v=a.redirectedFrom?pi(null,zi(a.redirectedFrom),null,n):a;c[h]=gi(r,v,this.exactPath),c[d]=this.exact||this.exactPath?c[h]:function(t,e){return 0===t.path.replace(fi,"/").indexOf(e.path.replace(fi,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,v);var m=c[h]?this.ariaCurrentValue:null,g=function(t){Wi(t)&&(e.replace?n.replace(i,qi):n.push(i,qi))},y={click:Wi};Array.isArray(this.event)?this.event.forEach((function(t){y[t]=g})):y[this.event]=g;var b={class:c},_=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:s,route:a,navigate:g,isActive:c[d],isExactActive:c[h]});if(_){if(1===_.length)return _[0];if(_.length>1||!_.length)return 0===_.length?t():t("span",{},_)}if("a"===this.tag)b.on=y,b.attrs={href:s,"aria-current":m};else{var x=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=Bi(l.path,s.params),c(l,s,a)}if(s.path){s.params={};for(var d=0;d-1}function ka(t,e){return wa(t)&&t._isRouter&&(null==e||t.type===e)}function ja(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function Ca(t){return function(e,n,r){var o=!1,i=0,a=null;Sa(t,(function(t,e,n,s){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var c,u=$a((function(e){var o;((o=e).__esModule||Pa&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:Hi.extend(e),n.components[s]=e,--i<=0&&r()})),l=$a((function(t){var e="Failed to resolve async component "+s+": "+t;a||(a=wa(t)?t:new Error(e),r(a))}));try{c=t(u,l)}catch(t){l(t)}if(c)if("function"==typeof c.then)c.then(u,l);else{var f=c.component;f&&"function"==typeof f.then&&f.then(u,l)}}})),o||r()}}function Sa(t,e){return Oa(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Oa(t){return Array.prototype.concat.apply([],t)}var Pa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function $a(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var Ea=function(t,e){this.router=t,this.base=function(t){if(!t)if(Gi){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Ta(t,e,n,r){var o=Sa(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=Hi.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return Oa(r?o.reverse():o)}function Aa(t,e){if(e)return function(){return t.apply(e,arguments)}}Ea.prototype.listen=function(t){this.cb=t},Ea.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Ea.prototype.onError=function(t){this.errorCbs.push(t)},Ea.prototype.transitionTo=function(t,e,n){var r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(ka(t,ga.redirected)&&i===hi||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Ea.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,s=function(t){!ka(t)&&wa(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},c=t.matched.length-1,u=o.matched.length-1;if(gi(t,o)&&c===u&&t.matched[c]===o.matched[u])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),s(((a=_a(i=o,t,ga.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var l=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=ha&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=La(t.base);t.current===hi&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){va(ki(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){ma(ki(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(La(this.base)!==this.current.fullPath){var e=ki(this.base+this.current.fullPath);t?va(e):ma(e)}},e.prototype.getCurrentLocation=function(){return La(this.base)},e}(Ea);function La(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(ki(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var Da=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=La(t);if(!/^\/#/.test(e))return window.location.replace(ki(t+"/#"+e)),!0}(this.base)||Ia()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ha&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;Ia()&&t.transitionTo(Ma(),(function(r){n&&ia(t.router,r,e,!0),ha||Fa(r.fullPath)}))},o=ha?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Ua(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Fa(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ma()!==e&&(t?Ua(e):Fa(e))},e.prototype.getCurrentLocation=function(){return Ma()},e}(Ea);function Ia(){var t=Ma();return"/"===t.charAt(0)||(Fa("/"+t),!1)}function Ma(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Na(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ua(t){ha?va(Na(t)):window.location.hash=t}function Fa(t){ha?ma(Na(t)):window.location.replace(Na(t))}var Ba=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){ka(t,ga.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Ea),za=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xi(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),Gi||(e="abstract"),this.mode=e,e){case"history":this.history=new Ra(this,t.base);break;case"hash":this.history=new Da(this,t.base,this.fallback);break;case"abstract":this.history=new Ba(this,t.base);break;default:0}},Ha={currentRoute:{configurable:!0}};za.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},Ha.currentRoute.get=function(){return this.history&&this.history.current},za.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Ra||n instanceof Da){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;ha&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},za.prototype.beforeEach=function(t){return Va(this.beforeHooks,t)},za.prototype.beforeResolve=function(t){return Va(this.resolveHooks,t)},za.prototype.afterEach=function(t){return Va(this.afterHooks,t)},za.prototype.onReady=function(t,e){this.history.onReady(t,e)},za.prototype.onError=function(t){this.history.onError(t)},za.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},za.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},za.prototype.go=function(t){this.history.go(t)},za.prototype.back=function(){this.go(-1)},za.prototype.forward=function(){this.go(1)},za.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},za.prototype.resolve=function(t,e,n){var r=zi(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?ki(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},za.prototype.getRoutes=function(){return this.matcher.getRoutes()},za.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},za.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(za.prototype,Ha);var qa=za;function Va(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}za.install=function t(e){if(!t.installed||Hi!==e){t.installed=!0,Hi=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",_i),e.component("RouterLink",Vi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},za.version="3.6.5",za.isNavigationFailure=ka,za.NavigationFailureType=ga,za.START_LOCATION=hi,Gi&&window.Vue&&window.Vue.use(za);n(97);n(90),n(127);var Wa={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(13)]).then(n.bind(null,308)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,254)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(21)]).then(n.bind(null,242)),"components/Home":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,280)),"components/NavLink":()=>n.e(25).then(n.bind(null,241)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(12)]).then(n.bind(null,265)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,305)),"components/Page":()=>Promise.all([n.e(0),n.e(11)]).then(n.bind(null,281)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(17)]).then(n.bind(null,267)),"components/PageNav":()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,268)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,282)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,283)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,266)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,255)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,253)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,313)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,309)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,310)),"layouts/404":()=>n.e(7).then(n.bind(null,311)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,312)),NotFound:()=>n.e(7).then(n.bind(null,311)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,312))},Ga={"v-1eac5cb4":()=>n.e(27).then(n.bind(null,314)),"v-40dcf956":()=>n.e(28).then(n.bind(null,315)),"v-dfcacf96":()=>n.e(33).then(n.bind(null,316)),"v-78306615":()=>n.e(32).then(n.bind(null,317)),"v-aedf3696":()=>n.e(29).then(n.bind(null,318)),"v-64abe1b5":()=>n.e(30).then(n.bind(null,319)),"v-b8121e94":()=>n.e(31).then(n.bind(null,320)),"v-225c66b5":()=>n.e(35).then(n.bind(null,321)),"v-178eb16c":()=>n.e(34).then(n.bind(null,322)),"v-43b0c156":()=>n.e(36).then(n.bind(null,323)),"v-085239d5":()=>n.e(23).then(n.bind(null,324)),"v-5a4af379":()=>n.e(37).then(n.bind(null,325)),"v-b5136f54":()=>n.e(39).then(n.bind(null,326)),"v-365886f1":()=>n.e(38).then(n.bind(null,327)),"v-76e59095":()=>n.e(40).then(n.bind(null,328)),"v-4df42816":()=>n.e(42).then(n.bind(null,329)),"v-42b19e9a":()=>n.e(41).then(n.bind(null,330)),"v-40aa7396":()=>n.e(43).then(n.bind(null,331)),"v-17b9aed6":()=>n.e(45).then(n.bind(null,332)),"v-a719b856":()=>n.e(44).then(n.bind(null,333)),"v-fc35af56":()=>n.e(46).then(n.bind(null,334)),"v-27dc3235":()=>n.e(47).then(n.bind(null,335)),"v-5351c127":()=>n.e(26).then(n.bind(null,336)),"v-326e2f8e":()=>n.e(48).then(n.bind(null,337)),"v-0570de42":()=>n.e(49).then(n.bind(null,338)),"v-31c5a575":()=>n.e(19).then(n.bind(null,339)),"v-84a4a916":()=>n.e(24).then(n.bind(null,340)),"v-90f25216":()=>n.e(51).then(n.bind(null,341)),"v-324d1e36":()=>n.e(53).then(n.bind(null,342)),"v-94bf939e":()=>n.e(52).then(n.bind(null,343)),"v-72824323":()=>n.e(20).then(n.bind(null,344)),"v-3a18de15":()=>n.e(54).then(n.bind(null,345)),"v-a8f38b16":()=>n.e(50).then(n.bind(null,346)),"v-7a9a4235":()=>n.e(56).then(n.bind(null,347)),"v-165e6eb5":()=>n.e(55).then(n.bind(null,348))};function Ka(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Ja=/-(\w)/g,Xa=Ka(t=>t.replace(Ja,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Qa=Ka(t=>t.replace(Ya,"-$1").toLowerCase()),Za=Ka(t=>t.charAt(0).toUpperCase()+t.slice(1));function ts(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Za(Xa(e))):t(Za(e))||t(Qa(e))}const es=Object.assign({},Wa,Ga),ns=t=>es[t],rs=t=>Ga[t],os=t=>Wa[t],is=t=>Wn.component(t);function as(t){return ts(rs,t)}function ss(t){return ts(os,t)}function cs(t){return ts(ns,t)}function us(t){return ts(is,t)}function ls(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!us(t)&&cs(t)){const e=await cs(t)();Wn.component(t,e.default)}}))}function fs(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var ps=n(87),ds=n.n(ps),hs=n(88),vs=n.n(hs),ms={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${vs()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=ys(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=bs(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return ds()([{name:"description",content:this.$description}],t,this.siteMeta,_s)},updateCanonicalLink(){gs(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",ys(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){bs(null,this.currentMetaTags),gs()}};function gs(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function ys(t=""){return t?``:""}function bs(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function _s(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var xs=n(89),ws={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(xs)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},ks=n(22),js=n.n(ks),Cs=[ms,ws,{mounted(){js.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Wn.component(t.name)||js.a.start(),n()}),this.$router.afterEach(()=>{js.a.done(),this.isSidebarOpen=!1})}}],Ss={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return fs("layout",t),Wn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Os=n(14),Ps=Object(Os.a)(Ss,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Ps,"mixins",Cs);const $s=[{name:"v-1eac5cb4",path:"/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-1eac5cb4").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-40dcf956",path:"/guide/javascript/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-40dcf956").then(n)}},{path:"/guide/javascript/index.html",redirect:"/guide/javascript/"},{name:"v-dfcacf96",path:"/guide/nextjs/nextjs-study-notes.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-dfcacf96").then(n)}},{name:"v-78306615",path:"/guide/nextjs/nextjs-basic.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-78306615").then(n)}},{name:"v-aedf3696",path:"/guide/javascript/js-array.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-aedf3696").then(n)}},{name:"v-64abe1b5",path:"/guide/javascript/js-study-notes.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-64abe1b5").then(n)}},{name:"v-b8121e94",path:"/guide/nextjs/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-b8121e94").then(n)}},{path:"/guide/nextjs/index.html",redirect:"/guide/nextjs/"},{name:"v-225c66b5",path:"/guide/react/react-study-notes.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-225c66b5").then(n)}},{name:"v-178eb16c",path:"/guide/react/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-178eb16c").then(n)}},{path:"/guide/react/index.html",redirect:"/guide/react/"},{name:"v-43b0c156",path:"/guide/react/reactBasics.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-43b0c156").then(n)}},{name:"v-085239d5",path:"/guide/react/reactRouter.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-085239d5").then(n)}},{name:"v-5a4af379",path:"/guide/react/reactHooks.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-5a4af379").then(n)}},{name:"v-b5136f54",path:"/guide/typescript/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-b5136f54").then(n)}},{path:"/guide/typescript/index.html",redirect:"/guide/typescript/"},{name:"v-365886f1",path:"/guide/react/reactRedux.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-365886f1").then(n)}},{name:"v-76e59095",path:"/guide/typescript/advanced.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-76e59095").then(n)}},{name:"v-4df42816",path:"/memo/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-4df42816").then(n)}},{path:"/memo/index.html",redirect:"/memo/"},{name:"v-42b19e9a",path:"/guide/typescript/basic.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-42b19e9a").then(n)}},{name:"v-40aa7396",path:"/memo/archtiect.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-40aa7396").then(n)}},{name:"v-17b9aed6",path:"/memo/config.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-17b9aed6").then(n)}},{name:"v-a719b856",path:"/memo/arrayusage.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-a719b856").then(n)}},{name:"v-fc35af56",path:"/memo/docker.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-fc35af56").then(n)}},{name:"v-27dc3235",path:"/memo/formikandyup.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-27dc3235").then(n)}},{name:"v-5351c127",path:"/memo/git.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-5351c127").then(n)}},{name:"v-326e2f8e",path:"/memo/graphql.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-326e2f8e").then(n)}},{name:"v-0570de42",path:"/memo/jenkins.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-0570de42").then(n)}},{name:"v-31c5a575",path:"/memo/jsreview.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-31c5a575").then(n)}},{name:"v-84a4a916",path:"/memo/strapi.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-84a4a916").then(n)}},{name:"v-90f25216",path:"/memo/typescript.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-90f25216").then(n)}},{name:"v-324d1e36",path:"/practice/",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-324d1e36").then(n)}},{path:"/practice/index.html",redirect:"/practice/"},{name:"v-94bf939e",path:"/memo/webpack.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-94bf939e").then(n)}},{name:"v-72824323",path:"/memo/redux.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-72824323").then(n)}},{name:"v-3a18de15",path:"/practice/github.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-3a18de15").then(n)}},{name:"v-a8f38b16",path:"/memo/reacthooks.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-a8f38b16").then(n)}},{name:"v-7a9a4235",path:"/practice/todolist.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-7a9a4235").then(n)}},{name:"v-165e6eb5",path:"/practice/shoppingcart.html",component:Ps,beforeEnter:(t,e,n)=>{ls("Layout","v-165e6eb5").then(n)}},{path:"*",component:Ps}],Es={title:"☻ itsyuimorii.space",description:" ",base:"/",headTags:[],pages:[{title:"Home",frontmatter:{home:!0,heroImage:"./logo.jpg",heroText:"itsyuimoriispace〰️",tagline:"私の技術ブログ - for sharing personal learning notes from 📚学び、💢知識、🪴成長する。",actionText:"Read more →",actionLink:"/zh/guide/",features:[{title:"📚 読書メモ",details:"Reading is a discount ticket to everywhere. - Mary Schmich"},{title:"📩 知識を共有する",details:"In the process of letting go you will lose many things from the past, but you will find yourself. - Deepak Chopra"},{title:"🪴 成長する",details:"The key to growth is the introduction of higher dimensions of consciousness into our awareness. - Lao Tzu"}],footer:"MIT Licensed | Copyright © 2022-present ♥ itsyuimoriispace"},regularPath:"/",relativePath:"README.md",key:"v-1eac5cb4",path:"/"},{title:"Javascript guide",frontmatter:{},regularPath:"/guide/javascript/",relativePath:"guide/javascript/README.md",key:"v-40dcf956",path:"/guide/javascript/"},{title:"⚪️ Next.js-articles の研究例をいくつか",frontmatter:{sidebarDepth:3},regularPath:"/guide/nextjs/nextjs-study-notes.html",relativePath:"guide/nextjs/nextjs-study-notes.md",key:"v-dfcacf96",path:"/guide/nextjs/nextjs-study-notes.html"},{title:"1. What is getStaticProps && getStaticPaths",frontmatter:{},regularPath:"/guide/nextjs/nextjs-basic.html",relativePath:"guide/nextjs/nextjs-basic.md",key:"v-78306615",path:"/guide/nextjs/nextjs-basic.html",headers:[{level:2,title:"1. What is getStaticProps && getStaticPaths",slug:"_1-what-is-getstaticprops-getstaticpaths"},{level:3,title:"getStaticProps",slug:"getstaticprops"},{level:3,title:"getStaticPaths",slug:"getstaticpaths"},{level:3,title:":lightbulbon: Considerations",slug:"light-bulb-on-considerations"},{level:2,title:"2. Deep understanding getStaticProps",slug:"_2-deep-understanding-getstaticprops"},{level:3,title:"Benefits",slug:"benefits"},{level:2,title:"Invocation Timing",slug:"invocation-timing"},{level:3,title:":lightbulbon:JSON File and Data Access",slug:"light-bulb-on-json-file-and-data-access"},{level:3,title:"Key Takeaways:",slug:"key-takeaways"},{level:2,title:"3. Deep understanding `getStaticPaths",slug:"_3-deep-understanding-getstaticpaths"},{level:3,title:":lightbulbon: Using getStaticPaths",slug:"light-bulb-on-using-getstaticpaths"},{level:3,title:":lightbulbon: Understanding getStaticPaths Operation:",slug:"light-bulb-on-understanding-getstaticpaths-operation"},{level:3,title:":lightbulbon: Understanding the fallback Parameter in Next.js",slug:"light-bulb-on-understanding-the-fallback-parameter-in-next-js"},{level:3,title:":lightbulbon: Understanding getStaticProps and getServerSideProps in Next.js",slug:"light-bulb-on-understanding-getstaticprops-and-getserversideprops-in-next-js"},{level:3,title:":lightbulbon: When to Use getStaticProps",slug:"light-bulb-on-when-to-use-getstaticprops"},{level:2,title:"Pre-rendering",slug:"pre-rendering"},{level:2,title:"Two Forms of Pre-rendering",slug:"two-forms-of-pre-rendering"},{level:3,title:"Static generation:",slug:"static-generation"},{level:3,title:"Server-Side Rendering (SSR)",slug:"server-side-rendering-ssr"},{level:2,title:"How to Enabling Static Generation",slug:"how-to-enabling-static-generation"},{level:3,title:"Production Server vs. Development Server",slug:"production-server-vs-development-server"},{level:2,title:"Fetching Data at Request Time",slug:"fetching-data-at-request-time"},{level:3,title:"Data Fetching with Dynamic Parameters and Client-Side Data Fetching",slug:"data-fetching-with-dynamic-parameters-and-client-side-data-fetching"},{level:3,title:"Combining Pre-rendering with Client-Side Data Fetching",slug:"combining-pre-rendering-with-client-side-data-fetching"}]},{title:"⚪️ 【JavaScript 入門】 配列の使い方と操作まとめ(初期化・追加・結合・検索・削除)",frontmatter:{sidebarDepth:3},regularPath:"/guide/javascript/js-array.html",relativePath:"guide/javascript/js-array.md",key:"v-aedf3696",path:"/guide/javascript/js-array.html",headers:[{level:2,title:"🔶 【実践】「配列」の活用技",slug:"🔶-【実践】「配列」の活用技"},{level:2,title:"🔶 方法详解",slug:"🔶-方法详解"},{level:3,title:"🔸 1. push()",slug:"🔸-1-push"},{level:3,title:"🔸 2. unshift()",slug:"🔸-2-unshift"},{level:3,title:"🔸 3. pop()",slug:"🔸-3-pop"},{level:3,title:"🔸 4. shift()",slug:"🔸-4-shift"},{level:3,title:"🔸 5. reverse()",slug:"🔸-5-reverse"},{level:3,title:"🔸 6. sort()",slug:"🔸-6-sort"},{level:3,title:"🔸 7. splice()",slug:"🔸-7-splice"},{level:3,title:"为什么需要深拷贝?",slug:"为什么需要深拷贝"},{level:3,title:"正确的做法",slug:"正确的做法"},{level:3,title:"🔸 8. concat()",slug:"🔸-8-concat"},{level:3,title:"🔸 9. join()",slug:"🔸-9-join"},{level:3,title:"🔸 10. slice()",slug:"🔸-10-slice"},{level:3,title:"🔸 11. toString()",slug:"🔸-11-tostring"},{level:3,title:"🔸 12. valueOf()",slug:"🔸-12-valueof"},{level:3,title:"🔸 13. indexOf()",slug:"🔸-13-indexof"},{level:3,title:"🔸 14. lastIndexOf()",slug:"🔸-14-lastindexof"},{level:3,title:"🔸 15. forEach()",slug:"🔸-15-foreach"},{level:3,title:"🔸 16. map()",slug:"🔸-16-map"},{level:3,title:"🔸 17. filter()",slug:"🔸-17-filter"},{level:3,title:"🔸 18. every()",slug:"🔸-18-every"},{level:3,title:"🔸 19. some()",slug:"🔸-19-some"},{level:3,title:"🔸 20. reduce()",slug:"🔸-20-reduce"},{level:3,title:"🔸 21. reduceRight()",slug:"🔸-21-reduceright"},{level:3,title:"🔸 22. includes()",slug:"🔸-22-includes"},{level:3,title:"23.🔸 from()",slug:"_23-🔸-from"},{level:3,title:"24. 🔸 find()",slug:"_24-🔸-find"},{level:3,title:"25. 🔸 findIndex()",slug:"_25-🔸-findindex"},{level:3,title:"26. 🔸 fill()",slug:"_26-🔸-fill"},{level:3,title:"27. 🔸 flat()",slug:"_27-🔸-flat"},{level:3,title:"28. 🔸 flatMap()",slug:"_28-🔸-flatmap"}]},{title:"⚪️ Javascript -articles の研究例をいくつか",frontmatter:{sidebarDepth:3},regularPath:"/guide/javascript/js-study-notes.html",relativePath:"guide/javascript/js-study-notes.md",key:"v-64abe1b5",path:"/guide/javascript/js-study-notes.html"},{title:"Next.js",frontmatter:{},regularPath:"/guide/nextjs/",relativePath:"guide/nextjs/README.md",key:"v-b8121e94",path:"/guide/nextjs/"},{title:"⚪️ React.js -articles の研究例をいくつか",frontmatter:{sidebarDepth:3},regularPath:"/guide/react/react-study-notes.html",relativePath:"guide/react/react-study-notes.md",key:"v-225c66b5",path:"/guide/react/react-study-notes.html",headers:[{level:2,title:"🔸 React SSR 原理解析和实践",slug:"🔸-react-ssr-原理解析和实践"},{level:2,title:"🔸 从零开始 React 服务器渲染(SSR)同构 😏(基于 Koa",slug:"🔸-从零开始-react-服务器渲染-ssr-同构-😏-基于-koa"},{level:2,title:"🔸 React 服务端渲染从入门到精通",slug:"🔸-react-服务端渲染从入门到精通"}]},{title:"React",frontmatter:{},regularPath:"/guide/react/",relativePath:"guide/react/README.md",key:"v-178eb16c",path:"/guide/react/",headers:[{level:2,title:"References",slug:"references"}]},{title:"⚪️React を基礎から理解する",frontmatter:{sidebarDepth:3},regularPath:"/guide/react/reactBasics.html",relativePath:"guide/react/reactBasics.md",key:"v-43b0c156",path:"/guide/react/reactBasics.html",headers:[{level:2,title:"🔶 React API とは",slug:"🔶-react-api-とは"},{level:2,title:"🔶 React API の種類",slug:"🔶-react-api-の種類"},{level:3,title:"▫️ React.createElement",slug:"▫️-react-createelement"},{level:3,title:"▫️ReactDOM.createRoot",slug:"▫️reactdom-createroot"},{level:3,title:"▫️ReactDOM.render",slug:"▫️reactdom-render"}]},{title:"⚪️ React Router を基礎から理解する",frontmatter:{sidebarDepth:3},regularPath:"/guide/react/reactRouter.html",relativePath:"guide/react/reactRouter.md",key:"v-085239d5",path:"/guide/react/reactRouter.html",headers:[{level:2,title:"🔶 Basic Purpose",slug:"🔶-basic-purpose"},{level:2,title:"🔶 様々なシーン",slug:"🔶-様々なシーン"},{level:3,title:"▫️ Takeaway 01: 理解匹配失敗的處理: 對象useRouteError() 和 errorElement",slug:"▫️-takeaway-01-理解匹配失敗的處理-對象userouteerror-和-errorelement"},{level:3,title:"▫️ Takeaway 02: 理解 nested-routes的概念",slug:"▫️-takeaway-02-理解-nested-routes的概念"},{level:3,title:"▫️ Takeaway 03: 👉 将侧边栏更改",slug:"▫️-takeaway-03-👉-将侧边栏更改-a-href-为-link-to"},{level:2,title:"🔶 loader and action",slug:"🔶-loader-and-action"},{level:3,title:"▫️ Takeaway 01: 傳統式 form 表單的提交",slug:"▫️-takeaway-01-傳統式-form-表單的提交"},{level:3,title:"▫️ Takeaway 02: 理解 loader and actionß",slug:"▫️-takeaway-02-理解-loader-and-actionß"},{level:2,title:"🔶 URL params in Loader",slug:"🔶-url-params-in-loader"},{level:2,title:"🔶 Updating data",slug:"🔶-updating-data"}]},{title:"⚪️ React Hooks を基礎から理解する",frontmatter:{sidebarDepth:3},regularPath:"/guide/react/reactHooks.html",relativePath:"guide/react/reactHooks.md",key:"v-5a4af379",path:"/guide/react/reactHooks.html",headers:[{level:2,title:"🔷 useState とは",slug:"🔷-usestate-とは"},{level:3,title:"▫️ useState の注意点",slug:"▫️-usestate-の注意点"},{level:2,title:"🔶 useReducer とは",slug:"🔶-usereducer-とは"},{level:3,title:"▫️ useReducer の注意点",slug:"▫️-usereducer-の注意点"},{level:2,title:"🔷 useContext とは",slug:"🔷-usecontext-とは"},{level:2,title:"🔷 useEffect とは",slug:"🔷-useeffect-とは"},{level:3,title:"▫️ 副作用を実行、制御するために useEffect を利用する",slug:"▫️-副作用を実行、制御するために-useeffect-を利用する"},{level:3,title:"▫️ 執行時機",slug:"▫️-執行時機"},{level:3,title:"▫️ useEffect の使い方",slug:"▫️-useeffect-の使い方"},{level:3,title:"▫️ useEffect 依賴項",slug:"▫️-useeffect-依賴項"},{level:2,title:"🔷 useRef とは",slug:"🔷-useref-とは"},{level:2,title:"🔷 useCallback とは",slug:"🔷-usecallback-とは"},{level:3,title:"🔺 Example",slug:"🔺-example"},{level:2,title:"🔷 useMemo とは",slug:"🔷-usememo-とは"},{level:2,title:"🔶 Hooks compare",slug:"🔶-hooks-compare"},{level:3,title:"▫️ useCallback vs useMemo",slug:"▫️-usecallback-vs-usememo"}]},{title:"Typescript Reference Guide",frontmatter:{},regularPath:"/guide/typescript/",relativePath:"guide/typescript/README.md",key:"v-b5136f54",path:"/guide/typescript/",headers:[{level:2,title:"Shortcut Reference",slug:"shortcut-reference"},{level:2,title:"Table of Contents",slug:"table-of-contents"}]},{title:"React Redux を基礎から理解する",frontmatter:{sidebarDepth:3},regularPath:"/guide/react/reactRedux.html",relativePath:"guide/react/reactRedux.md",key:"v-365886f1",path:"/guide/react/reactRedux.html"},{title:"⚪️ TypeScript Advanced Knowledge",frontmatter:{sidebarDepth:3},regularPath:"/guide/typescript/advanced.html",relativePath:"guide/typescript/advanced.md",key:"v-76e59095",path:"/guide/typescript/advanced.html",headers:[{level:2,title:"Type Aliases",slug:"type-aliases"},{level:2,title:"String Literal Types",slug:"string-literal-types"},{level:2,title:"Tuples",slug:"tuples"},{level:3,title:"Accessing Tuple Elements",slug:"accessing-tuple-elements"},{level:3,title:"Tuple Overflow",slug:"tuple-overflow"},{level:2,title:"Enum",slug:"enum"},{level:3,title:"Incremental Enum:",slug:"incremental-enum"},{level:3,title:"String Enum:",slug:"string-enum"},{level:3,title:"heterogeneous enum",slug:"heterogeneous-enum"},{level:3,title:"interface enum",slug:"interface-enum"},{level:3,title:"const enum",slug:"const-enum"},{level:3,title:"Reverse mapping",slug:"reverse-mapping"},{level:2,title:"Classes",slug:"classes"},{level:3,title:"readonly",slug:"readonly"},{level:3,title:"Instance Properties",slug:"instance-properties"},{level:3,title:"Static Properties",slug:"static-properties"},{level:3,title:"Access Modifiers",slug:"access-modifiers"},{level:3,title:"Getters and Setters",slug:"getters-and-setters"},{level:3,title:"Abstract Classes",slug:"abstract-classes"},{level:3,title:"Here are a few common scenarios where abstract classes are beneficial in TypeScript:",slug:"here-are-a-few-common-scenarios-where-abstract-classes-are-beneficial-in-typescript"},{level:2,title:"Class and Interface Interactions",slug:"class-and-interface-interactions"},{level:3,title:"Class Implements Interface",slug:"class-implements-interface"},{level:2,title:"generators and iterators",slug:"generators-and-iterators"},{level:3,title:"Iterators",slug:"iterators"},{level:3,title:"Generators",slug:"generators"},{level:3,title:"Using Generators and Iterators",slug:"using-generators-and-iterators"},{level:2,title:"Generics",slug:"generics"},{level:3,title:"Basic Usage",slug:"basic-usage"},{level:3,title:"Multiple Type Parameters",slug:"multiple-type-parameters"},{level:3,title:"Generic Constraints",slug:"generic-constraints"},{level:3,title:"Generic Interface",slug:"generic-interface"},{level:3,title:"Generic Class",slug:"generic-class"},{level:3,title:"Default Generic Types",slug:"default-generic-types"},{level:3,title:"More Generics",slug:"more-generics"},{level:2,title:"Common Techniques",slug:"common-techniques"},{level:3,title:"Extracting Variable Types",slug:"extracting-variable-types"},{level:3,title:"Binding Function this",slug:"binding-function-this"},{level:3,title:"Index Variables",slug:"index-variables"},{level:3,title:"Built-in Types",slug:"built-in-types"},{level:3,title:"🔹 index signature",slug:"🔹-index-signature"},{level:3,title:"Accessing object properties dynamically in TypeScript",slug:"accessing-object-properties-dynamically-in-typescript"},{level:2,title:"Reference Articles",slug:"reference-articles"}]},{title:"🔺 MEMO メモ",frontmatter:{},regularPath:"/memo/",relativePath:"memo/README.md",key:"v-4df42816",path:"/memo/",headers:[{level:3,title:"🔺 react",slug:"🔺-react"},{level:3,title:"🔺 reactHooks",slug:"🔺-reacthooks"},{level:3,title:"🔺 typescript",slug:"🔺-typescript"}]},{title:"🔶 TypeScript Basic Knowledge",frontmatter:{sidebarDepth:3},regularPath:"/guide/typescript/basic.html",relativePath:"guide/typescript/basic.md",key:"v-42b19e9a",path:"/guide/typescript/basic.html",headers:[{level:2,title:"🔸 Primitive Types",slug:"🔸-primitive-types"},{level:2,title:"Any Type",slug:"any-type"},{level:2,title:"🔸 Never",slug:"🔸-never"},{level:2,title:"型アノテーション(Type Annotation)",slug:"型アノテーション-type-annotation"},{level:2,title:"型推論(Type Inference)",slug:"型推論-type-inference"},{level:2,title:"Union Types",slug:"union-types"},{level:2,title:"Object Types - Interface",slug:"object-types-interface"},{level:2,title:"Array Types",slug:"array-types"},{level:2,title:"Function Types",slug:"function-types"},{level:2,title:"Type Assertion",slug:"type-assertion"},{level:2,title:"Declaration Files",slug:"declaration-files"},{level:3,title:"Declaration Merging",slug:"declaration-merging"}]},{title:"## Backend for Frontend",frontmatter:{},regularPath:"/memo/archtiect.html",relativePath:"memo/archtiect.md",key:"v-40aa7396",path:"/memo/archtiect.html",headers:[{level:2,title:"Backend for Frontend",slug:"backend-for-frontend"},{level:2,title:"GraphQL 来实现 BFF,需要掌握哪些技能?",slug:"graphql-来实现-bff-需要掌握哪些技能"},{level:3,title:"React Frontend Example",slug:"react-frontend-example"},{level:3,title:"Backend for Frontend (BFF) Example with Java/Spring Boot",slug:"backend-for-frontend-bff-example-with-java-spring-boot"}]},{title:"⚪️ コンフィギュレーション",frontmatter:{sidebarDepth:3},regularPath:"/memo/config.html",relativePath:"memo/config.md",key:"v-17b9aed6",path:"/memo/config.html",headers:[{level:2,title:"Install & Update nvm",slug:"install-update-nvm"}]},{title:"🔻 使用される場面",frontmatter:{sidebarDepth:3},regularPath:"/memo/arrayusage.html",relativePath:"memo/arrayusage.md",key:"v-a719b856",path:"/memo/arrayusage.html",headers:[{level:2,title:"🔻 使用される場面",slug:"🔻-使用される場面"},{level:3,title:"例子 1: JavaScript Data Transformation Using `Object.values` and `map`",slug:"例子-1-javascript-data-transformation-using-object-values-and-map"},{level:3,title:"例子 2: 用`Array.prototype.reduce` 把 `array` 轉換成 `object`",slug:"例子-2-用array-prototype-reduce-把-array-轉換成-object"},{level:3,title:"称为“属性访问器语法”",slug:"称为-属性访问器语法"},{level:2,title:"🔻 Dan tutorial チュートリアル",slug:"🔻-dan-tutorial-チュートリアル"}]},{title:"⚪️ dockers",frontmatter:{sidebarDepth:3},regularPath:"/memo/docker.html",relativePath:"memo/docker.md",key:"v-fc35af56",path:"/memo/docker.html"},{title:"⚪️ dockers",frontmatter:{sidebarDepth:3},regularPath:"/memo/formikandyup.html",relativePath:"memo/formikandyup.md",key:"v-27dc3235",path:"/memo/formikandyup.html"},{title:"⚪️ git and github への深い理解",frontmatter:{},regularPath:"/memo/git.html",relativePath:"memo/git.md",key:"v-5351c127",path:"/memo/git.html",headers:[{level:2,title:"git branch",slug:"git-branch"},{level:2,title:"git rebase fix old commit",slug:"git-rebase-fix-old-commit"},{level:2,title:"Fix the most recent commit message",slug:"fix-the-most-recent-commit-message"},{level:2,title:"git commit message",slug:"git-commit-message"},{level:3,title:"Scenario",slug:"scenario"},{level:3,title:"Development and Commits",slug:"development-and-commits"},{level:3,title:"Squashing Commits",slug:"squashing-commits"},{level:3,title:"Commit Message Following Conventional Commits",slug:"commit-message-following-conventional-commits"},{level:3,title:"Automating CHANGELOG with Conventional Commits",slug:"automating-changelog-with-conventional-commits"},{level:3,title:"Summary",slug:"summary"}]},{title:"⚪️ graphql",frontmatter:{sidebarDepth:3},regularPath:"/memo/graphql.html",relativePath:"memo/graphql.md",key:"v-326e2f8e",path:"/memo/graphql.html"},{title:"⚪️ jinkens",frontmatter:{sidebarDepth:3},regularPath:"/memo/jenkins.html",relativePath:"memo/jenkins.md",key:"v-0570de42",path:"/memo/jenkins.html"},{title:"⚪️ JavaScript 深い理解と実践",frontmatter:{sidebarDepth:3},regularPath:"/memo/jsreview.html",relativePath:"memo/jsreview.md",key:"v-31c5a575",path:"/memo/jsreview.html",headers:[{level:2,title:"🔶 Reference vs Primitive",slug:"🔶-reference-vs-primitive"},{level:3,title:"▫️ Reference Types in JavaScript:",slug:"▫️-reference-types-in-javascript"},{level:3,title:'▫️ Strange Behavior of "Reference Types"',slug:"▫️-strange-behavior-of-reference-types"},{level:3,title:"▫️ How to Copy Objects and Arrays:",slug:"▫️-how-to-copy-objects-and-arrays"},{level:2,title:"🔶 Deconstruction Assignment",slug:"🔶-deconstruction-assignment"},{level:3,title:"▫️ Deconstructing Objects",slug:"▫️-deconstructing-objects"},{level:3,title:"▫️ Deconstructing Arrays",slug:"▫️-deconstructing-arrays"},{level:2,title:"🔶 Arrow function の理解",slug:"🔶-arrow-function-の理解"},{level:2,title:'🔶 キーワード "this "の理解',slug:"🔶-キーワード-this-の理解"},{level:3,title:"アロー関数で書く理由 ① 関数を短く書きたい",slug:"アロー関数で書く理由-1-関数を短く書きたい"},{level:3,title:"アロー関数で書く理由 ② this を束縛しない",slug:"アロー関数で書く理由-2-this-を束縛しない"},{level:3,title:"メソッド呼び出しパターン",slug:"メソッド呼び出しパターン"},{level:2,title:'🔶 キーワード "class"の理解',slug:"🔶-キーワード-class-の理解"},{level:3,title:"Class の 基本概念",slug:"class-の-基本概念"},{level:3,title:"Strict mode && Class",slug:"strict-mode-class"},{level:3,title:"箭頭函數在 Class 中的影響",slug:"箭頭函數在-class-中的影響"},{level:3,title:"クラスの継承",slug:"クラスの継承"},{level:2,title:"🔶 Static Properties and Static Methods in Classes",slug:"🔶-static-properties-and-static-methods-in-classes"},{level:2,title:"🔷 Array 主なメソッド",slug:"🔷-array-主なメソッド"},{level:3,title:"▫️ Array.prototype.push()",slug:"▫️-array-prototype-push"},{level:3,title:"▫️Array.prototype.from()",slug:"▫️array-prototype-from"},{level:3,title:"▫️Array.prototype.fill()",slug:"▫️array-prototype-fill"},{level:3,title:"填充唯一對象",slug:"填充唯一對象"},{level:3,title:"使用 for 循環",slug:"使用-for-循環"},{level:3,title:"使用展開語法 (...)",slug:"使用展開語法"},{level:3,title:"🔸 Array.prototype.map()",slug:"🔸-array-prototype-map"},{level:3,title:"▫️ Array.prototype.filter()",slug:"▫️-array-prototype-filter"},{level:3,title:"▫️ Array.prototype.find()",slug:"▫️-array-prototype-find"},{level:3,title:"▫️ Array.prototype.reduce()",slug:"▫️-array-prototype-reduce"},{level:3,title:"▫️ Array.prototype.forEach()",slug:"▫️-array-prototype-foreach"},{level:2,title:"🔷 Object method",slug:"🔷-object-method"},{level:3,title:"▫️Object.defineProperties",slug:"▫️object-defineproperties"},{level:3,title:"▫️ Object.entries()",slug:"▫️-object-entries"},{level:3,title:"▫️ Object.fromEntries()",slug:"▫️-object-fromentries"},{level:3,title:"▫️ Object.assign()",slug:"▫️-object-assign"},{level:3,title:"▫️ Object.create()",slug:"▫️-object-create"},{level:2,title:"Data Structure",slug:"data-structure"},{level:3,title:"Object 和 Map 區別",slug:"object-和-map-區別"},{level:3,title:"Set 和 Map 區別",slug:"set-和-map-區別"}]},{title:"⚪️ Strapi への深い理解",frontmatter:{sidebarDepth:3},regularPath:"/memo/strapi.html",relativePath:"memo/strapi.md",key:"v-84a4a916",path:"/memo/strapi.html",headers:[{level:2,title:"project structure",slug:"project-structure"},{level:2,title:"API",slug:"api"},{level:2,title:"headless CMS とは?",slug:"headless-cms-とは"},{level:2,title:"Content Type Builder",slug:"content-type-builder"},{level:3,title:"Understanding Content Type Builder:",slug:"understanding-content-type-builder"},{level:3,title:"Example Use Case:",slug:"example-use-case"},{level:3,title:"Conclusion:",slug:"conclusion"},{level:3,title:"Understanding Content Type Builder:",slug:"understanding-content-type-builder-2"},{level:3,title:"Example Use Case:",slug:"example-use-case-2"},{level:2,title:"Content Manager",slug:"content-manager"}]},{title:"⚪️ Typescript 深い理解と実践",frontmatter:{sidebarDepth:3},regularPath:"/memo/typescript.html",relativePath:"memo/typescript.md",key:"v-90f25216",path:"/memo/typescript.html",headers:[{level:2,title:"🔸 Chapter 1: Start Here",slug:"🔸-chapter-1-start-here"},{level:2,title:"🔸 Chapter 2: Basic Types",slug:"🔸-chapter-2-basic-types"},{level:2,title:"🔸 Chapter 3: Arrays & Objects",slug:"🔸-chapter-3-arrays-objects"},{level:2,title:"🔸 Chapter 4: Functions",slug:"🔸-chapter-4-functions"},{level:2,title:"🔸 Chapter 5: Assertions",slug:"🔸-chapter-5-assertions"},{level:2,title:"🔸 Chapter 6: Classes",slug:"🔸-chapter-6-classes"},{level:2,title:"🔸 Chapter 7: Index Signatures & keyof Assertions",slug:"🔸-chapter-7-index-signatures-keyof-assertions"},{level:2,title:"🔸 Chapter 8: Generics",slug:"🔸-chapter-8-generics"},{level:2,title:"🔸 Chapter 9: Utility Types",slug:"🔸-chapter-9-utility-types"}]},{title:"プラクティス",frontmatter:{},regularPath:"/practice/",relativePath:"practice/README.md",key:"v-324d1e36",path:"/practice/"},{title:"⚪️ Webpack 深い理解と実践",frontmatter:{sidebarDepth:3},regularPath:"/memo/webpack.html",relativePath:"memo/webpack.md",key:"v-94bf939e",path:"/memo/webpack.html",headers:[{level:2,title:"🔶 Webpack とは?",slug:"🔶-webpack-とは"},{level:2,title:"🔶 なぜ Webpack を使うのか?",slug:"🔶-なぜ-webpack-を使うのか"},{level:2,title:"🔶 Webpack の詳細?",slug:"🔶-webpack-の詳細"},{level:3,title:"▫️ Loader for Different Resource Types",slug:"▫️-loader-for-different-resource-types"},{level:3,title:"▫️ Basic Functions of Webpack (Using Loaders)",slug:"▫️-basic-functions-of-webpack-using-loaders"},{level:3,title:"▫️ Two Key Features of Webpack",slug:"▫️-two-key-features-of-webpack"},{level:3,title:"▫️ Webpack Configuration",slug:"▫️-webpack-configuration"},{level:3,title:"▫️ Webpack Build Process",slug:"▫️-webpack-build-process"},{level:3,title:"▫️ Common Plugins",slug:"▫️-common-plugins"},{level:3,title:"▫️ Difference Between Loader and Plugin",slug:"▫️-difference-between-loader-and-plugin"},{level:3,title:"▫️ Webpack Hot Module Replacement (HMR) Principle",slug:"▫️-webpack-hot-module-replacement-hmr-principle"},{level:3,title:"▫️ Webpack Build Speed Optimization",slug:"▫️-webpack-build-speed-optimization"},{level:3,title:"▫️ webpack-bundle-analyzer",slug:"▫️-webpack-bundle-analyzer"},{level:3,title:"Basic Steps for Configuring and Using webpack-bundle-analyzer:",slug:"basic-steps-for-configuring-and-using-webpack-bundle-analyzer"},{level:3,title:"▫️ Conditional Usage in Development Environment:",slug:"▫️-conditional-usage-in-development-environment"},{level:3,title:"▫️ Detailed Configuration Options for BundleAnalyzerPlugin:",slug:"▫️-detailed-configuration-options-for-bundleanalyzerplugin"},{level:3,title:"▫️ Reference Links:",slug:"▫️-reference-links"}]},{title:"⚪️ React Redux を基礎から理解する",frontmatter:{sidebarDepth:3},regularPath:"/memo/redux.html",relativePath:"memo/redux.md",key:"v-72824323",path:"/memo/redux.html",headers:[{level:2,title:"Redux の基本概念",slug:"redux-の基本概念"},{level:2,title:"Redux's Core API:",slug:"redux-s-core-api"},{level:3,title:"createStore",slug:"createstore"},{level:3,title:"useSelector",slug:"useselector"},{level:3,title:"dispatch",slug:"dispatch"},{level:2,title:"Redux Toolkit",slug:"redux-toolkit"},{level:2,title:"Redux Toolkit's Core APIs:",slug:"redux-toolkit-s-core-apis"},{level:3,title:"State management with Redux",slug:"state-management-with-redux"},{level:3,title:"Process of using Redux Toolkit",slug:"process-of-using-redux-toolkit"},{level:2,title:"Handling Asynchronous Code:",slug:"handling-asynchronous-code"},{level:2,title:"Redux Thunk",slug:"redux-thunk"}]},{frontmatter:{},regularPath:"/practice/github.html",relativePath:"practice/github.md",key:"v-3a18de15",path:"/practice/github.html"},{title:"⚪️ ReactHooks を深く理解する",frontmatter:{sidebarDepth:3},regularPath:"/memo/reacthooks.html",relativePath:"memo/reacthooks.md",key:"v-a8f38b16",path:"/memo/reacthooks.html",headers:[{level:2,title:"🔷 useEffect",slug:"🔷-useeffect"},{level:3,title:"▫️ what is useEffect",slug:"▫️-what-is-useeffect"},{level:3,title:"▫️ Basic Purpose",slug:"▫️-basic-purpose"},{level:3,title:"▫️ Second Argument - Dependency Array",slug:"▫️-second-argument-dependency-array"},{level:3,title:"▫️ Return of Cleanup Function",slug:"▫️-return-of-cleanup-function"},{level:3,title:"▫️ Execution Timing",slug:"▫️-execution-timing"},{level:3,title:"▫️ Usage Limitation - Cannot Use async Functions Directly",slug:"▫️-usage-limitation-cannot-use-async-functions-directly"},{level:2,title:"🔷 useRef",slug:"🔷-useref"},{level:3,title:"▫️ what is useRef",slug:"▫️-what-is-useref"},{level:3,title:"▫️ Basic Purpose",slug:"▫️-basic-purpose-2"},{level:3,title:"▫️ Usage Limitation - Cannot Use useRef to Update State",slug:"▫️-usage-limitation-cannot-use-useref-to-update-state"}]},{title:"TodoList App",frontmatter:{sidebarDepth:3},regularPath:"/practice/todolist.html",relativePath:"practice/todolist.md",key:"v-7a9a4235",path:"/practice/todolist.html",headers:[{level:2,title:"プロジェクトの構成",slug:"プロジェクトの構成"},{level:2,title:"TdInput Component",slug:"tdinput-component"},{level:2,title:"TdList Component",slug:"tdlist-component"},{level:2,title:"TdItem Component",slug:"tditem-component"},{level:3,title:"定義 inputRef",slug:"定義-inputref"},{level:3,title:"定義 Itodo 接口",slug:"定義-itodo-接口"},{level:3,title:"定義 Iprops src/components/TodoList/Input/index.tsx",slug:"定義-iprops-src-components-todolist-input-index-tsx"},{level:2,title:"TodoList 父組件",slug:"todolist-父組件"},{level:3,title:"使用 useReducer 替代 useState",slug:"使用-usereducer-替代-usestate"},{level:3,title:"分析 1:親コンポーネントが子コンポーネントに提供する addTodo 関数を理解するには?",slug:"分析-1-親コンポーネントが子コンポーネントに提供する-addtodo-関数を理解するには"},{level:3,title:"分析 3 什麼是 action creator? 返回純函數的意思是?",slug:"分析-3-什麼是-action-creator-返回純函數的意思是"},{level:3,title:"分析 4: Iprops",slug:"分析-4-iprops"},{level:3,title:"IProps Interface for TdInput Component:",slug:"iprops-interface-for-tdinput-component"},{level:3,title:"IProps Interface for TdList Component:",slug:"iprops-interface-for-tdlist-component"},{level:3,title:"Common Aspects:",slug:"common-aspects"},{level:3,title:"IProps in the TodoList>input>index.tsx",slug:"iprops-in-the-todolist-input-index-tsx"}]},{title:"React and TypeScript Shopping Cart Application",frontmatter:{sidebarDepth:3},regularPath:"/practice/shoppingcart.html",relativePath:"practice/shoppingcart.md",key:"v-165e6eb5",path:"/practice/shoppingcart.html",headers:[{level:2,title:"🔷 CartProvider Component",slug:"🔷-cartprovider-component"},{level:3,title:"1. Type Definitions",slug:"_1-type-definitions"},{level:3,title:"2. Action Types Definition",slug:"_2-action-types-definition"},{level:3,title:"3. Reducer Function",slug:"_3-reducer-function"},{level:3,title:"4. Custom Hook: useCartContext",slug:"_4-custom-hook-usecartcontext"},{level:3,title:"5. React Context and Provider",slug:"_5-react-context-and-provider"},{level:3,title:"Usage Instructions",slug:"usage-instructions"},{level:3,title:"🔻 CartProvider Code review",slug:"🔻-cartprovider-code-review"},{level:2,title:"🔷 ProductsProvider Component",slug:"🔷-productsprovider-component"},{level:3,title:"1. Type Definitions",slug:"_1-type-definitions-2"},{level:3,title:"2. Initial State",slug:"_2-initial-state"},{level:3,title:"3. Context Type Definition",slug:"_3-context-type-definition"},{level:3,title:"4. React Context and Provider",slug:"_4-react-context-and-provider"},{level:3,title:"5. Fetching and Updating Product Data",slug:"_5-fetching-and-updating-product-data"},{level:3,title:"Usage Instructions",slug:"usage-instructions-2"},{level:3,title:"🔻 ProductsProvider Code review",slug:"🔻-productsprovider-code-review"},{level:2,title:"🔷 Hooks/useProducts Hook",slug:"🔷-hooks-useproducts-hook"},{level:2,title:"🔷 Hooks/useCart Hook",slug:"🔷-hooks-usecart-hook"},{level:2,title:"🔷 components/ProductList",slug:"🔷-components-productlist"},{level:2,title:"🔷 components/Product",slug:"🔷-components-product"},{level:2,title:"トラブルシューティング",slug:"トラブルシューティング"},{level:3,title:"▫️ useCartContext hooks",slug:"▫️-usecartcontext-hooks"},{level:3,title:"▫️ UseCartContextType",slug:"▫️-usecartcontexttype"}]}],themeConfig:{displayAllHeaders:!0,lastUpdated:"Last Updated",isDarkMode:!1,nav:[{text:"Home",link:"/"},{text:"✸ノート",items:[{text:"「学習ノート」",items:[{text:"▫️ React.js",link:"/guide/react/"},{text:"▫️ Typescript",link:"/guide/typescript/"},{text:"▫️ Javascript",link:"/guide/javascript/"},{text:"▫️ Next.js",link:"/guide/nextjs/"}]},{text:"「メモ帳」",items:[{text:"▫️ memoメモ",link:"/memo/"},{text:"▫️ プラクティス",link:"/practice/"}]}]},{text:"✸すべてを記録する",items:[{text:"ライフ",items:[{text:"読書メモ",link:"/life/reading/"},{text:"モーメント",link:"/life/moment/"}]}]},{text:"github",link:"https://github.com/itsyuimorii"}],sidebar:{"/guide/react/":["","reactBasics","reactHooks","reactRouter","reactRedux"],"/guide/typescript/":["","basic","advanced"],"/guide/javascript/":["","js-array","js-study-notes"],"/guide/nextjs/":["","nextjs-basic","nextjs-study-notes"],"/memo/":["","jsreview","typescript","reacthooks","redux","graphql","formikandyup","archtiect","strapi","jenkins","docker","webpack","config","git"],"/practice/":["","todolist","shoppingcart","github"],"/life/reading/":["","The48LawsofPower","101EssaysThatWillChangeTheWayYouThink","ThinkandGrowRich"],"/life/moment/":[""],"/":[""]}}};n(234);Wn.component("Badge",()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,313))),Wn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,309))),Wn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,310)));n(235);var Ts=[{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{}],As=[];class Rs extends class{constructor(){this.store=new Wn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Wn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(Rs.prototype,{getPageAsyncComponent:as,getLayoutAsyncComponent:ss,getAsyncComponent:cs,getVueComponent:us});var Ls={install(t){const e=new Rs;t.$vuepress=e,t.prototype.$vuepress=e}};function Ds(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var Is={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return fs("pageKey",e),Wn.component(e)||Wn.component(e,as(e)),Wn.component(e)?t(e):t("")}},Ms={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},Ns={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Us=(n(236),n(237),Object(Os.a)(Ns,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Fs={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Wn.config.productionTip=!1,Wn.use(qa),Wn.use(Ls),Wn.mixin(function(t,e,n=Wn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Wn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Ds(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Ds(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Ds(t,o)?r(o):Ds(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(Ts.filter(t=>"function"==typeof t).map(e=>e({Vue:Wn,options:r,router:n,siteData:Es,isServer:t})))}catch(t){console.error(t)}return{app:new Wn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},As.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file diff --git a/assets/js/vendors~docsearch.8ee43d73.js b/assets/js/vendors~docsearch.8ee43d73.js new file mode 100644 index 00000000..0decfd48 --- /dev/null +++ b/assets/js/vendors~docsearch.8ee43d73.js @@ -0,0 +1,3 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{306:function(t,e,n){ +/*! docsearch 2.6.3 | © Algolia | github.com/algolia/docsearch */ +var r;"undefined"!=typeof self&&self,r=function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=22)}([function(t,e,n){"use strict";var r,i=n(1);function s(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,r){t&&(n.isArray(t)?e[r]=[].concat(t):n.isObject(t)&&(e[r]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(r,i){n&&(n=e.call(null,r,i,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(r,i){if(e.call(null,r,i,t))return n=!0,!1})),n):n},getUniqueId:(r=0,function(){return r++}),templatify:function(t){if(this.isFunction(t))return t;var e=i.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return(n?"":".")+t+e},escapeHighlightedString:function(t,e,n){e=e||"";var r=document.createElement("div");r.appendChild(document.createTextNode(e)),n=n||"";var i=document.createElement("div");i.appendChild(document.createTextNode(n));var o=document.createElement("div");return o.appendChild(document.createTextNode(t)),o.innerHTML.replace(RegExp(s(r.innerHTML),"g"),e).replace(RegExp(s(i.innerHTML),"g"),n)}}},function(t,e,n){"use strict";t.exports={element:null}},function(t,e){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;t.exports=function(t,e,i){if("[object Function]"!==r.call(e))throw new TypeError("iterator must be a function");var s=t.length;if(s===+s)for(var o=0;o was loaded but did not call our provided callback"),JSONPScriptError:s("JSONPScriptError"," + + diff --git a/guide/javascript/js-array.html b/guide/javascript/js-array.html new file mode 100644 index 00000000..77cc790e --- /dev/null +++ b/guide/javascript/js-array.html @@ -0,0 +1,782 @@ + + + + + + ⚪️ 【JavaScript 入門】 配列の使い方と操作まとめ(初期化・追加・結合・検索・削除) | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ 【JavaScript 入門】 配列の使い方と操作まとめ(初期化・追加・結合・検索・削除)

    # 🔶 【実践】「配列」の活用技

    当然可以。下面是一个表格,展示了各个 JavaScript 数组方法的功能、返回值、是否改变原数组以及它们被引入的 ECMAScript 版本。

    顺序 方法名 功能 返回值 是否改变原数组 版本
    1 push() 向数组添加一个或多个元素(在数组尾部) 新数组的长度 ES5-
    2 unshift() 向数组添加一个或多个元素(在数组头部) 新数组的长度 ES5-
    3 pop() 删除数组的最后一个元素 被删除的元素 ES5-
    4 shift() 删除数组的第一个元素 被删除的元素 ES5-
    5 reverse() 反转数组中的元素 反转后的数组 ES5-
    6 sort() 对数组进行排序(默认按字符串 Unicode 码点) 排序后的数组 ES5-
    7 splice() 在指定位置删除或添加元素(可用于数组的增删改) 被删除的元素组成的数组 ES5-
    8 concat() 合并多个数组,返回新数组 合并后的数组 ES5-
    9 join() 将数组元素用特定字符连接成字符串 拼接后的字符串 ES5-
    10 slice() 从数组中提取一段元素,返回新数组 提取的元素组成的新数组 ES5-
    11 toString() 将数组转换为字符串 字符串表示的数组 ES5-
    12 valueOf() 返回数组的原始值 数组的原始值 ES5-
    13 indexOf() 查询数组中某元素首次出现的位置 元素位置,若不存在则返回-1 ES5-
    14 lastIndexOf() 反向查询数组中某元素首次出现的位置 元素位置,若不存在则返回-1 ES5-
    15 forEach() 遍历数组,对每个元素执行回调函数 无(undefined ES5-
    16 map() 遍历数组,使用回调函数处理每个元素,并返回新数组 新数组 ES5-
    17 filter() 遍历数组,筛选符合条件的元素,返回新数组 符合条件的元素组成的新数组 ES5-
    18 every() 检测数组所有元素是否都满足条件 所有元素满足返回true,否则false ES5-
    19 some() 检测数组中是否存在满足条件的元素 存在满足条件的元素返回true,否则false ES5-
    20 reduce() 从左到右应用一个函数对数组元素进行累计/归约 操作结果 ES5-
    21 reduceRight() 从右到左应用一个函数对数组元素进行累计/归约 操作结果 ES5-
    22 includes()

    判断数组是否包含特定值 | 包含则返回true,否则false | 否 | ES6 | +| 23 | Array.from() | 从类数组或可迭代对象创建新数组 | 新数组 | 否 | ES6 | +| 24 | find() | 查找数组中满足条件的第一个元素 | 满足条件的元素,否则undefined | 否 | ES6 | +| 25 | findIndex() | 查找数组中满足条件元素的索引 | 满足条件元素的索引,否则-1 | 否 | ES6 | +| 26 | fill() | 使用给定值填充数组 | 填充后的数组 | 是 | ES6 | +| 27 | flat() | 将嵌套数组"拉平"成一维数组 | 新数组 | 否 | ES6 | +| 28 | flatMap() | 先映射每个元素,然后将结果压平成一维数组 | 新数组 | 否 | ES6 |

    # 🔶 方法详解

    # 🔸 1. push()

    • 功能:在数组最后一位添加一个或多个元素,并返回新数组的长度。会改变原数组。
    • 示例:
      var arr = [1, 2, "c"];
      +var rel = arr.push("A", "B");
      +console.log(arr); // [1, 2, "c", "A", "B"]
      +console.log(rel); // 5 (数组长度)
      +

    # 🔸 2. unshift()

    • 功能:在数组第一位添加一个或多个元素,并返回新数组的长度。会改变原数组。
    • 示例:
      var arr = [1, 2, "c"];
      +var rel = arr.unshift("A", "B");
      +console.log(arr); // ["A", "B", 1, 2, "c"]
      +console.log(rel); // 5 (数组长度)
      +

    # 🔸 3. pop()

    • 功能:删除数组的最后一个元素,并返回被删除的元素。会改变原数组。
    • 示例:
      var arr = [1, 2, "c"];
      +var rel = arr.pop();
      +console.log(arr); // [1, 2]
      +console.log(rel); // c
      +

    # 🔸 4. shift()

    • 功能:删除数组的第一个元素,并返回被删除的元素。会改变原数组。
    • 示例:
      var arr = ["a", "b", "c"];
      +var rel = arr.shift();
      +console.log(arr); // ["b", "c"]
      +console.log(rel); // a
      +

    # 🔸 5. reverse()

    • 功能:反转数组中的元素。会改变原数组。
    • 示例:
      var arr = [1, 2, 3, "a", "b", "c"];
      +var rel = arr.reverse();
      +console.log(arr); // ["c", "b", "a", 3, 2, 1]
      +console.log(rel); // ["c", "b", "a", 3, 2, 1]
      +

    # 🔸 6. sort()

    • 功能:对数组的元素进行排序。默认排序顺序是根据字符串 Unicode 码点。
    • 示例:
      var arr1 = [10, 1, 5, 2, 3];
      +arr1.sort();
      +console.log(arr1); // 默认排序结果
      +// 使用自定义排序函数
      +arr1.sort(function (a, b) {
      +  return a - b;
      +});
      +console.log(arr1); // 从小到大排序
      +

    # 🔸 7. splice()

    # 功能:

    • 在指定位置添加或删除数组中的元素,或替换数组中的元素。会改变原数组。
    • splice 方法可以用于数组的增删改操作。
    • splice 方法的第一个参数是修改的起始位置(索引),第二个参数是删除的个数(如果是 0,则表示不删除元素),后面的参数是要添加进数组的元素。

    # 语法:

    • array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
    • start:指定修改的开始位置(从 0 计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1 计数,这意味着-n 是倒数第 n 个元素并且等价于 array.length-n),如果负数的绝对值大于数组的长度,则表示开始位置为第 0 位。
    • deleteCount:整数,表示要移除的数组元素的个数。如果deleteCount大于start之后的元素的总数,则从start后面的元素都将被删除(含第start位)。
    • item1, item2, ...:要添加进数组的元素,从start位置开始。如果不指定,则只删除数组元素。
    • 返回值:由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
    • 注意:splice 方法会改变原始数组。

    # 示例:

    var arr = ["a", "b", "c", 2, 3, 6];
    +var rel = arr.splice(2, 1, "add1", "add2");
    +console.log(arr); // 修改后的数组
    +console.log(rel); // 被删除的元素组成的数组
    +

    # 使用場景:

    在 React 中,通常推荐使用不可变数据模式来更新状态,尤其是当处理数组和对象时。splice 方法会直接修改原数组,这可能导致 React 的状态更新行为表现得不如预期。

    const remove = (index) => {
    +  const newGoods = [...goods];
    +  newGoods.splice(index, 1); // 删除 splice 方法, 会改变原数组, 返回被删除的元素
    +  setGoods(newGoods);
    +};
    +

    newGoods.splice(index, 1); 这行代码中,splice 被用于从 newGoods 数组中移除特定索引的元素。尽管这里使用了 newGoods 作为 goods 数组的副本,但由于数组是引用类型,在使用 splice 之前,应该创建 goods 的深拷贝。

    # 为什么需要深拷贝?

    当你使用 newGoods = [...goods] 这样的语句时,实际上创建的是原数组的浅拷贝。这意味着 newGoodsgoods 都指向相同的元素对象。当你在 newGoods 上使用 splice 时,虽然 goods 数组本身没有被直接修改,但数组中的对象可能会受到影响,这可能导致 React 的不预期行为。

    # 正确的做法

    为了避免这种问题,可以使用不会改变原数组的方法来处理数组。例如,可以使用 filter 方法来创建一个不包含特定索引元素的新数组,而不是使用 splice

    const remove = (index) => {
    +  const newGoods = goods.filter((_, i) => i !== index);
    +  setGoods(newGoods);
    +};
    +

    在这个修改后的 remove 函数中,filter 方法被用来创建一个新的数组,其中不包含指定索引的元素。这种方法不会修改原数组,符合 React 的不可变数据原则,能够确保状态更新的可预测性。

    # 🔸 8. concat()

    • 功能:连接两个或更多数组,并返回结果。不改变原数组。
    • 示例:
      var arr1 = [1, 2, 3];
      +var arr2 = ["a", "b", "c"];
      +var rel = arr1.concat(arr2);
      +console.log(rel); // 合并后的数组
      +

    # 🔸 9. join()

    • 功能:将数组的所有元素连接成一个字符串。
    • 示例:
      var list = ["a", "b", "c", "d"];
      +var result = list.join("-");
      +console.log(result); // "a-b-c-d"
      +

    # 🔸 10. slice()

    • 功能:返回数组的一个片段或子数组。不改变原数组。
    • 示例:
      var list = ["a", "b", "c", "d"];
      +var result = list.slice(1, 3);
      +console.log(result); // ["b", "c"]
      +

    # 🔸 11. toString()

    • 功能:将数组转换为字符串。不改变原数组。
    • 示例:
      var list = ["a", "b", "c", "d"];
      +var rel = list.toString();
      +console.log(rel); // "a,b,c,d"
      +

    # 🔸 12. valueOf()

    • 功能:返回数组的原始值。
    • 示例:
      var list = [1, 2, 3, 4];
      +var rel = list.valueOf();
      +console.log(rel); // [1, 2, 3, 4]
      +

    # 🔸 13. indexOf()

    • 功能:返回指定元素在数组中首次出现的索引。不存在则返回-1。

    • 示例:

      var list = [1, 2, 3, 4];
      +var index = list.indexOf(4);
      +
      +console.log(index); // 3
      +

    # 🔸 14. lastIndexOf()

    • 功能:返回指定元素在数组中最后一次出现的索引。不存在则返回-1。
    • 示例:
      var list = [1, 2, 3, 4];
      +var index = list.lastIndexOf(4);
      +console.log(index); // 3
      +

    # 🔸 15. forEach()

    # 功能:

    • 对数组的每个元素执行一次提供的函数, 不改变原数组

      • forEach cannot directly handle asynchronous operations with await.(forEach `doesn't wait for promises to resolve before moving on to the next iteration.)
    • forEach()方法需要一个回调函数(这种函数,是由我们创建但是不由我们调用的)作为参数

      arr.forEach(function (item, index, array) {
      +  console.log(item, index, array);
      +});
      +
    • 回调函数中传递三个参数:

      • 第一个参数,就是当前正在遍历的元素
      • 第二个参数,就是当前正在遍历的元素的索引
      • 第三个参数,就是正在遍历的数组
    • forEach本身是没有中断机制的。内部是遍历执行回调的。

      • 在回调中增加判断条件,满足条件就抛出异常。(通常是不建议这么跳出循环的)
      • 使用 for(let item in arr) {}这样的遍历方式,可以提前跳出循环
      • 使用.some 方法,一些场景判断,满足条件可以提前结束

    # 示例:

    //基本for 循環支持 await, 但是效率會很低.
    +async function fetaData() {
    +  let arrs = Array.from({ length: 3 }, (_, index) => index + 1);
    +  let datas = [];
    +  for (let i = 0; i < arrs.length; i++) {
    +    let data = await fetch(
    +      `https://jsonplaceholder.typicode.com/todos/${arrs[i]}`
    +    )
    +      .then((res) => res.json())
    +      .then((res) => res);
    +    datas.push(data);
    +  }
    +
    +  return datas;
    +}
    +fetaData().then((res) => console.log(res));
    +

    # 使用場景:

    当您需要对数组中的每个元素执行异步操作,例如逐个上传图片,但不需要收集这些异步操作的返回值时,您可以使用 forEach 方法结合 async/await。请注意,虽然 forEach 不能直接处理 await,但您可以在 forEach 的回调函数中定义一个立即执行的异步函数来实现这一点。

    以下是一个例子,演示了如何使用 forEach 方法逐个上传图片:

    async function uploadImage(image) {
    +  // 这里是一个假设的上传函数,实际情况下应替换为实际的上传逻辑
    +  // 假设这个函数返回一个 Promise
    +  return fetch("https://example.com/upload", {
    +    method: "POST",
    +    body: image,
    +  }).then((response) => response.json());
    +}
    +
    +function uploadImages(images) {
    +  images.forEach(async (image) => {
    +    try {
    +      const result = await uploadImage(image);
    +      console.log("Image uploaded:", result);
    +    } catch (error) {
    +      console.error("Error uploading image:", error);
    +    }
    +  });
    +}
    +
    +// 假设这个数组包含了要上传的图片
    +const imageArray = ["image1.png", "image2.png", "image3.png"];
    +
    +uploadImages(imageArray);
    +

    在这个例子中:

    1. uploadImage 函数是一个异步函数,用于上传单个图片,并返回一个 Promise 对象。
    2. uploadImages 函数接受一个图片数组,使用 forEach 遍历这个数组。
    3. forEach 的回调函数中,我们定义了一个立即执行的异步函数来处理图片上传。
    4. 每个图片上传的结果将会被打印出来,但整个 uploadImages 函数本身不会返回任何结果。

    请注意,由于 forEach 并不等待异步操作完成,所有的上传操作将会几乎同时开始,这可能会对服务器造成压力。如果需要控制上传速度,比如一次只上传一个图片,您可能需要使用基本的 for 循环或其他方法来顺序执行异步操作。

    # 其他可能場景:

    1. 处理菜单项

      • 如果您有一个菜单项数组,您可能需要使用 forEach 来遍历每个菜单项,以生成展示在网页上的菜单列表。
      • 对于每个菜单项,可能还需要根据特定属性(如类别、价格区间、是否为素食等)进行进一步处理或分类。
    2. 处理顾客评论

      • 如果您的网站有顾客评论功能,您可以使用 forEach 遍历评论数组,展示每个顾客的评分和评论。
    3. 订单处理

      • 在订单确认页面,您可能需要遍历订单中的每个项目,计算总价或应用折扣。
      • 如果需要将订单中的每个项目发送到后端处理(如库存检查、订单入库等),也可以使用 forEach
    4. 图片或媒体内容展示

      • 如果餐厅网站有图库展示餐厅内部、菜品等,您可以使用 forEach 来遍历图片数组,为每张图片创建相应的 HTML 元素。
    5. 员工管理

      • 在员工管理界面,forEach 可用于遍历员工列表,显示员工信息,或进行特定操作,如计算工资、安排班次等。
    6. 库存管理

      • 对于库存管理,forEach 可以用于遍历库存列表,更新库存状态或进行库存预警。
    7. 特殊活动或促销信息展示

      • 如果餐厅有特殊活动或促销,您可以使用 forEach 遍历活动数组,动态生成展示这些活动的界面元素。

    在这些场景中,forEach 循环提供了一种简洁的方式来处理数组中的每个元素,尤其是当您不需要返回新数组时。这有助于编写更加清晰和可维护的代码。


    # 🔸 16. map()

    # 功能:

    • 數組原型是一個函數,對數組遍歷不破壞原數組, 返回一個新數組, 按照原是數組元素順序依次執行給定的函數, 並將每一次函數執行的結果作為新數組的元素返回

    • map 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个新数组。

    • 參數: map 方法的回调函数接受三个参数:

      • element:就是当前正在遍历的元素
      • index, 就是当前正在遍历的元素的索引
      • array,就是正在遍历的数组, 調用了 map()的數組本身
    • 語法:

      • arr.map(callback(currentValue[, index[, array]])[, thisArg])
      • arr.map(callback(currentValue[, index[, array]])
        • thisArg 可选参数。执行 callback 函数时使用的 this 值。

    # 示例:

    1. 将数组中的每个对象都添加一个新属性,并设置为相同的值。
    let users = [{ name: "Alice" }, { name: "Bob" }, { name: "Charlie" }];
    +let updatedUsers = users.map((user) => ({
    +  ...user,
    +  isActive: true,
    +}));
    +
    +console.log(updatedUsers); // [{ name: "Alice", isActive: true }, { name: "Bob", isActive: true }, { name: "Charlie", isActive: true }]
    +
    const numbers: number[] = [1, 2, 3, 4, 5];
    +const doubled: number[] = numbers.map((number: number) => number * 2);
    +
    1. 從數組對象裡提取特定屬性
    type User = {
    +  name: string;
    +  age: number;
    +};
    +
    +const users: User[] = [
    +  { name: "Alice", age: 20 },
    +  { name: "Bob", age: 21 },
    +  { name: "Charlie", age: 22 },
    +];
    +
    +const names: string[] = users.map((user: User) => user.name);
    +
    1. 将字符串数组转换为对象数组
    const fruits: string[] = ["apple", "banana", "cherry"];
    +
    +type FruitObject = {
    +  name: string;
    +};
    +
    +const fruitObjects: FruitObject[] = fruits.map((fruit: string) => ({
    +  name: fruit,
    +}));
    +
    +console.log(fruitObjects); // [{ name: "apple" }, { name: "banana" }, { name: "cherry" }]
    +
    1. 对象数组中的数字属性进行转换
    type Product = {
    +  name: string;
    +  price: number;
    +  };
    +
    +const products: Product[] = [
    +{ name: 'Book', price: 15 },
    +{ name: 'Pen', price: 5 },
    +{ name: 'Pencil', price: 2 }
    +];
    +
    +const discountedProducts: Product[] = products.map((product: Product) => ({
    +...product,
    +price: product.price \* 0.9
    +}));
    +

    # 使用場景:

    在 TypeScript 结合 React 开发的外卖应用(Web Restaurant App)中,使用.map方法来渲染列表是非常常见的。这里我将提供一些示例,展示如何在 TypeScript 环境下使用.map方法处理和渲染餐厅应用中的数据。

    1. 渲染菜单列表: 假设你有一个菜单项的数组,你想渲染这些菜单项到页面上。
    interface MenuItem {
    +  id: number;
    +  name: string;
    +  price: number;
    +  description: string;
    +}
    +
    +const menuItems: MenuItem[] = [
    +  { id: 1, name: "Burger", price: 5.99, description: "A classic burger" },
    +  { id: 2, name: "Pizza", price: 7.99, description: "Cheesy pizza" },
    +  // more menu items...
    +];
    +
    +const MenuList: React.FC = () => (
    +  <div>
    +    {menuItems.map((item) => (
    +      <div key={item.id}>
    +        <h3>
    +          {item.name} - ${item.price}
    +        </h3>
    +        <p>{item.description}</p>
    +      </div>
    +    ))}
    +  </div>
    +);
    +
    1. 订单详情: 在订单详情页,你可能需要列出用户所选的菜品及其价格。
    interface OrderItem {
    +  id: number;
    +  name: string;
    +  quantity: number;
    +  price: number;
    +}
    +
    +const orderItems: OrderItem[] = [
    +  // 假设这些数据是用户选择的菜品
    +];
    +
    +const OrderDetails: React.FC = () => (
    +  <ul>
    +    {orderItems.map((item) => (
    +      <li key={item.id}>
    +        {item.name} x {item.quantity} - ${item.quantity * item.price}
    +      </li>
    +    ))}
    +  </ul>
    +);
    +
    1. 评分和评论, 显示用户对菜品的评分和评论。
    interface Review {
    +  id: number;
    +  user: string;
    +  rating: number;
    +  comment: string;
    +}
    +
    +const reviews: Review[] = [
    +  // 用户评论数据
    +];
    +
    +const ReviewsList: React.FC = () => (
    +  <div>
    +    {reviews.map((review) => (
    +      <div key={review.id}>
    +        <h4>{review.user}</h4>
    +        <p>Rating: {review.rating} / 5</p>
    +        <p>{review.comment}</p>
    +      </div>
    +    ))}
    +  </div>
    +);
    +
    1. 如果你需要同时处理多个异步操作并等待它们全部完成,你可以使用 Promise.all 结合 map 方法,而不是 forEach。当您需要同时处理多个异步操作并等待它们全部完成时,可以使用 Promise.all 结合 map 方法。这种方法特别适用于需要并行执行多个异步请求并等待所有请求完成的情况。

    示例:并行获取多个资源: 假设您有一个 URL 数组,您需要从每个 URL 获取数据。

    const urls: string[] = [
    +  "https://api.example.com/data1",
    +  "https://api.example.com/data2",
    +  "https://api.example.com/data3",
    +  // 更多URLs...
    +];
    +
    +// 定义一个异步函数来获取每个URL的数据
    +async function fetchData(url: string): Promise<any> {
    +  const response = await fetch(url);
    +  return response.json();
    +}
    +
    +// 使用Promise.all和map来并行获取所有数据
    +async function getAllData() {
    +  try {
    +    const allData = await Promise.all(urls.map((url) => fetchData(url)));
    +    console.log(allData); // 打印所有获取到的数据
    +  } catch (error) {
    +    console.error("Error fetching data:", error);
    +  }
    +}
    +
    +getAllData();
    +

    在这个示例中,urls.map(url => fetchData(url)) 会为每个 URL 创建一个 fetch 请求的 Promise。然后,Promise.all 接收这个 Promise 数组,并等待所有的 fetch 请求都完成。一旦所有请求完成,allData 变量将包含所有 URL 返回的数据。如果任何一个请求失败,catch 块将捕获错误。

    注意事项:

    • 当使用 Promise.all 时,如果任何一个 Promise 失败,整个 Promise.all 调用会立即失败。这意味着如果您有多个请求,一个请求失败,其他成功的请求的结果也会被丢弃。如果您需要不同的行为(例如,处理每个请求的单独成功或失败),您可能需要考虑使用 Promise.allSettled 或单独处理每个 Promise 的错误。
    • 使用 Promise.all 可以显著提高性能,因为它允许异步操作并行执行,而不是按顺序一个接一个执行。 +当然可以。在 TypeScript 和 React 结合使用的场景中,我们可以遇到更复杂的使用 map 方法的例子,特别是在处理嵌套数据结构或进行更高级的数据转换时。以下是一些复杂的使用场景示例:
    1. 渲染嵌套评论

    假设你有一个嵌套评论的数据结构,你需要递归地渲染每个评论及其子评论。

    interface Comment {
    +  id: number;
    +  text: string;
    +  user: string;
    +  replies: Comment[];
    +}
    +
    +const comments: Comment[] = [
    +  // 假设的评论数据,每个评论可能有回复(也是Comment类型)
    +];
    +
    +const renderComments = (comments: Comment[]): JSX.Element[] => {
    +  return comments.map((comment) => (
    +    <div key={comment.id}>
    +      <h4>{comment.user}</h4>
    +      <p>{comment.text}</p>
    +      {comment.replies && (
    +        <div className="replies">{renderComments(comment.replies)}</div>
    +      )}
    +    </div>
    +  ));
    +};
    +
    +const CommentsList: React.FC = () => <div>{renderComments(comments)}</div>;
    +
    1. 动态生成表格列

    在一个数据驱动的应用中,你可能需要根据数据对象的属性动态生成表格列。

    interface Product {
    +  id: number;
    +  name: string;
    +  price: number;
    +  stock: number;
    +}
    +
    +const products: Product[] = [
    +  // 产品数据
    +];
    +
    +const ProductTable: React.FC = () => (
    +  <table>
    +    <thead>
    +      <tr>
    +        {Object.keys(products[0]).map((key) => (
    +          <th key={key}>{key.toUpperCase()}</th>
    +        ))}
    +      </tr>
    +    </thead>
    +    <tbody>
    +      {products.map((product) => (
    +        <tr key={product.id}>
    +          {Object.values(product).map((value, index) => (
    +            <td key={index}>{value}</td>
    +          ))}
    +        </tr>
    +      ))}
    +    </tbody>
    +  </table>
    +);
    +
    1. 使用 map 处理 TypeScript 枚举

    当你有一个 TypeScript 枚举,并希望基于枚举的值生成一组元素时。

    enum OrderStatus {
    +  Pending = "pending",
    +  InProgress = "in_progress",
    +  Completed = "completed",
    +  Cancelled = "cancelled",
    +}
    +
    +const StatusSelector: React.FC = () => (
    +  <select>
    +    {Object.values(OrderStatus).map((status) => (
    +      <option key={status} value={status}>
    +        {status}
    +      </option>
    +    ))}
    +  </select>
    +);
    +
    1. 使用 Promise.all 与类型保护

    在处理多个异步请求时,你可能还需要进行类型保护,以确保每个响应都符合预期的类型。

    type ApiResponse = DataResponse | ErrorResponse;
    +
    +interface DataResponse {
    +  status: "ok";
    +  data: any;
    +}
    +
    +interface ErrorResponse {
    +  status: "error";
    +  message: string;
    +}
    +
    +const fetchData = async (url: string): Promise<ApiResponse> => {
    +  try {
    +    const response = await fetch(url);
    +    const data = await response.json();
    +    return { status: "ok", data };
    +  } catch (error) {
    +    return { status: "error", message: error.message };
    +  }
    +};
    +
    +async function getAllData(urls: string[]) {
    +  const responses = await Promise.all(urls.map(fetchData));
    +  responses.forEach((response) => {
    +    if (response.status === "ok") {
    +      console.log("Data:", response.data);
    +    } else {
    +      console.error("Error:", response.message);
    +    }
    +  });
    +}
    +

    在这个示例中,ApiResponse 类型是一个联合类型,包括 DataResponseErrorResponse。当处理 Promise.all 的结果时,使用类型保护来确定每个响应是成功的数据响应还是错误响应。

    这些例子展示了在更复杂的场景中使用 .map 方法的多样性,尤其是在 TypeScript 环境中处理类型安全和异步操作时。


    # 🔸 17. filter()

    # 功能:

    • filter 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个新数组。

    • 在回调函数中,返回值为 true 的元素将会被保留,返回值为 false 的元素将会被过滤掉。

    • filter 方法不会改变原数组。

    • filter 方法的回调函数接受三个参数:

      • element:就是当前正在遍历的元素
      • index, 就是当前正在遍历的元素的索引
      • array,就是正在遍历的数组, 調用了 filter()的數組本身
      • thisArg 可选参数。执行 callback 函数时使用的 this 值。
    • 語法:

      • arr.filter(callback(currentValue[, index[, array]])[, thisArg])
      • arr.filter(callback(currentValue[, index[, array]])

    # 示例:

    当然可以。下面是一些使用 filter 方法的 TypeScript 示例,包括处理数组对象,并在某些情况下利用索引。

    1. 过滤特定条件的对象
    interface Product {
    +  id: number;
    +  name: string;
    +  price: number;
    +  inStock: boolean;
    +}
    +
    +const products: Product[] = [
    +  { id: 1, name: "Apple", price: 1.2, inStock: true },
    +  { id: 2, name: "Banana", price: 0.5, inStock: false },
    +  { id: 3, name: "Cherry", price: 2.5, inStock: true },
    +];
    +
    +// 过滤出库存中的产品
    +const inStockProducts: Product[] = products.filter(
    +  (product) => product.inStock
    +);
    +
    1. 使用索引过滤
    const data: number[] = [10, 20, 30, 40, 50];
    +
    +// 只保留偶数索引的元素
    +const filteredData: number[] = data.filter((_, index) => index % 2 === 0);
    +
    1. 结合对象和索引过滤
    interface User {
    +  id: number;
    +  name: string;
    +  age: number;
    +}
    +
    +const users: User[] = [
    +  { id: 1, name: "Alice", age: 24 },
    +  { id: 2, name: "Bob", age: 30 },
    +  { id: 3, name: "Carol", age: 22 },
    +];
    +
    +// 过滤出年龄大于25的用户,并且只保留偶数索引的用户
    +const selectedUsers: User[] = users.filter(
    +  (user, index) => user.age > 25 && index % 2 === 0
    +);
    +
    1. 移除数组中的重复元素
    const numbers: number[] = [1, 2, 3, 2, 3, 4, 5, 4];
    +
    +const uniqueNumbers: number[] = numbers.filter(
    +  (value, index, arr) => arr.indexOf(value) === index
    +);
    +
    1. 根据多个条件过滤
    interface Book {
    +  id: number;
    +  title: string;
    +  author: string;
    +  year: number;
    +}
    +
    +const books: Book[] = [
    +  { id: 1, title: "1984", author: "George Orwell", year: 1949 },
    +  {
    +    id: 2,
    +    title: "The Great Gatsby",
    +    author: "F. Scott Fitzgerald",
    +    year: 1925,
    +  },
    +  { id: 3, title: "Brave New World", author: "Aldous Huxley", year: 1932 },
    +];
    +
    +// 过滤出在1930年之后出版的书籍,并且作者为 "Aldous Huxley"
    +const filteredBooks: Book[] = books.filter(
    +  (book) => book.year > 1930 && book.author === "Aldous Huxley"
    +);
    +
    1. mapfilter 鏈式調用,數組對象裡提取特定屬性
    type User = {
    +  id: number;
    +  name: string;
    +  age: number;
    +};
    +
    +const users: User[] = [
    +  { id: 1, name: "Alice" },
    +  { id: null, name: "Bob" },
    +  { id: 2, name: "Bob" },
    +  { id: 3, name: "Charlie" },
    +];
    +
    +const newUsers = users
    +  .filter((item) => item.id)
    +  .map((item) => ({ ...item, isMember: true }));
    +
    +console.log(newUsers); // [{ id: 1, name: "Alice", isMember: true }, { id: 2, name: "Bob", isMember: true }, { id: 3, name: "Charlie", isMember: true }]
    +

    # 其他使用場景:

    在一个复杂的餐厅程序中,我们可以设想几个更复杂的 filter 使用场景,这些场景涉及多条件筛选、嵌套数据结构以及和其他数组方法的结合使用。以下是一些 TypeScript 示例:

    1. 根据多个条件筛选菜单项

    假设你的餐厅应用需要根据多个条件(如价格范围、食物类型、客户评分)筛选菜单项。

    interface MenuItem {
    +  id: number;
    +  name: string;
    +  type: "starter" | "main" | "dessert";
    +  price: number;
    +  averageRating: number;
    +}
    +
    +const menuItems: MenuItem[] = [
    +  // 菜单项数据...
    +];
    +
    +const filterCriteria = {
    +  type: "main",
    +  priceRange: { min: 10, max: 20 },
    +  minRating: 4,
    +};
    +
    +const filteredMenuItems = menuItems.filter(
    +  (item) =>
    +    item.type === filterCriteria.type &&
    +    item.price >= filterCriteria.priceRange.min &&
    +    item.price <= filterCriteria.priceRange.max &&
    +    item.averageRating >= filterCriteria.minRating
    +);
    +
    1. 筛选包含特定配料的菜品及其变体

    考虑一个复杂的场景,其中菜品可能有多个变体(如不同的调味方式或配料)。你需要找到包含或排除特定配料的所有菜品及其变体。

    interface MenuItemVariant {
    +  variantId: number;
    +  ingredients: string[];
    +}
    +
    +interface MenuItem {
    +  id: number;
    +  name: string;
    +  variants: MenuItemVariant[];
    +}
    +
    +const menuItems: MenuItem[] = [
    +  // 菜单项及变体数据...
    +];
    +
    +const ingredientFilter = "cheese";
    +
    +const itemsWithIngredient = menuItems.filter((item) =>
    +  item.variants.some((variant) =>
    +    variant.ingredients.includes(ingredientFilter)
    +  )
    +);
    +
    1. 结合 filtermap 筛选并转换数据

    在某些情况下,你可能需要先筛选出符合条件的数据,然后转换这些数据以用于显示。

    const menuItemsWithRatings: MenuItem[] = [
    +  // 含评分的菜单项数据...
    +];
    +
    +const highRatedDishes = menuItemsWithRatings
    +  .filter((item) => item.averageRating >= 4)
    +  .map((item) => ({
    +    name: item.name,
    +    rating: item.averageRating,
    +    priceRange: item.price >= 20 ? "High" : "Medium",
    +  }));
    +
    1. 复杂订单过滤

    考虑到餐厅可能需要处理大量的订单数据,你可能需要根据订单的多个属性来筛选它们,如订单状态、金额、下单时间等。

    interface Order {
    +  id: number;
    +  totalAmount: number;
    +  status: "new" | "processing" | "delivered" | "cancelled";
    +  orderDate: Date;
    +}
    +
    +const orders: Order[] = [
    +  // 订单数据...
    +];
    +
    +const filteredOrders = orders.filter(
    +  (order) =>
    +    order.status === "delivered" &&
    +    order.totalAmount > 50 &&
    +    order.orderDate > new Date("2021-01-01")
    +);
    +

    # 🔸 18. every()

    # 功能:

    • 检测数组所有元素是否都满足指定条件。
    • every 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个布尔值。
    • 在回调函数中,如果所有元素都满足条件every 方法将返回 true,否则返回 false

    # 示例:

    var list = [32, 93, 77, 53, 38, 87];
    +var result = list.every(function (item) {
    +  return item >= 50;
    +});
    +console.log(result); // false
    +

    # 使用場景

    当您需要检测数组中的所有元素是否满足指定条件时,可以使用 every 方法。以下是一些 TypeScript 示例:

    1. 检测订单中的所有商品是否都有库存
    interface OrderItem {
    +  productId: number;
    +  quantity: number;
    +  price: number;
    +}
    +
    +const orderItems: OrderItem[] = [
    +  { productId: 1, quantity: 2, price: 10 },
    +  { productId: 2, quantity: 1, price: 20 },
    +  // 更多商品...
    +];
    +
    +const allItemsInStock = orderItems.every((item) => item.quantity > 0);
    +

    # 🔸 19. some()

    # 功能:

    • 检测数组中是否有元素满足指定条件。
    • some 方法会遍历数组中的每个元素,并使用回调函数处理每个元素,最终返回一个布尔值。
    • 在回调函数中,如果有一个元素满足条件some 方法将返回 true,否则返回 false

    # 示例:

    var list = [32, 93, 77, 53, 38, 87];
    +var result = list.some(function (item) {
    +  return item >= 50;
    +});
    +console.log(result); // true
    +

    every 方法类似,some 方法也可以用于检测数组中是否有元素满足指定条件。但是,some 方法只要有一个元素满足条件,就会返回 true,而不是所有元素都满足条件。

    # 🔸 20. reduce()

    # 功能:

    • 对数组中的每个元素执行一个由您提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。

    • reduce 方法對數組中每一個元素按序執行一個指定方法, 每一次允許reducer 會將先前元素的計算結果作為參數傳入, 最後返回一個累積的結果

    • reduce 方法接受两个参数:

      • reducer 函数:用于处理数组中的每个元素,并将其结果汇总为单个返回值。
      • initialValue:作为第一次调用 reducer 函数时的第一个参数使用的值。第一次回調函數的初始值,如果指定初始值,則會作為第一次調用 callback 函數時的第一個參數使用。如果沒有提供初始值,則將使用數組中的第一個元素。在沒有初始值的空數組上調用 reduce 將報錯。
    • reducer 函数接受四个参数:

      • accumulator:累加器累计回调的返回值; 它是上一次调用回调时返回的累积值,或 initialValue
      • currentValue:数组中正在处理的元素。
      • currentIndex:数组中正在处理的元素的索引。如果提供了 initialValue,则索引号为 0,否则索引为 1。
      • array:调用 reduce 的数组。
      • thisArg 可选参数。执行 callback 函数时使用的 this 值。

    # 示例:

    1. 计算订单总金额: 假设你有一个表示订单中各个商品及其数量的数组,你需要计算订单的总金额。
    interface OrderItem {
    +  productId: number;
    +  quantity: number;
    +  price: number;
    +}
    +
    +const orderItems: OrderItem[] = [
    +  { productId: 1, quantity: 2, price: 10 },
    +  { productId: 2, quantity: 1, price: 20 },
    +  // 更多商品...
    +];
    +
    +const totalAmount = orderItems.reduce((total, item) => {
    +  return total + item.quantity * item.price;
    +}, 0);
    +
    1. 将数组转换为对象 使用reduce 方法可以将数组转换为更复杂的数据结构,比如对象。
    interface User {
    +  id: number;
    +  name: string;
    +}
    +
    +const users: User[] = [
    +  { id: 1, name: "Alice" },
    +  { id: 2, name: "Bob" },
    +  // 更多用户...
    +];
    +//累加器:reduce 方法的第一个参数是一个回调函数,这个回调函数接收两个参数:当前的累加器(obj)和当前正在处理的数组元素(user)。
    +const usersById = users.reduce((obj, user) => {
    +  obj[user.id] = user; // *将用户对象添加到以用户ID为键的对象中*
    +  return obj;
    +
    +  console.log(obj); // { 1: { id: 1, name: "Alice" }, 2: { id: 2, name: "Bob" } }
    +}, {} as { [key: number]: User }); // 以空对象作为初始值
    +
    +console.log(usersById); // { 1: { id: 1, name: "Alice" }, 2: { id: 2, name: "Bob" } }
    +

    当你看到这种写法 obj[user.id] = user;,它是一种在 JavaScript 和 TypeScript 中常用的方式,用于将数组中的元素映射到一个对象的属性上。具体来说,这种写法是在构造一个以 user.id 作为键(key),user 对象本身作为值(value)的对象。

    在这个表达式中:

    • obj 是一个对象,通常是一个空对象 {},它在 reduce 函数的迭代过程中不断被更新。
    • user 是当前正在迭代的数组元素。
    • user.iduser 对象的一个属性,这里用作新对象的键。
    • obj[user.id] 表示在 obj 对象中创建或更新一个以 user.id 的值为键的属性。
    • obj[user.id] = user; 表示将当前的 user 对象赋值给这个键。
    1. 分类汇总数据: 对数组中的项目进行分类,并计算每个类别中的项目数量。
    interface Product {
    +  id: number;
    +  category: string;
    +}
    +
    +const products: Product[] = [
    +  { id: 1, category: "Electronics" },
    +  { id: 2, category: "Books" },
    +  // 更多产品...
    +];
    +
    +const categoryCount = products.reduce((count, product) => {
    +  count[product.category] = (count[product.category] || 0) + 1;
    +  return count;
    +}, {} as { [key: string]: number });
    +

    {} as { [key: string]: number }); 是一種 type assertion, 用來告訴編譯器, 這個空對象的類型是 { [key: string]: number }{ [key: string]: number }:这是一个索引签名类型。它描述了一个对象,这个对象可以拥有任意数量的属性,但所有属性的键(key)都是字符串类型,而对应的值(value)都是数字类型。

    [key: string]: 表示对象的键是字符串类型。key 在这里只是一个占位符,你可以使用任何名称。 +number: 表示属性值的类型必须是数字。

    1. 创建值的累积数组: 创建一个新数组,其中每个元素是原始数组中对应元素及其之前所有元素的累积和。
    const numbers = [1, 2, 3, 4, 5];
    +
    +const cumulativeSum = numbers.reduce((acc, value) => {
    +  if (acc.length > 0) {
    +    acc.push(value + acc[acc.length - 1]);
    +  } else {
    +    acc.push(value);
    +  }
    +  return acc;
    +}, [] as number[]);
    +

    # 使用場景:

    在餐厅应用程序(Restaurant App)的开发中,reduce 方法可以在许多场景中发挥重要作用,尤其是在处理数据汇总、统计分析以及复杂的数组转换时。以下是一些针对餐厅应用的 TypeScript 示例,展示了 reduce 方法的不同用途:

    1. 统计不同类型菜品的数量

    假设你的餐厅应用需要对菜单中不同类型的菜品进行统计。

    interface MenuItem {
    +  id: number;
    +  name: string;
    +  type: "starter" | "main" | "dessert";
    +}
    +
    +const menuItems: MenuItem[] = [
    +  // 菜单数据...
    +];
    +
    +const itemCountByType = menuItems.reduce((count, item) => {
    +  count[item.type] = (count[item.type] || 0) + 1;
    +  return count;
    +}, {} as { [key: string]: number });
    +
    1. 计算每日总销售额

    计算一天内所有订单的总销售额。

    interface Order {
    +  id: number;
    +  totalAmount: number;
    +  date: Date;
    +}
    +
    +const orders: Order[] = [
    +  // 当日订单数据...
    +];
    +
    +const totalSales = orders.reduce(
    +  (total, order) => total + order.totalAmount,
    +  0
    +);
    +
    1. 汇总顾客反馈

    将所有顾客的评论汇总成一个字符串。

    interface Review {
    +  id: number;
    +  comment: string;
    +}
    +
    +const reviews: Review[] = [
    +  // 顾客评论数据...
    +];
    +
    +const allComments = reviews.reduce(
    +  (comments, review) => comments + review.comment + " ",
    +  ""
    +);
    +
    1. 创建菜品成分列表

    假设你需要从所有菜品中创建一个包含所有独特成分的列表。

    interface Dish {
    +  id: number;
    +  ingredients: string[];
    +}
    +
    +const dishes: Dish[] = [
    +  // 菜品数据...
    +];
    +
    +const allIngredients = dishes
    +  .reduce(
    +    (ingredients, dish) => ingredients.concat(dish.ingredients),
    +    [] as string[]
    +  )
    +  .filter((value, index, self) => self.indexOf(value) === index); // 移除重复项
    +
    1. 分类订单并计算每类的总金额

    假设你需要按顾客类型(比如会员和非会员)分类订单,并计算每一类的总金额。

    interface CustomerOrder {
    +  id: number;
    +  customerId: number;
    +  totalAmount: number;
    +  isMember: boolean;
    +}
    +
    +const customerOrders: CustomerOrder[] = [
    +  // 顾客订单数据...
    +];
    +
    +const totalAmountByCustomerType = customerOrders.reduce((totals, order) => {
    +  const key = order.isMember ? "members" : "nonMembers";
    +  totals[key] = (totals[key] || 0) + order.totalAmount;
    +  return totals;
    +}, {} as { members: number; nonMembers: number });
    +

    # 🔸 21. reduceRight()

    • 功能:类似于reduce(),但从右到左执行。
    • 示例:
      // 示例与`reduce()`类似,仅改变迭代方向
      +

    # 🔸 22. includes()

    # 功能:

    • 判断数组是否包含指定的值, 返回布尔值。

    • 只能檢測基本類型的值, 不能檢測引用類型的值

    • includes 方法接受两个参数:

      • searchElement:要查找的元素。
      • fromIndex:可选参数。开始查找的位置。如果省略,则从数组的第一个元素(索引位置 0)开始查找。如果该值为负数,则按升序从 array.length + fromIndex 的索引开始搜索。如果 fromIndex 大于或等于数组的长度,则 includes 不会查找数组,返回 false

    # 示例:

    let site = ["facebook", "google", "youtube"];
    +console.log(site.includes("youtube")); // true
    +console.log(site.includes("yahoo")); // false
    +

    # 23.🔸 from()

    • 功能:从类数组或可迭代对象创建一个新数组。
    • 示例:
      var all = {
      +  0: "张飞",
      +  1: "28",
      +  2: "男",
      +  3: ["率土", "鸿图", "三战"],
      +  length: 4,
      +};
      +var list = Array.from(all);
      +console.log(list);
      +

    # 24. 🔸 find()

    • 功能:返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined
    • 示例:
      var list = [55, 66, 77, 88, 99, 100];
      +var res = list.find(function (item) {
      +  return item > 60;
      +});
      +console.log(res); // 66
      +

    # 25. 🔸 findIndex()

    • 功能:返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
    • 示例:
      var list = [55, 66, 77, 88, 99, 100];
      +var index = list.findIndex(function (item) {
      +  return item > 60;
      +});
      +console.log(index); // 1
      +

    # 26. 🔸 fill()

    • 功能:用一个固定值填充数组中从起始索引到终止索引内的全部元素。
    • 示例:
      var result = ["a", "b", "c"].fill("填充", 1, 2);
      +console.log(result); // ["a", "填充", "c"]
      +

    # 27. 🔸 flat()

    • 功能:创建一个新数组,其中所有子数组元素递归地连接到指定深度。

    • 示例:

      var list = [1, 2, [3, 4, [5]]];
      +var arr = list.flat();
      +console.log("拉平一次", arr); // [1, 2, 3, 4, [5]]
      +
      +var arr2 = list.flat(2); // 拉平两次
      +console.log("拉平两次", arr2); // [1, 2, 3, 4, 5]
      +

    # 28. 🔸 flatMap()

    • 功能:首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
    • 示例:
      var list = [55, 66, 77, 88, 99, 100];
      +var newArr = list.flatMap(function (item, index) {
      +  return [item, index];
      +});
      +console.log("flatMap方法:", newArr);
      +// 结果: [[55, 0], [66, 1], [77, 2], [88, 3], [99, 4], [100, 5]]
      +
    + + + diff --git a/guide/javascript/js-study-notes.html b/guide/javascript/js-study-notes.html new file mode 100644 index 00000000..27f16609 --- /dev/null +++ b/guide/javascript/js-study-notes.html @@ -0,0 +1,74 @@ + + + + + + ⚪️ Javascript -articles の研究例をいくつか | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ Javascript -articles の研究例をいくつか

    + + + diff --git a/guide/nextjs/index.html b/guide/nextjs/index.html new file mode 100644 index 00000000..a63ed6d3 --- /dev/null +++ b/guide/nextjs/index.html @@ -0,0 +1,74 @@ + + + + + + Next.js | ☻ itsyuimorii.space + + + + + + + + + + + + diff --git a/guide/nextjs/nextjs-basic.html b/guide/nextjs/nextjs-basic.html new file mode 100644 index 00000000..3b8f3f79 --- /dev/null +++ b/guide/nextjs/nextjs-basic.html @@ -0,0 +1,178 @@ + + + + + + 1. What is getStaticProps && getStaticPaths | ☻ itsyuimorii.space + + + + + + + + +

    # 1. What is getStaticProps && getStaticPaths

    # getStaticProps

    • Purpose: Primarily used for fetching static data at build time, which is then pre-rendered into HTML.
    • Execution Timing: By default, getStaticProps runs only once at build time, with subsequent requests serving the data fetched during this build.
    • Application Scenarios: +
      • SSG: In static site generation, getStaticProps provides necessary data for each page, optimizing SEO and load performance.
      • ISR: By specifying a revalidate option, getStaticProps supports incremental static regeneration, allowing pages to be updated periodically after deployment without rebuilding the entire site.

    # getStaticPaths

    • Purpose: Used for dynamic route pages, guiding Next.js on how to generate static pages for dynamic routes at build time.
    • Execution Timing: Runs at build time to pre-generate pages based on the returned paths.
    • Application Scenarios: +
      • Dynamic Routes: For pages with dynamic routes (e.g., pages/posts/[id].js), getStaticPaths determines which ids should be pre-rendered into static pages.
      • Integration with getStaticProps: Once getStaticPaths specifies certain paths, each path is then pre-rendered using getStaticProps to fetch the corresponding data.

    # :light_bulb_on: Considerations

    • Difference from getServerSideProps: getStaticProps fetches data at build time, suitable for data that changes infrequently; getServerSideProps, on the other hand, fetches data on every request, suitable for scenarios requiring real-time data.
    • Data Updates: To update data on pages pre-rendered with getStaticProps, you can trigger a site rebuild or utilize ISR for updates.
    • Page-Level Only: Both getStaticProps and getStaticPaths can only be used in page components, not within child components.

    # 2. Deep understanding getStaticProps

    // pages/products.tsx
    +import React from "react";
    +
    +interface Product {
    +  id: number;
    +  name: string;
    +  description: string;
    +  price: number;
    +}
    +
    +interface ProductsPageProps {
    +  products: Product[];
    +}
    +
    +const ProductsPage: React.FC<ProductsPageProps> = ({ products }) => {
    +  return (
    +    <div>
    +      <header>
    +        <h1>Our Products</h1>
    +      </header>
    +      <main>
    +        <ul>
    +          {products.map((product) => (
    +            <li key={product.id}>
    +              <h2>{product.name}</h2>
    +              <p>{product.description}</p>
    +              <strong>${product.price}</strong>
    +            </li>
    +          ))}
    +        </ul>
    +      </main>
    +    </div>
    +  );
    +};
    +
    +export const getStaticProps = async () => {
    +  // Simulating fetching data from an external API
    +  const res = await fetch("<https://fakestoreapi.com/products>");
    +  const products: Product[] = await res.json();
    +
    +  console.log("Fetched products at build time with getStaticProps");
    +
    +  return {
    +    props: {
    +      products,
    +    },
    +  };
    +};
    +
    +export default ProductsPage;
    +
    • **Page Component (**ProductsPage): This component is responsible for rendering the products page. It receives an array of products as a prop, iterating over the array to display each product's name, description, and price.
    • Data Fetching with getStaticProps: The getStaticProps function fetches data from an external API, in this case, a list of products. This function runs at build time, pre-fetching the data needed to render the products page.
    • Props Structure: The fetched data is structured under the props key and passed to the ProductsPage component. This approach ensures that the component has access to the product data when it's rendered.
    • Static Generation: By utilizing getStaticProps, Next.js pre-renders the products page with the fetched data at build time. The resulting static page includes all product information, ready to be served immediately to users, enhancing the page's load time and SEO.

    # Benefits

    • Improved Load Time: Since the data is fetched at build time and the page is pre-rendered, users experience faster page loads.
    • SEO Optimization: The pre-rendered page includes all product information in the HTML, making it easily indexable by search engines.
    • Build-time Data Fetching: Fetching data at build time is efficient for data that doesn't change frequently, reducing the need for real-time API calls on each request.

    # Invocation Timing

    1. During next build Execution:

      • getStaticProps is called once during the build process (next build). This means that for each page, getStaticProps fetches data and generates static HTML and a corresponding JSON file. These files can then be directly deployed to a CDN.
    2. When getStaticPaths Returns fallback as Not false:

      • For dynamic route pages, getStaticProps is used alongside getStaticPaths. If getStaticPaths sets fallback to true or 'blocking', getStaticProps will be invoked to generate static pages for new path requests that were not generated at build time.
    3. When Using revalidate:

      • When the object returned by getStaticProps includes a revalidate property, Incremental Static Regeneration (ISR) is enabled. The revalidate property specifies the interval at which the page data should be updated. Within this interval, the page will not be regenerated. Once surpassed, the next page request will trigger a re-generation of the page.

    # :light_bulb_on:JSON File and Data Access

    At build time, Next.js generates not only static HTML files but also corresponding JSON files for pages using getStaticProps. This JSON file contains the return value of getStaticProps. It enables Next.js to quickly load data from the JSON file during client-side navigation (e.g., through next/link or next/router), instead of reloading the entire page, thus achieving fast client-side route transitions.

    Example of a JSON file:

    {
    +  "pageProps": {
    +    "content": "Hello World"
    +  },
    +  "__N_SSG": true
    +}
    +

    Here, the **N_SSG flag indicates that this is a page generated through static generation, distinct from the **N_SSP flag used for pages generated through Server-Side Rendering (SSR), to differentiate between the data fetching methods.

    # Key Takeaways:

    getStaticProps offers an efficient method for data fetching and page pre-rendering, particularly suited for scenarios where content updates infrequently. By leveraging static generation, incremental generation for dynamic routes, and ISR, Next.js applications can combine the high performance of static files with the flexibility of dynamic content, optimizing both user experience and SEO.

    1. Server-Side Execution: getStaticProps operates exclusively on the server, ensuring no part of its code ends up in the client-side JavaScript bundle.
    2. Direct Server-Side Code: Within getStaticProps, you can write server-side code to access the file system via the fs module, query databases, or include sensitive information like API keys, all securely without exposing any of it to the client-side browser.
    3. Page-Specific and Pre-rendering Only: getStaticProps is exclusive to page components and cannot be used in regular presentation components. It's designed for pre-rendering pages at build time, not for client-side data fetching.
    4. Return Object Structure: getStaticProps must return an object containing a props key, which itself is an object. This structure ensures the returned data can be passed as props to the page component.
    5. Build Time and Development Mode Execution: getStaticProps runs at build time for static generation. In development mode (npm run dev), getStaticProps executes on every request, ensuring developers have up-to-date data while working on the application.

    # 3. Deep understanding `getStaticPaths

    # :light_bulb_on: Using getStaticPaths

    getStaticPaths is mainly used to build static pages in dynamic routes, which simply means that a dynamic route can be converted to multiple static pages by getStaticPaths.

    • pages/get-static-paths/[id].tsx
    function GetStaticPaths({ post }: { post: string }) {
    +  return (
    +    <div>
    +      <h1>Post: {post}</h1>
    +    </div>
    +  );
    +}
    +
    +export async function getStaticPaths() {
    +  const response = await fetch("https://jsonplaceholder.typicode.com/posts");
    +  const data = await response.json();
    +
    +  const paths = new Array(100).fill(null).map((_, i) => ({
    +    params: { id: String(i + 1) },
    +  }));
    +
    +  console.log("Generated paths:", paths);
    +
    +  return { paths, fallback: true };
    +}
    +
    +export async function getStaticProps({ params }: { params: { id: string } }) {
    +  console.log("Fetching data for post:", params);
    +
    +  return { props: { post: `Post content for ${params.id}` } };
    +}
    +
    +export default GetStaticPaths;
    +

    Here is a simple dynamic route, with getStaticPaths we can define the matching route values for this dynamic route, matching the parameters in the dynamic route with the params parameter in paths[number]. Here are the getStaticPaths and getStaticProps related parts of the next.js steps to convert it to a static page.

    • Invoke next build: Initiates the page data collection process in Next.js.
    • Detect Dynamic Routes: Next.js calls getStaticPaths for pages with dynamic routes to obtain paths for static generation.
    • Iterate paths: Each path from the getStaticPaths return value is matched with its corresponding dynamic route.
    • Generate Static Pages: Matches lead to the static generation process for each route.
    • Execute getStaticProps: The params from each path are passed to getStaticProps, which fetches data for the page.
    • Create HTML and JSON: The data returned from getStaticProps is used to produce HTML and JSON files for each static page.

    So the above code will generate 10 static pages [1-10].html and 10 JSON files [1-10].json in next build, the generated files can be viewed under .next/server/pages/.

    # :light_bulb_on: Understanding getStaticPaths Operation:

    • Static Resources: The posts document, along with associated JavaScript files (e.g., _app, framework, main, and webpack runtime), are downloaded. These scripts include the code for the entire application and are essential for the page to function correctly.

    • JSON Data Fetching: Alongside the static resources, there are JSON files named 1.json, 2.json, 3.json, etc. These files are fetched dynamically and correspond to the data for each post.

    • When using getStaticPaths, Next.js statically pre-renders pages at build time based on the paths returned from this function.

    • Each path corresponds to a page that can be accessed by a user, and for dynamic routes (like posts), Next.js generates a JSON file for each path.

    • These JSON files contain the data needed to hydrate the page with content on the client side after the initial HTML has been loaded.

    • The presence of 1.json, 2.json, and 3.json indicates that three posts have been pre-rendered, and their data is available for the application to use when rendering the pages client-side.

    • When a user navigates to a specific post, the corresponding JSON file is fetched, which provides the data necessary to render the page fully with all the post details.

    # :light_bulb_on: Understanding the fallback Parameter in Next.js

    The fallback parameter in getStaticPaths is a crucial feature for handling dynamic routes in Next.js applications. It determines the behavior of the application when a user accesses a route that hasn't been pre-rendered into a static page. There are three possible values for fallback: false, true, and blocking, each affecting the page access differently:

    # fallback: false

    • This is the default behavior where only the paths specified in getStaticPaths are pre-rendered at build time.
    • Accessing a non-existent page, such as /get-static-paths/11 when it's not defined in getStaticPaths, results in a 404 error page.
    • Suitable for applications where the set of valid paths is known and static.
    • 使用場景: +
      • 需要預渲染的路徑較少
      • 不經常添加新頁面

    # fallback: true

    • The path returned by getStaticProps will be rendered to html by getStaticProps at build time.
    • When a user navigates to a page that doesn't exist within the pre-rendered paths, instead of immediately presenting a 404 error, Next.js will render a fallback version of the page. This is especially relevant when the fallback key in getStaticPaths is set to true. During this time, if you want to display a loading state, you can use router.isFallback to check if the fallback is currently being displayed. Here's how you can integrate this into your component:
    import { useRouter } from "next/router";
    +
    +function MyComponent() {
    +  const router = useRouter();
    +
    +  if (router.isFallback) {
    +    // Render a loading state while the page is being statically generated
    +    return <h1>Loading...</h1>;
    +  }
    +
    +  // Render your page's content
    +}
    +
    • In the background, Next.js uses the page parameters to fetch data with getStaticProps, generates the static page and a JSON file, and then dynamically updates the page with the fetched data.
    • On subsequent visits to the same path, the pre-rendered static page is served directly, mirroring the behavior of existing pages.
    • This can be seen as a lazy build strategy, enabling on-demand static generation for paths not pre-rendered at build time.

    # fallback: 'blocking'

    • Similar to fallback: true, but with a critical difference: when accessing a non-existent page, the request waits for getStaticProps to finish fetching data and generating the static page before it is returned to the user.
    • This eliminates the need for a second data request and ensures that users get a consistent, pre-rendered page on the first access, whether asynchronously (with true) or synchronously (with blocking).

    Each fallback mode offers different advantages, depending on the specific needs of your application. fallback: false ensures fast performance and is suitable for known, unchanging routes. fallback: true offers flexibility and efficiency for applications with potentially infinite paths by generating pages on-demand. fallback: 'blocking' provides a seamless user experience by ensuring all users receive statically generated content, even if it means a slight delay on the first request to a non-pre-rendered path.

    📌 Here there is a need to pay attention to the problem is getStaticPaths params in the parameter needs to be a string, otherwise it will lead to a failure to match, guess for next.js in the type judgment or map operation, this in the follow-up source code to understand in the learning.

    # :light_bulb_on: Understanding getStaticProps and getServerSideProps in Next.js

    It's crucial to recognize that getStaticProps and getServerSideProps are not interchangeable within the same page in Next.js. getStaticProps is tailored for Static Site Generation (SSG) scenarios, while getServerSideProps is designed for Server-Side Rendering (SSR) scenarios. Attempting to use both in a single page will trigger a Next.js warning: You cannot use getStaticProps or getStaticPaths with getServerSideProps To use SSG, please remove getServerSideProps.

    From a design perspective, mixing them might seem logical: getStaticProps for fetching static data and getServerSideProps for dynamic data, with dynamic potentially overriding static. However, Next.js enforces a function singularity principle, advocating for clear separation of static and dynamic data fetching mechanisms to ensure optimal performance and predictability.

    # :light_bulb_on: When to Use getStaticProps

    The decision on when to utilize getStaticProps can be guided by the nature of the data on your page:

    • Static Data Updates: If your page content updates are triggered by publishing actions, getStaticProps is the ideal choice. It's essential, however, to be mindful of data security and privacy concerns.
    • Mix of Static and Dynamic Data: For pages containing both static and dynamic data, it's recommended to stick with getServerSideProps. This ensures that dynamic content is accurately rendered based on each request, maintaining up-to-date information and interaction.

    In summary, while getStaticProps offers significant benefits for pages with data that doesn't change frequently, scenarios requiring real-time data should leverage getServerSideProps for its ability to fetch and render content server-side on each request. The choice between these data fetching methods hinges on the specific requirements of your Next.js application and the data it needs to present.

    # Pre-rendering

    • Nextjs will pre-generate the HTML for each page, instead of letting client-side Javascript generate the HTML. Each HTML generated is associated with the minimum JavaScript code required for that page. When the browser loads the page, its JavaScript code works and makes the page fully interactive. (This process is called hydration.)

    # Two Forms of Pre-rendering

    # Static generation:

    • Static generation is the pre-rendering method where the HTML pages are generated at build time. It offers excellent performance since the HTML is generated once and reused for each request. There are two scenarios in Static Generation: +
      • Without Data: This is suitable for pages that do not require external data to be rendered. The HTML is generated at build time and can be cached and served by a CDN.
      • With Data: When the page content depends on external data (e.g., from a headless CMS), you can fetch this data at build time and generate the HTML based on that data. This approach is still static since the data fetching and HTML generation happen once during the build process.
        • Incremental Static Regeneration (ISR): An enhancement to static generation with data, ISR allows pages to be regenerated on a per-request basis, at a defined interval, without needing to rebuild the entire site. This makes it possible to have updated data without sacrificing the benefits of static generation

    # Server-Side Rendering (SSR)

    • Data Fetching: SSR dynamically generates the HTML for each page on every request, which means it can always serve the most up-to-date content. It's particularly useful for pages that fetch data that changes frequently, ensuring that users always get the latest information.
    • Dynamic Parameters Support: SSR is ideal for handling dynamic routes where the content of the page depends on parameters passed in the URL. The server can use these parameters to fetch specific data and render the page accordingly.
    Use Cases Static Generation Server-Side Rendering
    Blogging Sites:

    - Content updates infrequently.

    - At build time, articles are fetched from a headless CMS to generate static pages for fast access.
    E-commerce Sites:

    - Product information, prices, and stock levels change frequently.

    - SSR ensures that users see the most up-to-date product information.
    Documentation Sites:

    - Technical documentation with relatively low update frequency.

    - Static pages are easy to cache and distribute, speeding up access.
    Social Media Platforms:

    - User posts, comments, and other content are constantly updated.

    - SSR dynamically generates pages with the latest content, enhancing real-time interaction.

    # How to Enabling Static Generation

    Static Generation is a pre-rendering technique in Next.js that allows for the generation of HTML pages at build time. The most straightforward way to enable Static Generation is by using getStaticProps (for fetching page data) and getStaticPaths (for pages with dynamic routes) within your pages.

    # Production Server vs. Development Server

    • Production Server: When you run the next build command to build your application, Next.js generates static HTML for every page that utilizes getStaticProps. These pages are rendered at build time and subsequently, each request serves these pre-rendered static pages without regenerating them. This means that once the build is complete, the page content will not change unless a rebuild is executed.
    • Development Server: In development mode (usually initiated with npm run dev or yarn dev), getStaticProps is executed on every request for the sake of convenience in development. This ensures that you see the most up-to-date data and page changes while developing. The development mode simulates the static generation of the production mode but ensures hot reloading after each file change, offering a smoother development experience.

    # Fetching Data at Request Time

    # Data Fetching with Dynamic Parameters and Client-Side Data Fetching

    • Dynamic Parameter Support in Server-Side Rendering: Server-side rendering allows for dynamic data fetching based on request parameters, making it ideal for pages with dynamic routes. This flexibility enables the server to generate page content that specifically matches the parameters of each request.
    • Client-Side Data Fetching: Data can also be fetched on the client-side using JavaScript, which is suitable for scenarios where page content needs to be updated in real-time based on user interactions. This approach allows web applications to fetch and render data reactively, enhancing the user experience with dynamic content.

    # Combining Pre-rendering with Client-Side Data Fetching

    By integrating pre-rendering techniques with client-side data fetching, developers can create applications that are both fast to load and highly interactive. Static content is pre-rendered at build time for quick initial display to users, while dynamic content is fetched and updated on the client-side as users interact with the application. This combination offers the best of both worlds: the performance benefits of static generation and the flexibility of dynamic, client-side data updates.

    + + + diff --git a/guide/nextjs/nextjs-study-notes.html b/guide/nextjs/nextjs-study-notes.html new file mode 100644 index 00000000..c304914d --- /dev/null +++ b/guide/nextjs/nextjs-study-notes.html @@ -0,0 +1,74 @@ + + + + + + ⚪️ Next.js-articles の研究例をいくつか | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ Next.js-articles の研究例をいくつか

    + + + diff --git a/guide/react/index.html b/guide/react/index.html new file mode 100644 index 00000000..54d2e21c --- /dev/null +++ b/guide/react/index.html @@ -0,0 +1,76 @@ + + + + + + React | ☻ itsyuimorii.space + + + + + + + + +

    # React

    React は、インタラクティブなユーザインターフェイスの作成にともなう苦痛を取り除きます。アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。

    宣言的な View を用いてアプリケーションを構築することで、コードはより見通しが立ちやすく、デバッグのしやすいものになります。

    # References

    React 公式文書 (opens new window)

    ユーザインターフェース構築のための JavaScript ライブラリ (opens new window) React を学びましょう。

    Tao of React - Software Design, Architecture & Best Practices (opens new window)

    The new wave of React state management (opens new window) (Excellent read!)

    A Visual Guide to React Rendering - useMemo (opens new window)

    React as a UI Runtime (opens new window) (By Dan Abramov from the React team) +You Might Not Need an Effect (opens new window) (Official React docs)

    A Complete Guide to useEffect (opens new window) (By Dan Abramov) +useEffect sometimes fires before paint (opens new window)

    Making setInterval Declarative with React Hooks (opens new window) (By Dan Abramov)

    Redux - Not Dead Yet! (opens new window) (By Mark Erikson from the Redux team)

    Why React Context is Not a "State Management" Tool (opens new window) (By Mark Erikson)

    + + + diff --git a/guide/react/react-study-notes.html b/guide/react/react-study-notes.html new file mode 100644 index 00000000..0f83454a --- /dev/null +++ b/guide/react/react-study-notes.html @@ -0,0 +1,70 @@ + + + + + + ⚪️ React.js -articles の研究例をいくつか | ☻ itsyuimorii.space + + + + + + + + +
    + + + diff --git a/guide/react/reactBasics.html b/guide/react/reactBasics.html new file mode 100644 index 00000000..b319a807 --- /dev/null +++ b/guide/react/reactBasics.html @@ -0,0 +1,99 @@ + + + + + + ⚪️React を基礎から理解する | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️React を基礎から理解する

    # 🔶 React API とは

    React API とは、React が提供する機能のことです。React API は、React のコンポーネントを作成するために必要な機能を提供します。

    # 🔶 React API の種類

    React API には、以下の種類があります。

    • React.createElement() +React.createElement(type, [props], [...children])

      • 用来创建 React 元素
      • React の要素は、一度作成すると変更することができず、新しい要素を作成してレンダリングすることしかできない。
    • ReactDOM.createRoot() +createRoot(container[, options])

      • 用来创建 React 的根容器,容器用来放置 React 元素
    • ReactDOM.render() +root.render(element)

      • 用来将 React 元素渲染到根元素中
      • 根元素中所有的内容都会被删除,被 React 元素所替换
      • 当重复调用 render()时,React 会将两次的渲染结果进行比较,
      • 它会确保只修改那些发生变化的元素,对 DOM 做最少的修改

    # ▫️ React.createElement

    • React 要素を作成するためのメソッドで、DOM 要素ではなく React 要素を生成します。

    • DOM 要素は最終的にページに表示される要素であり、React 要素は実際に操作する要素です。

    • 両者は仮想 DOM を介して操作され、相互に関連しています。

    • 原則として、React 要素を操作する際には、原生の DOM 要素を直接操作せず、React の仮想 DOM 構造を壊さないように心がけるべきです。

    • React.createElement 関数の戻り値は React 要素であり、React 内の仮想 DOM 構造において操作されます。

    • React でのイベントはキャメルケースで表記されるべきであり、例えば、onClick、onMouseOver、onMouseOut などがあります。

    • React 要素は、type、props、children の 3 つのプロパティを持つオブジェクトである。

      • type: string | function
      • props: object
      • children: ReactElement | string | number
      • return: ReactElement
    • 要素の命名規則:

      • 要素の名前: HTML タグは小文字である必要があり、React では大文字はコンポーネントとして解釈されます。
      • 要素のプロパティ: オブジェクトで、キーがプロパティの名前、値がプロパティの値です。
      • 要素の子要素: 1 つ以上の子要素で、テキスト、または要素、または要素の配列が可能です。

      注意:React において、イベントの設定と属性の設定は異なります。イベントの設定時には、属性名をキャメルケースに変更する必要があります。例えば、onClickonclickではなくonClickとなります。これは、ネイティブイベントと React イベントを区別するためであり、そのため React イベントの属性名はキャメルケースである必要があります。

      React において、onClickはコードを受け取るのではなく、関数を受け取ります。これは、onClickがトリガーされたときに関数が実行されることを意味します。onClick={() => alert("click me")}のように書くと、レンダリング時に即座に実行されず、クリック時にのみ実行されます。onClick={() => alert("click me")}のように直接書くと、onClickにはalert("click me")の戻り値が代入され、レンダリング時に実行されてしまいます。これを避け、クリック時に実行されるようにするためには、アロー関数を使用することが適切です。

      • const div = React.createElement('div', {}, button) 可以在子元素裡直接放 button 進去
    <div id="root"></div>;
    +
    +.....
    +
    +//create a react element
    +const button = react.createElement("button", {
    +    id: "btn",
    +    type:'button',
    +    className:'btn',
    +    onClick=()=>{alert('clicked')}
    +}, "Click me");
    +
    +//get the root element, 就是把dom元素轉換成react裏的根元素, 這樣才能render,  這裏的rootElement就是一個dom元素
    +
    +const rootElement = document.getElementById("root");
    +
    +//render the react element into the root element
    +ReactDOM.render(button, rootElement);
    +

    # ▫️ReactDOM.createRoot

    • ReactDOM.createRoot 関数は、React の根要素を作成するための関数です。

    # ▫️ReactDOM.render

    • ReactDOM.render 関数は、React 要素をレンダリングするための関数です。
    + + + diff --git a/guide/react/reactHooks.html b/guide/react/reactHooks.html new file mode 100644 index 00000000..b9185ded --- /dev/null +++ b/guide/react/reactHooks.html @@ -0,0 +1,546 @@ + + + + + + ⚪️ React Hooks を基礎から理解する | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ React Hooks を基礎から理解する

    # 🔷 useState とは

    useState()は、関数コンポーネントで state を管理(state の保持と更新)するための React フックであり、最も利用されるフックです。

    state とはコンポーネントが内部で保持する「状態」のことで、画面上に表示されるデータ等、アプリケーションが保持している状態を指しています。state は props と違い後から変更することができます

    # ▫️ useState の注意点

    1. Accepts a single parameter, the initial state value, which can be any data type:

    唯一のパラメータを受け取り、それが状態の初期値であり、初期値は任意のデータ型であることができます。

    // Example with a string initial state
    +const [text, setText] = useState("Hello");
    +
    +// Example with a number initial state
    +const [count, setCount] = useState(0);
    +
    +// Example with an object initial state
    +const [person, setPerson] = useState({ name: "John", age: 25 });
    +
    +return (
    +  <div>
    +    <p>{text}</p>
    +    <p>{count}</p>
    +    <p>{person.name}</p>
    +    <p>{person.age}</p>
    +    <button onClick={() => setText("Bye")}>Change Text</button>
    +  </div>
    +);
    +

    2. Returns an array containing the state value and a method to update the state:

    戻り値は、状態値と状態を更新するためのメソッドが含まれた配列で、メソッド名は "set" で始まり、後に状態名が続きます。

    // Example using a boolean state
    +const [isActive, setIsActive] = useState(false);
    +

    3. useState() can be used multiple times to store multiple states:

    useState()は複数回使用でき、異なる状態値を保存できます。

    // Example with two different states
    +const [name, setName] = useState("John");
    +const [age, setAge] = useState(25);
    +

    4. Parameter can be a function, and the initial state is determined by the function's return value. The function is only called once, it used when the initial value is dynamic.:

    パラメータは関数であることができ、関数が返すものが初期状態になります。関数は一度だけ呼び出され、初期の動的値の場合に使用されます。

    // Example with a function as the initial state
    +function App(props) {
    +  // 從外部 props 中取得 count 的值,如果不存在,預設為 0
    +  const propsCount = props.count || 0;
    +
    +  // 使用 useState,將初始值設置為一個函數,這個函數會在初始化時被調用一次
    +  const [count, setCount] = useState(() => {
    +    // 這裡可以進行一些邏輯處理,例如動態計算初始值
    +    return propsCount;
    +  });
    +}
    +
    +//這樣寫是有錯誤的 ❌,因為每次渲染都會調用 useState,這樣會導致每次渲染都會調用函數,這樣就不是只調用一次了。 正確寫法如下:
    +function App(props) {
    +    const [count , setCount] = useState(() => {
    +        return props.count || 0;
    +    });
    +    //這樣,這個函數就只會在渲染的時候執行。
    +
    +

    5.状態の設定メソッドの引数は値または関数にすることができます(つまり、値を渡すことも、関数を渡すこともできます。関数の戻り値によって新しい状態が設定されます。

    setCount() の引数は値であるか、あるいは関数であるか選択できます。関数の場合、その関数の引数は現在の状態値であり、関数の戻り値が新しい状態値となります。

    // 値を渡す
    +setCount(新しい値);
    +
    +// 関数を渡す
    +setCount((現在のCount) => {
    +  // ここで計算やロジックを行います
    +  // 戻り値が新しい状態値になります
    +  return 何らかの計算(現在のCount);
    +});
    +
    // Example with a function as the parameter
    +function App() {
    +  const [count, setCount] = useState(0);
    +
    +  function handleCountChange() {
    +    // setCount(count + 1);
    +    setCount((prevCount) => prevCount + 1);
    +  }
    +
    +  return (
    +    <div>
    +      <p>{count}</p>
    +      <button onClick={handleCountChange}>Change Count</button>
    +    </div>
    +  );
    +}
    +

    6. 状態の設定メソッド自体が非同期です

    状態の更新は非同期で行われるため、setCount を即座に呼び出しても、React はすぐに状態を更新しません。状態更新後に何らかの操作を実行する必要がある場合は、useEffect を使用するか、関数式の更新で前の状態値を使用します。

    // useEffect を使用する例
    +useEffect(() => {
    +  // ここで何らかの操作を実行します。これは状態が更新された後に実行されます
    +  console.log("Count updated:", count);
    +}, [count]); // count を useEffect の依存リストに追加することを忘れずに
    +
    +// あるいは関数式の更新で前の状態値を使用する例
    +setCount((前のCount) => {
    +  // ここで前の状態値(前のCount)を使用します
    +  return 前のCount + 1;
    +});
    +

    7. useState() can be used in a custom hook:

    useState()はカスタムフックで使用できます。

    // Custom hook
    +function useCounter(initialCount) {
    +  const [count, setCount] = useState(initialCount);
    +
    +  function increment() {
    +    setCount((prevCount) => prevCount + 1);
    +  }
    +
    +  function decrement() {
    +    setCount((prevCount) => prevCount - 1);
    +  }
    +
    +  return [count, increment, decrement];
    +}
    +
    +// Component using the custom hook
    +function App() {
    +  const [count, increment, decrement] = useCounter(0);
    +
    +  return (
    +    <div>
    +      <p>{count}</p>
    +      <button onClick={increment}>Increment</button>
    +      <button onClick={decrement}>Decrement</button>
    +    </div>
    +  );
    +}
    +

    # 🔶 useReducer とは

    React hooks を基礎から理解する (useReducer 編) (opens new window)

    状態管理のためのフックで、useState と似たような機能。useStateuseReducer に内部実装されています。

    (state, action) => newState という型の reducer を受け取り、現在の statedispatch 関数の両方を返します。

    const [state, dispatch] = useReducer(reducer, "初期値");
    +

    reducerstate を更新するための関数で、dispatch は、reducer を実行するための呼び出し関数です。 (変数を宣言するときに、state の更新方法をあらかじめ設定しておくことが出来る。) +dispatch(action)で実行 +action は何をするのかを示すオブジェクト  +{type: increment, payload: 0}のように、type プロパティ(action の識別子)と値のプロパティで構成されている。

    # ▫️ useReducer の注意点

    1. useReduceruseState の代替ではない

    useState と useReducer の比較

    特性 useState useReducer
    扱える state 的 type 数値、文字列、オブジェクト、論理値 オブジェクト、配列
    関連する state 的取り扱い 複数を同時に取り扱うことが出来る
    ローカル or グローバル ローカル グローバル useContext() と一緒に取り扱う

    # 🔷 useContext とは

    React コンポーネントのツリーに対して「グローバル」とみなすデータについて利用するように設計されています。 +コンポーネントの再利用をより難しくする為、慎重に利用しなくてはなりません。

    Context によってコンポーネントツリー間におけるデータの橋渡しについて、すべての階層ごとに渡す必要性がなくなり、props バケツリレーをしなくても下の階層で Context に収容されているデータにアクセスできるようになりました。

    useContext とは、Context 機能をよりシンプルに使えるようになった機能。 +親から Props で渡されていないのに、Context に収容されているデータへよりシンプルにアクセスできるというものです。

    [React] useContextの使い方を改めて確認してみた


    • without useReducer
    const { useState } = React;
    +
    +function Child(props) {
    +  const { count, setCount } = props;
    +  return (
    +    <>
    +      <h2>Child - {count}</h2>
    +      <button onClick={() => setCount(count + 1)}>add</button>
    +    </>
    +  );
    +}
    +
    +function Parent(props) {
    +  const { count, setCount } = props;
    +  return (
    +    <>
    +      <h2>Parent - {count}</h2>
    +      <Child count={count} setCount={setCount} />
    +    </>
    +  );
    +}
    +
    +function MyApp() {
    +  const [count, setCount] = useState(0);
    +  return (
    +    <>
    +      <h2>Root - {count}</h2>
    +      <Parent count={count} setCount={setCount} />
    +    </>
    +  );
    +}
    +
    +const container = document.getElementById("root");
    +const root = ReactDOM.createRoot(container);
    +root.render(<MyApp />);
    +

    The above code leads to the problem that the more nested levels are, the more props are passed, and the more difficult the code is to maintain.

    • useReducer 使わない場合
    const { useState, createContext, useContext } = React;
    +
    +// 1. Create a context object
    +const MyContext = createContext();
    +
    +function Child() {
    +  // 3. Retrieve values from the context object using useContext and destructure the object
    +  const { count, setCount } = useContext(MyContext);
    +  return (
    +    <>
    +      <h2>Child - {count}</h2>
    +      <button onClick={() => setCount(count + 1)}>add</button>
    +    </>
    +  );
    +}
    +
    +function Parent() {
    +  // const { count, setCount } = props;
    +  // 4. Retrieve values from the context object using useContext and destructure the object
    +  const { count } = useContext(MyContext);
    +  return (
    +    <>
    +      <h2>Parent - {count}</h2>
    +      {/* <Child count={count} setCount={setCount} />
    +          Child component can access context values directly */}
    +
    +      <Child/>
    +    </Child>
    +  );
    +}
    +
    +function MyApp() {
    +  const [count, setCount] = useState(0);
    +  return (
    +    <>
    +        {/* 2. Configure the context provider and pass the value.
    +           The 'value' prop contains the data to be passed, and all child components,
    +           including nested ones, can access it using useContext. */}
    +      <MyContext.Provider value={{ count, setCount }}>
    +        <h2>Root - {count}</h2>
    +        {/* Parent component can access context values directly */}
    +        <Parent />
    +      </MyContext.Provider>
    +    </>
    +  );
    +}
    +
    +const container = document.getElementById("root");
    +const root = ReactDOM.createRoot(container);
    +root.render(<MyApp />);
    +
    • useReducer と useContext を使わない場合
    const { useState, createContext, useContext, useReducer } = React;
    +
    +// Define the initial state and reducer function
    +const initialState = { count: 0 };
    +
    +function reducer(state, action) {
    +  switch (action.type) {
    +    case "increment":
    +      return { count: state.count + 1 };
    +    default:
    +      return state;
    +  }
    +}
    +
    +// Create a context object
    +const MyContext = createContext();
    +
    +function Child() {
    +  // Retrieve values from the context object using useContext and destructure the object
    +  const { state, dispatch } = useContext(MyContext);
    +  return (
    +    <>
    +      <h2>Child - {state.count}</h2>
    +      <button onClick={() => dispatch({ type: "increment" })}>add</button>
    +    </>
    +  );
    +}
    +
    +function Parent() {
    +  // Retrieve values from the context object using useContext and destructure the object
    +  const { state } = useContext(MyContext);
    +  return (
    +    <>
    +      <h2>Parent - {state.count}</h2>
    +      {/* Child component can access context values directly */}
    +      <Child />
    +    </>
    +  );
    +}
    +
    +function MyApp() {
    +  // Use useReducer to manage state
    +  const [state, dispatch] = useReducer(reducer, initialState);
    +
    +  return (
    +    <>
    +      {/* Configure the context provider and pass the value */}
    +      <MyContext.Provider value={{ state, dispatch }}>
    +        <h2>Root - {state.count}</h2>
    +        {/* Parent component can access context values directly */}
    +        <Parent />
    +      </MyContext.Provider>
    +    </>
    +  );
    +}
    +
    +const container = document.getElementById("root");
    +const root = ReactDOM.createRoot(container);
    +root.render(<MyApp />);
    +

    # 🔷 useEffect とは

    'useEffect' を使うと、'useEffect' に渡された関数はレンダーの結果が画面に反映された後に動作します。 +つまり 'useEffect' とは、「関数の実行タイミングを React のレンダリング後まで遅らせる 'hook'」です。

    副作用の処理(DOM の書き換え、変数代入、API 通信など UI 構築以外の処理)を関数コンポーネントで扱えます。 +クラスコンポーネントでのライフサイクルメソッドに当たります。

    'componentDidMount' +'componentDidUpdate' +'componentWillUnmount'

    副作用フックの利用法 + (opens new window)

    # ▫️ 副作用を実行、制御するために useEffect を利用する

    useEffect()の基本構文は以下の通りです。関数コンポーネントのトップレベルで宣言します。

    useEffect(() => {
    +  /_ 第 1 引数には実行させたい副作用関数を記述_/;
    +  console.log("副作用関数が実行されました!");
    +}, [依存する変数の配列]); // 第 2 引数には副作用関数の実行タイミングを制御する依存データを記述
    +

    第 2 引数を指定することにより、第 1 引数に渡された副作用関数の実行タイミングを制御することができます。React は第 2 引数の依存配列の中身の値を比較して、副作用関数をスキップするかどうかを判断します。

    # ▫️ 執行時機

    可以把useEffect 函數卡奴走 componentDidiMount、componentDidUpdate、componentWillUnmount 三個生命週期函數的組合體。

    • useEffect(() => {}); componentDidMount + componentDidUpdate;
    • useEffect(() => {}, []); componentDidMount;
    • useEffect(() => () => {}); componentWillUnmount;

    以下是 useEffect 的理解:

    1. useEffect(() => {}); - componentDidMount + componentDidUpdate:

      • この形式の useEffect は、コンポーネントのレンダリング後に実行され、コンポーネントが更新されるたびにも実行されます。
      • componentDidMountcomponentDidUpdate の組み合わせに相当します。
      useEffect(() => {
      +  // ここにあるコードはコンポーネントのレンダリング後および更新時に実行されます
      +});
      +
    2. useEffect(() => {}, []); - componentDidMount:

      • この形式の useEffect は、コンポーネントのレンダリング後にのみ実行され、コンポーネントの更新時には実行されません。
      • componentDidMount だけが実行された場合と同じです。
      useEffect(() => {
      +  // ここにあるコードはコンポーネントのレンダリング後に一度だけ実行されます
      +}, []);
      +
    3. useEffect(() => () => {}); - componentWillUnmount:

      • この形式の useEffect では、返り値として返された関数はコンポーネントがアンマウント(消える)される際に実行され、componentWillUnmount に相当します。
      • 返り値として返された関数はコンポーネントがアンマウントされる前に実行され、リソースのクリーンアップや購読の解除に使用できます。
      useEffect(() => {
      +  // ここにあるコードはコンポーネントのレンダリング後に実行されます
      +
      +  // 返り値として返された関数はコンポーネントがアンマウントされる前に実行されます
      +  return () => {
      +    // リソースのクリーンアップや購読の解除などのコード
      +  };
      +}, []);
      +

    # ▫️ useEffect の使い方

    1. 為 window 對象添加滾動事件 - componentDidMount + componentDidUpdate
    import React, { useEffect } from "react";
    +
    +function App() {
    +  function onScroll() {
    +    console.log("onScroll");
    +  }
    +  useEffect(() => {
    +    // 組件渲染後,添加滾動事件
    +    window.addEventListener("scroll", onScroll);
    +    return () => {
    +      // 組件卸載時,移除滾動事件
    +      window.removeEventListener("scroll", onScroll);
    +    };
    +  }, []);
    +  return <div>App</div>;
    +}
    +
    +export default App;
    +
    1. 定時器:掛載定時器,要在組件渲染後才能掛載,所以要在 useEffect 中掛載定時器
    import React, { useEffect, useState } from "react";
    +import ReactDom from "react-dom";
    +
    +function App() {
    +  const [count, setCount] = useState(0);
    +  useEffect(() => {
    +    const timerId = setInterval(() => {
    +      setCount(count + 1);
    +    }, 1000);
    +    return () => {
    +      clearInterval(timerId);
    +    };
    +  }, []);
    +  return (
    +    <div>
    +      <span>{count}</span>
    +      <button onClick={() => ReactDOM.unmountComponentAtNode()}>
    +        卸載組件
    +      </button>
    +    </div>
    +  );
    +}
    +

    # ▫️ useEffect 依賴項

    依存配列の値が変化した場合のみ副作用関数を実行させる +useEffect()の第2引数に[count]を渡すと、count に変化があったときだけ副作用関数を実行します。

    import React, { useState, useEffect } from "react";
    +import { makeStyles } from "@material-ui/core/styles";
    +import ButtonGroup from "@material-ui/core/ButtonGroup";
    +import Button from "@material-ui/core/Button";
    +import Input from "@material-ui/core/Input";
    +
    +const useStyles = makeStyles((theme) => ({
    +  root: {
    +    "& > *": {
    +      margin: theme.spacing(1),
    +    },
    +  },
    +}));
    +
    +const EffectFunc = () => {
    +  const classes = useStyles();
    +  const [count, setCount] = useState(0);
    +  const [name, setName] = useState({
    +    lastName: "",
    +    firstName: "",
    +  });
    +  useEffect(() => {
    +    document.title = `${count}回クリックされました`;
    +  }, [count]);
    +
    +  return (
    +    <>
    +      <p>{`${count}回クリックされました`}</p>
    +      <ButtonGroup color="primary" aria-label="outlined primary button group">
    +        <Button onClick={() => setCount((prev) => prev + 1)}>ボタン</Button>
    +        <Button onClick={() => setCount(0)}>リセット</Button>
    +      </ButtonGroup>
    +      <p>{`私の名前は${name.lastName} ${name.firstName}です`}</p>
    +      <form className={classes.root} noValidate autoComplete="off">
    +        <Input
    +          placeholder="姓"
    +          value={name.lastName}
    +          onChange={(e) => {
    +            setName({ ...name, lastName: e.target.value });
    +          }}
    +        />
    +        <Input
    +          placeholder="名"
    +          value={name.firstName}
    +          onChange={(e) => {
    +            setName({ ...name, firstName: e.target.value });
    +          }}
    +        />
    +      </form>
    +    </>
    +  );
    +};
    +
    +export default EffectFunc;
    +

    # 🔷 useRef とは

    useRef 是 React 提供的一个 Hook,其主要特点是用于在函数组件中保存和访问可变的引用。以下是 useRef 的主要特点:

    1. 保存可变的引用: useRef 创建一个对象,该对象的 current 属性可以被赋值为任何可变的值。这使得在整个组件的生命周期内都可以访问和修改该值,而不引发组件重新渲染。

    2. 不触发重新渲染:useRefcurrent 属性被修改时,不会触发组件的重新渲染。这使得它非常适合存储不需要引起视图更新的数据,例如 DOM 元素引用、定时器 ID、或其他持久性数据。

    3. 持久性数据存储: useRef 创建的引用是持久的,即使组件重新渲染,引用仍然保持不变。这与 useState 不同,后者在重新渲染时会创建新的状态。

    4. 访问 DOM 元素: useRef 常用于引用 DOM 元素。当 ref 属性附加到 JSX 元素上时,useRefcurrent 属性将持有该元素的引用。

    5. 适用于保存上一个值: useRef 也常用于保存上一个状态值,因为它不会引发重新渲染,可以在渲染期间保留其值。

    下面是一个简单的示例,演示了 useRef 保存 DOM 元素引用的情况:

    import { useRef, useEffect } from "react";
    +
    +const ExampleComponent = () => {
    +  const inputRef = useRef < HTMLInputElement > null;
    +
    +  useEffect(() => {
    +    // 在组件挂载后,通过 inputRef.current 访问 input 元素
    +    if (inputRef.current) {
    +      inputRef.current.focus();
    +    }
    +  }, []);
    +
    +  return <input ref={inputRef} />;
    +};
    +

    在这个例子中,inputRef 用于引用 input 元素,而不需要通过 document.getElementById 或其他方式获取。

    key characteristics of the useRef hook:

    1. Mutable Reference: useRef creates a mutable object that persists across renders.

    2. Preservation of Value: The value assigned to current property of the useRef object persists between renders.

    3. Doesn't Trigger Re-renders: Updating the current property of a useRef does not trigger a re-render of the component.

    4. Preserving Values Without Re-renders: It's useful for holding values that need to be preserved between renders but don't require triggering a re-render.

    5. Common Use Cases:

    • Managing and maintaining references to DOM elements.
    • Holding values that should persist without causing re-renders.
    • Storing mutable values without triggering component updates.
    1. When to Use: useRef is useful for managing and maintaining references to DOM elements, storing mutable values that don't trigger re-renders, and storing mutable values that you want to persist across renders.

    2. When Not to Use: useRef should not be used to manage state or trigger re-renders.

    Note: useRef is not a replacement for useState. Always use useState when you need to manage state that changes over time. useRef is useful for storing mutable values that don't change over time, such as a reference to a DOM node or a value computed in a previous render.

    Note: useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

    Note: useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.

    # 🔷 useCallback とは

    # 🔺 Example

    在實際應用中,useCallback 的使用場景通常涉及到優化性能,特別是在 React 應用中傳遞回調函數給子組件的情況。以下是一個實際應用的例子:

    假設你有一個點餐應用(類似 SkipTheDishes),你有一個頁面顯示用戶的訂單列表。每個訂單都有一個狀態,比如"已下單"、"準備中"、"配送中"等。你的應用可能會有一個組件來顯示單個訂單的詳細信息,並且你希望在點擊"更新狀態"按鈕時觸發一個回調函數來更新訂單的狀態。

    import React, { useState, useCallback } from "react";
    +
    +const OrderDetails = ({ order, onUpdateStatus }) => {
    +  // ...
    +
    +  const handleUpdateStatus = useCallback(() => {
    +    // 在這裡處理更新訂單狀態的邏輯
    +    onUpdateStatus(order.id, newStatus);
    +  }, [onUpdateStatus, order.id, newStatus]);
    +
    +  return (
    +    <div>
    +      {/* 顯示訂單詳細信息 */}
    +      <p>Order ID: {order.id}</p>
    +      <p>Status: {order.status}</p>
    +
    +      {/* 更新狀態按鈕 */}
    +      <button onClick={handleUpdateStatus}>Update Status</button>
    +    </div>
    +  );
    +};
    +
    +const OrderList = ({ orders }) => {
    +  // ...
    +
    +  const handleUpdateStatus = useCallback((orderId, newStatus) => {
    +    // 在這裡處理更新訂單狀態的邏輯
    +    // 這個函數可能會在 OrderDetails 組件中使用,因此使用 useCallback 進行優化
    +    console.log(`Updating status of order ${orderId} to ${newStatus}`);
    +  }, []);
    +
    +  return (
    +    <div>
    +      <h2>Order List</h2>
    +      {/* 顯示訂單列表 */}
    +      {orders.map((order) => (
    +        <OrderDetails
    +          key={order.id}
    +          order={order}
    +          onUpdateStatus={handleUpdateStatus}
    +        />
    +      ))}
    +    </div>
    +  );
    +};
    +
    +const SkipTheDishesApp = () => {
    +  const [orders, setOrders] = useState(/* 初始訂單數據 */);
    +
    +  // ...
    +
    +  return <OrderList orders={orders} />;
    +};
    +

    在這個例子中,handleUpdateStatus 函數是一個回調函數,當你點擊"Update Status"按鈕時,這個函數會被觸發。由於它被傳遞給 OrderDetails 組件,我們使用 useCallback 來確保它只在 onUpdateStatusorder.idnewStatus 改變時才重新創建。這樣可以避免不必要的組件重新渲染,提高應用性能。


    # 🔷 useMemo とは

    Understanding useMemo and useCallback-Josh (opens new window)

    # 🔶 Hooks compare

    # ▫️ useCallback vs useMemo

    useMemouseCallback接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于 useMemo 返回的是函数运行的结果,useCallback 返回的是函数,这个回调函数是经过处理后的也就是说父组件传递一个函数给子组件的时候,由于是无状态组件每一次都会重新生成新的 props 函数,这样就使得每一次传递给子组件的函数都发生了变化,这时候就会触发子组件的更新,这些更新是没有必要的,此时我们就可以通过 useCallback 来处理此函数,然后作为 props 传递给子组件。

    /* 用react.memo */
    +const DemoChildren = React.memo((props) => {
    +  /* 只有初始化的时候打印了 子组件更新 */
    +  console.log("子组件更新");
    +  useEffect(() => {
    +    props.getInfo("子组件");
    +  }, []);
    +  return <div>子组件</div>;
    +});
    +
    +const DemoUseCallback = ({ id }) => {
    +  const [number, setNumber] = useState(1);
    +  /* 此时usecallback的第一参数 (sonName)=>{ console.log(sonName) }
    +     经过处理赋值给 getInfo */
    +  const getInfo = useCallback(
    +    (sonName) => {
    +      console.log(sonName);
    +    },
    +    [id]
    +  );
    +  return (
    +    <div>
    +      {/* 点击按钮触发父组件更新 ,但是子组件没有更新 */}
    +      <button onClick={() => setNumber(number + 1)}>增加</button>
    +      <DemoChildren getInfo={getInfo} />
    +    </div>
    +  );
    +};
    +
    + + + diff --git a/guide/react/reactRedux.html b/guide/react/reactRedux.html new file mode 100644 index 00000000..1b96be24 --- /dev/null +++ b/guide/react/reactRedux.html @@ -0,0 +1,74 @@ + + + + + + React Redux を基礎から理解する | ☻ itsyuimorii.space + + + + + + + + +

    # React Redux を基礎から理解する

    + + + diff --git a/guide/react/reactRouter.html b/guide/react/reactRouter.html new file mode 100644 index 00000000..490fc695 --- /dev/null +++ b/guide/react/reactRouter.html @@ -0,0 +1,302 @@ + + + + + + ⚪️ React Router を基礎から理解する | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ React Router を基礎から理解する

    # 🔶 Basic Purpose

    当我们谈论浏览器中的 URL 以及它如何与前端和后端路由相关时,我们指的是以下概念:

    瀏覽器地址欄的 URL URL => request => backend server

    前端路由

    攔截不同的 URL, 去渲染不同的組件,服務器是不知道的。 (組件中可能向後端請求 API 接口數據)

    • 前端路由主要负责在浏览器端处理不同的 URL 请求。
    • 它通过拦截 URL 的变化来决定渲染哪个组件,而不是将请求发送到服务器。
    • 在前端路由中,页面不会重新加载;相反,它通常会在当前页面动态地替换显示的内容(组件)。
    • 虽然前端路由处理的是 URL,但服务器通常对此无感知。在这种机制下,组件可能会根据需要向后端请求 API 数据。

    后端路由

    接收不同的 URL,執行不同的代碼處理,響應不同的數據(json)

    • 后端路由处理来自浏览器的请求,并根据不同的 URL 路径执行服务器上的特定代码。
    • 它负责接收请求,并根据请求的 URL 返回相应的数据(如 JSON 格式的数据)。
    • 后端路由是传统网页应用中常见的模式,每个 URL 请求通常对应服务器上的一个特定处理函数或模块。

    总结

    • 前端路由和后端路由共同作用于提供完整的网页应用体验。
    • 前端路由使得单页面应用(SPA)能够动态地更改显示的内容而无需加载新页面,提高用户体验。
    • 后端路由处理实际的数据请求和处理逻辑,为前端提供所需的数据。
    • 这种分离使得应用可以更灵活地响应用户的操作,同时优化性能和用户体验。

    React Router Tutorial (opens new window) 代碼例子 (opens new window)

    main.js

    import * as React from "react";
    +import * as ReactDOM from "react-dom/client";
    +import { createBrowserRouter, RouterProvider } from "react-router-dom";
    +import "./index.css";
    +import Root from "./routes/root";
    +
    +const router = createBrowserRouter([
    +  {
    +    path: "/",
    +    element: <Root />,
    +  },
    +]);
    +
    +ReactDOM.createRoot(document.getElementById("root")).render(
    +  <React.StrictMode>
    +    {/* 2. 配置使用- 路有對象 */}
    +    <RouterProvider router={router} />
    +  </React.StrictMode>
    +);
    +

    # 🔶 様々なシーン

    # ▫️ Takeaway 01: 理解匹配失敗的處理: 對象useRouteError()errorElement

    • 對象useRouteError()可以看到匹配失敗的信息

    • errorElement: 用於渲染匹配失敗的組件

      touch src/error-page.jsx

    import { useRouteError } from "react-router-dom";
    +
    +export default function ErrorPage() {
    +  //創建了一個error對象, 這個對象包含了匹配失敗的信息
    +  const error = useRouteError();
    +  //有錯誤才會渲染這個組件,然後在這個裡面獲取錯誤對象,拿到錯誤對象進行打印。
    +
    +  console.error(error);
    +
    +  return (
    +    <div id="error-page">
    +      <h1>Oops!</h1>
    +      <p>Sorry, an unexpected error has occurred.</p>
    +      <p>
    +        {/* statusText: 狀態文本 = Not Found */}
    +        <i>{error.statusText || error.message}</i>
    +      </p>
    +    </div>
    +  );
    +}
    +

    errorobject

    # ▫️ Takeaway 02: 理解 nested-routes (opens new window)的概念

    1. 👉 导入联系人组件并创建新路线
    /* existing imports */
    +import Contact from "./routes/contact";
    +
    +const router = createBrowserRouter([
    +  {
    +    path: "/",
    +    element: <Root />,
    +    errorElement: <ErrorPage />,
    +  },
    +  {
    +    path: "contacts/:contactId",
    +    element: <Contact />,
    +  },
    +]);
    +

    现在,如果我们单击其中一个链接或访问,/contacts/1 我们就会得到新组件!但是,它不在我们的root布局内 😠 +我们通过将联系路由设为根路由的子路由来实现这一点。 现在,您将再次看到根布局,但右侧有一个空白页面。我们需要告诉根路由我们希望它在哪里呈现其子路由。我们用 来做到这一点<Outlet>

    • 找到<div id="detail">并在里面放一个插座, 👉 渲染<Outlet>

      export default function Root() {
      +  return (
      +    <>
      +      {/* all the other elements */}
      +      <div id="detail">
      +        <Outlet />
      +      </div>
      +    </>
      +  );
      +}
      +
    • 👉 将联系人路由移至根路由的子路由 main.js

    const router = createBrowserRouter([
    +  {
    +    path: "/",
    +    element: <Root />,
    +    errorElement: <ErrorPage />,
    +    // 子路由, 應該是一個對象,裡面配置路由的路徑和組件
    +    children: [
    +      {
    +        path: "contacts/:contactId",
    +        element: <Contact />,
    +      },
    +    ],
    +  },
    +]);
    +

    為什麼要用<Link to>而不是<a href>? +因為a href會刷新頁面,而 Link 不會刷新頁面, 因為從服務器獲取頁面的代價是很大的,所以我們不希望刷新頁面。

    以下代碼, 在浏览器开发工具中打开网络选项卡,以查看它不再请求文档。

    import { Outlet, Link } from "react-router-dom";
    +
    +export default function Root() {
    +  return (
    +    <>
    +      <div id="sidebar">
    +        {/* other elements */}
    +
    +        <nav>
    +          <ul>
    +            <li>
    +              <Link to={`contacts/1`}>Your Name</Link>
    +            </li>
    +            <li>
    +              <Link to={`contacts/2`}>Your Friend</Link>
    +            </li>
    +          </ul>
    +        </nav>
    +
    +        {/* other elements */}
    +      </div>
    +    </>
    +  );
    +}
    +

    linktag

    # 🔶 loader and action

    # ▫️ Takeaway 01: 傳統式 form 表單的提交

    傳統式 form 表單的提交,會刷新頁面,然後服務器會返回一個新的頁面,然後頁面會重新加載,這樣就不是單頁面應用了。

    # ▫️ Takeaway 02: 理解 loader and actionß

    loader: 加載器, 用於加載數據, 顯示加載中的組件 +action: 用於加載數據, 顯示加載中的組件

    ▫️ 在 react-router 中,為什麼需要用 loader? 因為我們需要在獲取數據的時候,顯示加載中的組件,然後在獲取數據後,再顯示組件。 這樣就不會出現空白頁面的情況。 +▫️ 原因: react-router 希望我們把獲取數據的代碼放在 loader 中,然後在獲取數據後,再顯示組件。

    1. 👉 Configure the loader on the route main.jsx
    import Root, { loader as rootLoader } from "./routes/root";
    +const router = createBrowserRouter([
    +  {
    +   ....省略代碼
    +    loader: rootLoader,
    +    children: [
    +    ....省略代碼],
    +  },
    +]);
    +
    1. 👉 Export a loader from root.jsx

      獲取聯繫人列表,這裡是異步的獲取數據,然後獲取後,放入到 return 中 +一般是異步的獲取數據,

    import { Outlet, Link } from "react-router-dom";
    +import { getContacts } from "../contacts";
    +//異步的獲取數據
    +export async function loader() {
    +  const contacts = await getContacts();
    +  return { contacts }; //以對象的形式返回
    +}
    +....省略代碼
    +export default function Root() {}
    +....省略代碼
    +
    +
    1. 👉 Access and render the data
    import {
    +  Outlet,
    +  Link,
    +  useLoaderData,
    +} from "react-router-dom";
    +import { getContacts } from "../contacts";
    +
    +/* other code */
    +
    +export default function Root() {
    +  const { contacts } = useLoaderData();
    +
    +......省略代碼
    +  return....
    +<nav>
    +  {contacts.length ? (
    +    <ul>
    +      {contacts.map((contact) => (
    +        <li key={contact.id}>
    +          <Link to={`contacts/${contact.id}`}>
    +            {contact.first || contact.last ? (
    +              <>
    +                {contact.first} {contact.last}
    +              </>
    +            ) : (
    +              <i>No Name</i>
    +            )}{" "}
    +            {contact.favorite && <span></span>}
    +          </Link>
    +        </li>
    +      ))}
    +    </ul>
    +  ) : (
    +    <p>
    +      <i>No contacts</i>
    +    </p>
    +  )}
    +</nav>
    +
    1. Creating Contacts

    We'll create new contacts by exporting an action in our root route, wiring it up to the route config, and changing our <form> to a React Router <Form>.

    這裡需要理解,為什麼我要把 from 改為 Form? 因為我們轉發信息的時候,Form 會攔截,然後轉發給 action,然後 action 會獲取數據,然後再轉發給組件。 而傳統的 form 會直接發送請求到服務器,然後服務器會返回一個新的頁面,然後頁面會重新加載,這樣就不是單頁面應用了。

    import { Outlet, Link, Form } from "react-router-dom";
    +import { getContacts } from "../contacts";
    +
    +/* other code */
    +
    +<Form method="post">
    +  <button type="submit">New</button>
    +</Form>;
    +

    👉 Configure the loader and action on the route and Import and set the action on the route

    //封裝了action
    +import Root, {
    +  loader as rootLoader,
    +  action as rootAction,
    +} from "./routes/root";
    +//把action 綁定到這個路由上
    +const router = createBrowserRouter([
    +  {
    +    path: "/",
    +    element: <Root />,
    +    errorElement: <ErrorPage />,
    +    // 子路由, 應該是一個對象,裡面配置路由的路徑和組件
    +    loader: rootLoader,
    +    action: rootAction,
    +    children: [
    +      {
    +        path: "contacts/:contactId",
    +        element: <Contact />,
    +      },
    +    ],
    +  },
    +]);
    +

    思考:

    1. 那麼什麼時候用 loader, 什麼時候用 action 呢?
    • 當我們需要獲取數據的時候,就用 loader, 比如 get
    • 當我們需要提交數據的時候,就用 action, 比如 put,post
    1. 這裡有一個細節,
    <Form method="post">
    +  <button type="submit">New</button>
    +</Form>
    +
    1. 這裡配置時,並為配置 action, 所以提交表單後,會轉發到根目錄,也就是/, 然後根目錄配置了 action, 所以會轉發到 action 中,然後 action 中獲取數據,然後再轉發到組件中。

    2. 官網參考 +By convention, React Router uses this as a hint to automatically revalidate the data on the page after the action finishes. +action

    # 🔶 URL params in Loader

    These params are passed to the loader with keys that match the dynamic segment. For example, our segment is named :contactId so the value will be passed as params.contactId.

    //封裝loader 函數,用於獲取具體的聯繫信息
    +export async function loader({ params }) {
    +  console.log("params", params.contactId); //這裡每點擊new,就會打印出不同的id
    +  const contact = await getContact(params.contactId);
    +  return { contact };
    +}
    +
    +export default function Contact() {
    +  const { contact } = useLoaderData();
    +......省略代碼
    +
    const router = createBrowserRouter([
    +  {
    +......省略代碼
    +    children: [
    +      {
    +        path: "contacts/:contactId",
    +        element: <Contact />,
    +        loader: contactLoader,
    +      },
    +    ],
    +  },
    +]);
    +

    # 🔶 Updating data

    自定義的 Form 組件,意思就是還是會攔截,然後轉發給 action,然後 action 會獲取數據,然後再轉發給組件。

    <Form action="edit">
    +  <button type="submit">Edit</button>
    +</Form>
    +
    + + + diff --git a/guide/typescript/advanced.html b/guide/typescript/advanced.html new file mode 100644 index 00000000..d290ea80 --- /dev/null +++ b/guide/typescript/advanced.html @@ -0,0 +1,777 @@ + + + + + + ⚪️ TypeScript Advanced Knowledge | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ TypeScript Advanced Knowledge

    # Type Aliases

    Type aliases are used to give a new name to a type, often used with union types.

    type Name = string;
    +//Type Alias Name: This creates a type alias NameResolver for a function that takes no parameters and returns a string. It represents a function that resolves a name.
    +type NameResolver = () => string;
    +//Type Alias NameOrResolver: NameOrResolver is a union type alias that can be either a Name (string) or a NameResolver (function returning string). This allows flexibility in accepting different types for the getName function.
    +type NameOrResolver = Name | NameResolver;
    +//Function getName: The getName function takes a parameter x of type NameOrResolver. If x is a string, it's returned directly. If it's a function, the function is invoked to get the name. This function illustrates the flexibility provided by type aliases.
    +function getName(x: NameOrResolver) {
    +  if (typeof x === "string") {
    +    return x;
    +  }
    +  return x();
    +}
    +

    # Advantages:

    • Readability:

      • Type aliases allow you to give meaningful names to types, improving code readability. +In this example, Name, NameResolver, and NameOrResolver make the code more self-explanatory.
    • Reusability:

      • Type aliases promote the reuse of types throughout your codebase. +If you need to represent a name or a function that resolves a name in multiple places, using type aliases avoids redundancy.
    • Flexibility:

      • By combining different types into a union (NameOrResolver), you gain flexibility in function parameters. +This flexibility allows the getName function to accept either a name or a name resolver function.

    # String Literal Types

    Restrict values to a specific set of string literals.

    type EventNames = "click" | "scroll" | "mousemove";
    +function handleEvent(el: Element, event: EventNames) {
    +  // do something
    +}
    +
    +handleEvent(document.getElementById("hello") as Element, "scroll");
    +handleEvent(document.getElementById("hello") as Element, "jump"); // error
    +

    # Tuples

    Arrays store elements of the same type, while tuples store elements of different types.

    1. Tuple types allow you to express an array with a fixed number of elements whose types are known, but need not be the same.
    2. When accessing or modifying elements with a known index, the correct type is returned.
    3. During initialization, all internal elements must be included unless the element is marked as "optional."

    # Accessing Tuple Elements

    const john: [string, number] = ["John", 30];
    +let kevin: [string, number?];
    +
    +// 1.
    +john[0] = "johnny dept";
    +john[1] = "100"; // error
    +
    +// 2.
    +kevin = ["Kevin"]; // Initializing with missing elements will result in an error unless the element is optional.
    +

    # Tuple Overflow

    When adding elements beyond the original tuple limit, the type is restricted to the union type of each type in the tuple.

    let tom: [string, number] = ["Tom", 25];
    +tom.push("male");
    +tom.push(true);
    +// Type 'boolean' is not assignable to type 'string | number'. ts(2345)
    +

    # Enum

    Enums are used to define a set of named constants, making it easier to document or identify code. +Sure, here are the explanations in English:

    # Incremental Enum:

    In TypeScript, an incremental enum refers to a numeric enum where each member's value automatically increases. Here's an example:

    // Numeric Enum (increases by default)
    +enum Weekday {
    +  Monday, // 0
    +  Tuesday, // 1
    +  Wednesday, // 2
    +  Thursday, // 3
    +  Friday, // 4
    +  Saturday, // 5
    +  Sunday, // 6
    +}
    +
    +// Usage
    +let today = Weekday.Wednesday;
    +console.log(today); // Outputs: 2
    +

    In this example, Weekday is a numeric enum, and its members automatically increase starting from 0. If no value is specified for a member, TypeScript increments it based on the value of the preceding member.

    If you manually set a value for a member and want subsequent members to increment automatically, you can do it like this:

    enum Weekday {
    +  Monday = 1, // 1
    +  Tuesday, // 2
    +  Wednesday, // 3
    +  Thursday, // 4
    +  Friday, // 5
    +  Saturday, // 6
    +  Sunday, // 7
    +}
    +

    Here, Monday is manually set to 1, and the following members will increment accordingly. This kind of enum can enhance code clarity and readability in certain situations.

    # String Enum:

    String enums in TypeScript are enums where each member has an associated string value. They are beneficial for serialization and debugging because the runtime values are meaningful and readable. Here's an example:

    // String Enum
    +enum Direction {
    +  Up = "UP",
    +  Down = "DOWN",
    +  Left = "LEFT",
    +  Right = "RIGHT",
    +}
    +
    +// Usage
    +let myDirection = Direction.Left;
    +console.log(myDirection); // Outputs: "LEFT"
    +

    # heterogeneous enum

    In this example, Direction is a string enum where each member has an associated string value. This allows for more meaningful representations during runtime, especially when debugging or serializing enum values. +Heterogeneous Enums refer to enums where the member values have different data types. This situation typically occurs in enums that mix numeric and string members. Here's an example of a heterogeneous enum:

    enum Status {
    +  Success = 200,
    +  NotFound = "Not Found",
    +  Error = "Internal Server Error",
    +}
    +
    +// Usage
    +let successStatus: Status = Status.Success;
    +let notFoundStatus: Status = Status.NotFound;
    +let errorStatus: Status = Status.Error;
    +
    +console.log(successStatus); // Outputs: 200
    +console.log(notFoundStatus); // Outputs: "Not Found"
    +console.log(errorStatus); // Outputs: "Internal Server Error"
    +

    In this example, the Status enum has three members, each with a different data type for its value. One member has a numeric value (Success), and the other two have string values (NotFound and Error). This allows the enum to represent status codes or messages with different data types, and you can choose the appropriate member based on the context. The usage of heterogeneous enums is relatively less common and is typically employed when handling data of different types simultaneously.

    # interface enum

    In TypeScript, enum is commonly used to define a set of named numeric constants, while interface is used to define the structure of objects. These two concepts are typically used for different purposes, where one represents a group of related constants, and the other represents the shape of objects.

    Here is an example using both enum and interface:

    // Define a set of direction constants using enum
    +enum Direction {
    +  Up = "UP",
    +  Down = "DOWN",
    +  Left = "LEFT",
    +  Right = "RIGHT",
    +}
    +
    +// Define the structure of an object with coordinates and direction using interface
    +interface Point {
    +  x: number;
    +  y: number;
    +  direction: Direction; // Using constants from the enum
    +}
    +
    +// Create an object adhering to the Point interface using the defined enum
    +const point: Point = {
    +  x: 1,
    +  y: 2,
    +  direction: Direction.Right,
    +};
    +
    +console.log(point);
    +

    # const enum

    TypeScriptにおけるenumとconst enumの違いを、tscのコンパイル結果から確認してみる

    enumとconstsの使い分け

    # Reverse mapping

    Reverse mapping refers to the capability in an enum type where, in addition to the normal mapping from names to values, there is also a mapping from enum values back to their names. This feature provides more flexibility in certain programming scenarios.

    In TypeScript, when you assign initial values to enum members, TypeScript automatically generates both forward mapping (from enum names to values) and reverse mapping (from enum values to names). Here's an example:

    enum Direction {
    +  Up = "UP",
    +  Down = "DOWN",
    +  Left = "LEFT",
    +  Right = "RIGHT",
    +}
    +
    +// Forward mapping
    +console.log(Direction.Up); // Output: UP
    +
    +// Reverse mapping
    +console.log(Direction["UP"]); // Output: Up
    +

    In this example, the value of the enum member Direction.Up is the string "UP". Through Direction["UP"], you can retrieve the name of this member, which is "Up". This illustrates the concept of reverse mapping, where you find the corresponding name based on the enum value.

    Reverse mapping can be useful in various scenarios, such as generating labels on the user interface based on enum values or determining enum values based on user-inputted strings.

    In this example, enum Direction defines four constants representing different directions, and then interface Point defines the structure of an object with x, y, and direction properties, where direction uses constants from the Direction enum. Finally, an object point is created that conforms to the structure defined by the Point interface.

    # Classes

    While JavaScript has the concept of classes, many JavaScript programmers may not be very familiar with classes. Here's a brief introduction to class-related concepts:

    • Class: Defines the abstract characteristics of a thing, including its properties and methods.

    • Object: An instance of a class, created through the new keyword.

    • Object-Oriented Programming (OOP) Three Pillars: Encapsulation, Inheritance, and Polymorphism.

    • Encapsulation: Hides the details of data operations, exposing only the necessary interfaces. It ensures that external callers can interact with the object through provided interfaces without knowing the internal details.

    • Inheritance: A mechanism where a subclass inherits properties and behaviors from a superclass. The subclass retains the characteristics of the superclass and may have additional features.

    • Polymorphism: Different classes related through inheritance can respond to the same method in different ways. For example, a Cat and a Dog both inheriting from an Animal class may have different implementations of the eat method.

    • Accessors (Getter & Setter): Methods to change the reading and assigning behavior of properties.

    • Modifiers (Access Modifiers): Keywords that limit the nature of members or types, such as public indicating a public property or method.

    • Abstract Class: A base class meant for other classes to inherit from. Instances of an abstract class cannot be created, and abstract methods within it must be implemented by its subclasses.

    • Interfaces: Common properties or methods shared among different classes, abstracted into an interface. Classes can implement (or adhere to) multiple interfaces.

    # readonly

    The readonly keyword is used to declare read-only properties and can only appear in property declarations or index signatures.

    class Animal {
    +    readonly name;
    +    public constructor(name) {
    +        this.name = name;
    +    }
    +}
    +
    +let a = new Animal('Jack');
    +console.log(a.name); // Jack
    +a.name = 'Tom';
    +
    +// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property.
    +

    Note that if readonly is used along with other access modifiers, it should come after them.

    class Animal {
    +    // public readonly name;
    +    public constructor(public readonly name) {
    +        this.name = name;
    +    }
    +}
    +

    # Instance Properties

    In ES7 proposals, instance properties can be defined directly inside the class.

    class Animal {
    +  name = "Jack";
    +}
    +

    # Static Properties

    class Animal {
    +  static num = 42;
    +}
    +

    # Access Modifiers

    In TypeScript, access modifiers include public, private, and protected.

    • public: Accessible anywhere (default). The modified property or method is public, meaning it can be accessed from any part of the code. All properties and methods are public by default.

    • private: Cannot be accessed outside the declaring class. The modified property or method is private, and it cannot be accessed from outside the class where it is declared.

    • protected: Accessible within the declaring class and its subclasses. The modified property or method is protected, similar to private. However, it can be accessed within the declaring class and its subclasses.

    class Animal {
    +  private name;
    +  public constructor(name) {
    +    this.name = name;
    +  }
    +}
    +
    +let dog = new Animal("Cute");
    +console.log(dog.name); // 'name' is a private property and can only be accessed within class 'Animal'.
    +dog.name = "Tom"; // 'name' is a private property and can only be accessed within class 'Animal'.
    +

    Note: private does not restrict access in the compiled code; it provides compile-time checking only.

    # Getters and Setters

    class User {
    +  // Private property to store the password
    +  private _password: string = "******";
    +
    +  // Getter method to retrieve the password
    +  get password(): string {
    +    return this._password;
    +  }
    +
    +  // Setter method to update the password
    +  set password(newPass: string) {
    +    this._password = newPass;
    +
    +    // When printing the password in the setter, use this.password instead of u-password
    +    console.log(this.password);
    +  }
    +}
    +
    +// Example usage
    +const u = new User();
    +
    +// Get the current password
    +const currentPassword = u.password;
    +console.log(currentPassword); // Output: ******
    +
    +// Set a new password
    +u.password = "newPassword";
    +

    # Abstract Classes

    abstract is used to define abstract classes and abstract methods, and instances cannot be created from them.

    abstract class Animal {
    +  public name;
    +  public constructor(name) {
    +    this.name = name;
    +  }
    +  public abstract sayHi();
    +}
    +
    +let a = new Animal("Jack");
    +
    +// index.ts(9,11): error TS2511: Cannot create an instance of the abstract class 'Animal'.
    +

    In the example above, we define an abstract class Animal and an abstract method sayHi. Attempting to instantiate an abstract class directly results in an error.

    # Implementing Abstract Methods

    Secondly, abstract methods within an abstract class must be implemented by subclasses:

    abstract class Animal {
    +  public name;
    +  public constructor(name) {
    +    this.name = name;
    +  }
    +  public abstract sayHi();
    +}
    +
    +class Cat extends Animal {
    +  public eat() {
    +    console.log(`${this.name} is eating.`);
    +  }
    +}
    +
    +let cat = new Cat("Tom");
    +
    +// index.ts(9,7): error TS2515: Non-abstract class 'Cat' does not implement inherited abstract member 'sayHi' from class 'Animal'.
    +

    In this example, the Cat class inherits from Animal but fails to implement the abstract method sayHi, resulting in a compilation error.

    Here's a correct usage example:

    abstract class Animal {
    +  public name;
    +  public constructor(name) {
    +    this.name = name;
    +  }
    +  public abstract sayHi();
    +}
    +
    +class Cat extends Animal {
    +  public sayHi() {
    +    console.log(`Meow, My name is ${this.name}`);
    +  }
    +}
    +
    +let cat = new Cat("Tom");
    +

    In this corrected example, we implement the sayHi method in the Cat class, making it a valid subclass of the abstract Animal class.

    It's important to note that even though it's an abstract method, TypeScript still generates the corresponding class in the compiled result, as seen in the generated JavaScript code.

    Note: Abstract classes are present in the compiled code.

    # Here are a few common scenarios where abstract classes are beneficial in TypeScript:

    Abstract classes in TypeScript serve the primary purpose of providing a base class for deriving other classes. They can include both concrete implementations and abstract members, which must be implemented in derived classes. Abstract classes cannot be instantiated on their own; they are meant to be used as base classes for other classes.

    1. Sharing Implementation Logic: +Abstract classes can contain shared implementation logic that may be common across derived classes. By placing this logic in the abstract class, redundancy in code can be avoided.

      abstract class Shape {
      +  abstract calculateArea(): number;
      +
      +  displayArea(): void {
      +    console.log(`Area: ${this.calculateArea()}`);
      +  }
      +}
      +
      +class Circle extends Shape {
      +  constructor(private radius: number) {
      +    super();
      +  }
      +
      +  calculateArea(): number {
      +    return Math.PI * this.radius ** 2;
      +  }
      +}
      +
      +const circle = new Circle(5);
      +circle.displayArea(); // Outputs: Area: 78.54
      +
    2. Enforcing Specific Interface Implementation: +Abstract members in an abstract class must be implemented in derived classes. This helps ensure that derived classes have specific behavior or properties.

      abstract class Printer {
      +  abstract printDocument(document: string): void;
      +}
      +
      +class LaserPrinter extends Printer {
      +  printDocument(document: string): void {
      +    console.log(`Printing document (laser): ${document}`);
      +  }
      +}
      +
      +class InkjetPrinter extends Printer {
      +  printDocument(document: string): void {
      +    console.log(`Printing document (inkjet): ${document}`);
      +  }
      +}
      +
    3. Providing a Common Interface: +Abstract classes can define a set of common methods or properties to ensure a consistent interface across derived classes.

      abstract class Animal {
      +  abstract makeSound(): void;
      +
      +  move(): void {
      +    console.log("Moving...");
      +  }
      +}
      +
      +class Dog extends Animal {
      +  makeSound(): void {
      +    console.log("Woof! Woof!");
      +  }
      +}
      +
      +class Bird extends Animal {
      +  makeSound(): void {
      +    console.log("Chirp! Chirp!");
      +  }
      +}
      +

    In summary, abstract classes in TypeScript are a tool for building class hierarchies and providing a consistent interface. They help establish stricter relationships between classes and ensure certain behaviors remain consistent throughout the class hierarchy.

    # Class and Interface Interactions

    # Class Implements Interface

    When different classes share common features, interfaces can be used, and classes implement them.

    interface Chatroom {
    +  connect();
    +}
    +
    +class Customer {}
    +
    +class CustomA extends Customer implements Chatroom {
    +  connect() {
    +    console.log("welcome to A");
    +  }
    +}
    +
    +class CustomB extends Customer implements Chatroom {
    +  connect() {
    +    console.log("welcome to B");
    +  }
    +}
    +

    A class can implement multiple interfaces:

    interface Chatroom {
    +  connect();
    +}
    +
    +interface Shop {
    +  buy();
    +}
    +
    +class Customer {}
    +
    +class Custom extends Customer implements Chatroom, Shop {
    +  connect() {
    +    console.log("welcome~");
    +  }
    +  buy() {
    +    console.log("buy successful");
    +  }
    +}
    +

    For more interface and class interaction patterns, check here (opens new window).

    # generators and iterators

    In TypeScript, generators and iterators are often used together to provide a convenient way to implement iterable objects. Let's discuss generators, iterators, and how to use them in TypeScript.

    # Iterators

    In TypeScript, an iterator is an object with a next method. The next method returns an object with value and done properties, indicating the current value of the iteration and whether it is done.

    interface Iterator<T> {
    +  next(): { value: T; done: boolean };
    +}
    +
    +// Example: Iterator for a range of numbers
    +function createNumberRangeIterator(
    +  start: number,
    +  end: number
    +): Iterator<number> {
    +  let current = start;
    +  return {
    +    next(): { value: number; done: boolean } {
    +      const result = { value: current, done: current > end };
    +      current++;
    +      return result;
    +    },
    +  };
    +}
    +
    +const numberIterator = createNumberRangeIterator(1, 3);
    +console.log(numberIterator.next()); // { value: 1, done: false }
    +console.log(numberIterator.next()); // { value: 2, done: false }
    +console.log(numberIterator.next()); // { value: 3, done: false }
    +console.log(numberIterator.next()); // { value: undefined, done: true }
    +

    # Generators

    Generators are a special type of function declared using function*. They can pause execution using yield to return a value and can later resume execution. Generator functions return an iterator.

    // Example: Generator for a range of numbers
    +function* createNumberRangeGenerator(
    +  start: number,
    +  end: number
    +): Generator<number> {
    +  for (let i = start; i <= end; i++) {
    +    yield i;
    +  }
    +}
    +
    +const numberGenerator = createNumberRangeGenerator(1, 3);
    +console.log(numberGenerator.next()); // { value: 1, done: false }
    +console.log(numberGenerator.next()); // { value: 2, done: false }
    +console.log(numberGenerator.next()); // { value: 3, done: false }
    +console.log(numberGenerator.next()); // { value: undefined, done: true }
    +

    # Using Generators and Iterators

    Generators offer a more concise and readable syntax. You can use the for...of loop to iterate over the values generated by the generator.

    // Using a generator to create a number range
    +function* createNumberRangeGenerator(
    +  start: number,
    +  end: number
    +): Generator<number> {
    +  for (let i = start; i <= end; i++) {
    +    yield i;
    +  }
    +}
    +
    +// Iterating over the generator
    +for (const num of createNumberRangeGenerator(1, 3)) {
    +  console.log(num);
    +}
    +// Output:
    +// 1
    +// 2
    +// 3
    +

    Generators and iterators provide a flexible and clear way to handle a sequence of values, especially when dealing with large datasets or asynchronous operations.

    # Generics

    Generics allow you to define functions, interfaces, or classes without specifying the exact type, and instead, determine the type during usage.

    # Basic Usage

    Let's start with a function, createArray, that creates an array of a specified length and fills each element with a default value:

    function createArray(length: number, value: any): Array<any> {
    +  let result = [];
    +  for (let i = 0; i < length; i++) {
    +    result[i] = value;
    +  }
    +  return result;
    +}
    +
    +createArray(3, "x"); // Result: ['x', 'x', 'x']
    +

    The issue here is that the return type (Array<any>) allows any type in the array. To address this, we introduce generics:

    function createArray<T>(length: number, value: T): Array<T> {
    +  let result: T[] = [];
    +  for (let i = 0; i < length; i++) {
    +    result[i] = value;
    +  }
    +  return result;
    +}
    +
    +createArray<string>(3, "x"); // Result: ['x', 'x', 'x']
    +

    Now, the function is generic, and you can specify the type (e.g., string) when calling it.

    # Multiple Type Parameters

    Define multiple type parameters in a generic function, like in the swap function:

    function swap<T, U>(tuple: [T, U]): [U, T] {
    +  return [tuple[1], tuple[0]];
    +}
    +
    +swap([7, "seven"]); // Result: ['seven', 7]
    +

    Here, swap takes a tuple and swaps its elements.

    # Generic Constraints

    When using generic variables inside a function, you might need to constrain them. For example:

    interface Lengthwise {
    +  length: number;
    +}
    +
    +function loggingIdentity<T extends Lengthwise>(arg: T): T {
    +  console.log(arg.length);
    +  return arg;
    +}
    +
    +loggingIdentity({ length: 10 }); // Prints the length of the object
    +

    Here, loggingIdentity has a generic constraint to ensure that the type T extends the Lengthwise interface, which has a length property.

    # Generic Interface

    Interfaces can also be generic. Here's an example:

    interface CreateArrayFunc {
    +  <T>(length: number, value: T): Array<T>;
    +}
    +
    +let createArray: CreateArrayFunc;
    +createArray = function <T>(length: number, value: T): Array<T> {
    +  let result: T[] = [];
    +  for (let i = 0; i < length; i++) {
    +    result[i] = value;
    +  }
    +  return result;
    +};
    +
    +createArray(3, "x"); // Result: ['x', 'x', 'x']
    +

    You can also move the generic type parameter to the interface level.

    # Generic Class

    Like interfaces, classes can also use generics:

    class GenericNumber<T> {
    +  zeroValue: T;
    +  add: (x: T, y: T) => T;
    +}
    +
    +let myGenericNumber = new GenericNumber<number>();
    +myGenericNumber.zeroValue = 0;
    +myGenericNumber.add = function (x, y) {
    +  return x + y;
    +};
    +

    This GenericNumber class can work with various numeric types.

    # Default Generic Types

    Starting TypeScript 2.3, you can specify default types for generic parameters:

    function createArray<T = string>(length: number, value: T): Array<T> {
    +  let result: T[] = [];
    +  for (let i = 0; i < length; i++) {
    +    result[i] = value;
    +  }
    +  return result;
    +}
    +

    This allows you to provide a default type (string in this case) when a specific type is not explicitly provided.

    Generics enhance the flexibility and type safety of your code, allowing you to create reusable and type-agnostic components. They are particularly useful when you want to create functions or classes that can work with a variety of data types.

    # More Generics

    const echo = <T>(arg: T): T => arg;
    +
    +const isObj = <T>(arg: T): boolean => {
    +  return typeof arg === "object" && !Array.isArray(arg) && arg !== null;
    +};
    +
    +console.log(isObj(true)); // false
    +console.log(isObj("John")); // false
    +console.log(isObj([1, 2, 3])); // false
    +console.log(isObj({ name: "John" })); // true
    +console.log(isObj(null)); // false
    +
    +////////////////////////////////////
    +
    +const isTrue = <T>(arg: T): { arg: T; is: boolean } => {
    +  if (Array.isArray(arg) && !arg.length) {
    +    return { arg, is: false };
    +  }
    +  if (isObj(arg) && !Object.keys(arg as keyof T).length) {
    +    return { arg, is: false };
    +  }
    +  return { arg, is: !!arg };
    +};
    +
    +console.log(isTrue(false)); //{ arg: false, is: false }
    +console.log(isTrue(0)); //{ arg: 0, is: false }
    +console.log(isTrue(true)); //{ arg: true, is: true }
    +console.log(isTrue(1)); //{ arg: 1, is: true }
    +console.log(isTrue("Dave"));
    +console.log(isTrue(""));
    +console.log(isTrue(null));
    +console.log(isTrue(undefined));
    +console.log(isTrue({})); // modified
    +console.log(isTrue({ name: "Dave" }));
    +console.log(isTrue([])); // modified
    +console.log(isTrue([1, 2, 3]));
    +console.log(isTrue(NaN));
    +console.log(isTrue(-0));
    +
    +////////////////////////////////////
    +

    # Common Techniques

    # Extracting Variable Types

    Use typeof to extract variable types:

    let a = 123;
    +let b = { x: 0, y: 1 };
    +
    +type A = typeof a; // number
    +type B = typeof b; // { x: number, y: number }
    +

    # Binding Function this

    Bind this on the first parameter. See reference (opens new window)

    const obj = {
    +  say(name: string) {
    +    console.log("Hello: ", name);
    +  },
    +};
    +
    +function test(this: typeof obj, str: string) {
    +  console.log(this.say(str));
    +}
    +

    # Index Variables

    interface A {
    +  [key: string]: any;
    +}
    +
    +// 'in' iterates over sub-properties, resulting in the type: string
    +type B = {
    +  [key in "a" | "b" | "c"]: string;
    +};
    +

    # Built-in Types

    TypeScript provides built-in utility types:

    # Record

    Generates an object type with keys of type K and values of type T.

    type Record<K extends keyof any, T> = {
    +  [P in K]: T;
    +};
    +
    +const foo: Record<string, boolean> = {
    +  a: true,
    +};
    +
    +const bar: Record<"x" | "y", number> = {
    +  x: 1,
    +  y: 2,
    +};
    +

    # Partial

    Makes all properties of T optional.

    type Partial<T> = {
    +  [P in keyof T]?: T[P];
    +};
    +
    +interface Foo {
    +  a: string;
    +  b: number;
    +}
    +
    +const foo: Partial<Foo> = {
    +  b: 2, // 'a' is optional
    +};
    +

    # Required

    Opposite of Partial, makes all properties of T required.

    # Readonly

    Makes all properties of T readonly.

    # Pick

    Selects properties from T specified by K.

    type Pick<T, K extends keyof T> = {
    +  [P in K]: T[P];
    +};
    +
    +interface Foo {
    +  a: string;
    +  b: number;
    +  c: boolean;
    +}
    +
    +const foo: Pick<Foo, "b" | "c"> = {
    +  b: 1,
    +  c: false,
    +};
    +

    # Exclude

    Exclude from T those types that are assignable to U.

    type Exclude<T, U> = T extends U ? never : T;
    +
    +let foo: Exclude<"a" | "b" | "c", "b"> = "a";
    +foo = "c";
    +

    # Extract

    Extract from T those types that are assignable to U.

    type Extract<T, U> = T extends U ? T : never;
    +
    +let foo: Extract<"a" | "b" | "c", "b"> = "b";
    +

    # Parameters

    Returns a tuple type based on the parameters of a function.

    type Parameters<T extends (...args: any) => any> = T extends (
    +  ...args: infer P
    +) => any
    +  ? P
    +  : never;
    +
    +type Foo = (a: string, b: number) => void;
    +const a: Parameters<Foo> = ["a", 1]; // [string, number]
    +

    # ReturnType

    Returns the return type of a function.

    type ReturnType<T extends (...args: any) => any> = T extends (
    +  ...args: any
    +) => infer R
    +  ? R
    +  : any;
    +
    +type Foo = () => boolean;
    +const a: ReturnType<Foo> = true; // Returns boolean type
    +

    # 🔹 index signature

    // Index Signatures
    +
    +// interface TransactionObj {
    +//     readonly [index: string]: number
    +// }
    +
    +interface TransactionObj {
    +  readonly [index: string]: number;
    +  Pizza: number;
    +  Books: number;
    +  Job: number;
    +}
    +
    +const todaysTransactions: TransactionObj = {
    +  Pizza: -10,
    +  Books: -5,
    +  Job: 50,
    +};
    +
    +console.log(todaysTransactions.Pizza);
    +console.log(todaysTransactions["Pizza"]);
    +
    +let prop: string = "Pizza";
    +console.log(todaysTransactions[prop]);
    +
    +const todaysNet = (transactions: TransactionObj): number => {
    +  let total = 0;
    +  for (const transaction in transactions) {
    +    total += transactions[transaction];
    +  }
    +  return total;
    +};
    +
    +console.log(todaysNet(todaysTransactions));
    +
    +//todaysTransactions.Pizza = 40
    +console.log(todaysTransactions["Dave"]); // undefined
    +
    +///////////////////////////////////
    +
    +interface Student {
    +  [key: string]: string | number | number[] | undefined;
    +  name: string;
    +  GPA: number;
    +  classes?: number[];
    +}
    +
    +const student: Student = {
    +  name: "Doug",
    +  GPA: 3.5,
    +  classes: [100, 200],
    +};
    +
    +console.log(student.test); //because of the index signature, this is allowed
    +
    +for (const key in student) {
    +  console.log(`${key}: ${student[key as keyof Student]}`); //'name: Doug' ,'GPA: 3.5' ​​​​​, 'classes: 100,200' ​​​​​, 'test: undefined'
    +}
    +
    +Object.keys(student).map((key) => {
    +  console.log(student[key as keyof typeof student]); // 'Doug' , 3.5 , [ 100, 200 ]
    +});
    +
    +const logStudentKey = (student: Student, key: keyof Student): void => {
    +  console.log(`Student ${key}: ${student[key]}`); //'Student name: Doug'
    +};
    +
    +logStudentKey(student, "name");
    +
    +/////////////////////////////////
    +
    +// interface Incomes {
    +//     [key: string]: number
    +// }
    +
    +type Streams = "salary" | "bonus" | "sidehustle";
    +
    +type Incomes = Record<Streams, number>;
    +
    +const monthlyIncomes: Incomes = {
    +  salary: 500,
    +  bonus: 100,
    +  sidehustle: 250,
    +};
    +
    +for (const revenue in monthlyIncomes) {
    +  console.log(monthlyIncomes[revenue as keyof Incomes]); // 500 , 100 , 250
    +}
    +

    🔺 student[key as keyof typeof student]:

    Inside the function passed to map, each key is used to access the corresponding value in the student object. - key is a variable holding the current property name being iterated over. - key as keyof typeof student is a TypeScript type assertion. It tells TypeScript to treat key as one of the keys of the type of student. This is necessary because, by default, the type of key would be just string, which is too general. The keyof typeof student type is more specific, representing the union of all literal types of the keys in the student object.

    Object.keys(student).map((key) => {
    +  console.log(student[key as keyof typeof student]);
    +});
    +

    🔺 補充理解在 JavaScript 和 TypeScript 中,对象属性可以通过两种方式访问

    点符号(.)和方括号符号([])。在您提供的代码中,todaysTransactions 是一个对象,其中包含了不同的属性(如 PizzaBooksJob),每个属性都有对应的值。

    1. 点符号: todaysTransactions.Pizza。这种方式是直接访问对象的属性,其中 Pizza 是属性的字面量名称。

    2. 方括号符号: todaysTransactions['Pizza']todaysTransactions[prop]。这种方式用于当属性名是动态的或者是一个变量时。在这种情况下,属性名需要作为字符串传递。

    在代码中,prop 是一个字符串类型的变量,其值为 'Pizza'。因此,当你使用 todaysTransactions[prop] 时,它实际上是 todaysTransactions['Pizza'] 的简写。由于 prop 变量的值是 'Pizza',所以这个表达式最终访问的是 todaysTransactions 对象中 Pizza 这个属性的值。

    # Accessing object properties dynamically in TypeScript

    Accessing object properties dynamically in TypeScript can be achieved through various methods, including dot notation, square brackets, and the keyof operator. Each method has its specific use cases and benefits depending on the requirements of your application.

    1. Using Square Brackets: This method is particularly useful when the property name is dynamic, such as in the case of user input or other runtime conditions. For example, you might have a TypeScript React component where you need to access properties of an object based on user interactions or input. Here's a simple example:

      interface User {
      +  name: string;
      +  age: number;
      +  email: string;
      +}
      +
      +const user: User = {
      +  name: "Alice",
      +  age: 25,
      +  email: "alice@example.com",
      +};
      +
      +const propertyName = "email";
      +const propertyValue = user[propertyName];
      +console.log(propertyValue); // Outputs: alice@example.com
      +

      In this example, propertyName is a variable that holds the name of the property you want to access. This approach is useful in scenarios like handling form inputs dynamically.

    2. Using keyof with TypeScript: The keyof operator is another powerful feature in TypeScript, which you can use to create a union type of all the keys in an object. This is particularly useful for ensuring type safety when accessing properties dynamically. Here's an example:

      interface User {
      +  name: string;
      +  age: number;
      +  email: string;
      +}
      +
      +type UserKeys = keyof User;
      +
      +const user: User = {
      +  name: "Bob",
      +  age: 30,
      +  email: "bob@example.com",
      +};
      +
      +const propertyName: UserKeys = "name";
      +const propertyValue = user[propertyName];
      +console.log(propertyValue); // Outputs: Bob
      +

      In this example, propertyName is a variable of type UserKeys, which is a union of all keys in the User interface. This ensures that only valid property names can be assigned to propertyName.

    3. Dynamic Property Access in React Components: In React components, you might encounter scenarios where you need to dynamically access or update the state based on user input or interaction. For example, if you are building a form with multiple fields, you can use the square bracket notation to update the state for each field dynamically:

      import React, { useState } from "react";
      +
      +const FormComponent: React.FC = () => {
      +  const [formState, setFormState] = useState<{ [key: string]: string }>({});
      +
      +  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
      +    setFormState({
      +      ...formState,
      +      [event.target.name]: event.target.value,
      +    });
      +  };
      +
      +  return (
      +    <form>
      +      <input name="username" onChange={handleChange} />
      +      <input name="email" onChange={handleChange} />
      +      {/* ... other form fields ... */}
      +    </form>
      +  );
      +};
      +

      In this React component, handleChange function updates the formState dynamically based on the input field's name attribute.

    🔺 For more detailed information, you can refer to these resources:

    # Reference Articles

    1. TypeScript for Beginners (opens new window)
    2. TypeScript Practical Tips and Tricks (opens new window)
    + + + diff --git a/guide/typescript/basic.html b/guide/typescript/basic.html new file mode 100644 index 00000000..6ffe9a72 --- /dev/null +++ b/guide/typescript/basic.html @@ -0,0 +1,292 @@ + + + + + + 🔶 TypeScript Basic Knowledge | ☻ itsyuimorii.space + + + + + + + + +

    # 🔶 TypeScript Basic Knowledge

    # 🔸 Primitive Types

    string, number, boolean, null, undefined, Symbol

    // Known type
    +const str: string = "Hello World";
    +
    +// Unknown with expectation
    +let num = <unknown>getNumber();
    +// Known expectation
    +num = <number>getNumber();
    +
    +// Function returning a number
    +function getNumber(): number {
    +  return 30;
    +}
    +
    +// Void function
    +function count(): void {
    +  console.log(1 + 3);
    +}
    +

    # Any Type

    A variable of any type cannot change its type during operations.

    1. Any type allows any operation, and the return type is of any.
    2. When a variable is declared without specifying a type and no value is assigned, it defaults to any.
    let someText: any = 30; // Will cause an error if set to number
    +someText = "someText"; // Error
    +

    # 🔸 Never

    A function that never returns, or a function that always throws an error.

    • bottom level type
    • can be assigned to any type

    In TypeScript, the never type is often used in the context of exhaustiveness checking, particularly in situations like switch statements. The never type represents the type of values that never occur. It is used to indicate that a function will not return normally (e.g., it throws an error or has an infinite loop).

    Let's discuss how never is commonly used with switch statements and the default case:

    type Fruit = "Apple" | "Banana" | "Orange";
    +
    +function getFruitColor(fruit: Fruit): string {
    +  switch (fruit) {
    +    case "Apple":
    +      return "Red";
    +    case "Banana":
    +      return "Yellow";
    +    case "Orange":
    +      return "Orange";
    +    default:
    +      // The default case is marked as unreachable, and its return type is 'never'.
    +      // This is because TypeScript can infer that the switch is exhaustive, covering all possible values of 'Fruit'.
    +      const exhaustiveCheck: never = fruit;
    +      return exhaustiveCheck; // This line will never be reached.
    +  }
    +}
    +

    Explanation:

    1. The Fruit type is defined as a union of string literals representing different fruit names.
    2. The getFruitColor function takes a fruit argument of type Fruit and returns a string representing the color.
    3. The switch statement is used to handle different cases based on the value of fruit.
    4. For each known fruit case ('Apple', 'Banana', 'Orange'), the function returns the corresponding color.
    5. The default case is marked with never. This indicates to TypeScript that this case should never be reached because we've covered all possible values of Fruit.
    6. The exhaustiveCheck variable is of type never, which means TypeScript understands that it can never have a value, and this line will never be executed.

    This pattern helps TypeScript catch situations where you might forget to handle a specific case in a switch statement, providing better safety and avoiding unintentional bugs.

    # 型アノテーション(Type Annotation)

    TypeScript では value: Type というフォーマットで宣言時の変数 に型の注釈がつけられる +アノテー ションによって静的に型付けされた情報はコンパイル時のチェックに用いられ、書かれたコード中 に型の不整合があるとコンパイルエラーになる

    # 型推論(Type Inference)

    When the type is not explicitly specified, TypeScript infers the type based on the assigned value.

    let typeS = "seven";
    +typeS = 10; // Inferred as string due to the initial value being a string
    +
    +let typeA;
    +typeA = "six";
    +typeA = 30; // Inferred as any since no initial value is given
    +

    # Union Types

    Represents a value that can be one of multiple types, using | to separate types.

    let unionC: string | number = "Ray";
    +unionC = 100;
    +
    +function getLength(something: string | number): number {
    +  return something.length; // Can only access properties common to both types, error
    +}
    +

    # Object Types - Interface

    Commonly used to describe the shape of objects.

    1. Interface names typically start with a capital letter.
    2. Optional properties are denoted with ? to enhance flexibility.
    3. Index signatures allow any property of a certain type.
    4. Use readonly to mark properties as read-only.
    interface Person {
    +  readonly id: number;
    +  name: string;
    +  age?: number; // Optional property
    +  [prop: string]: any; // Any property of type any
    +  // [prop: string]: string; // Uncommenting restricts any property to string type
    +}
    +
    +let tom: Person = {
    +  id: 3387,
    +  name: "Tom",
    +  // age: 30,
    +};
    +// Constraints Tom to have the same shape as Person (no more, no less)
    +
    +// Cannot modify readonly property after initialization, error
    +tom.id = 4069;
    +

    Function interfaces or interfaces with function properties are also possible:

    interface MyFunction {
    +  (a: number): void;
    +}
    +
    +interface MyObject {
    +  jump: (a: number) => void;
    +}
    +

    # Array Types

    Several ways to define array types:

    1. Type + square brackets
    2. Array generics (Array)
    3. Interface for arrays
    4. Tuple types (IArguments, NodeList, HTMLCollection, Element...)
    // 1.
    +const myArr: number[] = [1, 2, 3];
    +myArr.push("4"); // Method calls are type-checked, error
    +
    +// 2.
    +const myArr2: Array<number> = [1, 2, 3];
    +myArr2[2] = "3"; // Error
    +
    +// 3.
    +interface NumberArray {
    +  [index: number]: number;
    +}
    +const myArr3: NumberArray = [1, 2, 3];
    +
    +// 4. Built-in array interfaces
    +function sum() {
    +  let args: IArguments = arguments;
    +}
    +

    For more built-in objects, refer to this link (opens new window).

    # Function Types

    Functions have input and output types, considering both is crucial.

    1. Declaration

    2. Expression

      • Be cautious when using the => syntax; it might be confusing and is recommended to use the declaration syntax.
    3. Interface definition

    4. Optional parameters marked with ?, which cannot follow required parameters.

    5. Default parameter values make parameters optional.

    6. Rest parameters can be defined using an array type (any[]).

    7. Overloads allow a function to accept different numbers or types of parameters.

    // 1.
    +function sumFn(x: number, y: number): number {
    +  return x + y;
    +}
    +
    +sumFn(1); // Error
    +sumFn(1, 2, 3); // Error
    +
    +// 2.
    +const sumFnEx: (x: number, y: number) => number = function (
    +  x: number,
    +  y: number
    +): number {
    +  return x + y;
    +};
    +
    +// 3.
    +interface Isum {
    +  (x: number, y: number): number;
    +}
    +
    +const mySum: Isum = function (x: number, y: number): number {
    +  return x + y;
    +};
    +
    +// 4. & 5.
    +function buildName(
    +  firstName: string,
    +  lastName?: string,
    +  age: number = 30
    +): string {
    +  return `${firstName} ${lastName}, now age ${age}`;
    +}
    +buildName("johnny");
    +
    +// 6.
    +function push(array: any[], ...items: any[]) {
    +  items.forEach((item) => {
    +    array.push(item);
    +  });
    +}
    +
    +// 7.
    +// Define precise input and output types for numbers, then implement logic
    +function reverse(x: number): number;
    +function reverse(x: string): string;
    +function reverse(x: number | string): number | string {
    +  if (typeof x === "number") {
    +    return Number(x.toString().split("").reverse().join(""));
    +  } else if (typeof x === "string") {
    +    return x.split("").reverse().join("");
    +  }
    +  return 0;
    +}
    +

    # Type Assertion

    Manually specify a value's type, commonly used in React's TSX (TS for JSX) to distinguish between TypeScript and ES6 arrow functions.

    1. When dealing with union types, sometimes a specific type's property needs to be accessed.

      • Caution is needed to avoid runtime errors when accessing properties immediately after assertion.
    2. Parent class inheritance assertion

    3. "XXX as any" should be a last resort for solving type issues, use sparingly.

    4. Type assertion reinforcement (for old code returning any, explicitly assert its type after calling)

    5. Type assertions are only effective during compilation, having no impact on the compiled code.

    6. Type declarations are stricter; prefer using them whenever possible.

    // 1.
    +interface Cat {
    +  name: string;
    +  run(): void;
    +}
    +
    +interface Fish {
    +  name: string;
    +  swim(): void;
    +}
    +
    +function getName(animal: Cat | Fish) {
    +  // Accessing swim directly after assertion may cause runtime errors
    +  // if (typeof animal.swim === 'function') {
    +  if (typeof (animal as Fish).swim === "function") {
    +    console.log("Is a fish");
    +  } else {
    +    // ...
    +  }
    +}
    +
    +// 2.
    +class ApiError extends Error {
    +  code: number = 0;
    +}
    +
    +class HttpError extends Error {
    +  statusCode: number = 200;
    +}
    +
    +function isApiError(error: Error): boolean {
    +  if (typeof (error as ApiError).code === "number") {
    +    return true;
    +  }
    +  return false;
    +}
    +
    +// 3.
    +// Accessing any property is legal, but this is a last resort
    +window.foo = 1; // Error
    +(window as any).foo = 1;
    +
    +// 4.
    +function getCache(key: string): any {
    +  return (window as any).cache[key];
    +}
    +
    +interface Cat {
    +  name: string;
    +  run(): void;
    +}
    +
    +// Type assertion
    +const tomCat = getCache("tom") as Cat;
    +// Type declaration (more strict)
    +// const tomCat: Cat = getCache('tom');
    +tomCat.run();
    +

    # Declaration Files

    When using third-party libraries, include their declaration files to enable type checking.

    Usually, declaration statements are placed in separate files, e.g., jQuery.d.ts.

    1. declare var/let/const
    2. declare namespace creates a namespace to avoid global pollution; use the namespace when accessing its interfaces.
    3. For library declaration files, it is recommended to use @types for centralized management. Install with npm install @types/library --save-dev. No further configuration is needed for global declarations.
    4. For NPM declaration files, export and import are required to use types within modules.
    // 1. Using jQuery as an example
    +declare const jQuery: (selector: string) => any;
    +
    +// 2. Example (illustrative purposes only)
    +declare namespace Vue {
    +  function component(name: string, data: any): any;
    +  function mixin(data: any): void;
    +}
    +

    # Declaration Merging

    Taking jQuery as an example, it is both a function and an object with properties. Multiple declaration statements that do not conflict will be merged.

    declare function jQuery(selector: string): any;
    +declare namespace jQuery {
    +  function ajax(url: string, settings?: any): void;
    +}
    +
    + + + diff --git a/guide/typescript/index.html b/guide/typescript/index.html new file mode 100644 index 00000000..c6d5b6ff --- /dev/null +++ b/guide/typescript/index.html @@ -0,0 +1,74 @@ + + + + + + Typescript Reference Guide | ☻ itsyuimorii.space + + + + + + + + +
    + + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..67038dc2 --- /dev/null +++ b/index.html @@ -0,0 +1,78 @@ + + + + + + ☻ itsyuimorii.space + + + + + + + + +
    hero

    + itsyuimoriispace〰️ +

    + 私の技術ブログ - for sharing personal learning notes from 📚学び、💢知識、🪴成長する。 +

    + Read more → +

    📚 読書メモ

    Reading is a discount ticket to everywhere. - Mary Schmich

    📩 知識を共有する

    In the process of letting go you will lose many things from the past, but you will find yourself. - Deepak Chopra

    🪴 成長する

    The key to growth is the introduction of higher dimensions of consciousness into our awareness. - Lao Tzu

    + + + diff --git a/logo.gif b/logo.gif new file mode 100644 index 00000000..2fe02f8f Binary files /dev/null and b/logo.gif differ diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 00000000..3e0c12a4 Binary files /dev/null and b/logo.jpg differ diff --git a/memo/archtiect.html b/memo/archtiect.html new file mode 100644 index 00000000..111daa9b --- /dev/null +++ b/memo/archtiect.html @@ -0,0 +1,168 @@ + + + + + + ## Backend for Frontend | ☻ itsyuimorii.space + + + + + + + + +

    #

    # Backend for Frontend

    学习 BFF(Backend for Frontend)并不要求专门学习 Java 的某个特定部分。BFF 是一种架构模式,可以在多种后端编程语言中实现,包括 Java。要学习 BFF,你需要掌握以下关键概念和技能:

    1. 后端开发基础:你需要了解后端开发的基本原理,包括处理 HTTP 请求和响应、路由、数据存储等。这些原理在不同的后端编程语言中都是通用的。

    2. Java 编程语言:如果你选择在 Java 中实现 BFF,那么你需要掌握 Java 编程语言的基础知识,包括语法、数据结构、面向对象编程等。

    3. Spring Framework:Spring 是一个流行的 Java 开发框架,它提供了一套丰富的工具和库,用于构建后端应用程序。学习 Spring 框架可以帮助你更轻松地实现 BFF。

    4. RESTful API 设计:BFF 通常是为前端应用程序提供 RESTful API 的一部分。你需要了解如何设计和实现 RESTful API,包括资源的表示、HTTP 方法的使用等。

    5. 安全性:了解如何保护后端服务和 API 的安全性是非常重要的。学习关于身份验证、授权、数据验证和防止安全漏洞的最佳实践。

    6. 前端开发基础:虽然 BFF 是后端的一部分,但它的目标是为前端应用程序提供服务。因此,了解前端开发的基本原理和技能也是有益的,以更好地理解前后端之间的交互。

    总之,学习 BFF 需要你掌握后端开发的基础知识,以及如果选择 Java 作为实现语言,那么需要学习 Java 编程和 Spring 框架。同时,了解前端开发基础也有助于更好地满足前端应用程序的需求。

    # GraphQL 来实现 BFF,需要掌握哪些技能?

    如果你打算使用 GraphQL 来实现 BFF,那么你需要学习以下关键概念和技能:

    1. GraphQL 基础知识:首先,你需要理解 GraphQL 的基本概念,包括如何定义和查询数据模型,以及 GraphQL 查询语言的语法和结构。

    2. 后端开发:BFF 通常是作为后端服务的一部分,用于处理前端应用程序的数据需求。你需要具备后端开发的基础知识,包括如何编写 GraphQL 服务、处理查询和变异等。

    3. GraphQL 服务器:选择适合你的编程语言的 GraphQL 服务器。在 Java 中,你可以使用一些库和框架来构建 GraphQL 服务器,如 Apollo Server、GraphQL-Java、Spring GraphQL 等。

    4. 数据模型和解析器:定义你的数据模型,并创建相应的解析器来处理 GraphQL 查询。你需要了解如何映射数据模型到 GraphQL 类型,以及如何编写解析器来获取和转换数据。

    5. 查询优化:GraphQL 允许客户端指定其需要的数据,因此查询的优化非常重要。学习如何优化查询以减少数据传输和提高性能。

    6. 安全性:了解如何在 GraphQL 服务中实现安全性措施,包括身份验证和授权,以确保只有授权的用户能够访问特定的数据。

    7. 前端开发基础:虽然 BFF 是后端的一部分,但了解前端开发基础也有助于更好地满足前端应用程序的需求,特别是在设计 GraphQL 查询时。

    总之,学习如何使用 GraphQL 来实现 BFF 需要你掌握 GraphQL 的基础知识,后端开发技能,以及选择适合你的编程语言的 GraphQL 服务器和工具。同时,了解如何优化查询、确保安全性和理解前端开发基础也是有帮助的。

    BFF 筆記:

    這時候就需要一個統一的接口, 這個接口就是 BFF . 就可以做到真正的前後端分離

    BFF 的背景:

    • 应用程序通常有多个平台,如 PC WebApp、iOS、Android、微信小程序等,它们直接向后端服务发送请求。
    • 每个平台的请求可能不同,导致后端需要为每个平台构建一个服务器,这会增加开发成本和服务器负担。
    • 单个请求可能需要多个接口,这会增加网络开销和降低性能。

    BFF 的作用:

    • BFF 是一种统一的接口,用于解决不同平台请求的问题,实现前后端分离。
    • BFF 可以根据请求的平台返回相应的数据,避免了后端的复杂判断逻辑。

    BFF 的实现方式:

    • BFF 可以通过代理(Proxy)来实现,而不需要安装额外的服务器,只需要配置代理即可。
    • BFF 可以生成一个用于前端服务器的分发包(dist),使前端服务器能够找到接口。
    • BFF 还可以支持同构化,允许在服务器端和客户端共享代码,提高性能。

    总结: +BFF 是一种解决多平台应用请求管理和性能优化的重要工具,它可以通过统一接口、代理和分发包来实现。 BFF 的使用可以简化后端逻辑,降低开发成本,提高性能。

    Certainly! Below is a simple example of how a React frontend might interact with a Backend for Frontend (BFF) which is then communicating with a set of Java-based microservices.

    # React Frontend Example

    Here's a basic React component that interacts with a BFF to get the details of a product for display:

    import React, { useState, useEffect } from "react";
    +
    +function ProductDetails({ productId }) {
    +  const [product, setProduct] = useState(null);
    +  const [loading, setLoading] = useState(false);
    +  const [error, setError] = useState(null);
    +
    +  useEffect(() => {
    +    const fetchProduct = async () => {
    +      setLoading(true);
    +      try {
    +        const response = await fetch(`/bff/products/${productId}`);
    +        if (!response.ok) throw new Error("Product not found");
    +        const data = await response.json();
    +        setProduct(data);
    +      } catch (err) {
    +        setError(err.message);
    +      } finally {
    +        setLoading(false);
    +      }
    +    };
    +
    +    fetchProduct();
    +  }, [productId]);
    +
    +  if (loading) return <div>Loading...</div>;
    +  if (error) return <div>Error: {error}</div>;
    +  if (!product) return <div>No product details available.</div>;
    +
    +  return (
    +    <div>
    +      <h1>{product.name}</h1>
    +      <p>Price: {product.price}</p>
    +      <img src={product.thumbnailUrl} alt={product.name} />
    +      {/* ... other product details */}
    +    </div>
    +  );
    +}
    +
    +export default ProductDetails;
    +

    # Backend for Frontend (BFF) Example with Java/Spring Boot

    Your BFF might be a Spring Boot application that routes requests to different microservices:

    @RestController
    +@RequestMapping("/bff/products")
    +public class ProductBFFController {
    +
    +    private final ProductService productService;
    +
    +    public ProductBFFController(ProductService productService) {
    +        this.productService = productService;
    +    }
    +
    +    @GetMapping("/{id}")
    +    public ResponseEntity<ProductDTO> getProduct(@PathVariable Long id) {
    +        try {
    +            ProductDTO product = productService.getProductById(id);
    +            return ResponseEntity.ok(product);
    +        } catch (ProductNotFoundException e) {
    +            return ResponseEntity.notFound().build();
    +        }
    +    }
    +}
    +

    Here's the ProductService that the BFF controller might use to communicate with the product microservice:

    @Service
    +public class ProductService {
    +
    +    private final RestTemplate restTemplate;
    +
    +    public ProductService(RestTemplate restTemplate) {
    +        this.restTemplate = restTemplate;
    +    }
    +
    +    public ProductDTO getProductById(Long id) {
    +        String productMicroserviceUrl = "http://product-microservice/api/products/" + id;
    +        ResponseEntity<ProductDTO> response = restTemplate.getForEntity(productMicroserviceUrl, ProductDTO.class);
    +
    +        if (response.getStatusCode() == HttpStatus.OK) {
    +            return response.getBody();
    +        } else {
    +            throw new ProductNotFoundException("Product not found with ID: " + id);
    +        }
    +    }
    +}
    +

    And the ProductDTO might look like this:

    public class ProductDTO {
    +    private Long id;
    +    private String name;
    +    private String description;
    +    private BigDecimal price;
    +    private String thumbnailUrl;
    +
    +    // Getters and setters...
    +}
    +

    In this example, when the React component makes a request to the BFF (/bff/products/{productId}), the BFF controller in the Spring Boot application receives the request, uses the ProductService to make a call to the product microservice, gets the product information, and returns it to the frontend formatted as needed.

    Remember, for a real-world application, you'd need to handle cross-origin resource sharing (CORS) in the BFF, have proper error handling, use environment variables for service URLs, implement security, and consider using asynchronous communication patterns where appropriate.

    + + + diff --git a/memo/arrayusage.html b/memo/arrayusage.html new file mode 100644 index 00000000..48139e2e --- /dev/null +++ b/memo/arrayusage.html @@ -0,0 +1,134 @@ + + + + + + 🔻 使用される場面 | ☻ itsyuimorii.space + + + + + + + + +

    # 🔻 使用される場面

    # 例子 1: JavaScript Data Transformation Using Object.values and map

    import { animals, colors } from "../constants";
    +
    +const ANIMAL_OPTIONS: SelectOption[] = Object.values(animals).map((animal) => ({
    +  value: animal,
    +  label: animal.charAt(0) + animal.slice(1).toLowerCase(),
    +}));
    +
    +const COLOR_OPTIONS: SelectOption[] = Object.values(colors).map((color) => ({
    +  value: color,
    +  label: color.charAt(0) + color.slice(1).toLowerCase(),
    +}));
    +
    1. Extracting Object Values with Object.values:

      • Object.values is a method that takes an object as an argument and returns an array containing all the values of that object's properties.
      • Example Usage: In the context of a countries object, Object.values(countries) would extract all country names and create an array of these names, such as ['CANADA', 'UNITED KINGDOM', 'AUSTRALIA'].
    2. Transforming Array Elements with map:

      • The map method creates a new array by performing a specified operation on each element of an array.
      • In the given example, map is used to transform each country name into an object with two properties: value and label. +
        • value: The original country name.
        • label: The country name formatted with the first letter in uppercase and the rest in lowercase, achieved through country.charAt(0) (first character) and country.slice(1).toLowerCase() (remaining characters in lowercase).
    3. Resulting Data Structure:

      • The combination of Object.values and map results in an array of objects, each representing a country option. Each object has a value (the original uppercase country name) and a label (formatted with only the first letter capitalized).
      • Example Output: An array of objects like { canada: 'Canada', unitedkingdom: 'United Kingdom', australia: 'Australia' }, where the keys are lowercase versions of the country names and the values are formatted as specified.

    Key Takeaways:

    • These methods are effective for converting and preparing data from objects into a specific format, such as options for a dropdown menu.
    • Object.values and map offer a common and powerful pattern for data handling and transformation in JavaScript, ensuring consistency and readability in your code.

    # **例子 2: 用Array.prototype.reducearray 轉換成 object **

    1. Defining the Array: +First, define an array containing country names. For example:

      const countries = ["Canada", "United Kingdom", "Australia"];
      +
    2. Using reduce to Transform into an Object: +Use the reduce method to iterate over the array, transforming each array element (country name) into both key and value of the object.

      const countriesObject = countries.reduce((obj, country) => {
      +  const key = country.toLowerCase().replace(/ /g, "");
      +  obj[key] = country;
      +  return obj;
      +}, {});
      +

      In this example, the reduce method takes two parameters: an accumulator (obj) and the current element (country). We first convert the country name to lowercase and remove all spaces to create the key, then assign the original country name (country) as the value.

    3. Accessing Country Names Using the Object: +Once the object is created, you can use it as Cameron described:

      if (country === countriesObject.canada) {
      +  // Logic to handle the scenario
      +}
      +

      在您提供的代码示例中,使用 reduce 方法创建对象时,指定了键(key)和值(value)的过程如下:

      • 键(Key)的创建

        • 键是通过将国家名转换为小写并移除所有空格来创建的。在代码中,这是通过 country.toLowerCase().replace(/ /g, '') 实现的。
        • 这里,country 是数组中的当前元素(即国家名)。toLowerCase() 方法将国家名转换为小写,replace(/ /g, '') 方法则移除所有空格。
        • 这个转换后的字符串(国家名的小写无空格版本)被用作对象的键。
      • 值(Value)的指定

        • 值直接使用原始的国家名(即数组中的当前元素 country)。
        • obj[key] = country; 这行代码中,obj 是累加器对象,key 是经过处理的国家名,country是原始的国家名。
        • 因此,每次迭代时,都会在obj 对象中添加一个新属性,其属性名为处理后的国家名,属性值为原始国家名。

      这种方式确保了在生成的对象中,每个键(处理后的国家名)都对应一个值(原始的国家名)。例如,如果 countries 数组包含 'Canada',则生成的对象会有一个属性,其键为 'canada',值为 'Canada'

    # 称为“属性访问器语法”

    在 Javascript 中, 使用 obj[key] = country; 这种使用方括号 ([]) 的语法是访问或设置对象属性的一种方式,称为“属性访问器语法”。在这个特定的上下文中,它用于动态地设置对象的属性。当您需要动态地将变量的值用作对象键(key)时,使用方括号 ([]) 语法是非常重要和实用的。这种语法使您可以根据变量的值来动态设置或访问对象的属性。

    使用方括号语法动态处理对象属性:

    1. 动态属性名

      • 使用 obj[key] 时,key 是一个变量,其值可以在每次迭代或函数调用中改变。方括号允许使用变量的值作为属性名。
      • 相比之下,点语法(如 obj.key)用于访问名为 "key" 的固定属性,而不是变量 key 的值。
    2. 设置对象属性

      • 表达式 obj[key] = country 表示在对象 obj 上设置一个属性,其属性名为变量 key 的值,属性值为 country
      • 在迭代过程中,根据每个 country 的值动态创建或更新 obj 的属性。
    3. 灵活性和实用性

      • 方括号语法在运行时动态确定属性名,特别适用于处理变量属性名或由表达式计算得到的属性名。
      • 这种方法提高了灵活性,允许根据不同情况和数据设置不同的属性名。
    4. 应用场景

      • 当处理需要根据运行时数据动态创建或访问对象属性的场景(如用户输入、结果计算或数组迭代)时,方括号语法是必需的。

    结论: +使用方括号 (obj[key]) 语法是 JavaScript 中一种强大的特性,允许您的代码根据不同情况动态地处理对象属性。它在如 reduce 方法这样的场景中特别有用,因为它允许根据数组中的每个元素动态构建对象的属性,确保代码的灵活性和一致性。

    # 🔻 Dan tutorial チュートリアル

    
    +const people = [{
    +  name: 'bob',
    +  age: 20,
    +  position: 'developer',
    +},
    +{
    +  name: 'peter',
    +  age: 25,
    +  position: 'designer',
    +},
    +{
    +  name: 'susy',
    +  age: 30,
    +  position: 'the boss',
    +},
    +];
    +
    +// without using map method
    +const name =[]
    +for( let person of People){
    +  names.push(person.name.toUpperCase())
    +}
    +console.log(names); // ["BOB", "PETER", "SUSY"]
    +
    +//with map method
    +const names = people.map(person=>{
    +  return person.name.toUpperCase()
    +})
    +
    +//with map method
    +const names= people.map(person=>person.name.toUpperCase())
    +
    +//with map method
    +const name, age = []
    +const newPeople = people.map((person)=>{
    +  firstName: person.name.toUpperCase(),
    +  oldAge: person.age + 20
    +})
    +
    + + + diff --git a/memo/config.html b/memo/config.html new file mode 100644 index 00000000..44db5e8a --- /dev/null +++ b/memo/config.html @@ -0,0 +1,111 @@ + + + + + + ⚪️ コンフィギュレーション | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ コンフィギュレーション

    # Install & Update nvm

    To install or update Node Version Manager (nvm), you can use the following commands:

    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
    +
    +export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
    +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
    +

    Don't forget to source your shell configuration file after the installation:

    source ~/.bashrc
    +

    For zsh users, you can modify your .zshrc file using the following steps:

    nano .zshrc
    +

    To automatically call nvm use if .nvmrc is present, you can add the following snippet to your .zshrc:

    export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
    +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    +
    +# Place this after nvm initialization!
    +autoload -U add-zsh-hook
    +
    +load-nvmrc() {
    +  local nvmrc_path
    +  nvmrc_path="$(nvm_find_nvmrc)"
    +
    +  if [ -n "$nvmrc_path" ]; then
    +    local nvmrc_node_version
    +    nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
    +
    +    if [ "$nvmrc_node_version" = "N/A" ]; then
    +      nvm install
    +    elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
    +      nvm use
    +    fi
    +  elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
    +    echo "Reverting to nvm default version"
    +    nvm use default
    +  fi
    +}
    +
    +add-zsh-hook chpwd load-nvmrc
    +load-nvmrc
    +

    This configuration will ensure that nvm use is called automatically based on the presence of a .nvmrc file in your project directory.

    + + + diff --git a/memo/docker.html b/memo/docker.html new file mode 100644 index 00000000..e66dc353 --- /dev/null +++ b/memo/docker.html @@ -0,0 +1,78 @@ + + + + + + ⚪️ dockers | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ dockers

    + + + diff --git a/memo/formikandyup.html b/memo/formikandyup.html new file mode 100644 index 00000000..33dc050f --- /dev/null +++ b/memo/formikandyup.html @@ -0,0 +1,78 @@ + + + + + + ⚪️ dockers | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ dockers

    + + + diff --git a/memo/git.html b/memo/git.html new file mode 100644 index 00000000..3a28c31f --- /dev/null +++ b/memo/git.html @@ -0,0 +1,93 @@ + + + + + + ⚪️ git and github への深い理解 | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ git and github への深い理解

    🔺 常用一些 Git 命令 (opens new window)

    # git branch

    
    +git checkout staging/name
    +git pull origin staging/name  # Ensure you have the latest changes
    +git checkout -b branch-name staging/name
    +

    # git rebase fix old commit

    gitrebase

    1. git rebase -i HEAD~ 2

    2. change the pick to edit r

    3. git commit --amend

    4. wq: write and quit
      +q!: quit without saving
      +i: insert mode
      +

    # Fix the most recent commit message

    git commit --amend
    +

    🔺 ### Reference:

    # git commit message

    # Scenario

    Imagine you're developing a new feature that allows users to send feedback via email. During development, you made the following three commits:

    1. Added a form to collect user feedback
    2. Implemented logic to process the form data
    3. Added functionality to send feedback via email

    # Development and Commits

    In Git, you might commit these changes like so:

    git commit -m "Add feedback form"
    +git commit -m "Implement feedback processing logic"
    +git commit -m "Add email sending functionality"
    +

    # Squashing Commits

    Before merging this feature into the main branch, you decide to squash these three commits into one. This can be done in a pull request or by using interactive rebase in your local branch:

    git rebase -i HEAD~3
    +

    This opens an editor listing the last 3 commits. You can change the pick command to squash (or just s for short) for the second and third commits, instructing Git to squash them into the first one.

    # Commit Message Following Conventional Commits

    After squashing, you're prompted to provide a new commit message that should follow the Conventional Commits specification. For our example, the commit message could be:

    feat(email): add user feedback email functionality
    +
    +- Add feedback form
    +- Implement feedback processing logic
    +- Add functionality to send feedback via email
    +

    This message clearly describes the nature of the commit (feat), the module affected (email), and the specific changes made. This format helps automated tools (like those generating CHANGELOGs) to understand the intent and scope of each commit.

    # Automating CHANGELOG with Conventional Commits

    Once you start following the Conventional Commits specification, you can use tools like standard-version to automate CHANGELOG generation. standard-version automatically bumps the version number based on your commit history and generates or updates the CHANGELOG file.

    To install standard-version:

    npm install --save-dev standard-version
    +

    Then, you can create a new release and CHANGELOG by running:

    npx standard-version
    +

    This command automatically determines the type of version bump (major, minor, or patch) based on your commit history (identifying feat, fix, etc.), updates the version number in package.json, and generates or updates the CHANGELOG based on your commits.

    # Summary

    Through this practical example, we explored how to keep commit history clean by using squash commits during development and how to enhance the readability and automation of commit messages by adhering to the Conventional Commits standard. These practices are highly beneficial for team collaboration, project maintenance, and automated version control.

    + + + diff --git a/memo/graphql.html b/memo/graphql.html new file mode 100644 index 00000000..9625795e --- /dev/null +++ b/memo/graphql.html @@ -0,0 +1,78 @@ + + + + + + ⚪️ graphql | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ graphql

    + + + diff --git a/memo/index.html b/memo/index.html new file mode 100644 index 00000000..61d86edf --- /dev/null +++ b/memo/index.html @@ -0,0 +1,74 @@ + + + + + + 🔺 MEMO メモ | ☻ itsyuimorii.space + + + + + + + + +
    + + + diff --git a/memo/jenkins.html b/memo/jenkins.html new file mode 100644 index 00000000..1ad70a53 --- /dev/null +++ b/memo/jenkins.html @@ -0,0 +1,78 @@ + + + + + + ⚪️ jinkens | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ jinkens

    + + + diff --git a/memo/jsreview.html b/memo/jsreview.html new file mode 100644 index 00000000..0cc94d43 --- /dev/null +++ b/memo/jsreview.html @@ -0,0 +1,562 @@ + + + + + + ⚪️ JavaScript 深い理解と実践 | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ JavaScript 深い理解と実践

    # 🔶 Reference vs Primitive

    In JavaScript, objects and arrays are examples of reference types, which are distinct from primitive types like stringsand Boolean, numbers, undefined, Null.

    heapandstack

    # ▫️ Reference Types in JavaScript:

    • Objects and Arrays:

      • Objects, like the person object, are reference types.
      • They can hold properties with primitive values or other reference types.
      • Nesting of objects or arrays inside a reference type doesn't change its reference type nature.
    • Hobbies Array:

      • The hobbies array, though holding strings (primitive values), is a reference type.
      • Arrays in JavaScript are always considered reference types.

    Difference in Memory Management:

    • Memory Types:

      • JavaScript uses two types of memory: The Stack and the Heap.
    • Stack Memory:

      • The stack is easy-to-access memory, managing items in a stack-like structure.
      • Suitable for items with known sizes in advance (numbers, strings, booleans).
    • Heap Memory:

      • The heap is used for items with dynamic · s and structures, like objects and arrays.
      • Objects and arrays go into the heap since they can be mutated and change at runtime.
    • Pointer Mechanism:

      • Each heap item has an exact address stored in a pointer.
      • The pointer, pointing at the item in the heap, is stored on the stack.

    # ▫️ Strange Behavior of "Reference Types"

    • What's actually stored in the person variable in the following snippet? +b. var person = { name: 'Max' }

    It's b. A pointer to the person object is stored in the variable. The same would be the case for the hobbies array.

    • What does the following code spit out then?
    var person = { name: "Max" };
    +var newPerson = person;
    +newPerson.name = "Anna";
    +console.log(person.name); // What does this line print? 'Anna'
    +
    • Why?

      • Because you never copied the person object itself to newPerson.
      • You only copied the pointer!
      • It still points at the same address in memory though. Hence changing newPerson.name also changes person.name because newPerson points at the exactly same object!

    # ▫️ How to Copy Objects and Arrays:

    Now that we know that we only copy the pointer - how can we actually copy the value behind the pointer? The actual object or array?

    You basically need to construct a new object or array and immediately fill it with the properties or elements of the old object or array.

    You got multiple ways of doing this - also depending on which kind of JavaScript version you're using (during development).

    Here are the two most popular approaches for arrays:

    1. Use the slice() is a standard array method provided by JavaScript. You can check out its full documentation here.

      var hobbies = ["Sports", "Cooking"];
      +var copiedHobbies = hobbies.slice();
      +

    It basically returns a new array which contains all elements of the old element, starting at the starting index you passed (and then up to the max number of elements you defined). If you just call slice(), without arguments, you get a new array with all elements of the old array.

    1. Use the spread operator +If you're using ES6+, you can use the spread operator.

      var hobbies = ["Sports", "Cooking"];
      +var copiedHobbies = [...hobbies];
      +

    Here, you also create a new array (manually, by using []) and you then use the spread operator (...)to "pull all elements of the old array out" and add them to the new array.

    For objects

    1. You can use the Object.assign() syntax which is explained in greater detail here.

      var person = { name: "Max" };
      +var copiedPerson = Object.assign({}, person);
      +

    This syntax creates a new object (the {} part) and assigns all properties of the old object (the second argument) to that newly created one. This creates a copy.

    1. Just as with arrays, you can also use the spread operator on objects.

      var person = { name: "Max" };
      +var copiedPerson = { ...person };
      +

    This will also create a new object (because you used { }) and will then pull all properties of person out of it, into the brand-new objects.

    # 🔶 Deconstruction Assignment

    ES6 Practical Deep Deconstruction Assignment Methods for Deconstructed Objects, Arrays, Hybrid Deconstruction, and Continuous Deconstruction

    # ▫️ Deconstructing Objects

    Without destructuring assignment, accessing the properties of an object or the elements of an array requires dot notation or bracket notation:

    1.1 basic deconstruction format

    let object = { name: "XXX", age: 22 };
    +let name = object.name;
    +let age = object.age;
    +console.log(name, age); // XXX 22
    +

    1.2 variable alias

    if you want to use a different variable name than the property name, you can use the following syntax:

    let object = { name: "XXX", age: 22 };
    +let { name: myName, age: myAge } = object;
    +console.log(myName, myAge); // XXX 22
    +

    1.3 default value

    if 目標對象屬性中沒有要解構的屬性,不指定默認值, 那麼將會是 undefined, 此時可以給要解構變量寫 default 值.

    let { name, age, gender = "female" } = { name: "XXX", age: 22 };
    +

    此種為變量設置默認值的方法,常用與函數參數中,加入調用函數時沒傳遞參數,有可能會對函數運行造成錯誤,那就可以形參位置進行對象解構, 對變量指定默認值。

    function fn({name:'xxx', age = 30 }={}){
    +  console.log(name, age);// xxx 30
    +}
    +

    # ▫️ Deconstructing Arrays

    解構數組和對象有些不同, 解構對象的時候屬性前後位置不影響, 但是解構數組,需要按照 index 順序解構

    2.1 basic deconstruction format +without destructuring assignment, accessing the properties of an object or the elements of an array requires dot notation or bracket notation:

    let array = ["XXX", 22];
    +let name = array[0];
    +let age = array[1];
    +console.log(name, age); // XXX 22
    +

    if with deconstructing assignment, you can use the following syntax:

    let array = ["XXX", 22];
    +let [name, age] = array;
    +console.log(name, age); // XXX 22
    +

    🔻 Scenario 01: To destructure the nested data object within the main data property of a response object to get to the inner data array.

    // Assuming the response object is named `response`
    +const {
    +  data: {
    +    data: [innerData],
    +  },
    +} = response;
    +
    +console.log(innerData); // This will log the inner object represented by the {...} in your screenshot
    +

    This snippet assumes that response is the name of the variable holding the entire object you've shown in your screenshot. The destructuring pattern { data: { data: [innerData] } } navigates through the object structure to the inner data array and grabs the first item from that array, assigning it to the innerData variable. If you want to access other properties at the same level, you can add them to the destructuring pattern accordingly.

    destrcturing

    async function banner() {
    +  // Simulating the structure from your screenshot
    +  const response = await db
    +    .collection("banner-list")
    +    .orderBy("sort", "desc")
    +    .limit(1)
    +    .get();
    +
    +  // Correct destructuring pattern based on the screenshot you provided
    +  let {
    +    data: {
    +      data: [result],
    +    },
    +  } = response;
    +
    +  console.log(result); // This will log the first object from the data array
    +}
    +

    In this updated code, response represents the object returned from the database query. The destructuring pattern { data: { data: [result] } } navigates through the first data object and then the data array to extract the first item of that array into the result variable.

    Please make sure that the db.collection(...).get() method indeed returns an object with a structure similar to the one in your screenshot, with nested data properties. If the structure is different, you'll need to adjust the destructuring pattern accordingly.

    # 🔶 Arrow function の理解

    1. 只有一個參數的函數 (Arrow Function with a Single Parameter):
    (參數) => 返回值;
    +// 例如:
    +(x) => x * 2;
    +
    1. 沒有參數或多個參數的函數 (Arrow Function with No or Multiple Parameters):

      // 沒有參數時使用空的小括號
      +() => 返回值
      +
      +// 多個參數時使用小括號括起來
      +(參數1, 參數2) => 返回值
      +// 例如:
      +(a, b) => a + b
      +
    2. 箭頭後面的值就是返回值 (Arrow Function Expression):

      • 返回值必須是一個表達式。什麼叫表達式?有返回值的語句就是表達式。
    3. 如果返回值是一個對象,需要用括號包起來 (Object as Return Value):

      () => ({ key: "value" });
      +
    4. 如果需要在 arrow function 裡定義邏輯, 可以直接在箭頭後跟一個代碼塊,代碼塊中的語法和普通函數沒有區別。

      (參數1, 參數2) => {
      +  // 邏輯
      +  return 返回值;
      +};
      +

    # 🔶 キーワード "this "の理解

    # アロー関数で書く理由 ① 関数を短く書きたい

    //アロー関数
    +const arrowAddFunc = (a, b) => {
    +  return a + b;
    +};
    +
    +//1個しか評価項目が無い場合は以下のようにも書ける
    +//中括弧とreturnの省略が出来る
    +const arrowAddFunc = (a, b) => a + b;
    +
    +//評価項目が1個だけ、かつ引数が1個しか無い場合はこのようにも書ける
    +//括弧も省略できる
    +const arrowDoubleFunc = (a) => 2 * a;
    +

    省略して、1行で書ける事も出来ますが、アロー関数を書き慣れていない人がパッと見た時に、やや分かりづらいかもしれません。必ずしも1行で書かなければいけない理由はありません。いずれにしろ、 function をいちいち書く必要がなく、短く書く事が出来ます。しかしアロー関数の真価は this を束縛しないという点にあるでしょう。

    # アロー関数で書く理由 ② this を束縛しない

    アロー関数で短く書けます!と説明されても、へーそうなんだ。。。で終わると思いますが、アロー関数を使う上でちゃんと理解しておきたいのは、こちらの方かと思います。

    それは、this の値は関数定義時に決まる(=this を束縛しない) というルールです。 +this を束縛しない、という説明はやや分かりづらいので、ここでは、アロー関数を使えば、this の値は関数定義時に決める事ができる、という理解で大丈夫でしょう。

    JavaScript で this を扱う時、最初は分かりづらい...直感的でない...という事は、JavaScript を書いてる方なら、分かって頂けるかなと思います。this の呼び出しパターンにはいくつかあるのですが、ここでは、アロー関数を使うメリットを説明する上で、メソッド呼び出しパターンと関数呼び出しパターンを事前に例として挙げておきます。this を理解する上で大切なのは、呼び出し元が何であるかという事です。まずはメソッド呼び出しパターンから説明します。

    # メソッド呼び出しパターン

    以下のコードを実際に打ち込んで、console.log で確認してみましょう。

    const object = {
    +  value: "test",
    +  method1: function () {
    +    return this; //①何が返されるでしょう?
    +  },
    +  method2: function () {
    +    return this.value; //②何が返されるでしょう?
    +  },
    +};
    +
    +//① thisはobject自身を参照している
    +console.log(object.method1()); //{ value: 'test', method: [Function: method] }
    +//② thisはobject自身を参照しているので、valueプロパティにもアクセスできる
    +console.log(object.method2()); // test
    +

    # 🔶 キーワード "class"の理解

    # Class の 基本概念

    A class is a template for an object that defines its properties and methods. In JavaScript, classes can be defined using the class keyword.

    class MyClass {
    +  // class of constructor functions that are called when the instance is created.
    +  constructor() {
    +    console.log(this); // In a constructor function, this points to the instance object.
    +  }
    +
    +  // 類的實例方法
    +  myMethod() {
    +    console.log(this); // In the method, this still points to the instance object.
    +  }
    +
    +  // 類的靜態方法
    +  static myStaticMethod() {
    +    console.log(this); // In static methods, this points to the class itself.
    +  }
    +}
    +
    +// Examples of Creation
    +const myInstance = new MyClass();
    +
    +// Calling Example Methods
    +myInstance.myMethod();
    +
    +// Calling the static method
    +MyClass.myStaticMethod();
    +

    # Strict mode && Class

    • All code in the class is executed in strict mode
    • In strict mode, when a function is called in the global context, this is no longer a global object (usually a window), but is undefined.
    "use strict";
    +
    +class MyClass {
    +  constructor() {
    +    console.log(this); // 在構造函數中,this 仍然指向實例對象
    +  }
    +
    +  myMethod() {
    +    console.log(this); // 在方法中,this 仍然指向實例對象
    +  }
    +
    +  static myStaticMethod() {
    +    console.log(this); // 在靜態方法中,this 是指向類本身
    +  }
    +}
    +
    +// 創建類的實例
    +const myInstance = new MyClass();
    +
    +// 調用實例方法
    +myInstance.myMethod();
    +
    +// 調用靜態方法
    +MyClass.myStaticMethod();
    +
    +// 在全局上下文中,調用函數(不是在類中)
    +function globalFunction() {
    +  console.log(this); // 在嚴格模式下,全局上下文中的 this 將是 undefined
    +}
    +
    +// 在嚴格模式下,全局上下文中的 this 將是 undefined
    +globalFunction();
    +

    # 箭頭函數在 Class 中的影響

    • 如果類中的方法是以箭頭函數定義的,則方法中的 this 將指向類的實例對象。
    class MyClass {
    +  myArrowMethod = () => {
    +    console.log(this); // 在箭頭函數中,this 指向類的實例對象
    +  };
    +}
    +
    +const myInstance = new MyClass();
    +myInstance.myArrowMethod(); // 調用箭頭函數方法
    +

    この形式の書き方は、アロー関数内の this が常にクラスのインスタンスオブジェクトを指すようにし、関数の呼び出し方法の影響を受けないように確保します。

    # クラスの継承

    • 継承を使用すると、クラス内のプロパティやメソッドを利用でき、さらに新しいプロパティやメソッドをサブクラスに追加できます。
    • extends を使用してクラスを継承し、継承後はまるでそのクラスのコードが現在のクラスにコピーされたかのようになります。
    • 親クラスのメソッドを上書きすることができますが、親クラスのメソッドは上書きされず、サブクラスに同じ名前のメソッドが追加されます。

    サブクラスで親クラスのコンストラクタを上書きする場合、サブクラスのコンストラクタ内で super() を呼び出さなければなりません。そうしないとエラーが発生します。

    # 🔶 Static Properties and Static Methods in Classes

    ...待補充

    # 🔷 Array 主なメソッド

    Standard built-in objects-Array (opens new window)

    # ▫️ Array.prototype.push()

    # ▫️Array.prototype.from()

    • 用途:從具有長度屬性的對象或可迭代對象創建數組。
    • 示例
    let filledArray = Array.from({ length: 10 }, () => ({ hello: "goodbye" }));
    +

    # ▫️Array.prototype.fill()

    • 用途:填充數組的每個元素為相同的值。
    • 示例
      let filledArray = new Array(10).fill("hello");
      +
    • 特點:適用於不可變值(如數字、字符串、布爾值)。
    • 問題:用於對象時,填充的是對同一對象的引用。
      let filledArray = new Array(10).fill({ hello: "goodbye" });
      +

    # 填充唯一對象

    • 方法:結合 fillmap
      let filledArray = new Array(10).fill(null).map(() => ({ hello: "goodbye" }));
      +
    • 特點:創建具有唯一對象引用的數組。
    • 注意map 方法可能對大數據集來說代價昂貴。

    # 使用 for 循環

    • 方法:傳統的 for 循環。
      let filledArray = new Array(10);
      +for (let i = 0; i < 10; i++) {
      +  filledArray[i] = { hello: "goodbye" };
      +}
      +
    • 特點:避免了使用 map 方法。

    # 使用展開語法 (...)

    • 方法:結合展開語法和 map
      let filledArray = [...new Array(10)].map(() => {'hello':'goodbye'});
      +
    • 特點:避免使用 fill,但仍使用 map

    # 🔸 Array.prototype.map()

    Array.prototype.map() + (opens new window)

    • map() メソッドは、新しい配列を作成し、元の配列の各要素をコールバック関数で処理した結果を含みます。
    • コールバック関数が必要で、その戻り値が新しい配列内の各要素になります。
    const array = [1, 4, 9, 16];
    +
    +// マップに関数を渡す
    +const result = array.map((item) => item * 2);
    +
    +// 回調函數中會出現三個參數:當前元素、當前索引和原始數組。
    +result = arr.map(function (currentValue, index, arr) {
    +
    +}[, thisArg]);
    +
    +console.log(result);
    +// 期待される出力: Array [2, 8, 18, 32]
    +

    使用シーン:ウェブページで配列を表示し、各配列要素にはラベルが必要な場合。

    const fruits = ["apple", "banana", "orange"];
    +
    +const result = fruits.map((fruit) => `<li>${fruit}</li>`);
    +

    🔻 使用シナリオ

    例子 1:使用 get 方法获取 Map 中的值

    const userPreferences = new Map();
    +
    +// 添加用户喜好设置
    +userPreferences.set("theme", "dark");
    +userPreferences.set("language", "en");
    +
    +// 获取特定键的值
    +const theme = userPreferences.get("theme");
    +console.log(theme); // 输出 'dark'
    +

    例子 2:使用 set 方法添加或更新 Map 中的键值对

    const userData = new Map();
    +
    +// 添加用户数据
    +userData.set("username", "user123");
    +userData.set("email", "user@example.com");
    +
    +// 更新用户数据
    +userData.set("email", "newuser@example.com");
    +

    例子 3:使用 has 方法检查 Map 中是否存在键

    const userPermissions = new Map();
    +
    +// 检查是否存在特定权限
    +userPermissions.set("admin", true);
    +userPermissions.set("editor", false);
    +
    +if (userPermissions.has("admin")) {
    +  console.log("用户是管理员");
    +} else {
    +  console.log("用户不是管理员");
    +}
    +

    例子 4:使用 delete 方法从 Map 中删除键值对

    const dataStore = new Map();
    +
    +// 添加数据
    +dataStore.set("key1", "value1");
    +dataStore.set("key2", "value2");
    +
    +// 删除数据
    +dataStore.delete("key1");
    +

    例子 5:使用 size 属性获取 Map 的大小

    const cartItems = new Map();
    +
    +// 添加购物车商品
    +cartItems.set("item1", { name: "Product A", price: 10 });
    +cartItems.set("item2", { name: "Product B", price: 15 });
    +
    +// 获取购物车商品数量
    +const itemCount = cartItems.size;
    +console.log(`购物车中有 ${itemCount} 件商品`);
    +

    例子 6:使用 forEach 方法迭代 Map 中的键值对

    const userRoles = new Map();
    +
    +// 添加用户角色
    +userRoles.set("user123", "user");
    +userRoles.set("admin456", "admin");
    +
    +// 遍历用户角色
    +userRoles.forEach((role, username) => {
    +  console.log(`${username} 的角色是 ${role}`);
    +});
    +

    例子 7:使用 keys 方法获取 Map 中的所有键

    const menuItems = new Map();
    +
    +// 添加菜单项
    +menuItems.set("home", "Home Page");
    +menuItems.set("about", "About Us");
    +menuItems.set("contact", "Contact Us");
    +
    +// 获取所有菜单项的键
    +const menuItemKeys = Array.from(menuItems.keys());
    +console.log(menuItemKeys); // 输出 ['home', 'about', 'contact']
    +

    # ▫️ Array.prototype.filter()

    • filter() メソッドは、指定された関数によって評価された元の配列の要素から構成される新しい配列を作成します。 +
      • 配列から条件に合致する要素を取得できます。
      • コールバック関数の結果に基づいて、要素の保持または削除が決まります。結果が true なら保持し、false なら削除します。
    const array = [1, 2, 3, 4];
    +
    +const result = array.filter((item) => item % 2 === 0);
    +
    +//代碼處理邏輯: number%2 === 0 ? true : false 如果返回true,就留,否則就不留
    +console.log(result);
    +// expected output: Array [2, 4]
    +

    # ▫️ Array.prototype.find()

    • find() メソッドは、与えられたテスト関数を満たす配列内の最初の要素の値を返します。そうでなければ、undefined を返します。
    const array = [5, 12, 8, 130, 44];
    +const found = array.find((element) => element > 10);
    +
    +console.log(found);
    +// expected output: 12
    +

    # ▫️ Array.prototype.reduce() (opens new window)

    • reduce() メソッドは、アキュムレータと配列の各要素(左から右へ)をコールバック関数に渡し、配列を単一の値にまとめます。

      • 配列の各要素に対して、コールバック関数を実行します。
      • コールバック関数の戻り値をアキュムレータに代入します。
      • reduce() メソッドは、関数をアキュムレータとして受け取り、配列の各値を(左から右へ)最終値まで縮小していきます。
      • 配列の要素が結合され、値が返されます。
    const array1 = [1, 2, 3, 4];
    +
    +// 0 + 1 + 2 + 3 + 4
    +const initialValue = 0;
    +const sumWithInitial = array1.reduce(
    +  (accumulator, currentValue) => accumulator + currentValue,
    +  initialValue
    +);
    +
    +console.log(sumWithInitial);
    +// Expected output: 10
    +

    🔺 応用シナリオ

    1. Calculating Total Amount in a Shopping Cart +Suppose you have a shopping cart application, where each item has a price and quantity, and you want to calculate the total amount.
    const cart = [
    +  { item: "Apple", price: 1.2, quantity: 2 },
    +  { item: "Banana", price: 0.5, quantity: 5 },
    +  { item: "Orange", price: 0.8, quantity: 3 },
    +];
    +

    # ▫️ Array.prototype.forEach()

    • forEach() メソッドは、与えられた関数を配列の各要素に対して一度ずつ実行します。
    const array = [1, 2, 3, 4];
    +
    +array.forEach((item) => {
    +  console.log(item);
    +  // expected output: 1
    +});
    +

    # 🔷 Object method

    # ▫️Object.defineProperties

    //使用 Object.defineProperties
    +//創建和配置對象屬性: Object.defineProperties 被用來在 obj 對象上定義兩個屬性 a 和 b。這些屬性被配置為有特定值(分別為 1 和 2),並且是可枚舉的(enumerable: true)。
    +
    +//屬性值和可枚舉性: 設置 value 來指定屬性的值,並通過 enumerable 標記屬性是否應該出現在對象的枚舉屬性中。
    +
    +const obj = {};
    +
    +Object.defineProperties(Obj, {
    +  a: {
    +    value: 1,
    +    enumerable: true,
    +  },
    +  b: {
    +    value: 2,
    +    enumerable: true,
    +  },
    +});
    +

    # ▫️ Object.entries()

    • 使用 Object.entries(obj) 將 obj 對象轉換為一個鍵值對的數組(二維數組)。每個子數組包含一個鍵和對應的值。
    • 返回值:给定对象自己的可枚举字符串键控属性键值对的数组。每个键值对都是一个包含两个元素的数组:第一个元素是属性键(始终是字符串),第二个元素是属性值。
    const object = {
    +  a: "someString",
    +  b: 42,
    +};
    +const testArr = Object.entries(object);
    +console.log(testArr);
    +
    +//遍歷鍵值對列表: 使用 for...of 循環遍歷 Object.entries(obj) 返回的鍵值對列表,並打印每個鍵和對應的值。 `new Map([["a", 1], ["b", 2]])` 創建了一個包含兩個鍵值對的 Map 對象。
    +for (let [k, v] of testArr) {
    +  console.log(k, v);
    +}
    +
    +//用map方法將鍵值對列表轉換成map類型的數據: 通過將鍵值對的數組傳遞給 Map 的構造函數來創建一個新的 Map 對象。
    +
    +const m = new Map([
    +  ["a", 1],
    +  ["b", 2],
    +]);
    +
    • 應用 1: Converting an Object to a Map: +
      • The Map() constructor accepts an iterable of entries. With Object.entries, you can easily convert from Object to Map:
    const obj = { foo: "bar", baz: 42 };
    +const map = new Map(Object.entries(obj));
    +console.log(map); // Map(2) {"foo" => "bar", "baz" => 42}
    +
    • 應用 2: Iterating through an Object
    // Using for...of loop
    +const obj = { a: 5, b: 7, c: 9 };
    +for (const [key, value] of Object.entries(obj)) {
    +  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
    +}
    +
    +// Using array methods
    +Object.entries(obj).forEach(([key, value]) => {
    +  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
    +});
    +

    # ▫️ Object.fromEntries()

    • Object.fromEntries() 是 Object.entries() 的逆操作,作用是将一个键值对数组转化为對象,返回的是新對象,不改变原对象
    • 只是 Object.entries() 只返回字符串键属性,而 Object.fromEntries() 还可以创建符号键属性。
    Object.fromEntries([
    +  ["a", "1"],
    +  ["b", 2],
    +]);
    +
    • 也可以传入一个 Map 将其转为对象
    const map = new Map().set("a", 1).set("b", 2);
    +
    +Object.fromEntries(map);
    +

    Object.fromEntries()實際應用:

    1. 過濾屬性
    function foo(obj, ...keys) {
    +  return Object.fromEntries(
    +    Object.entries(obj).filter(([key]) => keys.includes(key))
    +  );
    +}
    +
    +console.table(foo({ name: "oli", age: "12" }, "name"));
    +

    這個 foo 函數接受一個對象和一系列鍵作為參數,然後返回一個新的對象,其中只包含指定的鍵及其相應的值。具體來說:

    1. Object.entries(obj) 會將 obj 轉換為一個二維數組,每個內部數組包含一對鍵值(例如 [['name', 'oli'], ['age', '12']])。

    2. .filter(([key]) => keys.includes(key)) 會過濾這個數組,只保留那些鍵存在於 keys 參數中的鍵值對。

    3. Object.fromEntries() 將過濾後的二維數組轉回為對象。

    在您的例子中,調用 foo({ name: "oli", age: "12" }, "name") 會返回一個只包含 name 鍵和其對應值的新對象。因此,這個函數調用的輸出將是:

    { "name": "oli" }
    +

    console.table 會以表格的形式在控制台輸出這個對象,顯示 name 這一列及其對應的值 oli

    1. 将 url 查询字符串转为对象
    query = Object.fromEntries(new URLSearchParams("foo=bar&baz=qux"));
    +

    🔻 應用 1: 使用 Object.entriesObject.fromEntries 的代碼例子

    例子 1:将对象转换为 Map 并操作数据

    const obj = { a: 1, b: 2, c: 3 };
    +
    +// 使用Object.entries将对象转换为Map
    +const map = new Map(Object.entries(obj));
    +
    +// 在Map上进行数据操作
    +map.set("d", 4);
    +map.delete("b");
    +
    +// 使用Object.fromEntries将Map转换回对象
    +const newObj = Object.fromEntries(map);
    +
    +console.log(newObj); // 输出 { a: 1, c: 3, d: 4 }
    +

    例子 2:将路由参数对象转换为 Map 并重新映射键名

    const routeParamsObj = { userId: 123, actionType: "edit" };
    +
    +// 使用Object.entries将路由参数对象转换为Map
    +const routeParamsMap = new Map(Object.entries(routeParamsObj));
    +
    +// 重新映射键名
    +routeParamsMap.set("id", routeParamsMap.get("userId"));
    +routeParamsMap.delete("userId");
    +
    +// 使用Object.fromEntries将Map转换回路由参数对象
    +const newRouteParamsObj = Object.fromEntries(routeParamsMap);
    +
    +console.log(newRouteParamsObj); // 输出 { id: 123, actionType: 'edit' }
    +

    这些示例演示了如何使用 Object.entriesObject.fromEntries 来进行对象和 Map 之间的转换,并对数据进行操作和重映射。

    🔻 應用 2: 將對象轉換為 Map

    當將对象转换为 Map 时,有许多应用场景,以下是其中一些示例:

    1. API 响应数据解析: 当从 API 获取数据时,通常以 JSON 对象的形式返回。将 JSON 对象转换为 Map 可以更容易地提取和操作所需的数据字段。
    const apiResponse = { id: 1, name: "John", age: 30 };
    +const dataMap = new Map(Object.entries(apiResponse));
    +console.log(dataMap.get("name")); // 输出 'John'
    +
    1. 表单数据处理: 在 Web 应用程序中,用户提交的表单数据通常作为对象传输。将表单数据转换为 Map 可以更容易地验证、操作和处理这些数据。
    const formData = { username: "user123", email: "user@example.com" };
    +const formDataMap = new Map(Object.entries(formData));
    +console.log(formDataMap.get("email")); // 输出 'user@example.com'
    +
    1. 路由参数: 在一些 Web 框架中,路由参数可能作为对象传递给控制器或路由处理程序。将路由参数转换为 Map 可以更方便地访问它们。
    const routeParams = { id: 123, action: "edit" };
    +const routeParamsMap = new Map(Object.entries(routeParams));
    +console.log(routeParamsMap.get("id")); // 输出 123
    +
    1. 配置管理: 在应用程序中,通常需要存储和管理配置数据。将配置对象转换为 Map 可以提供更好的配置管理和访问。
    const config = { apiKey: "your-api-key", apiUrl: "https://api.example.com" };
    +const configMap = new Map(Object.entries(config));
    +console.log(configMap.get("apiUrl")); // 输出 'https://api.example.com'
    +
    1. 数据转换和处理: 在某些情况下,需要对数据进行转换或处理,例如将对象中的某些字段重新映射到新的键。将对象转换为 Map 可以帮助执行这些操作。
    const person = { first_name: "John", last_name: "Doe" };
    +const personMap = new Map(Object.entries(person));
    +personMap.set(
    +  "full_name",
    +  `${personMap.get("first_name")} ${personMap.get("last_name")}`
    +);
    +console.log(personMap.get("full_name")); // 输出 'John Doe'
    +

    # ▫️ Object.assign()

    # ▫️ Object.create()

    Reference: +Object.fromEntries (opens new window)

    # Data Structure

    # Object 和 Map 區別

    共同點: Object 和 Map 都允許你按鍵存取一個值、刪除鍵、檢查一個鍵是否存在、以及迭代其餘的鍵。

    1. 構造方法的不同
    • Object 的构造方法:Object可以使用对象字面量的方式创建,也可以使用new Object()Object.create(null)来创建。

      const obj = {
      +key1: "value1",
      +key2: "value2",
      +};
      +
      +//構造方法
      +const obj = new Object();
      +const ojb2= Object.create(null);
      +
    • Map 的构造方法:Map 需要使用new Map()的方式来创建,也可以通过传入一个包含键值对的数组来初始化。

      const map = new Map()
      +const map = new Map([
      +["key1", "value1"],
      +["key2", "value2"],
      +]);
      +
    1. value 的類型的不同
    • Object: 鍵類型必須是 String 或者 Symbol,如果是非 String 類型,會進行數據類型轉換,轉換成 String 類型,再進行操作。

      const obj = {
      +1: "value1",
      +true: "value2",
      +undefined: "value3",
      +null: "value4",
      +[Symbol()]: "value5",
      +};
      +
      +console.log(obj); // {1: "value1", true: "value2", undefined: "value3", null: "value4", Symbol(): "value5"}
      +

    mapobject

    • Map: 鍵類型可以是任意類型,包括原始類型和引用類型, 不會進行數據類型轉換。 在添加鍵值對時, 會通過 === 來判斷鍵是否相等。

      const map = new Map( );
      +map.set(1, "value1");
      +map.set('a',1)
      +map.set(true, "value2");
      +map.set(undefined, "value3");
      +map.set(null, "value4");
      +map.set(Symbol(), "value5");
      +
      +console.log(map); // Map(5) {1 => "value1", true => "value2", undefined => "value3", null => "value4", Symbol() => "value5"}
      +
    1. 鍵的順序
    • Object

      • key 是無序的, 不會按照添加的順序返回。 1.對於>=0 的整數, 會按照大小排序。對於小數和負數, 會當作字符串處理。
      • 對於字符串, 會按照定義的順序輸出
      • symbol 類型,會直接過濾掉,不會進行輸出。如果想輸出, 需要使用Object.getOwnPropertySymbols方法。
    • Maps

      • key 是有序的, 會按照添加的順序返回。
      • key 可以是任意類型, 包括原始類型和引用類型。
      • key 的比較是===, 即使是兩個看起來一樣的數字, 也會被認為是不同的鍵。
      • size 屬性可以獲取 Map 的大小。
    1. 鍵值對的訪問
    • Object

      • 添加或者修改屬性, 通過 點或者中括號的方式訪問。
      • 判斷屬性是否存在, 通過 in 或者 hasOwnProperty方法。
      • 刪除屬性, 通過 delete 操作符。
    • Map

      • 添加或者修改屬性, 通過set方法。
      • 判斷屬性是否存在, 通過has方法。
      • 刪除屬性, 通過delete方法。
      • get 方法可以獲取屬性值。
      • clear 方法可以清空所有屬性。
      • 通過keys方法可以獲取所有的 key。
      • 通過values方法可以獲取所有的 value。
      • 通過entries方法可以獲取所有的 key value。
    1. 迭代
    • Object

      • 不具備 Iterator 特性,無法使用 for...of 循環迭代。
    • Map

      • 具備 Iterator 特性,可以使用 for...of 循環迭代。
    const map = new Map([
    +  ["key1", "value1"],
    +  ["key2", "value2"],
    +]);
    +
    +for (const [key, value] of map) {
    +  console.log(`${key} ${`v`alue}`); // "key1 value1", "key2 value2"
    +}
    +
    1. JSON.stringify() 轉換
    • Map 類型的數據無法使用 JSON.stringify() 方法轉換為 JSON 字符串, 需要先轉換為對象。
    const obj = { a: 1, b: 2, c: 3 };
    +const map = new Map([
    +  ["key1", "value1"],
    +  ["key2", "value2"],
    +]);
    +
    +console.log(JSON.stringify(obj)); // {"a":1,"b":2,"c":3}
    +
    1. ObjectMap 的性能比較
    2. size-Object
    • Object 沒有 size 屬性, 需要通過 Object.keys(obj).length 來獲取對象的大小。
    • Map 有 size 屬性, 可以直接獲取 Map 的大小。

    🔺 Reference: +4 Ways to Populate an Array in JavaScript (opens new window)

    # Set 和 Map 區別

    以下是 Set 和 Map 之间的一些主要区别和用途:

    1. Set(集合):
      • 用于存储唯一值,不允许重复的元素。
      • 主要用途是存储一组唯一的元素,如集合、去重和检查元素是否存在。
      • 不需要键值对,只存储单个值。
      • 可以通过add方法添加元素,使用has方法检查元素是否存在,使用delete方法删除元素。
    const uniqueNumbers = new Set([1, 2, 3, 2, 4, 5]);
    +console.log(uniqueNumbers); // 输出 Set { 1, 2, 3, 4, 5 }
    +
    1. Map(映射):
      • 用于存储键值对,允许根据键来访问值。
      • 主要用途是创建键值对的映射,可以用于任何需要键值关联的场景。
      • 存储键值对,键可以是任何数据类型,值也可以是任何数据类型。
      • 可以通过set方法添加键值对,使用get方法根据键获取值,使用delete方法删除键值对。
    const userPreferences = new Map();
    +userPreferences.set("theme", "dark");
    +userPreferences.set("language", "en");
    +console.log(userPreferences.get("theme")); // 输出 'dark'
    +

    Set 是 JavaScript 中的一种数据结构,它具有许多优势,使其在各种应用场景中非常有用。以下是 Set 的一些主要优势:

    1. 唯一性: Set 中的值是唯一的,不会重复。这意味着你可以使用 Set 来存储一组唯一的元素,而不必担心重复值。
    const uniqueNumbers = new Set([1, 2, 3, 2, 4, 5]);
    +console.log(uniqueNumbers); // 输出 Set { 1, 2, 3, 4, 5 }
    +
    1. 查找和去重: 使用 Set 可以轻松查找特定元素是否存在于集合中,并且在添加元素时自动去重。
    const fruits = new Set();
    +fruits.add("apple").add("banana").add("apple");
    +
    +console.log(fruits.has("apple")); // 输出 true
    +console.log(fruits.size); // 输出 2,自动去重
    +
    1. 集合操作: Set 提供了各种集合操作方法,如交集、并集和差集,使你能够方便地进行数据操作。
    const set1 = new Set([1, 2, 3]);
    +const set2 = new Set([2, 3, 4]);
    +
    +// 交集
    +const intersection = new Set([...set1].filter((value) => set2.has(value)));
    +console.log(intersection); // 输出 Set { 2, 3 }
    +
    +// 并集
    +const union = new Set([...set1, ...set2]);
    +console.log(union); // 输出 Set { 1, 2, 3, 4 }
    +
    +// 差集
    +const difference = new Set([...set1].filter((value) => !set2.has(value)));
    +console.log(difference); // 输出 Set { 1 }
    +
    1. 队列操作: Set 的特性允许你实现一个简单的队列结构。可以使用 Set 来添加元素到队尾,并从队首删除元素。
    const queue = new Set();
    +
    +queue.add("item1");
    +queue.add("item2");
    +
    +const firstItem = queue.values().next().value; // 获取队首元素
    +queue.delete(firstItem); // 删除队首元素
    +queue.delete(queue.value.next().value); // 删除队首元素
    +

    总之,Set 在 JavaScript 中的使用非常灵活,适用于处理唯一值的情况以及各种集合操作。它可以在查找、去重、集合操作和队列等多种场景中提供便利的解决方案。

    + + + diff --git a/memo/reacthooks.html b/memo/reacthooks.html new file mode 100644 index 00000000..4ed9a716 --- /dev/null +++ b/memo/reacthooks.html @@ -0,0 +1,321 @@ + + + + + + ⚪️ ReactHooks を深く理解する | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ ReactHooks を深く理解する

    # 🔷 useEffect

    # ▫️ what is useEffect

    useEffect 是 React 中的一個 Hook,它主要用於處理副作用操作,例如異步數據的獲取、對已渲染的結果進行更新渲染等。

    • 第二個參數:依賴數組

      useEffect 的第二個參數,通常是一個依賴數組,決定了 useEffect 何時執行。這個參數的作用有以下幾種情況:

      1. 空數組 []:當依賴數組為空時,useEffect 只會在組件挂載時運行一次,就像 componentDidMount。這對於僅在組件挂載和卸載時執行一次的操作非常有用,例如初始化資料

      2. 非空數組 [依賴1, 依賴2, ...]:當依賴數組中的任何一個依賴發生變化時,useEffect 會運行。這對於需要根據特定狀態或 prop 執行操作的情況非常有用。如果你希望 useEffect 在每次渲染時都運行,則不傳入第二個參數即可。

      簡而言之,useEffect 的第二個參數決定了該 hook 何時執行,它提供了對 hook 執行的細粒度控制。

    • side effect(外部影響內部): 從外部獲取數據,對內部渲染的結果產生了作用

    # ▫️ Basic Purpose

    import React, { useState, useEffect } from "react";
    +
    +function MyComponent() {
    +  const [count, setCount] = useState(0);
    +
    +  useEffect(() => {
    +    console.log("---回调中---");
    +    console.log(document.querySelector("h1"));
    +    console.log("當前的值: ", count);
    +  }, []); // 这里的空数组表示只在组件挂载时运行一次
    +
    +  console.log("***组件中***");
    +
    +  return (
    +    <>
    +      <h1 onClick={() => setCount(count + 1)}>Hello World! {count}</h1>
    +    </>
    +  );
    +}
    +
    +const container = document.getElementById("root"); // 这里假设你的根 DOM 元素的 id 是 "root"
    +
    +export default MyComponent;
    +

    輸出結果

    • 如果组件首次挂载(加载),那么输出将如下所示:

      ***组件中***
      +---回调中---
      +null
      +當前的值: 0
      +
      • ***组件中***会在每次组件函数被调用时输出。
      • ---回调中---会在useEffect的回调函数内部输出,只有在组件挂载时才会执行一次。
      • null是因为在组件挂载时,<h1>元素还没有被渲染到 DOM 中,所以document.querySelector("h1")返回null
      • 當前的值: 0表示count的初始值为 0。
    • 如果用户点击<h1>元素以增加count的值,那么每次点击后的输出将如下所示,以点击两次为例:

      ***组件中***
      +---回调中---
      +<h1>Hello World! 1</h1>
      +當前的值: 1
      +***组件中***
      +---回调中---
      +<h1>Hello World! 2</h1>
      +當前的值: 2
      +
      • ***组件中***会在每次组件函数被调用时输出。
      • ---回调中---会在useEffect的回调函数内部输出,但它只在组件挂载时执行一次,所以之后点击<h1>元素不会再次触发该输出。
      • <h1>Hello World! 1</h1><h1>Hello World! 2</h1>是每次点击后,React 重新渲染组件后生成的<h1>元素。
      • 當前的值: 1當前的值: 2表示count的值在每次点击后更新。

    # ▫️ Second Argument - Dependency Array

    import React, { useState, useEffect } from "react";
    +
    +function App() {
    +  const [count, setCount] = useState(0);
    +  const [page, setPage] = useState(1);
    +
    +  useEffect(() => {
    +    console.log("---回调中---");
    +    console.log(document.querySelector("h1"));
    +    console.log("當前的值: ", count);
    +    console.log();
    +  }, [page]); // 这里的空数组表示只在组件挂载时运行一次
    +
    +  console.log("***组件中***");
    +
    +  return (
    +    <>
    +      <h1 onClick={() => setCount(count + 1)}>Hello World! {count}</h1>
    +      <button onClick={() => setPage(page + 1)}>Next Page </button>
    +    </>
    +  );
    +}
    +
    +export default App;
    +

    如果同时点击 "Hello World!" <h1> 元素和 "Next Page" 按钮,会同时触发countpage的更新,因此useEffect将在两者之间交替触发。以下是可能的打印结果示例:

    1. 初始渲染(挂载)后,点击 "Hello World!" <h1> 元素和 "Next Page" 按钮:

      ***组件中***
      +---回调中---
      +<h1>Hello World! 0</h1>
      +當前的值: 0
      +***组件中***
      +---回调中---
      +<h1>Hello World! 0</h1>
      +當前的值: 0
      +
      • 初始渲染时,count 的值为 0,page 的值为 1。
      • 同时点击 "Hello World!" <h1> 元素和 "Next Page" 按钮,countpage 的值会同时更新,但是由于useEffect的依赖数组包含了这两者,它会在其中任何一个发生变化时触发。所以 useEffect 打印了新的 count 值为 0 和新的 page 值为 2,以及其他信息。
    2. 点击 "Hello World!" <h1> 元素后再点击 "Next Page" 按钮:

      ***组件中***
      +---回调中---
      +<h1>Hello World! 0</h1>
      +當前的值: 0
      +***组件中***
      +---回调中---
      +<h1>Hello World! 0</h1>
      +當前的值: 0
      +***组件中***
      +---回调中---
      +<h1>Hello World! 0</h1>
      +當前的值: 0
      +***组件中***
      +---回调中---
      +<h1>Hello World! 1</h1>
      +當前的值: 1
      +
      • 首先点击 "Hello World!" <h1> 元素,count 的值递增到 1,但 page 仍然是 1,所以 useEffect 不会触发。
      • 然后点击 "Next Page" 按钮,page 的值从 1 增加到 2,同时 count 仍然是 1,这次 useEffect 会触发,并打印新的 page 值为 2,以及其他信息。

    总结:同时点击 "Hello World!" <h1> 元素和 "Next Page" 按钮会导致countpage的值同时更新,但是由于useEffect的依赖数组包含了这两者,它会在其中任何一个发生变化时触发,从而打印出相应的信息。***组件中*** 在每次组件函数被调用时都会输出,但它与这两个值无关。

    # ▫️ Return of Cleanup Function

    理解清除函数 (return 函数) 在 useEffect 中的作用非常重要,它用于处理副作用的清理和资源释放。以下是关于为什么需要清除函数以及一些常见用例的优化笔记:

    为什么需要清除函数?

    1. 因為 useEffect 會反覆執行

    2. 资源释放useEffect 可以用于处理需要清理的操作,比如关闭数据库连接、取消网络请求、清除定时器等。这是因为在组件卸载或下一次 useEffect 触发之前,React 会调用清除函数,以确保资源被正确释放,避免内存泄漏和不必要的资源占用。

    3. 防止副作用的重复执行:在某些情况下,组件的重新渲染可能会导致 useEffect 多次触发。通过清除函数,你可以在每次 useEffect 触发前清理之前的副作用,以确保只执行最新的操作,而不重复执行。

    🔻 シナリオ

    • 清除定时器
    useEffect(() => {
    +  const timerId = setInterval(() => {
    +    // 执行一些操作
    +  }, 1000);
    +
    +  // 清除定时器
    +  return () => clearInterval(timerId);
    +}, []);
    +

    上述代码示例创建了一个定时器,并且通过返回的清除函数来清除定时器。这样可以确保在组件卸载或下一次 useEffect 触发之前,定时器会被正确清除,防止内存泄漏和不必要的执行。

    • 断开数据库连接
    useEffect(() => {
    +  // 连接到数据库
    +
    +  // 清理数据库连接
    +  return () => {
    +    // 断开数据库连接
    +  };
    +}, []);
    +

    在这个示例中,useEffect 用于连接数据库,并通过返回的清除函数来断开数据库连接。这确保了在组件卸载或下一次 useEffect 触发之前,数据库连接会被正确关闭。

    • 取消网络请求
    useEffect(() => {
    +  const controller = new AbortController();
    +
    +  fetch("https://api.example.com/data", { signal: controller.signal })
    +    .then((response) => {
    +      // 处理响应数据
    +    })
    +    .catch((error) => {
    +      if (error.name === "AbortError") {
    +        // 请求被取消
    +      } else {
    +        // 处理其他错误
    +      }
    +    });
    +
    +  // 清除控制器以取消网络请求
    +  return () => controller.abort();
    +}, []);
    +

    在这个示例中,我们使用 AbortController 来控制网络请求,并通过返回的清除函数来取消网络请求。这样可以确保在组件卸载或下一次 useEffect 触发之前,网络请求会被正确取消。

    总之,清除函数在处理副作用的清理和资源释放时非常重要。它允许你在组件生命周期中管理资源,确保它们被正确释放,从而避免潜在的问题。

    # ▫️ Execution Timing

    在 useEffect 的回调函数中,当依赖数组中的某些依赖发生变化或者组件被卸载时,React 会执行回调函数中的返回值函数(清除函数)。这是确保在重新运行 useEffect 之前,清理之前副作用的机制。

    • 組件被銷毀時

    • 第二次執行回調時,會先執行上一次回調中的返回值函數

      useEffect(() => {
      +  console.log("---回调中---");
      +  return () => {
      +    console.log("~~~回調中返回值函數~~~", count);
      +  };
      +}, [page]);
      +console.log("***組件中***");
      +

      打印結果:

    1. 第一次打印:

      ***組件中***
      +---回调中---
      +
    2. 第二次打印:

      ***組件中***
      +~~~回調中返回值函數~~~ 0
      +---回调中---
      +

    從第二次打印中,可以看出,如果 page 的值发生了变化,那么 useEffect的回调函数将会再次执行。但在执行新的回调函数之前,React 会先执行上一次回调函数中的返回值函数(清除函数),然后再执行新的回调函数。这确保了在重新运行 useEffect 之前,可以清理之前的副作用。

    # ▫️ Usage Limitation - Cannot Use async Functions Directly

    因为 async 函数返回的是一个 Promise 对象。这是因为 useEffect 的回调函数应该是同步的,而不应该返回一个 Promise 对象。

    如果你需要在 useEffect 中执行异步操作,可以在回调函数内部创建一个 async 函数,然后在这个 async 函数内部执行异步操作。以下是一个示例:

    useEffect(() => {
    +  async function fetchData() {
    +    try {
    +      const response = await fetch("https://api.example.com/data");
    +      const data = await response.json();
    +      // 执行其他操作,例如更新 state
    +    } catch (error) {
    +      console.error("发生错误:", error);
    +    }
    +  }
    +
    +  fetchData();
    +}, []);
    +

    在这个示例中,我们在 useEffect 的回调函数内部创建了一个名为 fetchData 的 async 函数,然后在其中执行异步操作。这种方式可以让你在 useEffect 中处理异步逻辑,但依然保持了回调函数的同步性质。

    需要注意的是,虽然 async 函数内部可以使用 await 关键字等待异步操作完成,但整个回调函数仍然是同步执行的,不会等待异步操作的完成。因此,在使用 async 函数时,要确保正确处理异步操作的结果和错误。

    # 🔷 useRef

    # ▫️ what is useRef

    useRef 是 React 中的一个 Hook,它可以用于获取或存储组件的引用。它类似于 class 组件中的 ref 属性,但是它可以用于函数组件。 useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

    # ▫️ Basic Purpose

    import React, { useRef } from "react";
    +
    +function App() {
    +  const inputRef = useRef(null);
    +
    +  function handleClick() {
    +    inputRef.current.focus();
    +  }
    +
    +  return (
    +    <>
    +      <input ref={inputRef} type="text" />
    +      <button onClick={handleClick}>聚焦输入框</button>
    +    </>
    +  );
    +}
    +
    +export default App;
    +

    在这个示例中,我们使用 useRef 创建了一个名为 inputRef 的 ref 对象,并将其传递给 <input> 元素的 ref 属性。这样,我们就可以通过 inputRef.current 来获取 <input> 元素的引用。

    handleClick 函数中,我们使用 inputRef.current.focus() 来聚焦 <input> 元素。这样,当用户点击 "Focus the input" 按钮时,<input> 元素就会被聚焦。

    # ▫️ Usage Limitation - Cannot Use useRef to Update State

    useRef 不能用于更新组件的 state。这是因为 useRef 返回的 ref 对象在组件的整个生命周期内保持不变,而 useState 会在每次渲染时返回一个新的 state 值。

    如果你需要在 useRef 中更新 state,可以使用 useRef.current 属性来存储 state 的值。以下是一个示例:

    import React, { useState, useRef } from "react";
    +
    +function App() {
    +  const [count, setCount] = useState(0);
    +  const countRef = useRef(0);
    +
    +  function handleAlertClick() {
    +    setTimeout(() => {
    +      alert("You clicked on: " + countRef.current);
    +    }, 3000);
    +  }
    +
    +  return (
    +    <>
    +      <h1>{count}</h1>
    +      <button onClick={() => setCount(count + 1)}>Increment-useState</button>
    +      <button onClick={handleAlertClick}>Show alert-useRef</button>
    +    </>
    +  );
    +}
    +
    +export default App;
    +

    在這個示例中, 我們使用 useRef 創建了一個名為 countRef 的 ref 對象,並將其初始化為 0。然後,我們在 handleAlertClick 函數中使用 countRef.current 來獲取 count 的值。這樣,當用戶點擊 "Show alert" 按鈕時,我們就可以獲取 count 的值。

    當點擊 Increment 後, count 的值會增加,但是 countRef.current 的值仍然是 0。這是因為 useRef 返回的 ref 對象在組件的整個生命周期內保持不變,而 useState 會在每次渲染時返回一個新的 state 值。

    useState useRef
    修改值的時候 觸發重新渲染 觸發重新渲染
    組件重新渲染時 獲取之前的值 獲取之前值

    🔺 シナリオ:

    • 定時器案例:當我們不需要它渲染後的值,而是需要它渲染前的值時,就可以使用 useRef

    不使用 useRef 的情況, 以下: 每次點擊,都清除之前的定時器,看上去沒有問題。 但其實如果組件重新渲染,是不會清除之前定時器的, 本次的 timer 與上一次的 timer 不一樣

    function App() {
    +  let timer;
    +  const handleClick = () => {
    +    clearInterval(timer.current);
    +    timer = setInterval(() => {
    +      console.log("timer");
    +    }, 1000);
    +  };
    +  return <></>;
    +}
    +

    使用useRef 之後

    function App() {
    +  const timer = useRef(null);
    +  const handleClick = () => {
    +    clearInterval(timer.current);
    +    timer.current = setInterval(() => {
    +      console.log("timer");
    +    }, 1000);
    +  };
    +  return <></>;
    +}
    +

    在這個示例中, 我們使用 useRef 創建了一個名為 countRef 的 ref 對象,並將其初始化為 0。然後,我們在 handleAlertClick 函數中使用 countRef.current 來獲取 count 的值。這樣,當用戶點擊 "Show alert" 按鈕時,我們就可以獲取 count 的值。

    當點擊 Increment 後, count 的值會增加,但是 countRef.current 的值仍然是 0。這是因為 useRef 返回的 ref 對象在組件的整個生命周期內保持不變,而 useState 會在每次渲染時返回一個新的 state 值。

    • 修改dom的值
    1. 變量引用的方式 - 在<h1>元素上使用 ref 属性,将 h1Ref 引用对象与该 DOM 元素关联。这样,h1Ref.current 就可以访问到这个 DOM 元素。
    import React, { useRef } from "react";
    +
    +function App() {
    +  const h1Ref = useRef(null);
    +
    +  function handleClick() {
    +    h1Ref.current.innerHTML = "Hello World!";
    +  }
    +
    +  return (
    +    <>
    +      <h1 ref={h1Ref}>Hello React!</h1>
    +      <button onClick={handleClick}>Change the h1</button>
    +    </>
    +  );
    +}
    +
    • 在这个 React 函数组件中,要注意渲染和拿到值的顺序如下:

      1. 在组件渲染之初,会创建一个h1Ref引用对象,并初始化为null。在元素上使用 ref 属性,将h1Ref引用对象与该 DOM 元素关联。这样,h1Ref.current就可以访问到这个 DOM 元素。

      2. 渲染阶段:React 会首先渲染组件的 UI,包括 元素和按钮。此时,h1Ref仍然是null。当页面首次渲染时, 元素的内容显示为"Hello React!"。

      3. 用户点击按钮后,触发handleClick函数。

      4. handleClick函数内部,通过h1Ref.current来访问引用的 DOM 元素,尝试修改其innerHTML属性为"Hello World!"。

      5. 由于 React 的生命周期,上述 DOM 修改是在组件的渲染完成后才执行的。这是因为 React 会在渲染阶段记录下需要进行的 DOM 更新操作,并在渲染完成后才执行这些操作,以确保性能和一致性。

      所以,虽然在handleClick函数中访问了h1Ref.current,但实际的 DOM 操作是在渲染完成后才进行的。因此,当用户点击按钮时,页面上的 元素会被修改为"Hello World!"。这就是 React 的渲染和 DOM 更新机制的基本工作原理。

    1. 回調函數的方式
    import React, { useRef } from "react";
    +
    +function App() {
    +  const h1Ref = useRef(null);
    +
    +  function handleClick() {
    +    h1Ref.current.innerHTML = "Hello World!";
    +  }
    +
    +  return (
    +    <>
    +      <h1
    +        ref={(thisDom) => {
    +          if (thisDom) {
    +            thisDom.style.background = "green";
    +            h1Ref.current = thisDom; // Update the reference of h1Ref
    +          }
    +        }}
    +      >
    +        Hello React!
    +      </h1>
    +      <button onClick={handleClick}>Change the h1</button>
    +    </>
    +  );
    +}
    +
    • useRef的回调函数方式来引用 DOM 元素并修改其样式。

      1. <h1>元素上使用ref属性,传递一个回调函数。这个回调函数接收一个参数thisDom,它代表了<h1>元素的 DOM 对象。

      2. 在回调函数中,首先检查thisDom是否存在,以防止在某些情况下为null。如果thisDom存在,就在其中设置样式background为'green'。

      3. 然后,通过h1Ref.current = thisDom来更新h1Ref的引用,以确保h1Ref引用的始终是当前的 DOM 元素。

      现在,当组件渲染时,<h1>元素的背景颜色会被设置为绿色,并且你仍然可以使用h1Ref.current来访问它以进行其他操作。

    + + + diff --git a/memo/redux.html b/memo/redux.html new file mode 100644 index 00000000..34711730 --- /dev/null +++ b/memo/redux.html @@ -0,0 +1,293 @@ + + + + + + ⚪️ React Redux を基礎から理解する | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ React Redux を基礎から理解する

    # Redux の基本概念

    • Redux Overview:

      • Redux serves as an alternative to React Context, offering a centralized data store for the entire application.
      • The store manages all states, eg. critical data like authentication status and user input states.
      • It provides a unified state management approach by acting as a single store applicable to the entire application.

      redux

    • Subscription to Central Store:

      • Components subscribe to the central store for updates.
      • Subscribed components receive notifications when data changes occur in the Redux store.
      • Components selectively retrieve needed data, such as authentication status, from specific portions of the Redux store.
      • This establishes a unidirectional flow, enabling components to access and utilize data provided by the Redux store.
    • Important Rule:

      • Components refrain from direct data manipulation.
      • Subscriptions are established for components to receive updates, ensuring an indirect and controlled data flow.
      • Components avoid engaging in a direct data flow towards the storage.
    • Introducing Reducers:

      • Reducers handle data mutations and changes within the stored data.
      • The term "reducer" in Redux differs from the reducer hook in React.
      • A reducer function takes input, transforms it, and produces a new output, adhering to general programming concepts.
    • Understanding Reducer Functions:

      • Redux reducer functions accept input, transform it, and generate a new output.
      • They play a crucial role in updating stored data, following general programming principles.
    • Components and Actions:

      • Components do not directly manipulate stored data; they use subscriptions for updates.
      • Actions, triggered by components, describe the type of operation a reducer should execute.
      • Components dispatch actions as simple JavaScript objects, specifying the operation type.
      • Redux forwards actions to the appropriate reducer, which performs the specified operation.
      • The reducer outputs a new state, effectively replacing the existing state in the central data store.
      • Subscribed components receive notifications of state updates, facilitating UI refresh.
    • Three Principles of Redux:

      1. Single Data Source: The entire application's state is stored in a single store.
      2. State is Read-Only: State changes occur only through triggering actions, containing a required type attribute.
      3. Use Pure Functions for Actions: Reducers, implemented as pure functions, describe how actions change the state tree.

    redux

    • Store and Reducer Relationship:

      • The store manages data, and its content is determined by the reducer function.
      • The reducer function produces a new state snapshot whenever an action reaches it.
      • Upon the initial code execution, the reducer also executes with a default action, typically setting the initial state.
      • It is crucial for the reducer function to return a new state object consistently.
      • The reducer function is a standard JavaScript function, always receiving the old/existing state and the dispatched action.
    • Reducer Function Structure:

      • The reducer function is a JavaScript function, typically created using arrow function syntax.
      • It must always return a new state object, ensuring it adheres to the principles of a pure function.
      • Pure functions guarantee that the same inputs yield the same outputs and have no internal side effects.
    • Default State in Reducer:

      • During the first execution, when the store initializes, the state might be undefined.
      • Provide a default value for the state parameter in the reducer function to handle this initial case.
      • The default value ensures that the state is set to an initial value, preventing undefined errors.
    • Creating and Subscribing to Store:

      • Components subscribe to the store using a subscriber function.
      • The subscriber function is notified whenever data and the store change.
      • Use the subscribe method on the store, passing the subscriber function, to establish the subscription.
    • Dispatching Actions:

      • Dispatch actions using the dispatch method on the store.
      • Actions are JavaScript objects with a type attribute acting as an identifier.
      • The type attribute should be a unique string, representing the type of action to be performed.
    • Sample Action and State Update:

      • Example of dispatching an action to increment a counter.
      • The dispatched action contains a type attribute indicating an increment action.
      • The reducer function interprets the action type and produces a new state with an incremented counter.
      • Subscribed components are notified of the state update.
    • Understanding Output:

      • Executing the code demonstrates the incrementing counter as actions are dispatched.
      • The store initialization and dispatching actions lead to state updates reflected in the output.

    # Redux's Core API:

    1. Redux.createStore(reducer, [preloadedState], [enhancer])
    2. store.dispatch(action)
    3. store.subscribe(listener)
    4. store.getState()
    5. store.replaceReducer(nextReducer)

    # createStore

    createStore(reducer, [preloadedState], [enhancer])

    • Creates a Redux store that holds the complete state tree of the app.

    • There should only be a single store in the app.

    • createStore accepts three parameters:

      • reducer: A reducing function that returns the next state tree, given the current state tree and an action to handle.
      • [preloadedState]: The initial state.
      • [enhancer]: The store enhancer. You may optionally specify it to enhance the store with third-party capabilities such as middleware, time travel, persistence, etc. The only store enhancer that ships with Redux is applyMiddleware().

    store/index.js

    import { createStore } from "redux";
    +const counterReducer = (state = { counter: 0 }, action) => {
    +  if (action.type === "increment") {
    +    return {
    +      counter: state.counter + 1,
    +    };
    +  }
    +  if (action.type === "decrement") {
    +    return {
    +      counter: state.counter - 1,
    +    };
    +  }
    +  return state;
    +};
    +const store = createStore(counterReducer);
    +export default store;
    +

    index.js

    import React from "react";
    +import ReactDOM from "react-dom/client";
    +import { Provider } from "react-redux";
    +
    +import "./index.css";
    +import App from "./App";
    +import store from "./store/index";
    +
    +const root = ReactDOM.createRoot(document.getElementById("root"));
    +root.render(
    +  <Provider store={store}>
    +    <App />
    +  </Provider>
    +);
    +

    Counter.js

    import classes from "./Counter.module.css";
    +import { useSelector, useDispatch } from "react-redux";
    +
    +const Counter = () => {
    +  // Again, this function will be executed for us by React Redux. it will then pass the Redux state in order to manage the data into this function when it is executed, and then basically execute this code to retrieve the state portion of this component that is needed. then use select or overall to return the value. useSelector((state) => state.counter);
    +  const counter = useSelector((state) => state.counter);
    +  // Redux automatically sets up a subscription to the Redux store for this component. So whenever the data in the Redux store changes, your component will be updated and automatically receive the latest counter. So it's an automatic reaction that changes to the Redux store will cause this component function to be re-executed. So you'll always have the most up-to-date counter.
    +
    +  const dispatch = useDispatch();
    +  // dispatch is a function we can call, that will dispatch an action on our Redux store.
    +  const decrementHandler = () => {
    +    dispatch({ type: "decrement" });
    +  };
    +
    +  const toggleCounterHandler = () => {};
    +
    +  return (
    +    <main className={classes.counter}>
    +      <h1>Redux Counter</h1>
    +      <div className={classes.value}>{counter}</div>
    +      <div>
    +        <button onClick={incrementHandler}>Increment</button> 
    +        <button onClick={decrementHandler}>Decrement</button>
    +      </div>
    +      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    +    </main>
    +  );
    +};
    +
    +export default Counter;
    +

    # useSelector

    In React Redux, the useSelector hook requires two parameters:

    1. Selector Function:

      • This is a function that takes the entire Redux state as a parameter and returns the portion of the state you want to extract. For example, if you have a Redux state tree with an object named stock, and within the stock object, there's a property named counter, your selector function might be (state) => state.stock.counter. This function determines the data that useSelector will return.
    2. Equality Function (Optional):

      • This is an optional parameter used to compare the values returned by the selector function in consecutive calls to determine if the component should be re-rendered. If omitted, useSelector will use reference equality (===), meaning it will re-render only if the object references from the previous and current calls are the same. If you need to customize when the component should re-render based on some condition, you can provide a custom equality function.

    For example:

    const counter = useSelector(
    +  (state) => state.stock.counter,
    +  (prev, next) => prev === next
    +);
    +

    In this example, the first parameter is the selector function, extracting state.stock.counter. The second parameter is a custom equality function that uses reference equality to determine whether to re-render the component based on the returned values from the selector function.

    # dispatch

    const dispatch = useDispatch();
    +// dispatch is a function we can call, that will dispatch an action on our Redux store.
    +const decrementHandler = () => {
    +  dispatch({ type: "decrement" });
    +  //Attaching Payloads to Actions
    +};
    +

    # Redux Toolkit (opens new window)

    When our application grows in complexity, using Redux can become more intricate. In this course, we'll explore a simpler approach to utilizing Redux. Before we proceed, let's consider some potential issues:

    Potential Issues:

    1. Action Type Identifiers:

      • As the application grows, there may be numerous operations, leading to confusion with identifiers.
      • Issues such as misspelling or conflicts in identifiers might arise.
    2. Data Volume Management:

      • With an increase in data volume, the state object becomes larger.
      • The Reducer function becomes more complex and may be challenging to maintain.
    3. Respecting State Immutability:

      • Ensuring the consistent return of a new state snapshot and avoiding unintentional alterations to the existing state.
      • Complex nested object and array data can lead to unpredictable state changes.

    Solutions:

    1. Unique Identifier Issue:

      • Use constants to store identifiers, avoiding spelling errors and ensuring type consistency.
    2. Data Volume Management and Complex Reducer Issue:

      • Redux Toolkit provides solutions, such as splitting the Reducer into smaller ones.
    3. State Immutability Issue:

      • Manual implementation of solutions is possible, or Redux Toolkit tools can be used to automate state copying, ensuring unintentional state edits are avoided.

    # Redux Toolkit's Core APIs:

    • configureStore(): wraps createStore to provide simplified configuration options and good defaults. It can automatically combine your slice reducers, adds whatever Redux middleware you supply, includes redux-thunk by default, and enables use of the Redux DevTools Extension.

    • createReducer(): that lets you supply a lookup table of action types to case reducer functions, rather than writing switch statements. In addition, it automatically uses the immer library to let you write simpler immutable updates with normal mutative code, like state.todos[3].completed = true.

    • createAction(): generates an action creator function for the given action type string. The function itself has toString() defined, so that it can be used in place of the type constant.

    • createSlice(): accepts an object of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types.

    • createAsyncThunk: accepts an action type string and a function that returns a promise, and generates a thunk that dispatches pending/fulfilled/rejected action types based on that promise

    # State management with Redux

    1. Redux Store Setup:

      • Purpose: This section is responsible for setting up the global Redux store using the configureStore function from the @reduxjs/toolkit library. The store is configured with the combined reducers that handle different parts of the application state.
    2. Wrap the App with the Redux Provider:

      • Purpose: The Provider component from react-redux is wrapped around the main application component (in this case, App). This ensures that the Redux store is accessible to all components within the application. It essentially "provides" the Redux store to the entire component tree.
    3. Creating a Redux Slice:

      • Purpose: A Redux slice is a unit of the Redux state that corresponds to a specific feature or part of the application. In this example, the exampleSlice manages a list of items with corresponding actions like adding and removing items. It provides a clean and organized way to define the initial state and actions related to a specific feature.
    4. Using Redux in a Component:

      • Purpose: This section demonstrates how to use the useSelector hook to access the Redux store's state within a React component. In the example, SomeComponent uses useSelector to retrieve a list of items from the Redux store and render them.
    5. Dispatching Actions in Another Component:

      • Purpose: This section shows how to use the useDispatch hook to dispatch actions to the Redux store from a React component. In the example, AnotherComponent allows the user to input a new item, and when a button is clicked, the addItem action is dispatched to add the new item to the Redux store.

    # Process of using Redux Toolkit

    This setup provides a basic structure for handling state management with Redux in a JavaScript app. Action creators generate actions, reducers specify how the state should change, and the store manages the overall application state. The useSelector hook is used to access the state, and useDispatch is used to dispatch actions.

    🟦 Create the Redux Store:

    // store.js
    +import { configureStore } from "@reduxjs/toolkit";
    +import rootReducer from "./reducers"; // Import your combined reducers
    +
    +const store = configureStore({
    +  reducer: rootReducer,
    +});
    +
    +export default store;
    +

    🟦 Wrap the App with the Redux Provider:

    // index.js or App.js
    +import React from "react";
    +import { Provider } from "react-redux";
    +import store from "./store";
    +import App from "./App";
    +
    +const MainApp = () => {
    +  return (
    +    <Provider store={store}>
    +      <App />
    +    </Provider>
    +  );
    +};
    +
    +export default MainApp;
    +

    🟦 Creating a Redux Slice:

    // exampleSlice.js
    +import { createSlice } from "@reduxjs/toolkit";
    +
    +const initialState = {
    +  entities: {},
    +  ids: [],
    +};
    +
    +export const exampleSlice = createSlice({
    +  name: "example",
    +  initialState,
    +  reducers: {
    +    addItem: (state, action) => {
    +      const { id, data } = action.payload;
    +      state.entities[id] = data;
    +      state.ids.push(id);
    +    },
    +    removeItem: (state, action) => {
    +      const idToRemove = action.payload;
    +      delete state.entities[idToRemove];
    +      state.ids = state.ids.filter((id) => id !== idToRemove);
    +    },
    +  },
    +});
    +
    +export const { addItem, removeItem } = exampleSlice.actions;
    +export default exampleSlice.reducer;
    +

    🟦 Using Redux in a Component:

    // SomeComponent.js
    +import React from "react";
    +import { useSelector } from "react-redux";
    +
    +function SomeComponent() {
    +  const items = useSelector((state) =>
    +    state.example.ids.map((id) => state.example.entities[id])
    +  );
    +
    +  return (
    +    <div>
    +      {items.map((item) => (
    +        <div key={item.id}>{item.name}</div>
    +      ))}
    +    </div>
    +  );
    +}
    +
    +export default SomeComponent;
    +

    🟦 Dispatching Actions in Another Component:

    // AnotherComponent.js
    +import React, { useState } from "react";
    +import { useDispatch } from "react-redux";
    +import { addItem } from "./exampleSlice";
    +
    +function AnotherComponent() {
    +  const dispatch = useDispatch();
    +  const [newItem, setNewItem] = useState("");
    +
    +  const handleAddItem = () => {
    +    const id = Math.random().toString(36).substring(7); // Generate a unique ID
    +    const data = { id, name: newItem }; // Example data structure
    +    dispatch(addItem({ id, data }));
    +    setNewItem("");
    +  };
    +
    +  return (
    +    <div>
    +      <input
    +        type="text"
    +        value={newItem}
    +        onChange={(e) => setNewItem(e.target.value)}
    +      />
    +      <button onClick={handleAddItem}>Add Item</button>
    +    </div>
    +  );
    +}
    +
    +export default AnotherComponent;
    +

    🔵 useSelector(): Accessing State

    • Purpose: useSelector is a React hook provided by the react-redux library. Its primary purpose is to select and access the current state from the Redux store. It takes a selector function as an argument, which allows you to extract specific pieces of data from the state. By using useSelector, components can efficiently subscribe to changes in the Redux state and re-render when relevant data is updated.

    🔵 useDispatch(): Modifying State with Actions

    • Purpose: useDispatch is another React hook from the react-redux library. Its primary purpose is to provide a reference to the dispatch function of the Redux store. This allows components to dispatch actions, which are plain JavaScript objects containing a type property and, optionally, a payload. By using useDispatch, components can trigger state changes by dispatching actions. These actions are then processed by reducers, modifying the state in a predictable and controlled manner.

    🔵 Summary:

    • Redux Store Setup: Configured a global store using configureStore from @reduxjs/toolkit.
    • Provider Usage: Wrapped the main application component with Provider to make the Redux store accessible throughout the component tree.
    • Redux Slice Creation: Created a Redux slice using createSlice to manage a list of items in the state.
    • Component Interaction: Used useSelector to access state data and useDispatch to dispatch actions from React components.

    # Handling Asynchronous Code:

    Redux Core Principle:

    • Reducer functions in Redux must be pure, without side effects, and synchronous.
    • Pure functions produce the same output for the same input, ensuring consistency and predictability.

    Handling Asynchronous Code:

    • A challenge arises when dealing with asynchronous actions, like HTTP requests, in Redux.
    • Reducer functions are unsuitable for asynchronous code due to their synchronous nature.

    Options for Handling Asynchronous Code:

    1. Component-Level Side Effects:

      • Place side effect code, including asynchronous operations, directly in the component.
      • Dispatch actions after the side effect completion to inform Redux.
    2. Custom Action Creators:

      • Write custom action creators for handling asynchronous tasks without altering the reducer function.
      • Allows running asynchronous tasks as part of the action creator.

    Redux Toolkit Solution:

    • Redux Toolkit provides a solution for handling asynchronous tasks within action creators.
    • It allows the execution of side effects without violating the synchronous nature of reducer functions.

    reduxasync

    # Redux Thunk

    Redux Thunk:

    • Redux Thunk is a middleware that allows the execution of asynchronous tasks in Redux.
    • It enables the dispatch of asynchronous actions, such as HTTP requests, in Redux.
    export const sendCartData = (cart) => {
    +  //instead of return an action object, 如 { type: 'SOME_ACTION', payload: someData }。 我們創建一個一個action creator return another function
    +  return async (dispatch) => {
    +    dispatch(
    +      uiActions.showNotification({
    +        status: "pending",
    +        title: "Sending...",
    +        message: "Sending cart data!",
    +      })
    +    );
    +
    +    const sendRequest = async () => {
    +      const response = await fetch(
    +        "https://react-http-6b4a6.firebaseio.com/cart.json",
    +        {
    +          method: "PUT",
    +          body: JSON.stringify(cart),
    +        }
    +      );
    +
    +      if (!response.ok) {
    +        throw new Error("Sending cart data failed.");
    +      }
    +    };
    +
    +    try {
    +      await sendRequest();
    +
    +      dispatch(
    +        uiActions.showNotification({
    +          status: "success",
    +          title: "Success!",
    +          message: "Sent cart data successfully!",
    +        })
    +      );
    +    } catch (error) {
    +      dispatch(
    +        uiActions.showNotification({
    +          status: "error",
    +          title: "Error!",
    +          message: "Sending cart data failed!",
    +        })
    +      );
    +    }
    +  };
    +};
    +

    The provided code demonstrates the use of a Redux thunk as an action creator. In contrast to regular action creators, which directly return an action object (e.g., { type: 'SOME_ACTION', payload: someData }), this action creator returns a function.

    Here are some key differences in this approach:

    1. Returning a Function Instead of a Direct Action Object:

      • Regular action creators typically return a plain action object. In this case, the action creator returns a function.
    2. Incorporating Asynchronous Logic:

      • The returned function contains asynchronous logic. In this example, it involves sending shopping cart data to a server using async/await with the fetch function to make a PUT request.
    3. Dispatching Actions Before and After Asynchronous Logic:

      • Before the asynchronous logic starts, an action is dispatched to indicate that the data is pending ("pending" notification). After the asynchronous logic succeeds or fails, corresponding actions are dispatched to display notifications with success or error messages.
    4. Error Handling:

      • Errors are handled using a try-catch block. If an error occurs during the asynchronous logic, an action is dispatched to show an "error" notification along with the appropriate error message.
    5. More Flexible Control Flow:

      • Thunks provide a more flexible control flow, allowing you to dispatch different actions at different stages of asynchronous logic. For instance, dispatching a "pending" action at the start, a "success" action upon success, and an "error" action upon failure.

    In summary, this approach enables action creators to execute more complex logic, including asynchronous operations, conditional checks, and error handling. Thunks allow you to abstract away this logic from the components, allowing them to focus on user interface interactions without having to deal directly with complex asynchronous or side-effect logic.

    + + + diff --git a/memo/strapi.html b/memo/strapi.html new file mode 100644 index 00000000..249ad815 --- /dev/null +++ b/memo/strapi.html @@ -0,0 +1,144 @@ + + + + + + ⚪️ Strapi への深い理解 | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ Strapi への深い理解

    # project structure (opens new window)

    以下の構成は、strapi new で作成されるプロジェクトの構成です。

    . # root of the application
    +├──── .strapi # auto-generated folder — do not update manually
    +│     └──── client # files used by bundlers to render the application
    +│           ├ index.html
    +│           └ app.js
    +├──── .tmp
    +├──── build # build of the admin panel
    +├──── config # API configurations
    +│     ├ api.js
    +│     ├ admin.js
    +│     ├ cron-tasks.js
    +│     ├ database.js
    +│     ├ middlewares.js
    +│     ├ plugins.js
    +│     └ server.js
    +├──── database
    +│     └──── migrations
    +├──── node_modules # npm packages used by the project
    +├──── public # files accessible to the outside world
    +│     └──── uploads
    +├──── src
    +│     ├──── admin # admin customization files
    +│           ├──── extensions # files to extend the admin panel
    +│     │     ├ app.js
    +│     │     └ webpack.config.js
    +│     ├──── api # business logic of the project split into subfolders per API
    +│     │     └──── (api-name)
    +│     │           ├──── content-types
    +│     │           │     └──── (content-type-name)
    +│     │           │           └ lifecycles.js
    +│     │           │           └ schema.json
    +│     │           ├──── controllers
    +│     │           ├──── middlewares
    +│     │           ├──── policies
    +│     │           ├──── routes
    +│     │           ├──── services
    +│     │           └ index.js
    +│     ├──── components
    +│     │     └──── (category-name)
    +│     │           ├ (componentA).json
    +│     │           └ (componentB).json
    +│     ├──── extensions # files to extend installed plugins
    +│     │     └──── (plugin-to-be-extended)
    +│     │           ├──── content-types
    +│     │           │     └──── (content-type-name)
    +│     │           │           └ schema.json
    +│     │           └ strapi-server.js
    +│     ├──── middlewares
    +│     │     └──── (middleware-name).js
    +│     ├──── plugins # local plugins files
    +│     │     └──── (plugin-name)
    +│     │           ├──── admin
    +│     │           │     └──── src
    +│     │           │           └ index.js
    +│     │           ├──── server
    +│     │           │     ├──── content-types
    +│     │           │     ├──── controllers
    +│     │           │     └──── policies
    +│     │           ├ package.json
    +│     │           ├ strapi-admin.js
    +│     │           └ strapi-server.js
    +│     ├─── policies
    +│     └ index.js # include register(), bootstrap() and destroy() functions
    +├ .env
    +└ package.json
    +

    Understand the project structure of a Strapi project.

    1. Project Root: The top-level directory of the Strapi application, containing all the files and subdirectories needed for the application to run.

    2. .strapi Directory: This is an auto-generated folder. It's created and managed by Strapi itself. You shouldn't manually update files in this directory as they are managed by the Strapi framework. It typically includes client-side files used by bundlers to render the application.

      • index.html and app.js are examples of files in this directory, which are key to rendering the Strapi admin panel in a web browser.
    3. .tmp Directory: A temporary directory used by Strapi during runtime for storing temporary files.

    4. build Directory: This is where the built version of the admin panel resides. The "build" process involves compiling and bundling all the necessary files (like JavaScript, CSS, HTML) into a format suitable for deployment. This is done so that the admin panel can be served efficiently in a production environment.

      • The "build" process is usually done after development when you're ready to deploy your application. It optimizes the application for better performance in a production environment.

    # API (opens new window)

    # headless CMS とは?

    Headless CMS, like Strapi, represents a significant shift in how content management systems operate, particularly in the relationship between the front-end and the back-end. Let's break down what it means and how it's particularly beneficial for a React JavaScript environment:

    1. Traditional vs. Headless CMS:

      • Traditional CMS: Systems like WordPress tightly couple the front-end (what you see) and the back-end (where content is stored and managed). This means the way content is created, stored, and displayed is predefined and linked. Customizing the front-end or integrating with different technologies can be challenging.
      • Headless CMS: Strapi, as a headless CMS, decouples the front-end and the back-end. It provides only the back-end (headless) part, where content is stored and managed via an API. The front-end part (the "head") is entirely separate and can be built using any technology – like React in your case.
    2. API-Driven Approach:

      • In a headless CMS, content is delivered through APIs, typically RESTful or GraphQL. This approach offers greater flexibility in how content is retrieved and displayed. A front-end developer can query the API to fetch content and display it using React or any other front-end framework.
    3. Benefits for Front-End Developers:

      • Flexibility: You can use your preferred front-end technology (React, Angular, Vue.js, etc.) to build your user interface.
      • Customization: Since the front-end is separate, you have complete control over the user experience and can build custom UIs without the constraints of traditional CMS themes or templates.
      • Scalability: APIs make it easier to scale your application. You can develop new features or change the front-end without altering the back-end.
      • Omnichannel Content Delivery: Content can be used across different platforms – web, mobile apps, IoT devices, etc., without needing to adjust the back-end for each case.
    4. Why "Headless" for React Development:

      • React is a powerful library for building user interfaces. Pairing React with a headless CMS like Strapi allows you to create dynamic, interactive web applications with content that's easy to manage and update.
      • You can fetch data from the Strapi API using AJAX calls (with fetch, axios, or any other HTTP client) and then render this data using React components. This setup offers a modern, efficient way to build web applications.

    Strapi 的「無頭」性質意味著它提供後端功能(例如透過 API 進行內容儲存、管理和交付),而無需規定前端應如何建置或呈現。這種分離允許前端開發人員利用 React 等現代框架的強大功能來建立豐富的互動式使用者介面,同時仍受益於 CMS 強大的內容管理功能。

    # Content Type Builder (opens new window)

    The Content Type Builder in Strapi is a powerful feature that enables you to quickly generate API endpoints for managing data through CRUD (Create, Read, Update, Delete) operations. Here's a summary of its functionalities and an example to illustrate its use:

    # Understanding Content Type Builder:

    1. Purpose:

      • Enables the creation of Content Types (data structures) in Strapi.
      • Facilitates the definition and customization of fields for these Content Types.
    2. Functionality:

      • Data Structure Creation: You can define new Content Types (akin to tables in a database) directly within Strapi's admin panel. This includes specifying the fields and data types.
      • API Generation: Once a Content Type is created, Strapi automatically generates RESTful or GraphQL API endpoints for it. This means you can perform CRUD operations on the data associated with this Content Type.
      • Customization: The fields of a Content Type can be tailored to fit the data requirements of your application. You can choose from various field types like text, number, media, relational fields (to establish relationships between different Content Types), and more.
    3. User Interface:

      • The Content Type Builder offers a user-friendly interface within the Strapi admin panel for designing and modifying Content Types without writing any code.

    # Example Use Case:

    1. Creating a Blog Post Content Type:
      • Objective: To create a Content Type for managing blog posts.
      • Steps:
        1. Access the Content Type Builder in the Strapi admin panel.
        2. Create a new Content Type named BlogPost.
        3. Define fields such as title (text type), content (rich text type), publishedDate (date type), and author (relational field linking to a User Content Type).
        4. Save the Content Type. Strapi then generates API endpoints for BlogPost.
      • Outcome: You can now use the generated API endpoints to create, retrieve, update, or delete blog posts in your application.

    # Conclusion:

    The Content Type Builder in Strapi streamlines the process of creating data structures and corresponding APIs, making it an ideal tool for developers looking to build and manage content-driven applications efficiently. Its user-friendly interface and customization options allow for a great degree of flexibility in defining the data model according to the specific needs of your application.

    The Content Type Builder in Strapi is a powerful feature that enables you to quickly generate API endpoints for managing data through CRUD (Create, Read, Update, Delete) operations. Here's a summary of its functionalities and an example to illustrate its use:

    # Understanding Content Type Builder:

    1. Purpose:

      • Enables the creation of Content Types (data structures) in Strapi.
      • Facilitates the definition and customization of fields for these Content Types.
    2. Functionality:

      • Data Structure Creation: You can define new Content Types (akin to tables in a database) directly within Strapi's admin panel. This includes specifying the fields and data types.
      • API Generation: Once a Content Type is created, Strapi automatically generates RESTful or GraphQL API endpoints for it. This means you can perform CRUD operations on the data associated with this Content Type.
      • Customization: The fields of a Content Type can be tailored to fit the data requirements of your application. You can choose from various field types like text, number, media, relational fields (to establish relationships between different Content Types), and more.
    3. User Interface:

      • The Content Type Builder offers a user-friendly interface within the Strapi admin panel for designing and modifying Content Types without writing any code.

    # Example Use Case:

    contenttypebuilder

    1. Creating a Blog Post Content Type:
      • Objective: To create a Content Type for managing blog posts.
      • Steps:
        1. Access the Content Type Builder in the Strapi admin panel.
        2. Create a new Content Type named BlogPost.
        3. Define fields such as title (text type), content (rich text type), publishedDate (date type), and author (relational field linking to a User Content Type). +contenttypebuilder
        4. Save the Content Type. Strapi then generates API endpoints for BlogPost.
      • Outcome: You can now use the generated API endpoints to create, retrieve, update, or delete blog posts in your application.

    # Content Manager (opens new window)

    + + + diff --git a/memo/typescript.html b/memo/typescript.html new file mode 100644 index 00000000..1c576714 --- /dev/null +++ b/memo/typescript.html @@ -0,0 +1,78 @@ + + + + + + ⚪️ Typescript 深い理解と実践 | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ Typescript 深い理解と実践

    # 🔸 Chapter 1: Start Here

    # 🔸 Chapter 2: Basic Types

    # 🔸 Chapter 3: Arrays & Objects

    # 🔸 Chapter 4: Functions

    # 🔸 Chapter 5: Assertions

    # 🔸 Chapter 6: Classes

    # 🔸 Chapter 7: Index Signatures & keyof Assertions

    # 🔸 Chapter 8: Generics

    泛型-chocolate blog (opens new window) dave gray

    # 🔸 Chapter 9: Utility Types

    + + + diff --git a/memo/webpack.html b/memo/webpack.html new file mode 100644 index 00000000..a8cae8d6 --- /dev/null +++ b/memo/webpack.html @@ -0,0 +1,141 @@ + + + + + + ⚪️ Webpack 深い理解と実践 | ☻ itsyuimorii.space + + + + + + + + +

    # ⚪️ Webpack 深い理解と実践

    # 🔶 Webpack とは?

    • Webpack は複数の JavaScript ファイルを一つのファイルにまとめて出力するツールです。この「一つのファイルにまとめる」ことをバンドル(bundle)と言い、また「モジュールを一つのファイルにまとめて出力するツール」のことをモジュールバンドラー(module bundler)と呼びます。

    • 公式 Document で Webpack は、👇 のように静的モジュールバンドラーと紹介されています。

    • webpack is a static module bundler for modern JavaScript applications

    • 公式には 👇 のような図が記載されています。バンドルの雰囲気がわかりやすいですね。 +Concepts | webpack (opens new window)

    # 🔶 なぜ Webpack を使うのか?

    複数の JavaScript ファイルを一つにまとめることで、ブラウザからのリクエスト数を減らし、ファイル転送の最適化が可能です。これが Webpack などのモジュールバンドラーを使う大きな理由です。

    JavaScript ファイルが複数存在することでリクエスト回数が増えて転送効率が落ちるのであれは、最初から一つのファイルに記載することも可能ですが、可読性や保守性などの観点から現実的でありません。また、機能を複数ファイルに分割したままだと、ブラウザからのリクエスト回数が増えてファイル転送効率が落ちます。こういったつらみに対して、Webpack を利用することで機能をファイルごとに分割しながら開発し、実行時は一つのファイルとしてブラウザに提供することが可能となります。

    👇 の記事では、dev ツールで実際のファイルサイズを細かく見ながら、Webpack のメリットについて言及されていますので、参考までに。 +Why am'I using the webpack tool? (opens new window)

    # 🔶 Webpack の詳細?

    # ▫️ Loader for Different Resource Types

    Webpack uses loaders for different resource types, such as:

    • CSS: css-loader, style-loader
    • Less: less-loader
    • Sass: sass-loader
    • JavaScript: ts-loader, babel-loader
    • Vue: vue-loader
    • Static Resources: url-loader (images, audio, video), file-loader (files), json-loader (JSON)

    # ▫️ Basic Functions of Webpack (Using Loaders)

    1. Code Transformation: TypeScript to JavaScript, ES6 to ES5, SCSS to CSS, etc.
    2. Code Syntax Checking: Automatic code syntax checking using eslint-loader.
    3. Code Splitting: Splitting code into chunks for on-demand loading, reducing initialization time, and improving first-screen rendering efficiency.
    4. Automatic Compilation and Page Refresh: Automatically compile and refresh the page on local source code changes.
    5. Automatic Deployment (Not commonly used): Automatically build and deploy code to the production system.
    6. File Compression: Compress JavaScript, CSS, and HTML files to reduce file size.
    7. Module Concatenation: Merge modules into a single file during compilation.

    # ▫️ Two Key Features of Webpack

    1. Code Splitting: Breaks down code into chunks for on-demand loading, reducing initialization time.
    2. Loader: Handles various types of static files and supports chaining operations.

    # ▫️ Webpack Configuration

    Webpack runs in the Node.js environment, and its configuration file (webpack.config.js) follows the CommonJS pattern. It exports a JSON object with the following basic configuration options:

    • entry: Specifies the entry point of the modules.
    • output: Configures output file locations, names, and base paths.
    • module: Configures rules for different file types.
    • resolve: Configures aliases or module resolution rules.
    • plugins: Configures additional plugins to extend Webpack's functionality.
    • devServer: Implements local HTTP server features.

    # ▫️ Webpack Build Process

    1. Start from the entry point and recursively transform dependent modules.
    2. For each module found, use the corresponding loader to transform it.
    3. Continue transforming the dependencies of the current module until there are no more dependencies.
    4. Group modules by entry point, creating chunks.
    5. Convert all chunks into output files.

    # ▫️ Common Plugins

    • html-webpack-plugin: Generates HTML pages based on a template.
    • clean-webpack-plugin: Cleans specified directories.
    • copy-webpack-plugin: Copies files.
    • uglifyjs-webpack-plugin: Minifies JavaScript code.
    • mini-css-extract-plugin: Extracts CSS into separate files.

    # ▫️ Difference Between Loader and Plugin

    • Loader: Acts as a translator, transforming non-JavaScript resources during the build process.
    • Plugin: Extends Webpack's functionality by listening to events and altering the output.

    # ▫️ Webpack Hot Module Replacement (HMR) Principle

    HMR allows modules to be replaced without refreshing the entire page. The key steps include establishing a WebSocket connection, monitoring file changes, and notifying the client about the changes.

    # ▫️ Webpack Build Speed Optimization

    • Use the latest Webpack and Node.js versions.

    • Minify code using plugins like uglifyjs-webpack-plugin.

    • Utilize multiple threads or processes for building (e.g., thread-loader or HappyPack).

    • Narrow down the scope of file resolution.

    • Leverage caching for faster secondary builds.

    • Implement Tree Shaking to eliminate unused code.

    • Optimize module dependencies using Scope Hoisting.

    • Use CDN for basic packages to reduce bundle size.

    • Separate CSS from JavaScript using mini-css-extract-plugin.

    • Loadable Components (opens new window)

    # ▫️ webpack-bundle-analyzer

    webpack を可視化するツールを紹介 (opens new window)

    # Basic Steps for Configuring and Using webpack-bundle-analyzer:

    1. Install the webpack-bundle-analyzer plugin using the following command in your project directory:

      npm install --save-dev webpack-bundle-analyzer
      +
    2. In your webpack configuration file (e.g., webpack.config.js), import the webpack-bundle-analyzer plugin:

      const BundleAnalyzerPlugin =
      +  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
      +
    3. Add a new instance of BundleAnalyzerPlugin to the plugins property in your webpack configuration file:

      module.exports = {
      +  // ...
      +  plugins: [new BundleAnalyzerPlugin()],
      +  // ...
      +};
      +
    4. Save your webpack configuration file and run your webpack build command. After the build is complete, webpack-bundle-analyzer will open a page on a server where you can view detailed analysis results.

    # ▫️ Conditional Usage in Development Environment:

    const BundleAnalyzerPlugin =
    +  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
    +
    +let plugins = [];
    +
    +if (process.env.NODE_ENV === "development") {
    +  plugins.push(new BundleAnalyzerPlugin());
    +}
    +
    +module.exports = {
    +  //...
    +  plugins: plugins,
    +  //...
    +};
    +

    In this code, the BundleAnalyzerPlugin is added to the plugins array only when the NODE_ENV is set to 'development'. This helps in avoiding the generation of additional data in the production environment.

    # ▫️ Detailed Configuration Options for BundleAnalyzerPlugin:

    new BundleAnalyzerPlugin({
    +  // Accepts a string to specify the format and channel of the generated report. It can be 'server', 'static', or 'disabled'.
    +  // 'server' starts an HTTP server to provide an interactive report view, defaulting to localhost:8888.
    +  // 'static' generates a single HTML file to describe the report.
    +  // 'disabled' can be useful in some scenarios to temporarily disable the plugin while keeping the configuration code.
    +  analyzerMode: "server",
    +
    +  // In 'server' mode, defines the hostname for the HTTP server.
    +  analyzerHost: "127.0.0.1",
    +
    +  // In 'server' mode, defines the port number for the HTTP server.
    +  analyzerPort: 8888,
    +
    +  // In 'static' mode, defines the filename for the generated report.
    +  reportFilename: "report.html",
    +
    +  // Defines the method for calculating module sizes. Can be 'stat', 'parsed', or 'gzip'.
    +  // 'stat' describes the size before any code is parsed (size between modules).
    +  // 'parsed' describes the size of all parsed code (code that has been processed and parsed by loaders).
    +  // 'gzip' describes the gzip size of all parsed code (if this value is defined).
    +  defaultSizes: "parsed",
    +
    +  // Specifies whether a module should be shown. You can use this option to hide unnecessary modules.
    +  // You can pass a function that takes a module as a parameter and returns a boolean value.
    +  filterModules: false,
    +
    +  // If you want the content of the generated report file to be a custom data structure, you can pass a function.
    +  // This function receives stats data as a parameter and should return a serialized JSON object or a Promise.
    +  generateStatsFile: false,
    +
    +  // If you want to customize the filename of the generated stats file, you can modify this option.
    +  statsFilename: "stats.json",
    +
    +  // Defines whether to generate a report when generating stats files.
    +  statsOptions: null,
    +
    +  // Defines a logging function.
    +  logLevel: "info",
    +});
    +
    • analyzerMode: Specifies the format and channel for report generation ('server', 'static', or 'disabled').
    • analyzerHost and analyzerPort: Define the hostname and port for the HTTP server in 'server' mode.
    • reportFilename: Specifies the filename for the generated report in 'static' mode.
    • defaultSizes: Defines how module sizes should be calculated ('stat', 'parsed', or 'gzip').
    • filterModules: A function to determine whether a module should be displayed in the report.
    • generateStatsFile: Allows customization of the generated stats file content using a function.
    • statsFilename: Specifies the filename for the generated stats file.
    • statsOptions: Defines options for generating stats files.
    • logLevel: Defines the log level for the plugin.
    + + + diff --git a/practice/github.html b/practice/github.html new file mode 100644 index 00000000..67786220 --- /dev/null +++ b/practice/github.html @@ -0,0 +1,74 @@ + + + + + + ☻ itsyuimorii.space + + + + + + + + + + + + diff --git a/practice/index.html b/practice/index.html new file mode 100644 index 00000000..73b72a54 --- /dev/null +++ b/practice/index.html @@ -0,0 +1,74 @@ + + + + + + プラクティス | ☻ itsyuimorii.space + + + + + + + + + + + + diff --git a/practice/shoppingcart.html b/practice/shoppingcart.html new file mode 100644 index 00000000..546a9703 --- /dev/null +++ b/practice/shoppingcart.html @@ -0,0 +1,596 @@ + + + + + + React and TypeScript Shopping Cart Application | ☻ itsyuimorii.space + + + + + + + + +

    # React and TypeScript Shopping Cart Application

    # 🔷 CartProvider Component

    path: src/Context/CartProvider.tsx

    # 1. Type Definitions

    CartItemType

    Defines the structure of a single shopping cart item.

    export type CartItemType = {
    +  sku: string;
    +  name: string;
    +  price: number;
    +  qty: number;
    +};
    +

    CartStateType

    Defines the type for the shopping cart state.

    type CartStateType = { cart: CartItemType[] };
    +

    # 2. Action Types Definition

    REDUCER_ACTION_TYPE

    An object defining various action types for updating the state.

    const REDUCER_ACTION_TYPE = {
    +  ADD: "ADD",
    +  REMOVE: "REMOVE",
    +  QUANTITY: "QUANTITY",
    +  SUBMIT: "SUBMIT",
    +};
    +

    ReducerActionType

    Extracts the type of REDUCER_ACTION_TYPE object.

    export type ReducerActionType = typeof REDUCER_ACTION_TYPE;
    +

    ReducerAction

    Defines the structure of the action object expected by the reducer function.

    export type ReducerAction = {
    +  type: string;
    +  payload?: CartItemType;
    +};
    +

    # 3. Reducer Function

    reducer

    A core function that handles changes in the shopping cart state.

    const reducer = (state: CartStateType, action: ReducerAction) => {
    +  // ...switch case statements
    +};
    +

    # 4. Custom Hook: useCartContext

    useCartContext

    A custom React Hook providing a context related to the shopping cart.

    const useCartContext = (initialCartState: CartStateType) => {
    +  // ...hook implementation
    +};
    +

    # 5. React Context and Provider

    CartContext

    Creates a React Context to share the shopping cart state across components.

    export const CartContext = createContext<UseCartContextType>(
    +  initalCartContextState
    +);
    +

    CartProvider

    A React component using useCartContext Hook and CartContext.Provider to provide the shopping cart context to the application.

    export const CartProvider = ({ children }: ChildrenType): ReactElement => {
    +  // ...provider implementation
    +};
    +

    # Usage Instructions

    Use useContext(CartContext) in components that need to access or modify the shopping cart state. +Example: To add an item to the cart, use dispatch({ type: 'ADD', payload: newItem }).

    # 🔻 CartProvider Code review

    
    +//path: src/context/CartProvider.tsx
    +
    +import { ReactElement, createContext, useMemo, useReducer } from "react";
    +
    +//用於描述單個購物車項目的結構。
    +
    +export type CartItemType = {
    +sku: string;
    +name: string;
    +price: number;
    +qty: number;
    +};
    +//1. 定義購物車相關的 TypeScript 類型
    +//定義購物車狀態類型
    +//它是一個包含單個屬性 cart 的對象,而 cart 是一個 CartItemType[] 類型的數組。
    +type CartStateType = { cart: CartItemType[] };
    +
    +const initialCartState: CartStateType = { cart: [] };
    +
    +//2. 定義用於更新購物車狀態的 Action 類型
    +//2.1 這是一個對象,其中定義了用於更新狀態的各種 action 的類型。如 ADD,REMOVE,QUANTITY,SUBMIT。 這些是你將在應用中用來描述發生的事件的常量。
    +const REDUCER_ACTION_TYPE = {
    +ADD: "ADD",
    +REMOVE: "REMOVE",
    +QUANTITY: "QUANTITY",
    +SUBMIT: "SUBMIT",
    +};
    +
    + //2.2 通過 typeof 獲取 REDUCER_ACTION_TYPE 的對象的類型,並將這個類型導出為 ReducerActionType。 這樣做的好處是你獲得了一個精確的類型,代表 REDUCER_ACTION_TYPE 的結構,而不僅僅是一個簡單的對象。這在 TypeScript 中有助於提高類型安全性和自動完成。
    +
    +
    +
    +export type ReducerActionType = typeof REDUCER_ACTION_TYPE;
    +//2.3 定義了傳遞給 reducer 函數的 action 對象的結構。 包含 type(動作類型)和 payload(附加數據,可選)。
    +
    +//這是另一個 TypeScript 類型定義,用於描述 reducer 函數期望接收的 action 對象的結構。每個 action 都有一個 type 屬性,它是一個字符串,應對應於 REDUCER_ACTION_TYPE 中定義的一個值。payload 是一個可選屬性,包含了任何附加的數據(在這種情況下是 CartItemType)。
    +export type ReducerAction = {
    +type: string;
    +payload?: CartItemType;
    +};
    +
    +//3. Reducer 函數
    +//3.1 Reducer Function (reducer): 這是核心功能之一,用於處理購物車狀態的變化。它根據不同的動作(添加、移除、修改數量、提交)來更新狀態。這種方式能夠集中管理狀態的變更,是 Redux 架構中的一部分。
    +const reducer = (state: CartStateType, action: ReducerAction) => {
    +switch (action.type) {
    +case REDUCER_ACTION_TYPE.ADD: {
    +if (!action.payload) {
    +throw new Error("action.payload missing in ADD action");
    +}
    +const { sku, name, price } = action.payload;
    +//如果 sku 不等于给定的值,这个元素就会被保留在新数组 filteredCart 中,否则将被排除。
    +const filteredCart: CartItemType[] = state.cart.filter(
    +(item) => item.sku !== sku
    +);
    +
    +      const itemExisted: CartItemType | undefined = state.cart.find(
    +        (item) => item.sku === sku
    +      );
    +
    +      const qty: number = itemExisted ? itemExisted.qty + 1 : 1;
    +      return { ...state, cart: [...filteredCart, { sku, name, price, qty }] };
    +    }
    +
    +    case REDUCER_ACTION_TYPE.REMOVE: {
    +      if (!action.payload) {
    +        throw new Error("action.payload missing in REMOVE action");
    +      }
    +      const { sku } = action.payload;
    +
    +      const filteredCart: CartItemType[] = state.cart.filter(
    +        (item) => item.sku !== sku
    +      );
    +      return { ...state, cart: [...filteredCart] };
    +    }
    +    //然后,它创建一个名为 updatedItem 的对象,该对象是购物车中现有商品的副本,但具有更新的 qty。最后,它创建一个名为 filteredCart 的新数组,其中包含所有其他商品,但不包括要更新的商品。
    +    case REDUCER_ACTION_TYPE.QUANTITY: {
    +      if (!action.payload) {
    +        throw new Error("action.payload missing in QUANTITY action");
    +      }
    +      const { sku, qty } = action.payload;
    +
    +      const itemExists: CartItemType | undefined = state.cart.find(
    +        (item) => item.sku === sku
    +      );
    +
    +      if (!itemExists) {
    +        throw new Error("item must exist in order to update quantity");
    +      }
    +      // 创建一个更新后的商品对象
    +      const updatedItem: CartItemType = { ...itemExists, qty };
    +
    +      // 创建一个新的购物车数组,其中包括更新后的商品
    +      const filteredCart: CartItemType[] = state.cart.filter(
    +        (item) => item.sku !== sku
    +      );
    +      return { ...state, cart: [...filteredCart, updatedItem] };
    +      // map 方法 : 创建一个新的购物车数组,其中包括更新后的商品
    +      // const filteredCart: CartItemType[] = state.cart.map((item) =>
    +      // item.sku === sku ? updatedItem : item
    +      // );
    +      // 返回更新后的购物车状态
    +      // return { ...state, cart: filteredCart };
    +    }
    +
    +    case REDUCER_ACTION_TYPE.SUBMIT: {
    +      return { ...state, cart: [] };
    +    }
    +    default:
    +      throw new Error("Unidentified reducer action type");
    +
    +}
    +};
    +// 4. 自定義 Hook:useCartContext
    +
    +/\*\*
    +*使用 useReducer 來管理購物車狀態。
    +*用 useMemo 來緩存計算結果(REDUCER_ACTIONS)。
    +*計算購物車的總數量和總價格。
    +*對購物車中的商品進行排序。\*/
    +
    +//useCartContext 是一个自定义的 React Hook,它的作用是为你的应用程序提供一个与购物车相关的上下文。这个上下文包含了购物车的状态以及与购物车操作相关的函数,例如添加商品、删除商品、更新商品数量等。
    +
    +//自定義 Hook 如 useCartContext 被用來封裝和共享邏輯,相同的邏輯可以在應用中的多個地方使用,而不必重複相同的代碼。 useCartContext 接受一个参数 initialCartState,它是购物车的初始状态,包含一个空的购物车数组。
    +const useCartContext = (initialCartState: CartStateType) => {
    +const [state, dispatch] = useReducer(reducer, initialCartState);
    +
    +//useMemo 主要用于缓存计算结果,并在依赖项(dependencies)发生变化时重新计算。
    +const REDUCER_ACTIONS = useMemo(() => {
    +return REDUCER_ACTION_TYPE;
    +}, []);
    +
    +const totalItems = state.cart.reduce((previousValue, cartItem) => {
    +return previousValue + cartItem.qty;
    +}, 0);
    +
    +const totalPrice = new Intl.NumberFormat("en-US", {
    +style: "currency",
    +currency: "USD",
    +}).format(
    +state.cart.reduce((previousValue, cartItem) => {
    +return previousValue + cartItem.qty \* cartItem.price;
    +}, 0)
    +);
    +
    +// 这段代码的作用是对购物车中的商品进行排序,排序的规则是按照商品的 sku 属性的后四位数字进行升序排序。
    +const cart = state.cart.sort((a, b) => {
    +//分别提取了商品 a 和 b 的 sku 属性的后四位数字部分。这些数字会被转换成数值类型。
    +const itemA = Number(a.sku.slice(-4));
    +const itemB = Number(b.sku.slice(-4));
    +//表示根据提取出的数字进行升序排序,即如果 itemA 小于 itemB,返回负数;如果 itemA 等于 itemB,返回零;如果 itemA 大于 itemB,返回正数。
    +return itemA - itemB;
    +});
    +
    +return { dispatch, REDUCER_ACTIONS, totalPrice, totalItems, cart };
    +};
    +//这里使用了 TypeScript 的 ReturnType 工具类型,它用于获取一个函数返回值的类型 。typeof useCartContext 表示获取 useCartContext 函数的类型,ReturnType<typeof useCartContext> 则是这个函数返回值的类型。这个类型被用作下面 CartContext 的类型参数。
    +
    +//返回值是什么 : useCartContext Hook 的返回值是一个对象,包含了与购物车相关的数据和函数。这通常包括购物车的状态(如商品列表、总价等)以及用于更新这些状态的方法(如 dispatch 方法)。
    +export type UseCartContextType = ReturnType<typeof useCartContext>;
    +
    +//Context and Provider (CartContext 和 CartProvider): 這個部分創建了一個 React Context 來跨組件共享購物車的狀態和操作。CartProvider 組件則將這個上下文應用於應用程序的根組件。
    +
    +//这里定义了初始的上下文状态。initalCartContextState 符合 UseCartContextType 类型,包含了 dispatch 函数、REDUCER_ACTIONS 常量、以及一些购物车相关的状态如 totalItems、totalPrice 和 cart。dispatch 函数是一个空函数,表示在默认情况下不执行任何操作。
    +const initalCartContextState: UseCartContextType = {
    +dispatch: () => {},
    +REDUCER_ACTIONS: REDUCER_ACTION_TYPE,
    +totalItems: 0,
    +totalPrice: "",
    +cart: [],
    +};
    +
    +//5. React Context 和 Provider
    +
    +// 創建一個 React Context,允許跨組件共享購物車狀態。 用於在應用程序中提供購物車的狀態和操作。其他組件可以使用這個 Context 來訪問購物車的狀態。
    +//const SomeContext = createContext(defaultValue)
    +export const CartContext = createContext<UseCartContextType>(
    +initalCartContextState
    +);
    +
    +type ChildrenType = {
    +children?: ReactElement | ReactElement[];
    +};
    +
    +//使用 CartContext.Provider 來將 useCartContext 的返回值作為上下文值提供給其子組件。 CartProvider 組件:這是一個 React 組件,它使用 useCartContext Hook 並通過 CartContext.Provider 提供購物車上下文給應用程序。它包裝了應用程序的根組件,使購物車上下文對整個應用程序可用。
    +export const CartProvider = ({ children }: ChildrenType): ReactElement => {
    +return (
    +<CartContext.Provider value={useCartContext(initialCartState)}>
    +{children}
    +</CartContext.Provider>
    +);
    +};
    +
    +//使用 Custom Hook 和 Context:
    +
    +//在需要訪問或修改購物車狀態的組件中,使用 useContext(CartContext) 來獲取購物車的狀態和 dispatch 函數。例如,如果需要向購物車中添加一個商品,可以使用 dispatch({ type: 'ADD', payload: newItem })。
    +
    +export default CartContext;
    +
    +/_ 使用說明
    +在需要訪問或修改購物車狀態的組件中,使用 useContext(CartContext) 來獲取購物車的狀態和 dispatch 函數。
    +例如,添加商品到購物車可以使用 dispatch({ type: 'ADD', payload: newItem })。 _/
    +
    +

    # 🔷 ProductsProvider Component

    path: src/Context/ProductsProvider.tsx

    # 1. Type Definitions

    ProductType

    Defines the structure of a product.

    export type ProductType = {
    +  sku: string;
    +  name: string;
    +  price: number;
    +};
    +

    # 2. Initial State

    initialState

    An array that holds the initial state of the product list.

    const initialState: ProductType[] = [];
    +

    # 3. Context Type Definition

    UseProductsContextType

    Defines the shape of the context used for managing product information.

    export type UseProductsContextType = {
    +  products: ProductType[];
    +};
    +

    # 4. React Context and Provider

    ProductsContext

    Creates a React Context for sharing and managing product information globally.

    export const ProductsContext =
    +  createContext<UseProductsContextType>(initialContextState);
    +

    ProductsProvider

    A React component that provides the product context to the application using the ProductsContext.Provider.

    export const ProductsProvider = ({ children }: ChildrenType): ReactElement => {
    +  // ...provider implementation
    +};
    +

    # 5. Fetching and Updating Product Data

    useEffect Hook

    Fetches product data from an external source and updates the state.

    useEffect(() => {
    +  // Function to fetch products and error handling
    +}, []);
    +

    # Usage Instructions

    Use useContext(ProductsContext) in components that need to access or modify the product information. +Example: To access the list of products, use const { products } = useContext(ProductsContext).

    This Markdown note provides a structured overview of your React and TypeScript product management application, outlining type definitions, initial state, context and provider, along with instructions for fetching and updating product data.

    # 🔻 ProductsProvider Code review

    
    +////这里定义了一个名为 ProductType 的 TypeScript
    +类型,该类型描述了产品的结构,包括sku(库存单位)、name(名称)和price(价格)等属性。
    +...
    +
    +
    +import { ReactElement, createContext, useState, useEffect } from "react";
    +
    +export type ProductType = {
    +  sku: string;
    +  name: string;
    +  price: number;
    +};
    +//const initState: ProductType[] = []
    +
    +
    +
    +const initialState: ProductType[] = [];
    +
    + //这里定义了一个名为 initState的常量,它是一个数组,包含了一些产品对象。这个数组通常用于初始化应用程序的状态,可以在React的上下文中使用。
    +
    +// export const initialState: ProductType[] = [
    +//   {
    +//     sku: "item0001",
    +//     name: "Widget",
    +//     price: 9.99,
    +//   },
    +//   {
    +//     sku: "item0002",
    +//     name: "Premium Widget",
    +//     price: 19.99,
    +//   },
    +//   {
    +//     sku: "item0003",
    +//     name: "Deluxe Widget",
    +//     price: 29.99,
    +//   },
    +// ];
    +
    +//它描述了一个用于管理产品信息的上下文的形状。具体来说,它包含一个属性(object) products,其值是一个 ProductType 类型的数组,用于存储产品信息。
    +export type UseProductsContextType = {
    +  products: ProductType[];
    +};
    +
    +const initialContextState: UseProductsContextType = {
    +  products: [],
    +};
    +
    +  //最后,它创建了一个名为 ProductsContext 的上下文对象,使用了之前定义的 UseProductsContextType 类型作为泛型参数,并将初始状態initialContextState传递给createContext函数。这个上下文对象可以在应用程序中使用,用于共享和管理产品信息的全局状态。
    +
    +type ChildrenType = { children?: ReactElement | ReactElement[] };
    +
    +export const ProductsContext =
    +  createContext<UseProductsContextType>(initialContextState);
    +
    +export const ProductsProvider = ({ children }: ChildrenType): ReactElement => {
    +  const [products, setProducts] = useState<ProductType[]>(initialState);
    +
    +  useEffect(() => {
    +    const fetchProducts = async (): Promise<ProductType[]> => {
    +      try {
    +        const res = await fetch("http://localhost:3500/products");
    +        if (!res.ok) {
    +          throw new Error("Network response was not ok");
    +        }
    +        const data: ProductType[] = await res.json();
    +        return data; // 返回产品数据
    +      } catch (error) {
    +        console.error((error as Error).message); // 使用类型断言将 error 标记为 Error 类型
    +        throw error; // 抛出错误,使外部可以捕获
    +      }
    +    };
    +
    +    fetchProducts()
    +      .then((products) => setProducts(products))
    +      // eslint-disable-next-line @typescript-eslint/no-unused-vars
    +      .catch((error) => {
    +        // 在此处可以进一步处理错误,例如显示错误消息
    +      });
    +  }, []);
    +
    +  return (
    +    <ProductsContext.Provider value={{ products }}>
    +      {children}
    +    </ProductsContext.Provider>
    +  );
    +};
    +
    +export default ProductsContext;
    +

    ProductType[]是一个表示产品数组的类型定义。而 UseProductContextType是另一个类型定义,它定义了一个对象,这个对象包含了一个名为products的字段,其类型为 ProductType[]

    # 🔷 Hooks/useProducts Hook

    import { useContext } from "react";
    +import ProductsContext from "../context/ProductsProvider";
    +import { UseProductsContextType } from "../context/ProductsProvider";
    +
    +const useProducts = (): UseProductsContextType => {
    +  return useContext(ProductsContext);
    +};
    +
    +export default useProducts;
    +

    # 🔷 Hooks/useCart Hook

    它的作用是简化了在组件中使用购物车上下文(CartContext)的过程。这个 Hook 返回了 CartContext 的值,使得在组件中访问购物车数据和操作更加直观和便捷。这种模式非常适用于将上下文的逻辑封装起来,以便在多个组件中重用。

    import { useContext } from "react";
    +import CartContext from "../context/CartProvider";
    +import { UseCartContextType } from "../context/CartProvider";
    +//通过指定返回类型为 UseCartContextType,这个 Hook 的使用者可以得到关于返回值的类型提示和校验。
    +const useCart = (): UseCartContextType => {
    +  return useContext(CartContext);
    +};
    +
    +export default useCart;
    +

    # 🔷 components/ProductList

    import { ReactElement } from "react";
    +import useCart from "../hooks/useCart";
    +import useProdudcts from "../hooks/useProducts";
    +import Product from "./Product";
    +
    +const ProductList = () => {
    +  const { dispatch, REDUCER_ACTIONS, cart } = useCart();
    +  const { products } = useProdudcts();
    +
    +  //使用 some 方法檢查:具體地,inCart 的值是通過檢查購物車(cart)中是否存在具有相同 sku 值的產品來確定的。這通過使用 Array.prototype.some 方法實現,這個方法會測試陣列中是否至少有一個元素滿足提供的函數。如果滿足條件(即購物車中已有相同 sku 的產品),則 inCart 為 true;否則,為 false。
    +
    +  let pageContent: ReactElement | ReactElement[] = <p>Loading...</p>;
    +
    +  if (products?.length) {
    +    pageContent = products.map((product) => {
    +      const inCart: boolean = cart.some((item) => item.sku === product.sku);
    +
    +      return (
    +        <Product
    +          key={product.sku}
    +          product={product}
    +          dispatch={dispatch}
    +          REDUCER_ACTIONS={REDUCER_ACTIONS}
    +          inCart={inCart}
    +        />
    +      );
    +    });
    +  }
    +
    +  const content = <main className="main main--products">{pageContent}</main>;
    +
    +  return content;
    +};
    +export default ProductList;
    +

    # 🔷 components/Product

    // 引入所需的依賴和類型
    +import { ProductType } from "../context/ProductsProvider";
    +import { ReducerActionType, ReducerAction } from "../context/CartProvider";
    +import { ReactElement, memo } from "react";
    +
    +// 定義 PropsType,用於描述 Product 組件的屬性
    +type PropsType = {
    +  product: ProductType; // 產品信息
    +  dispatch: React.Dispatch<ReducerAction>; // 購物車操作的 dispatch 函數
    +  REDUCER_ACTIONS: ReducerActionType; // 購物車操作的行為類型
    +  inCart: boolean; // 產品是否已在購物車中的標記
    +};
    +
    +// Product 組件定義
    +const Product = ({
    +  product,
    +  dispatch,
    +  REDUCER_ACTIONS,
    +  inCart,
    +}: PropsType): ReactElement => {
    +  // 產品圖片的路徑
    +  const img: string = new URL(`../images/${product.sku}.jpg`, import.meta.url)
    +    .href;
    +  console.log(img);
    +
    +  // 添加產品到購物車的事件處理函數
    +  const onAddToCart = () =>
    +    dispatch({ type: REDUCER_ACTIONS.ADD, payload: { ...product, qty: 1 } });
    +
    +  // 如果產品已在購物車中,顯示標記
    +  const itemInCart = inCart ? " → Item in Cart: ✔️" : null;
    +
    +  // 產品的展示內容
    +  const content = (
    +    <article className="product">
    +      <h3>{product.name}</h3>
    +      <img src={img} alt={product.name} className="product__img" />
    +      <p>
    +        {new Intl.NumberFormat("en-US", {
    +          style: "currency",
    +          currency: "USD",
    +        }).format(product.price)}
    +        {itemInCart}
    +      </p>
    +      <button onClick={onAddToCart}>Add to Cart</button>
    +    </article>
    +  );
    +
    +  return content;
    +};
    +
    +// 比較函數,用於優化性能,避免不必要的重新渲染
    +function areProductsEqual(
    +  { product: prevProduct, inCart: prevInCart }: PropsType,
    +  { product: nextProduct, inCart: nextInCart }: PropsType
    +) {
    +  return (
    +    Object.keys(prevProduct).every((key) => {
    +      return (
    +        prevProduct[key as keyof ProductType] ===
    +        nextProduct[key as keyof ProductType]
    +      );
    +    }) && prevInCart === nextInCart
    +  );
    +}
    +
    +// 使用 memo 包裝 Product 組件,優化渲染性能
    +const MemoizedProduct = memo<typeof Product>(Product, areProductsEqual);
    +
    +export default MemoizedProduct;
    +

    # トラブルシューティング

    # ▫️ useCartContext hooks

    這段代碼定义了一个名为 useCartContext 的自定义 React Hook。这个 Hook 使用了 React 的几个内置功能,如 useReduceruseMemo,来管理和优化购物车应用的状态。下面是对每个部分的详细解释:

    const useCartContext = (initialCartState: CartStateType) => {
    +  const [state, dispatch] = useReducer(reducer, initialCartState);
    +
    +  //useMemo 主要用于缓存计算结果,并在依赖项(dependencies)发生变化时重新计算。
    +  const REDUCER_ACTIONS = useMemo(() => {
    +    return REDUCER_ACTION_TYPE;
    +  }, []);
    +
    +  const totalItems = state.cart.reduce((previousValue, cartItem) => {
    +    return previousValue + cartItem.qty;
    +  }, 0);
    +
    +  const totalPrice = new Intl.NumberFormat("en-US", {
    +    style: "currency",
    +    currency: "USD",
    +  }).format(
    +    state.cart.reduce((previousValue, cartItem) => {
    +      return previousValue + cartItem.qty * cartItem.price;
    +    }, 0)
    +  );
    +
    +  // 这段代码的作用是对购物车中的商品进行排序,排序的规则是按照商品的 sku 属性的后四位数字进行升序排序。
    +  const cart = state.cart.sort((a, b) => {
    +    //分别提取了商品 a 和 b 的 sku 属性的后四位数字部分。这些数字会被转换成数值类型。
    +    const itemA = Number(a.sku.slice(-4));
    +    const itemB = Number(b.sku.slice(-4));
    +    //表示根据提取出的数字进行升序排序,即如果 itemA 小于 itemB,返回负数;如果 itemA 等于 itemB,返回零;如果 itemA 大于 itemB,返回正数。
    +    return itemA - itemB;
    +  });
    +
    +  return { dispatch, REDUCER_ACTIONS, totalPrice, totalItems, cart };
    +};
    +

    useReducer

    const [state, dispatch] = useReducer(reducer, initialCartState);
    +
    • 这里使用了 useReducer Hook 来管理购物车的状态。useReducer 是一个替代 useState 的 Hook,适用于复杂的状态逻辑,可以让你根据 action 更新状态。
    • reducer 是一个函数,定义了状态如何响应不同的 action 类型。
    • initialCartState 是购物车的初始状态。
    • state 代表当前的状态,dispatch 是一个函数,用来发送 action 到 reducer。

    useMemo

    const REDUCER_ACTIONS = useMemo(() => {
    +  return REDUCER_ACTION_TYPE;
    +}, []);
    +
    • useMemo 用于缓存计算的结果。这里它被用来缓存 REDUCER_ACTION_TYPE 对象。
    • 依赖项数组([])为空,这意味着 REDUCER_ACTIONS 只会在组件首次渲染时计算一次。

    计算总数和总价

    const totalItems = state.cart.reduce((previousValue, cartItem) => {
    +  return previousValue + cartItem.qty;
    +}, 0);
    +
    +const totalPrice = new Intl.NumberFormat("en-US", {
    +  style: "currency",
    +  currency: "USD",
    +}).format(
    +  state.cart.reduce((previousValue, cartItem) => {
    +    return previousValue + cartItem.qty * cartItem.price;
    +  }, 0)
    +);
    +
    • 这两个变量使用 reduce 方法来计算购物车中商品的总数量 (totalItems) 和总价 (totalPrice)。

    对购物车商品进行排序

    const cart = state.cart.sort((a, b) => {
    +  const itemA = Number(a.sku.slice(-4));
    +  const itemB = Number(b.sku.slice(-4));
    +  return itemA - itemB;
    +});
    +
    • 这段代码对购物车中的商品根据 sku 的后四位数字进行升序排序。

    返回值

    return { dispatch, REDUCER_ACTIONS, totalPrice, totalItems, cart };
    +
    • useCartContext 返回一个包含 dispatch 函数、动作类型 (REDUCER_ACTIONS)、购物车总价 (totalPrice)、总数量 (totalItems) 和排序后的购物车商品列表 (cart) 的对象。
    • 这个 Hook 可以被用于组件中,以便于访问和操作购物车的状态。

    总的来说,useCartContext Hook 为购物车应用提供了一个集中的状态管理方案,使得状态的读取和更新更加方便和高效。

    # ▫️ UseCartContextType

    在 TypeScript 中定义 UseCartContextType 类型作为 ReturnType<typeof useCartContext> 的原因是为了确保类型安全和代码的清晰性。这里解释一下具体原因和用途:

    export type UseCartContextType = ReturnType<typeof useCartContext>;
    +

    为什么要确定返回值的类型

    1. 类型安全:
    • TypeScript 强类型系统的一个主要优点是它提供了类型安全。通过明确指定函数返回值的类型,你可以在编译时捕捉潜在的错误,而不是在运行时。
    • 在这个案例中,useCartContext 是一个自定义 Hook,它可能返回一个复杂的对象,包含多个属性和方法。使用 ReturnType 可以确保你完全理解并正确处理这个 Hook 返回的数据结构。
    1. 自动推断:
    • ReturnType<typeof useCartContext> 自动推断 useCartContext Hook 的返回值类型。这意味着如果 useCartContext 的实现更改了返回值的结构,UseCartContextType 也会相应地更新,无需手动更改。

    返回值是什么

    • 返回值:
    • useCartContext Hook 的返回值是一个对象,包含了与购物车相关的数据和函数。这通常包括购物车的状态(如商品列表、总价等)以及用于更新这些状态的方法(如 dispatch 方法)。

    在什么地方用

    1. 在 Context 提供者中:
    • 当你创建一个 Context 并且想要在整个应用中共享 useCartContext 提供的数据和函数时,可以使用这个类型。例如,在 CartProvider 组件中,你可能会将 useCartContext 的返回值作为 Context 的值。
    1. 在消费者组件中:
    • 组件可以通过 useContext(CartContext) 使用这个类型来访问购物车的数据和操作函数。这样可以确保组件正确地使用了 Context 提供的数据,同时也享受到了 TypeScript 的类型检查和自动完成的好处。

    总之,UseCartContextType 的定义和使用使得你的 React 组件可以高效且安全地与购物车相关的状态和操作进行交互,同时保持代码的清晰和可维护性。

    + + + diff --git a/practice/todolist.html b/practice/todolist.html new file mode 100644 index 00000000..c7ae3ca3 --- /dev/null +++ b/practice/todolist.html @@ -0,0 +1,462 @@ + + + + + + TodoList App | ☻ itsyuimorii.space + + + + + + + + +

    # TodoList App

    # プロジェクトの構成

    • TodoList

      • Manages the overall state of the todo list.
      • Provides the addTodo function to add new todos.
      • Logs the current state of the todo list.
      • index:TdList & TdInput
    • Input(TdInput): Responsible for the input field

      • index: Main view with the input field
      • Handles user input for adding new todos.
      • Validates input and prevents the addition of duplicate todos.
      • Calls the parent's TodoList addTodo function to update the todo list.
    • List(TdList): Responsible for displaying the list of todos

      • index(TdList):Manages and displays all items in the list (including all TdItems)
      • Item(TdItem): Responsible for displaying a single item
    import React from "react";
    +import TdInput from "./Input";
    +import TdList from "./List";
    +
    +const TodoList = () => {
    +  return (
    +    <div className="todo-list">
    +      <TdInput />
    +      <TdList />
    +    </div>
    +  );
    +};
    +export default TodoList;
    +

    # TdInput Component

    1. Input Handling:
    • Utilizes the useRef hook to create a reference (inputRef) to the input element. This reference is used to access the input element's value imperatively.
    • Defines a function (handleAddTodoItem) to handle the addition of new todo items based on user input.
    1. Validation and Interaction:
    • Ensures that the input value is trimmed and not empty. Displays an alert if a todo with the same content already exists.
    • Calls the addTodo function passed as a prop from the parent component (TodoList) to add a new todo item.
    1. User Interface:
    • Renders an input field and a button within a div with the class "todo-input."
    • The button triggers the handleAddTodoItem function when clicked.
    import React from "react";
    +
    +const TdInput = () => {
    +  return (
    +    <div className="todo-input">
    +      <form>
    +        <input type="text" placeholder="Enter your todo here" />
    +        <button type="submit">Add</button>
    +      </form>
    +    </div>
    +  );
    +};
    +
    +export default TdInput;
    +

    # TdList Component

    import React from "react";
    +import TdItem from "./Item";
    +
    +const TdList = () => {
    +  return (
    +    <div className="td-list">
    +      <TdItem />
    +    </div>
    +  );
    +};
    +
    +export default TdList;
    +

    # TdItem Component

    // Each item
    +import React from "react";
    +
    +const TdItem = () => {
    +  return (
    +    <div className="todo-item">
    +      <ul>
    +        <li>
    +          <input type="checkbox" />
    +          <span>Placeholder text here</span>
    +        </li>
    +      </ul>
    +    </div>
    +  );
    +};
    +
    +export default TdItem;
    +
    • Props: Every functional component (FC) has a collection of external properties (props) that it can receive. However, in the provided TdItem component, no props are explicitly defined or used.

    • Return Value: Every functional component returns a ReactElement, which is an object containing properties such as type, props, ref, key, etc.

    import React, { FC, ReactElement, useRef } from "react";
    +
    +// IProps is a generic parameter, indicating the expected type of properties (props) this component should receive.
    +interface IProps {}
    +
    +// The component (TdInput) is declared with the FC (FunctionComponent) type, as it uses ref, and for that, generics are needed.
    +const TdInput: FC<IProps> = ({}): ReactElement => {};
    +

    Takeaways:

    • Prop: In functional components, external properties are received through the props collection. 每一個函數組件都有一個外部傳入的 props 屬性集合。
    • Every functional component has a return value, which is a ReactElement object, representing JSX. 每一個函數組件是有一個返回值的,返回的是 ReactElement 對象,即 jsx
    • ReactElement Object: A comprehensive object containing properties like type, props, ref, key, etc.

    Explanation:

    • Props, short for properties, are external attributes passed to functional components.
    • Functional components, unlike class components, inherently produce ReactElement objects as their output.
    • A ReactElement is an object encapsulating information such as the component type, its properties (props), +references (ref), keys, and more, making it a fundamental unit in React's rendering process.

    In summary, functional components receive external attributes through props and, in turn, generate ReactElement objects, forming the basis of JSX rendering in React applications.

    import React, { FC, ReactElement, useRef } from "react";
    +
    +// IProps is a generic parameter, indicating the expected type of properties (props) this component should receive.
    +interface IProps {}
    +
    +// The component (TdInput) is declared with the FC (FunctionComponent) type, as it uses ref, and for that, generics are needed.
    +const TdInput: FC<IProps> = ({}): ReactElement => {};
    +

    Explanation: The TdInput component is a functional component that is expected to receive props conforming to the IProps interface. It uses the FC (FunctionComponent) type, a generic type provided by React for defining functional components. The function returns a React element (ReactElement), indicating that this component will render JSX. The empty object ({}) in the parameter list represents the expected props, and it can be adjusted based on the actual props needed by the component. This component is defined to handle input functionality within the TodoList app.

    # 定義 inputRef

    const inputRef = useRef < HTMLInputElement > null;
    +

    # 定義 Itodo 接口

    interface Itodo {
    +  id: number;
    +  description: string;
    +  status: boolean;
    +}
    +

    # 定義 Iprops src/components/TodoList/Input/index.tsx

    interface IProps {
    +  //為什麼沒有返回值? 因為這裡是一個函數組件,不是一個函數。
    +  addTodo: (todo: ITodo) => void; // 这里 addTodo 是一个属性,其类型为一个函数,这个函数接受一个 ITodo 类型的参数 todo,并且没有返回值(void)。在使用这个组件时,你需要从父组件传递一个满足这个函数签名的函数给 addTodo 属性。
    +}
    +

    思考

    • onClick 中應該放什麼?
    • useRef 的使用方式: 使用了 useRef(null),但您在代碼中沒有使用這個 inputRef。如果您希望在按鈕點擊時獲取輸入的值,您需要使用 inputRef.current.value。
    import React, { useRef, FC, ReactElement } from "react";
    +import { ITodo } from "../../types";
    +
    +interface IProps {
    +  addTodo: (todo: ITodo) => void;
    +}
    +
    +const TdInput: FC<IProps> = ({ addTodo }): ReactElement => {
    +    //inputRef 是一個對象,裡面有一個current屬性,current屬性指向input元素,用於獲取input元素的值。
    +  const inputRef = useRef<HTMLInputElement>(null);
    +
    +  return (
    +     {/* 这里,inputRef是一个useRef具有current属性的对象。该current属性最初设置为,但在安装组件时null将更新为指向DOM 元素。input之后,您可以使用inputRef.current来引用实际的inputDOM 元素。 */}
    +    <div className="todo-input">
    +      <input type="text" placeholder="please input to do list" ref={inputRef} />
    +      <button onClick={   ????  }>add</button>
    +    </div>
    +  );
    +};
    +
    +export default TdInput;
    +
    +

    接下來,應該是對 input 取值, 那麼就需要一個 handleAddTodoItem的方法, 並且在 onClick 中調用它。

    // IProps interface representing the properties (props) expected by the component.
    +interface IProps {
    +  // addTodo is a function that takes a todo (of type ITodo) and returns void.
    +  addTodo: (todo: ITodo) => void;
    +  // todoList is an array of ITodo objects, representing the list of to-do items.
    +  todoList: ITodo[];
    +}
    +.....
    +const handleAddTodoItem = (): void => {
    +  //inputRef.current用于获取输入元素(用户输入的文本)的当前值。这允许您直接访问输入字段的值,而无需使用 React 状态。当您需要在通常的 React 状态和事件处理机制之外强制访问输入字段的当前值时,这种模式很常见。
    +  const val: string = inputRef.current!.value.trim();
    +
    +  // Check if the trimmed value is not empty
    +  if (val.length) {
    +    // Check if a todo with the same content already exists in the todoList
    +    const isExist = todoList.find((todo) => todo.content === val);
    +
    +    // If a todo with the same content exists, show an alert and return from the function
    +    if (isExist) {
    +      alert("To-do list item already exists");
    +      return;
    +    }
    +
    +      //執行父類的addTodo方法, 把子類的val 傳給父類。
    +      id: new Date().getTime(), // Generate a unique id (using timestamp)
    +      content: val,
    +      completed: false,
    +    });
    +
    +    // Clear the input field by setting its value to an empty string
    +    inputRef.current!.value = "";
    +  }
    +};
    +.....
    +
    +  return (
    +    <div className="todo-input">
    +    {/* 这里,inputRef是一个useRef具有current属性的对象。该current属性最初设置为,但在安装组件时null将更新为指向DOM 元素。input之后,您可以使用inputRef.current来引用实际的inputDOM 元素。 */}
    +      <input type="text" placeholder="please input to do list" ref={inputRef} />
    +      <button onClick={handleAddTodoItem}>add</button>
    +    </div>
    +  );
    +};
    +
    +
    +

    # TodoList 父組件

    1. State Management:
    • Manages the state of the todo list using the useState hook. The state is initialized as an empty array.
    • Logs the current state of todoList using the useEffect hook whenever todoList changes.
    1. addTodo Function:
    • Defines an addTodo function using useCallback. This function takes a todo item as a parameter and updates the todoList state by appending the new todo.
    • The useCallback hook ensures that the addTodo function maintains a stable reference across renders, optimizing performance by preventing unnecessary re-renders.
    1. Rendering Child Components:
    • Renders two child components, TdInput and TdList, within a div with the class "todo-list."
    • Passes the addTodo function and the current todoList state as props to TdInput.
    
    +// 定義一個狀態,用 useState,為了讓子組件能夠獲取到父組件的狀態,所以要用 useState
    +const [todoList, setTodoList] = useState<ITodo[]>([]);
    +//當 useEffect 被觸發時,它內部的回調函數就會執行。即當新的代辦事項被添加到 todoList 時,useEffect 的回調函數就會執行。
    +useEffect(() => {
    +  console.log(todoList);
    +}, [todoList]);
    +
    +//addTodo 函數的目的: addTodo 函數的目的是將代表待辦事項的物件添加到 todoList 狀態中。這是透過使用 setTodoList 更新 todoList 狀態實現的。
    +const addTodo = useCallback((todo: ITodo) => {
    +  console.log(todo);
    +  // 在實際應用中,你應該使用 setTodoList 更新 todoList 狀態
    +  // setTodoList((prevTodoList) => [...prevTodoList, todo]);
    +  setTodoList((todoList) => [...todoList, todo]);
    +}, []);
    +
    +//將 addTodo 作為 prop 傳遞給 TdInput 子組件: 在 return 語句中,addTodo 函數作為 prop 傳遞給了 TdInput 子組件,這樣子組件就能夠使用父組件中的這個函數。
    +return (
    +  <div className="todo-list">
    +    {/* 將 addTodo 函數作為 prop 傳遞給子組件 TdInput */}
    +
    +    <TdInput addTodo={addTodo} todoList={todoList} />
    +    <TdList />
    +  </div>
    +);
    +

    useCallback 是 React 中的一個 Hook,用於優化函數引用,特別是在子組件的 props 中使用。在這個特定的代碼中,useCallback 用於優化 addTodo 函數的引用,以防止不必要的重新渲染。

    1. useCallback 用途:

    在 React 中,每次父組件渲染時,內聯函數都會被重新創建。為了避免不必要的函數重新創建,特別是在子組件的 props 中使用函數時,可以使用 useCallback 進行優化。在這裡,useCallback 用於優化 addTodo 函數的引用,以防止不必要的重新渲染。

    1. useCallback 的作用:
    • 避免不必要的函數重新創建: 使用 useCallback 可以緩存函數的實例,只有當 useCallback 的依賴項發生變化時才會創建一個新的函數實例。這減少了子組件的不必要重新渲染,提高了應用程序性能。

    • 子組件性能優化: 如果子組件使用了 React.memo 進行性能優化(防止不必要的重新渲染),useCallback 的使用能夠確保即使父組件重新渲染,子組件不會因 addTodo 函數的實際邏輯未改變而重新渲染。

    useEffect: 簡單來說,當使用者在 TdInput 組件中點擊 "add" 按鈕時,handleAddTodoItem 函數被觸發,並且它內部調用了由父組件 TodoList 提供的 addTodo 函數。這樣做的目的是將新的待辦事項添加到父組件的 todoList 狀態中,從而觸發 useEffect 並在控制台中輸出新的 todoList

    # 使用 useReducer 替代 useState

    //path: todo-list-app/src/components/TodoList/reducer.ts
    +
    +import { ACTION_TYPE, IAction, IState, ITodo } from "./types";
    +//todoReducer 是一個純函數,用於處理有關待辦事項應用程序狀態的變化。
    +function todoReducer(state: IState, action: IAction): IState {
    +  const { type, payload } = action;
    +  //返回一個IState,todoList: []的集合
    +
    +  //action包含兩個值:一個是payload, 另一個是type。 payload 其實就是我們要傳遞的參數,也就是todo的內容,就是const addTodo = useCallback((todo: ITodo) => 裡面的todo,另一個是type則是我們要做的事情
    +
    +  switch (type) {
    +    case ACTION_TYPE.ADD_TODO:
    +      return {
    +        ...state,
    +        todoList: [...state.todoList, payload as ITodo],
    +      };
    +    default:
    +      return state;
    +  }
    +}
    +
    +export { todoReducer };
    +
    +
    //path: src/components/TodoList/index.tsx
    +import React, {
    +  FC,
    +  ReactElement,
    +  useCallback,
    +  useEffect,
    +  useReducer,
    +} from "react";
    +import TdInput from "./Input";
    +import TdList from "./List";
    +import { ITodo, IState, ACTION_TYPE } from "./types";
    +import { todoReducer } from "./reducer";
    +
    +const initialState: IState = {
    +  todoList: [],
    +};
    +
    +const TodoList: FC = (): ReactElement => {
    +  const [state, dispatch] = useReducer(todoReducer, initialState);
    +
    +  //當 useEffect 被觸發時,它內部的回調函數就會執行。,即當新的代辦事項被添加到 todoList 時,useEffect 的回調函數就會執行。
    +  useEffect(() => {
    +    console.log(state.todoList);
    +  }, [state.todoList]);
    +
    +  //可理解為redux裡的action creator, 用來創建action,是純粹的函數, 它們返回一個action對象,而這個對象然後被傳遞給 dispatch()方法。
    +  const addTodo = useCallback((todo: ITodo) => {
    +    // setTodoList((todoList) => [...todoList, todo]);
    +    dispatch({
    +      type: ACTION_TYPE.ADD_TODO,
    +      payload: todo,
    +    });
    +  }, []);
    +
    +  return (
    +    <div className="todo-list">
    +      <TdInput addTodo={addTodo} todoList={state.todoList} />
    +      <TdList />
    +    </div>
    +  );
    +};
    +export default TodoList;
    +

    # 分析 1:親コンポーネントが子コンポーネントに提供する addTodo 関数を理解するには?

    在提供給 TdInput 子組件的 addTodo 函數和 handleAddTodoItem 函數之間有一個簡單的對應關係:

    1. addTodo 函數:
      • 定義在父組件 TodoList 中。
      • 使用 useCallback 優化函數引用。
      • 負責將新的待辦事項(todo 物件)添加到 todoList 狀態中。
    const addTodo = useCallback((todo: ITodo) => {
    +  dispatch({
    +    type: ACTION_TYPE.ADD_TODO,
    +    payload: todo,
    +  });
    +}, []);
    +
    1. handleAddTodoItem 函數:
      • 定義在子組件 TdInput 中。
      • 負責處理使用者輸入的待辦事項,並通過呼叫父組件提供的 addTodo 函數將新的待辦事項添加到 todoList 中。
    const handleAddTodoItem = (): void => {
    +  // ...(省略其他處理邏輯)
    +  addTodo({
    +    id: new Date().getTime(),
    +    content: val,
    +    completed: false,
    +  });
    +  // ...(省略其他處理邏輯)
    +};
    +

    todolist

    1. TodoList 組件:

      • TodoList 組件是一個 React 函數組件,負責渲染待辦事項應用的主要 UI。
      • 使用 useReducer Hook 管理狀態,並將狀態和派發函數 dispatch 作為 todoReducer 的參數。
    2. TdInput 組件:

      • TdInput 組件是 TodoList 組件的子組件,負責處理待辦事項的輸入部分。
      • 接收 addTodo 函數作為 prop,用來添加新的待辦事項。
      • 使用 inputRef 來獲取用戶輸入的值,並在點擊 "add" 按鈕時調用 handleAddTodoItem 函數。
    3. todoReducer 函數:

      • todoReducer 是一個純函數,用於處理與待辦事項應用的狀態相關的操作。
      • 接收當前應用程序的狀態 (state) 和一個描述操作的對象 (action)。
      • 在這個特定的應用中,只處理一種操作類型 ACTION_TYPE.ADD_TODO,用來將新的待辦事項添加到 todoList 中。

    這三個組件/函數之間的關係是通過 React 的層級組件結構和 props 傳遞建立的。主要的工作流程是:

    • TodoList 組件中使用 useReducer 來初始化應用的狀態並獲取 dispatch 函數。
    • TodoList 將狀態和 addTodo 函數作為 prop 傳遞給 TdInput 子組件。
    • TdInput 中,使用 inputRef 獲取用戶輸入的值,並在點擊 "add" 按鈕時調用 addTodo 函數。
    • addTodo 函數內部調用 dispatch 並傳遞一個描述添加待辦事項操作的 action 對象。
    • dispatch 調用 todoReducer 函數來修改應用的狀態。
    • useEffect Hook 監聽 state.todoList 的變化,並在變化時輸出日誌。
    
    +//path: todo-list-app/src/components/TodoList/reducer.ts
    +/**
    + * Redux 中 reducer 函數內的 switch case,用於處理不同的 action types。
    +
    + * 在 todoReducer 中,這些 case 實際上是 action types 的不同分支,用於決定根據不同的 action type 如何更新應用的狀態。
    +
    + * Reducer 是一個純函數,它接收先前的狀態和一個 action 物件,然後根據 action 的類型執行相應的操作,返回新的狀態。
    + */
    +import { ACTION_TYPE, IAction, IState, ITodo } from "./types";
    +function todoReducer(state: IState, action: IAction): IState {
    +  const { type, payload } = action;
    +
    +  switch (type) {
    +    case ACTION_TYPE.ADD_TODO:
    +      return {
    +        ...state,
    +        todoList: [...state.todoList, payload as ITodo],
    +      };
    +
    +    /**
    +       * 這裡的目的是從 todoList 中移除指定 id 的待辦事項。具體步驟如下:
    +
    +      1. 使用 filter 方法遍歷 state.todoList 中的每個待辦事項 (todo)。
    +      2. 對於每個待辦事項,檢查其 id 是否等於 payload(payload 是從 action 中傳入的待辦事項的 id)。
    +      3. 如果待辦事項的 id 與 payload 不相等,則保留該待辦事項;如果相等,則過濾掉該待辦事項。
    +      4. 將過濾後的待辦事項列表更新到新的 state 中。
    +       */
    +
    +    case ACTION_TYPE.REMOVE_TODO:
    +      return {
    +        ...state,
    +        todoList: state.todoList.filter((todo) => todo.id !== payload),
    +      };
    +
    +    /**
    +     * 這裡的目的是切換指定 `id` 的待辦事項的完成狀態(`completed`)。具體步驟如下:
    +
    +      1. 使用 `map` 方法遍歷 `state.todoList` 中的每個待辦事項 (`todo`)。
    +      2. 對於每個待辦事項,檢查其 `id` 是否等於 `payload`(`payload` 是從 `action` 中傳入的待辦事項的 `id`)。
    +      3. 如果待辦事項的 `id` 與 `payload` 相等,則將該待辦事項的 `completed` 狀態取反(切換完成狀態)。
    +      4. 將修改後的待辦事項列表更新到新的 `state` 中。
    +     */
    +
    +    case ACTION_TYPE.TOGGLE_TODO:
    +      return {
    +        ...state,
    +        todoList: state.todoList.map((todo) => {
    +          return todo.id === payload
    +            ? { ...todo, completed: !todo.completed }
    +            : { ...todo };
    +        }),
    +      };
    +    default:
    +      return state;
    +  }
    +}
    +
    +export { todoReducer };
    +

    # 分析 3 什麼是 action creator? 返回純函數的意思是?

    在 Redux 中,一個 action creator 是一個返回 action 物件的函數。這個 action 物件包含了描述 action 類型(type)和相關數據(payload)的信息。一個典型的 action creator 純函數如下:

    // action creator
    +const addTodo = (text) => {
    +  return {
    +    type: "ADD_TODO",
    +    payload: {
    +      text,
    +      completed: false,
    +    },
    +  };
    +};
    +
    +// 使用 action creator 來創建一個 action 物件
    +const newTodoAction = addTodo("Buy groceries");
    +

    在這個例子中,addTodo 是一個 action creator 函數。當你調用它時,它返回一個包含 action 信息的物件。這個 action 物件至少包含 type 屬性,用來指定 action 的類型,以及 payload 屬性,用來包含相關的數據。

    Redux 的 reducer 函數則根據這些 action 物件的 type 屬性,來決定如何更新應用的狀態。在 reducer 內部,通常使用一個 switch case 來處理不同的 action types。這就是為什麼在 Redux 中的 action creators 是純函數的原因,因為它們返回一個描述 action 的純函數,而不執行對應的非純操作。

    簡而言之,Redux 中的 action creators 是純函數,因為它們只返回描述 action 的物件,而不執行其他可能引起副作用的操作。這有助於保持 Redux 應用的可預測性和可測試性。

    # 分析 4: Iprops

    //IProps 具有属性 todoList、toggleTodo 和 的接口 removeTodo 用于 TdItem(item) 和 TdList(list) 组件,以定义这些组件应接收的预期 props。

    # IProps Interface for TdInput Component:

    interface IProps {
    +  addTodo: (todo: ITodo) => void;
    +  todoList: ITodo[];
    +}
    +
    • addTodo: This property is a function that takes an ITodo parameter and returns void. It suggests that the TdInput component expects a function to be passed down that will handle the addition of a new todo item to the list.

    • todoList: This property is an array of ITodo items. It represents the list of todos that the TdInput component needs access to, possibly for checking if a todo already exists before adding a new one.

    # IProps Interface for TdList Component:

    interface IProps {
    +  todoList: ITodo[];
    +  toggleTodo: (id: number) => void;
    +  removeTodo: (id: number) => void;
    +}
    +
    • todoList: This property is an array of ITodo items. It represents the list of todos that the TdList component will render.

    • toggleTodo: This property is a function that takes a number (presumably the id of a todo item) and returns void. It suggests that the TdList component expects a function to be passed down that will handle toggling the completion status of a todo item.

    • removeTodo: This property is a function that takes a number (presumably the id of a todo item) and returns void. It suggests that the TdList component expects a function to be passed down that will handle removing a todo item from the list.

    # Common Aspects:

    • Both interfaces include a todoList property, indicating that both components need access to the list of todos.
    • The ITodo type is referenced in both interfaces, suggesting that it defines the structure of a todo item.

    Understanding these interfaces helps clarify what kind of props each component expects and how they interact with the rest of the application.

    # IProps in the TodoList>input>index.tsx

    //path: src/components/TodoList/Input/index.tsx
    +import React, { useRef, FC, ReactElement } from "react";
    +import { ITodo } from "../types";
    +
    +//addTodo接口中属性的存在IProps表明TdInput组件期望将函数作为 prop 传递,并且该函数应该具有签名(todo: ITodo) => void。这表明该函数的目的可能是处理添加新的待办事项。
    +interface IProps {
    +  //addTodo:它是一个以ITodo对象作为参数并返回的函数void。该函数预计可以处理添加新的待办事项。
    +  addTodo: (todo: ITodo) => void;
    +
    +  //todoList:它是一个对象数组ITodo。该数组表示组件将与之交互的待办事项列表TdInput,专门用于检查列表中是否已存在新的待办事项。
    +  todoList: ITodo[];
    +}
    +
    +/**
    + * addTodoProp: 是一个向下传递给TdInput组件的函数。在函数内部handleAddTodoItem,当即将添加新的待办事项时,将调用此函数。该addTodo函数负责将新的待办事项添加到整个待办事项列表中。
    +
    + * todoListProp: 是待办事项的数组。它在handleAddTodoItem函数中用于检查列表中是否已存在具有相同内容的新待办事项。如果是,则会显示警报,并且不会添加新的待办事项。
    + */
    +
    +const TdInput: FC<IProps> = ({ addTodo, todoList }): ReactElement => {
    +  const inputRef = useRef<HTMLInputElement>(null);
    +
    +  const handleAddTodoItem = (): void => {
    +    const val: string = inputRef.current!.value.trim();
    +
    +    if (val.length) {
    +      const isExist = todoList.find((todo) => todo.content === val);
    +
    +      if (isExist) {
    +        alert("to do list has existed");
    +        return;
    +      }
    +      //在该函数中,addTodo使用新的 todo 对象作为参数来调用该函数。addTodo这与界面中的属性设置的期望一致IProps。
    +      addTodo({
    +        id: new Date().getTime(),
    +        content: val,
    +        completed: false,
    +      });
    +      inputRef.current!.value = "";
    +    }
    +  };
    +  return (
    +    <div className="todo-input">
    +      <input type="text" placeholder="please input to do list" ref={inputRef} />
    +      <button onClick={handleAddTodoItem}>add</button>
    +    </div>
    +  );
    +};
    +
    +export default TdInput;
    +
    + + +