diff --git a/.github/ISSUE_TEMPLATE/Bug REPORT.md b/.github/ISSUE_TEMPLATE/Bug REPORT.md new file mode 100644 index 0000000000..e3e6e572e3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug REPORT.md @@ -0,0 +1,22 @@ +--- +name: ๐Ÿž Bug report +about: ko.javascript.info์— ๋Œ€ํ•œ ๋ฒ„๊ทธ +title: "[Bug report] " +--- + +## ๐Ÿ› Bug report + + +## ์˜ˆ์ƒ๋œ ๊ธฐ๋Šฅ ํ˜น์€ ํ™”๋ฉด + +## ํ™˜๊ฒฝ + + +## ์žฌ์—ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..c9241b89b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: true +contact_links: + - name: ๐Ÿ’ฌ ์นด์นด์˜ค ์˜คํ”ˆ์ฑ„ํŒ…๋ฐฉ + url: https://open.kakao.com/o/gSBnoLab + about: ์นด์นด์˜คํ†ก ์˜คํ”ˆ์ฑ„ํŒ…๋ฐฉ์€ ๊ตต์งํ•œ ๊ณต์ง€์‚ฌํ•ญ๋“ค์„ ์ „๋‹ฌํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + - name: ๐Ÿ“ƒ ๋ฒˆ์—ญ ๋ชจ๋ฒ” ์‚ฌ๋ก€ + url: https://github.com/javascript-tutorial/ko.javascript.info/wiki/%EB%B2%88%EC%97%AD-%EB%AA%A8%EB%B2%94-%EC%82%AC%EB%A1%80 + about: ๋ฒˆ์—ญ ๋ชจ๋ฒ” ์‚ฌ๋ก€ Wiki + - name: โš™๏ธ ๋กœ์ปฌ ์„œ๋ฒ„ ์„ธํŒ…ํ•˜๊ธฐ + url: https://github.com/javascript-tutorial/ko.javascript.info/wiki/%EB%A1%9C%EC%BB%AC-%EC%84%9C%EB%B2%84-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0 + about: ๋กœ์ปฌ ์„œ๋ฒ„ ์„ธํŒ…ํ•˜๊ธฐ Wiki + - name: ๐Ÿ”ง ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ ์ด๋ฏธ์ง€๊ฐ€ ๋ณด์ด์ง€ ์•Š์„ ๋•Œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• + url: https://github.com/javascript-tutorial/ko.javascript.info/wiki/%EB%A1%9C%EC%BB%AC-%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80%EA%B0%80-%EB%B3%B4%EC%9D%B4%EC%A7%80-%EC%95%8A%EC%9D%84-%EB%95%8C-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95 + about: ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ ์ด๋ฏธ์ง€๊ฐ€ ๋ณด์ด์ง€ ์•Š์„ ๋•Œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• Wiki \ No newline at end of file diff --git "a/.github/ISSUE_TEMPLATE/\352\260\234\354\204\240\354\240\234\354\225\210.md" "b/.github/ISSUE_TEMPLATE/\352\260\234\354\204\240\354\240\234\354\225\210.md" new file mode 100644 index 0000000000..5a0712c747 --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\352\260\234\354\204\240\354\240\234\354\225\210.md" @@ -0,0 +1,15 @@ +--- +name: โœ๏ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŠœํ† ๋ฆฌ์–ผ ํ•œ๊ตญ ์ €์žฅ์†Œ ๊ฐœ์„ ์ œ์•ˆ +about: ๊ฐœ์„ ์ œ์•ˆ์— ๋Œ€ํ•œ ์„ค๋ช….. +title: "[๊ฐœ์„ ์ œ์•ˆ] " +--- + +## ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŠœํ† ๋ฆฌ์–ผ ํ•œ๊ตญ ์ €์žฅ์†Œ ๊ฐœ์„ ์„ ์œ„ํ•ด ์ œ์•ˆํ•  ์‚ฌํ•ญ + + +## ์ œ์•ˆํ•œ ์ด์œ  + + +## ์ถ”๊ฐ€์ ์œผ๋กœ ๋…ผ์˜ํ•  ์‚ฌํ•ญ + + diff --git "a/.github/ISSUE_TEMPLATE/\353\214\200\354\213\234\353\263\264\353\223\234_\352\266\214\355\225\234_\354\232\224\354\262\255.md" "b/.github/ISSUE_TEMPLATE/\353\214\200\354\213\234\353\263\264\353\223\234_\352\266\214\355\225\234_\354\232\224\354\262\255.md" new file mode 100644 index 0000000000..04820d4078 --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\353\214\200\354\213\234\353\263\264\353\223\234_\352\266\214\355\225\234_\354\232\224\354\262\255.md" @@ -0,0 +1,19 @@ +--- +name: ๐Ÿ’ช ๋Œ€์‹œ๋ณด๋“œ ์ˆ˜์ • ๊ถŒํ•œ ์š”์ฒญ +about: Dashboard ์ˆ˜์ • ๊ถŒํ•œ์„ ์œ„ํ•œ ์š”์ฒญ +title: "[๋Œ€์‹œ๋ณด๋“œ ์ˆ˜์ • ๊ถŒํ•œ ์š”์ฒญ] " +--- + +## ๋ชจ๋˜ JavaScript ํŠœํ† ๋ฆฌ์–ผ์„ ์•Œ๊ฒŒ ๋œ ๊ฒฝ๋กœ +ex) ์นœ๊ตฌ๊ฐ€ ์ถ”์ฒœํ•ด์ค˜์„œ ์•Œ๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +## ์ปจํŠธ๋ฆฌ๋ทฐํŒ… ๊ฐ€์ด๋“œ์™€ ๋งํฌ ๊ฑธ๋ฆฐ ๋ฌธ์„œ๋ฅผ 1ํšŒ ์ด์ƒ ์ •๋…ํ•˜์…จ๋‚˜์š”? +ex) ๋„ค. ์ •๋…ํ•˜์˜€์Šต๋‹ˆ๋‹ค. + +## Gmail ์•„์ด๋”” +ex) modernjs@gmail.com + +## ์ฃผ์˜ ์‚ฌํ•ญ +๊ถŒํ•œ์„ ๋“œ๋ ธ์ง€๋งŒ, ๋ฌธ์„œ ์ˆ˜์ •์ด ์•ˆ ๋œ๋‹ค๊ณ  ๋ฌธ์˜ํ•˜์‹œ๋Š” ๋ถ„๋“ค์ด ์žˆ์œผ์‹ญ๋‹ˆ๋‹ค. ๊ถŒํ•œ ์ถ”๊ฐ€๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๋ฉ”์ผ์ด ์™”์œผ๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ˆ˜์ • ๊ถŒํ•œ์ด ์ฃผ์–ด์ง„ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. + +๊ถŒํ•œ ๊ด€๋ จ ๋ฉ”์ผ์„ ๋ฐ›์œผ์…จ์ง€๋งŒ, ์ˆ˜์ •์ด ์•ˆ ๋œ๋‹ค๋ฉด ๋กœ๊ทธ์ธ๋˜์–ด์žˆ๋Š” ๊ณ„์ •์ด ๋ณธ ์ด์Šˆ์— ์ ์–ด์ฃผ์‹  ๊ณ„์ •๊ณผ ์ผ์น˜ํ•œ ์ง€ ํ™•์ธ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ํŠนํžˆ gmail ๊ณ„์ •์„ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉ์ค‘์ด์‹œ๋ผ๋ฉด ์ฃผ์˜ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. diff --git "a/.github/ISSUE_TEMPLATE/\354\213\240\352\267\234_\353\262\210\354\227\255.md" "b/.github/ISSUE_TEMPLATE/\354\213\240\352\267\234_\353\262\210\354\227\255.md" new file mode 100644 index 0000000000..936ff937ca --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\354\213\240\352\267\234_\353\262\210\354\227\255.md" @@ -0,0 +1,9 @@ +--- +name: ๐Ÿ“ ์‹ ๊ทœ ๋ฒˆ์—ญ +about: ์ƒˆ๋กœ ์ž‘์—…ํ•  ๋‚ด์šฉ์— ๋Œ€ํ•œ ๊ณต์œ  +title: "[์‹ ๊ทœ ๋ฒˆ์—ญ] " +--- + +### ์ž‘์—…ํ•  ๋‚ด์šฉ +ex) [Part 1. 1.1 An Introduction to JavaScript](https://javascript.info/intro)์— ๋Œ€ํ•œ ๋ฒˆ์—ญ + diff --git "a/.github/ISSUE_TEMPLATE/\354\230\244\353\262\210\354\227\255\354\210\230\354\240\225.md" "b/.github/ISSUE_TEMPLATE/\354\230\244\353\262\210\354\227\255\354\210\230\354\240\225.md" new file mode 100644 index 0000000000..b9b3b77625 --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\354\230\244\353\262\210\354\227\255\354\210\230\354\240\225.md" @@ -0,0 +1,24 @@ +--- +name: ๐Ÿค” ์˜ค๋ฒˆ์—ญ์ˆ˜์ • +about: ์–ด์ƒ‰ํ•œ ํ‘œํ˜„, ์ž˜๋ชป ๋ฒˆ์—ญ๋œ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ด์Šˆ +title: "[์˜ค๋ฒˆ์—ญ์ˆ˜์ •] " +--- + + +## ์˜ค๋ฒˆ์—ญ + + +## ๋ฒˆ์—ญ + + +## ์ด์Šˆ + + +## Pull Request(PR)๋ฅผ ํ†ตํ•ด ์ˆ˜์ •ํ•  ์˜ํ–ฅ์ด ์žˆ์Šต๋‹ˆ๊นŒ? + + diff --git "a/.github/ISSUE_TEMPLATE/\354\230\244\355\203\200\354\210\230\354\240\225.md" "b/.github/ISSUE_TEMPLATE/\354\230\244\355\203\200\354\210\230\354\240\225.md" new file mode 100644 index 0000000000..f0b432219e --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\354\230\244\355\203\200\354\210\230\354\240\225.md" @@ -0,0 +1,21 @@ +--- +name: ๐Ÿ” ์˜คํƒ€์ˆ˜์ • +about: ์˜คํƒ€ ๊ด€๋ จ ์ด์Šˆ +title: "[์˜คํƒ€์ˆ˜์ •] " +--- + +## ์›๋ฌธ + + +## ์˜คํƒ€์ˆ˜์ • + +## ์ด์Šˆ + + +## Pull Request(PR)๋ฅผ ํ†ตํ•ด ์ˆ˜์ •ํ•  ์˜ํ–ฅ์ด ์žˆ์Šต๋‹ˆ๊นŒ? \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 48b09f0454..8de4288460 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,16 @@ +# ์š”์•ฝ + + +# ์—ฐ๊ด€ ์ด์Šˆ +(fix #์ผ์ด์‚ผ) + + # Pull Request ์ฒดํฌ๋ฆฌ์ŠคํŠธ ## TODO - [ ] [๋ฒˆ์—ญ ๊ทœ์น™์„ ํ™•์ธํ•˜์…จ๋‚˜์š”?](https://github.com/javascript-tutorial/ko.javascript.info#%EB%B2%88%EC%97%AD-%EA%B7%9C%EC%B9%99) - [ ] ์ค„ ๋ฐ”๊ฟˆ๊ณผ ๋‹จ๋ฝ์„ '์›๋ฌธ๊ณผ ๋™์ผํ•˜๊ฒŒ' ์œ ์ง€ํ•˜์…จ๋‚˜์š”? - [ ] [๋งž์ถค๋ฒ• ๊ฒ€์‚ฌ๊ธฐ](http://speller.cs.pusan.ac.kr/)๋กœ ๋งž์ถค๋ฒ•์„ ํ™•์ธํ•˜์…จ๋‚˜์š”? - - [ ] ๊ณต๋ฐฑ(์ŠคํŽ˜์ด์Šค), ํฐ๋”ฐ์˜ดํ‘œ("), ์ž‘์€๋”ฐ์˜ดํ‘œ('), ๋Œ€์‹œ(-), ๋ฐฑํ‹ฑ(`)์„ ๋น„๋กฏํ•œ ๋ชจ๋“  ํŠน์ˆ˜๋ฌธ์ž๋Š” ๊ทธ๋Œ€๋กœ ๋‘์…จ๋‚˜์š”? + - [ ] ๋งˆํฌ๋‹ค์šด ๋ฌธ๋ฒ•์— ์‚ฌ์šฉ๋˜๋Š” ๊ณต๋ฐฑ(์ŠคํŽ˜์ด์Šค), ํฐ๋”ฐ์˜ดํ‘œ("), ์ž‘์€๋”ฐ์˜ดํ‘œ('), ๋Œ€์‹œ(-), ๋ฐฑํ‹ฑ(`) ๋“ฑ์˜ ํŠน์ˆ˜๋ฌธ์ž๋Š” ๊ทธ๋Œ€๋กœ ๋‘์…จ๋‚˜์š”? - [ ] [๋กœ์ปฌ ์„œ๋ฒ„ ์„ธํŒ…](https://github.com/javascript-tutorial/ko.javascript.info/wiki/%EB%A1%9C%EC%BB%AC-%EC%84%9C%EB%B2%84-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0) ํ›„ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธํ•ด ๋ณด์…จ๋‚˜์š”? - [ ] PR ํ•˜๋‚˜์—” ๋ฒˆ์—ญ๋ฌธ ํ•˜๋‚˜๋งŒ ๋„ฃ์œผ์…จ๋‚˜์š”? - [ ] ์˜๋ฏธ ์žˆ๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์ž‘์„ฑํ•˜์…จ๋‚˜์š”? diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index 9916e4d726..693d29b18d 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -4,7 +4,7 @@ ## ์ •์˜ -*์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ*๋Š” *"์›นํŽ˜์ด์ง€์— ์ƒ๋™๊ฐ์„ ๋ถˆ์–ด๋„ฃ๊ธฐ ์œ„ํ•ด"* ๋งŒ๋“ค์–ด์ง„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. +*์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ*๋Š” '์›นํŽ˜์ด์ง€์— ์ƒ๋™๊ฐ์„ ๋ถˆ์–ด๋„ฃ๊ธฐ ์œ„ํ•ด' ๋งŒ๋“ค์–ด์ง„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ž‘์„ฑํ•œ ํ”„๋กœ๊ทธ๋žจ์„ *์Šคํฌ๋ฆฝํŠธ(script)* ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋Š” ์›นํŽ˜์ด์ง€์˜ HTML ์•ˆ์— ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์›นํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @@ -13,20 +13,20 @@ ์ด๋Ÿฐ ๊ด€์ ์—์„œ ๋ณด๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” [์ž๋ฐ”(Java)](https://en.wikipedia.org/wiki/Java_(programming_language))์™€๋Š” ๋งค์šฐ ๋‹ค๋ฅธ ์–ธ์–ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```smart header="์™œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ธ๊ฐ€์š”?" -์ฒ˜์Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์„ ๋•Œ๋Š” "LiveScript"๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ถˆ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ๋‹น์‹œ ์ž๋ฐ”์˜ ์ธ๊ธฐ๊ฐ€ ์•„์ฃผ ๋†’์€ ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จ์ธ๋“ค์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž๋ฐ”์˜ "๋™์ƒ" ๊ฒฉ์ธ ์–ธ์–ด๋กœ ํ™๋ณดํ•˜๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๋Š” ์˜์‚ฌ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ณ  ์ด๋ฆ„์„ ๋ฐ”๊ฟจ์Šต๋‹ˆ๋‹ค. +์ฒ˜์Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์„ ๋•Œ๋Š” 'LiveScript'๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ถˆ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ๋‹น์‹œ ์ž๋ฐ”์˜ ์ธ๊ธฐ๊ฐ€ ์•„์ฃผ ๋†’์€ ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จ์ธ๋“ค์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž๋ฐ”์˜ '๋™์ƒ' ๊ฒฉ์ธ ์–ธ์–ด๋กœ ํ™๋ณดํ•˜๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๋Š” ์˜์‚ฌ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ณ  ์ด๋ฆ„์„ ๋ฐ”๊ฟจ์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„์€ ์ž๋ฐ”์—์„œ ์ฐจ์šฉํ•ด ์™”์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋ฐ”์™€๋Š” ๋…์ž์ ์ธ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๊พธ์ค€ํžˆ ๋ฐœ์ „์„ ๊ฑฐ๋“ญํ•˜๋ฉด์„œ [ECMAScript](http://en.wikipedia.org/wiki/ECMAScript)๋ผ๋Š” ๊ณ ์œ ํ•œ ๋ช…์„ธ๋ฅผ ๊ฐ–์ถ˜ ๋…๋ฆฝ์ ์ธ ์–ธ์–ด๊ฐ€ ๋˜์—ˆ์ฃ . ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋ฐ”์™€ ์•„๋ฌด๋Ÿฐ ์—ฐ๊ด€์ด ์—†์Šต๋‹ˆ๋‹ค. ``` -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์„œ๋ฒ„์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์—๋„ [์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„(JavaScript engine)](https://en.wikipedia.org/wiki/javascript_engine)์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ํŠน๋ณ„ํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ๋“ค์–ด ์žˆ๋Š” ๋ชจ๋“  ๋””๋ฐ”์ด์Šค์—์„œ๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์„œ๋ฒ„์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์—๋„ [์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„(JavaScript engine)](https://en.wikipedia.org/wiki/JavaScript_engine)์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ํŠน๋ณ„ํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ๋“ค์–ด ์žˆ๋Š” ๋ชจ๋“  ๋””๋ฐ”์ด์Šค์—์„œ๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -๋ธŒ๋ผ์šฐ์ €์—” "์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ€์ƒ ๋จธ์‹ "์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ์—”์ง„์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ €์—” '์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ€์ƒ ๋จธ์‹ '์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ์—”์ง„์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—”์ง„์˜ ์ข…๋ฅ˜๋Š” ๋‹ค์–‘ํ•œ๋ฐ, ์—”์ง„๋งˆ๋‹ค ํŠน์œ ์˜ ์ฝ”๋“œ๋„ค์ž„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ ๋ง์ด์ฃ . -- [V8](https://en.wikipedia.org/wiki/V8_(javascript_engine)) -- Chrome๊ณผ Opera์—์„œ ์“ฐ์ž…๋‹ˆ๋‹ค. +- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- Chrome๊ณผ Opera์—์„œ ์“ฐ์ž…๋‹ˆ๋‹ค. - [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- Firefox์—์„œ ์“ฐ์ž…๋‹ˆ๋‹ค. -- IE๋Š” ๋ฒ„์ „์— ๋”ฐ๋ผ "Trident"๋‚˜ "Chakra"๋ผ ๋ถˆ๋ฆฌ๋Š” ์—”์ง„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. "ChakraCore"๋Š” Microsoft Edge์— ์‚ฌ์šฉ๋˜๋ฉฐ, "SquirrelFish"๋Š” Safari์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +- IE๋Š” ๋ฒ„์ „์— ๋”ฐ๋ผ 'Trident'๋‚˜ 'Chakra'๋ผ ๋ถˆ๋ฆฌ๋Š” ์—”์ง„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 'ChakraCore'๋Š” Microsoft Edge์— ์‚ฌ์šฉ๋˜๋ฉฐ, 'SquirrelFish'๋Š” Safari์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ๋„ค์ž„์€ ๊ฐœ๋ฐœ ๊ด€๋ จ ๊ธ€์—์„œ ์ข…์ข… ์–ธ๊ธ‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์–ตํ•ด ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋„ ํ•ด๋‹น ์ฝ”๋“œ๋„ค์ž„์„ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. "X๋ผ๋Š” ๊ธฐ๋Šฅ์€ V8์—์„œ๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค."๋ผ๋Š” ์‹์œผ๋กœ ๋ง์ด์ฃ . ์ด๋Ÿฐ ๋ฌธ์žฅ์„ ๋งŒ๋‚˜๋ฉด Chrome๊ณผ Opera์—์„œ๋งŒ ์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค๊ณ  ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. @@ -34,8 +34,8 @@ ์—”์ง„์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋ ค๋ฉด ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์„ ์Ÿ์•„๋ถ€์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. -1. ์—”์ง„(๋ธŒ๋ผ์šฐ์ €๋ผ๋ฉด ๋‚ด์žฅ ์—”์ง„)์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค("ํŒŒ์‹ฑ"). -2. ์ฝ์–ด ๋“ค์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ๊ณ„์–ด๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค("์ปดํŒŒ์ผ"). +1. ์—”์ง„(๋ธŒ๋ผ์šฐ์ €๋ผ๋ฉด ๋‚ด์žฅ ์—”์ง„)์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค(ํŒŒ์‹ฑ). +2. ์ฝ์–ด ๋“ค์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ๊ณ„์–ด๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค(์ปดํŒŒ์ผ). 3. ๊ธฐ๊ณ„์–ด๋กœ ์ „ํ™˜๋œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๊ณ„์–ด๋กœ ์ „ํ™˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ์†๋„๊ฐ€ ๋น ๋ฆ…๋‹ˆ๋‹ค. ์—”์ง„์€ ํ”„๋กœ์„ธ์Šค ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ปดํŒŒ์ผ์ด ๋๋‚˜๊ณ  ์‹คํ–‰ ์ค‘์ธ ์ฝ”๋“œ๋ฅผ ๊ฐ์‹œํ•˜๋ฉด์„œ, ์ด ์ฝ”๋“œ๋กœ ํ˜๋Ÿฌ๊ฐ€๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ , ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ํ† ๋Œ€๋กœ ๊ธฐ๊ณ„์–ด๋กœ ์ „ํ™˜๋œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ตœ์ ํ™”ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉด ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์†๋„๋Š” ๋”์šฑ ๋” ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค. @@ -43,7 +43,7 @@ ## ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ -๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” "์•ˆ์ „ํ•œ" ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๋‚˜ CPU ๊ฐ™์€ ์ €์ˆ˜์ค€ ์˜์—ญ์˜ ์กฐ์ž‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์• ์ดˆ์— ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์ด ํ•„์š”์น˜ ์•Š์€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋งŒ๋“  ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . +๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” '์•ˆ์ „ํ•œ' ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๋‚˜ CPU ๊ฐ™์€ ์ €์ˆ˜์ค€ ์˜์—ญ์˜ ์กฐ์ž‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์• ์ดˆ์— ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์ด ํ•„์š”์น˜ ์•Š์€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋งŒ๋“  ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋Šฅ๋ ฅ์€ ์‹คํ–‰ ํ™˜๊ฒฝ์— ์ƒ๋‹นํ•œ ์˜ํ–ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. [Node.js](https://wikipedia.org/wiki/Node.js) ํ™˜๊ฒฝ์—์„  ์ž„์˜์˜ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ณ , ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. @@ -55,7 +55,7 @@ - ๋งˆ์šฐ์Šค ํด๋ฆญ์ด๋‚˜ ํฌ์ธํ„ฐ์˜ ์›€์ง์ž„, ํ‚ค๋ณด๋“œ ํ‚ค ๋ˆŒ๋ฆผ ๋“ฑ๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์ž ํ–‰๋™์— ๋ฐ˜์‘ํ•˜๊ธฐ - ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์›๊ฒฉ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, ์—…๋กœ๋“œํ•˜๊ธฐ([AJAX](https://en.wikipedia.org/wiki/Ajax_(programming))๋‚˜ [COMET](https://en.wikipedia.org/wiki/Comet_(programming))๊ณผ ๊ฐ™์€ ๊ธฐ์ˆ  ์‚ฌ์šฉ) - ์ฟ ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•˜๊ธฐ. ์‚ฌ์šฉ์ž์—๊ฒŒ ์งˆ๋ฌธ์„ ๊ฑด๋„ค๊ฑฐ๋‚˜ ๋ฉ”์‹œ์ง€ ๋ณด์—ฌ์ฃผ๊ธฐ -- ํด๋ผ์ด์–ธํŠธ ์ธก์— ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ("๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€") +- ํด๋ผ์ด์–ธํŠธ ์ธก์— ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ(๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€) ## ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•  ์ˆ˜ ์—†๋Š” ์ผ @@ -65,12 +65,12 @@ - ์›นํŽ˜์ด์ง€ ๋‚ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋””์Šคํฌ์— ์ €์žฅ๋œ ์ž„์˜์˜ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ณ , ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•  ๋•Œ ์ œ์•ฝ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ง์ ‘ ์“ฐ์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰ํ˜€์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. - ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŒŒ์ผ์„ ๋‹ค๋ฃฐ ์ˆœ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ ‘๊ทผ์€ ์ œํ•œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์— ํŒŒ์ผ์„ "๋Œ์–ด๋‹ค ๋‘๊ฑฐ๋‚˜" `` ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ์„ ์„ ํƒํ•  ๋•Œ์™€ ๊ฐ™์ด ํŠน์ • ์ƒํ™ฉ์—์„œ๋งŒ ํŒŒ์ผ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. + ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŒŒ์ผ์„ ๋‹ค๋ฃฐ ์ˆœ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ ‘๊ทผ์€ ์ œํ•œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์— ํŒŒ์ผ์„ '๋Œ์–ด๋‹ค ๋‘๊ฑฐ๋‚˜' `` ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ์„ ์„ ํƒํ•  ๋•Œ์™€ ๊ฐ™์ด ํŠน์ • ์ƒํ™ฉ์—์„œ๋งŒ ํŒŒ์ผ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์นด๋ฉ”๋ผ๋‚˜ ๋งˆ์ดํฌ ๊ฐ™์€ ๋””๋ฐ”์ด์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋ ค๋ฉด ์‚ฌ์šฉ์ž์˜ ๋ช…์‹œ์ ์ธ ํ—ˆ๊ฐ€๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ™œ์„ฑํ™”๋œ ํŽ˜์ด์ง€๋ผ๋„ ์‚ฌ์šฉ์ž ๋ชฐ๋ž˜ ์›น ์นด๋ฉ”๋ผ๋ฅผ ์ž‘๋™ ์‹œ์ผœ ์ˆ˜์ง‘ํ•œ ์ •๋ณด๋ฅผ [๊ตญ๊ฐ€์•ˆ๋ณด๊ตญ(NSA)](https://en.wikipedia.org/wiki/National_Security_Agency)๊ณผ ๊ฐ™์€ ๊ณณ์— ๋ชฐ๋ž˜ ์ „์†กํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -- ๋ธŒ๋ผ์šฐ์ € ๋‚ด ํƒญ๊ณผ ์ฐฝ์€ ๋Œ€๊ฒŒ ์„œ๋กœ์˜ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ํ•œ ์ฐฝ์—์„œ ๋‹ค๋ฅธ ์ฐฝ์„ ์—ด ๋•Œ๋Š” ์˜ˆ์™ธ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ์—๋„ ๋„๋ฉ”์ธ์ด๋‚˜ ํ”„๋กœํ† ์ฝœ, ํฌํŠธ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +- ๋ธŒ๋ผ์šฐ์ € ๋‚ด ํƒญ๊ณผ ์ฐฝ์€ ๋Œ€๊ฐœ ์„œ๋กœ์˜ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ํ•œ ์ฐฝ์—์„œ ๋‹ค๋ฅธ ์ฐฝ์„ ์—ด ๋•Œ๋Š” ์˜ˆ์™ธ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ์—๋„ ๋„๋ฉ”์ธ์ด๋‚˜ ํ”„๋กœํ† ์ฝœ, ํฌํŠธ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - ์ด๋Ÿฐ ์ œ์•ฝ์‚ฌํ•ญ์„ "๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same Origin Policy)"์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด ์ •์ฑ…์„ ํ”ผํ•˜๋ ค๋ฉด *๋‘ ํŽ˜์ด์ง€*๋Š” ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ๋™์˜ํ•ด์•ผ ํ•˜๊ณ , ๋™์˜์™€ ๊ด€๋ จ๋œ ํŠน์ˆ˜ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์ถ”ํ›„ ํ•™์Šตํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. + ์ด๋Ÿฐ ์ œ์•ฝ์‚ฌํ•ญ์„ '๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same Origin Policy)'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด ์ •์ฑ…์„ ํ”ผํ•˜๋ ค๋ฉด *๋‘ ํŽ˜์ด์ง€*๋Š” ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ๋™์˜ํ•ด์•ผ ํ•˜๊ณ , ๋™์˜์™€ ๊ด€๋ จ๋œ ํŠน์ˆ˜ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์ถ”ํ›„ ํ•™์Šตํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ•์กฐํ•˜์ง€๋งŒ, ์ด๋Ÿฐ ์ œ์•ฝ์‚ฌํ•ญ์€ ์‚ฌ์šฉ์ž์˜ ๋ณด์•ˆ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. `http://anysite.com`์—์„œ ๋ฐ›์•„์˜จ ํŽ˜์ด์ง€๊ฐ€ `http://gmail.com`์—์„œ ๋ฐ›์•„์˜จ ํŽ˜์ด์ง€ ์ƒ์˜ ์ •๋ณด์— ์ ‘๊ทผํ•ด ์ค‘์š”ํ•œ ๊ฐœ์ธ์ •๋ณด๋ฅผ ํ›”์น˜๋Š” ๊ฑธ ๋ง‰๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. - ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•œ ์„œ๋ฒ„์™€ ์‰ฝ๊ฒŒ ์ •๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํƒ€ ์‚ฌ์ดํŠธ๋‚˜ ๋„๋ฉ”์ธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ฑด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค ํ• ์ง€๋ผ๋„ ์›๊ฒฉ ์„œ๋ฒ„์—์„œ ๋ช…ํ™•ํžˆ ์Šน์ธ์„ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค(HTTP ํ—ค๋” ๋“ฑ์„ ์ด์šฉ). ์ด ์—ญ์‹œ ๋ณด์•ˆ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ์ œ์•ฝ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. @@ -94,20 +94,20 @@ ์ด ์™ธ์—๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด ์„œ๋ฒ„๋‚˜ ๋ชจ๋ฐ”์ผ ์•ฑ ๋“ฑ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -## ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ "๋„ˆ๋จธ์˜" ์–ธ์–ด๋“ค +## ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ '๋„ˆ๋จธ์˜' ์–ธ์–ด๋“ค ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์€ ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ์š”๊ตฌ๋ฅผ ์ถฉ์กฑ์‹œํ‚ค์ง„ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋งˆ๋‹ค ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์š”๊ตฌ์‚ฌํ•ญ์ด ์ฒœ์ฐจ๋งŒ๋ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ๋‹น์—ฐํ•œ ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. -์ด๋กœ ์ธํ•ด ๊ทผ๋ž˜์—” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๋˜๊ธฐ ์ „์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ *ํŠธ๋žœ์ŠคํŒŒ์ผ(transpile, ๋ณ€ํ™˜)*ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ์–ธ์–ด๋“ค์ด ๋งŽ์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. +์ด๋กœ ์ธํ•ด ๊ทผ๋ž˜์—” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๋˜๊ธฐ ์ „์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ *ํŠธ๋žœ์ŠคํŒŒ์ผ(transpile, ๋ณ€ํ™˜)* ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ์–ธ์–ด๋“ค์ด ๋งŽ์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. -์ตœ์‹  ํˆด์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋žœ์ŠคํŒŒ์ผ์„ ๋น ๋ฅด๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹ ๋„๊ตฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด์™ธ์˜ ์–ธ์–ด๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ "๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์—์„œ" ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. +์ตœ์‹  ํˆด์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋žœ์ŠคํŒŒ์ผ์„ ๋น ๋ฅด๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹ ๋„๊ตฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด์™ธ์˜ ์–ธ์–ด๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ '๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์—์„œ' ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผ์ด ๊ฐ€๋Šฅํ•œ ์–ธ์–ด ๋ช‡ ๊ฐ€์ง€๋ฅผ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. -- [CoffeeScript](http://coffeescript.org/)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์œ„ํ•œ "syntactic sugar"์ž…๋‹ˆ๋‹ค. ์งง์€ ๋ฌธ๋ฒ•์„ ๋„์ž…ํ•˜์—ฌ ๋ช…๋ฃŒํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Ruby ๊ฐœ๋ฐœ์ž๋“ค์ด ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. -- [TypeScript](http://www.typescriptlang.org/)๋Š” ๊ฐœ๋ฐœ์„ ๋‹จ์ˆœํ™” ํ•˜๊ณ  ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์ง€์›ํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ "์ž๋ฃŒํ˜•์˜ ๋ช…์‹œํ™”(strict data typing)"์— ์ง‘์ค‘ํ•ด ๋งŒ๋“  ์–ธ์–ด์ž…๋‹ˆ๋‹ค. Microsoft๊ฐ€ ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค. +- [CoffeeScript](http://coffeescript.org/)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์œ„ํ•œ 'syntactic sugar'์ž…๋‹ˆ๋‹ค. ์งง์€ ๋ฌธ๋ฒ•์„ ๋„์ž…ํ•˜์—ฌ ๋ช…๋ฃŒํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Ruby ๊ฐœ๋ฐœ์ž๋“ค์ด ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. +- [TypeScript](http://www.typescriptlang.org/)๋Š” ๊ฐœ๋ฐœ์„ ๋‹จ์ˆœํ™” ํ•˜๊ณ  ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์ง€์›ํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ '์ž๋ฃŒํ˜•์˜ ๋ช…์‹œํ™”(strict data typing)'์— ์ง‘์ค‘ํ•ด ๋งŒ๋“  ์–ธ์–ด์ž…๋‹ˆ๋‹ค. Microsoft๊ฐ€ ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค. - [Flow](http://flow.org/) ์—ญ์‹œ ์ž๋ฃŒํ˜•์„ ๊ฐ•์ œํ•˜๋Š”๋ฐ, TypeScript์™€๋Š” ๋‹ค๋ฅธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Facebook์ด ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค. - [Dart](https://www.dartlang.org/)๋Š” ๋ชจ๋ฐ”์ผ ์•ฑ๊ณผ ๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๋Š” ๊ณ ์œ ์˜ ์—”์ง„์„ ๊ฐ€์ง„ ๋…์ž์  ์–ธ์–ด์ž…๋‹ˆ๋‹ค. Google์ด ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค. @@ -116,5 +116,5 @@ ## ์š”์•ฝ - ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์“ธ ๋ชฉ์ ์œผ๋กœ ๊ณ ์•ˆ๋œ ์–ธ์–ด์ด์ง€๋งŒ, ์ง€๊ธˆ์€ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ์“ฐ์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -- ์˜ค๋Š˜๋‚  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์–ธ์–ด๋กœ ์ž๋ฆฌ๋งค๊น€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. HTML/CSS์™€ ์™„์ „ํ•œ ํ†ตํ•ฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ "ํŠธ๋žœ์ŠคํŒŒ์ผ"ํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด๋Š” ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ฐ ์–ธ์–ด๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ฃ . ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ˆ™๋‹ฌํ•œ ๋’ค์— ์ด ์–ธ์–ด๋“ค์„ ์‚ดํŽด๋ณผ ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค. +- ์˜ค๋Š˜๋‚  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์–ธ์–ด๋กœ ์ž๋ฆฌ๋งค๊น€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. HTML/CSS์™€ ์™„์ „ํ•œ ํ†ตํ•ฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ 'ํŠธ๋žœ์ŠคํŒŒ์ผ'ํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด๋Š” ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ฐ ์–ธ์–ด๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ฃ . ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ˆ™๋‹ฌํ•œ ๋’ค์— ์ด ์–ธ์–ด๋“ค์„ ์‚ดํŽด๋ณผ ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค. diff --git a/1-js/01-getting-started/1-intro/limitations.svg b/1-js/01-getting-started/1-intro/limitations.svg index a7863c63cc..76ea43fd7a 100644 --- a/1-js/01-getting-started/1-intro/limitations.svg +++ b/1-js/01-getting-started/1-intro/limitations.svg @@ -1 +1 @@ -https://javascript.info<script> ... </script>https://gmail.comhttps://javascript.info \ No newline at end of file +https://javascript.info<script> ... </script>https://gmail.comhttps://javascript.info \ No newline at end of file diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md index 78bb64d36b..16e0affb2e 100644 --- a/1-js/01-getting-started/2-manuals-specifications/article.md +++ b/1-js/01-getting-started/2-manuals-specifications/article.md @@ -1,19 +1,19 @@ # ๋งค๋‰ด์–ผ๊ณผ ๋ช…์„ธ์„œ -๋ณธ *ํŠœํ† ๋ฆฌ์–ผ*์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋А ์ •๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ต์ˆ™ํ•ด์ง€๋ฉด ํŠœํ† ๋ฆฌ์–ผ ์ด์™ธ์˜ ์ž๋ฃŒ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์ด ์˜ต๋‹ˆ๋‹ค. +๋ณธ *ํŠœํ† ๋ฆฌ์–ผ*์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ๋ณธ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋А ์ •๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ต์ˆ™ํ•ด์ง€๋ฉด ํŠœํ† ๋ฆฌ์–ผ ์ด์™ธ์˜ ์ž๋ฃŒ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์ด ์˜ต๋‹ˆ๋‹ค. ## ๋ช…์„ธ์„œ [ECMA-262 ๋ช…์„ธ์„œ(specification)](https://www.ecma-international.org/publications/standards/Ecma-262.htm)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๊ด€๋ จ๋œ ๊ฐ€์žฅ ์‹ฌ๋„ ์žˆ๊ณ  ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ณต์‹ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. ์ด ๋ช…์„ธ์„œ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ผ๋Š” ์–ธ์–ด๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. -ECMA-262 ๋ช…์„ธ์„œ์˜ ๊ณ ์œ ํ•œ ํ˜•์‹ ๋•Œ๋ฌธ์— ๋ช…์„ธ์„œ๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ์€ ๊ทธ ๋‚ด์šฉ์„ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์‹ ๋ขฐํ• ๋งŒํ•œ ์ž๋ฃŒ์ด๊ธด ํ•˜์ง€๋งŒ ์ผ์ƒ์ ์ธ ์ฐธ๊ณ ์ž๋ฃŒ๋กœ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์ฃ . +ECMA-262 ๋ช…์„ธ์„œ์˜ ๊ณ ์œ ํ•œ ํ˜•์‹ ๋•Œ๋ฌธ์— ๋ช…์„ธ์„œ๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ์€ ๊ทธ ๋‚ด์šฉ์„ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์‹ ๋ขฐํ•  ๋งŒํ•œ ์ž๋ฃŒ์ด๊ธด ํ•˜์ง€๋งŒ ์ผ์ƒ์ ์ธ ์ฐธ๊ณ  ์ž๋ฃŒ๋กœ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์ฃ . ECMA-262๋ช…์„ธ์„œ๋Š” ์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ๋งค๋…„ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฒ„์ „์ด ๋‚˜์˜ค๊ธฐ ์ด์ „์˜ ์ตœ์‹  ์ดˆ์•ˆ์€ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ฐ“ ๋ช…์„ธ์„œ์— ๋“ฑ๋ก๋œ ๊ธฐ๋Šฅ์ด๋‚˜ "๋“ฑ๋ก๋˜๊ธฐ ๋ฐ”๋กœ ์ง์ „"์— ์žˆ๋Š” ๊ธฐ๋Šฅ("์Šคํ…Œ์ด์ง€(stage)3 ์ƒํƒœ์˜ ๊ธฐ๋Šฅ"), ์ œ์•ˆ ๋ชฉ๋ก์€ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฐ“ ๋ช…์„ธ์„œ์— ๋“ฑ๋ก๋œ ๊ธฐ๋Šฅ์ด๋‚˜ '๋“ฑ๋ก๋˜๊ธฐ ๋ฐ”๋กœ ์ง์ „'์— ์žˆ๋Š” ๊ธฐ๋Šฅ(์Šคํ…Œ์ด์ง€(stage)3 ์ƒํƒœ์˜ ๊ธฐ๋Šฅ), ์ œ์•ˆ ๋ชฉ๋ก์€ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋ณธ ํŠœํ† ๋ฆฌ์–ผ์˜ [๋‘ ๋ฒˆ์งธ ๋Œ€ ๋‹จ์›](info:browser-environment)์—์„œ ๋ธŒ๋ผ์šฐ์ €์™€ ๊ด€๋ จ๋œ ๋ช…์„ธ์„œ๋ฅผ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๋ฏ€๋กœ, ๋งŒ์•ฝ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋Œ์•„๊ฐ€๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ํ•ด๋‹น ๋‚ด์šฉ์„ ํ™•์ธํ•ด ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +๋ณธ ํŠœํ† ๋ฆฌ์–ผ์˜ [๋‘ ๋ฒˆ์งธ ๋Œ€ ๋‹จ์›](info:browser-environment)์—์„œ ๋ธŒ๋ผ์šฐ์ €์™€ ๊ด€๋ จ๋œ ๋ช…์„ธ์„œ๋ฅผ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๋ฏ€๋กœ, ๋งŒ์•ฝ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋Œ์•„๊ฐ€๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ํ•ด๋‹น ๋‚ด์šฉ์„ ํ™•์ธํ•ด ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ## ๋งค๋‰ด์–ผ @@ -21,12 +21,7 @@ ECMA-262๋ช…์„ธ์„œ๋Š” ์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ๋งค๋…„ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฒ„์ „์ด ๋งํฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. - ์œ„ ์‚ฌ์ดํŠธ์— ๋“ค์–ด๊ฐ€์„œ ์›ํ•˜๋Š” ๋‚ด์šฉ์„ ์ง์ ‘ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ, ๊ฐ€๋”์€ ๊ฒ€์ƒ‰ ์—”์ง„์„ ์ด์šฉํ•ด ๋‚ด์šฉ์„ ์ฐพ๋Š” ๊ฒŒ ๋” ๋‚˜์„ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Google ๊ฒ€์ƒ‰ ์—”์ง„์— ์ ‘์†ํ•ด "MDN [์›ํ•˜๋Š” ์šฉ์–ด]"๋ฅผ ์ž…๋ ฅํ•ด ๋ด…์‹œ๋‹ค. `parseInt` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ™์ด ๊ฒ€์ƒ‰ํ•˜๋Š” ์‹์œผ๋กœ ๋ง์ด์ฃ . - - -- Microsoft๊ฐ€ ์šด์˜ํ•˜๋Š” **MSDN**๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(ํ•ด๋‹น ์‚ฌ์ดํŠธ์—์„  JScript๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค)์™€ ๊ด€๋ จ๋œ ๊ด‘๋ฒ”์œ„ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ธฐ์— ์ข‹์€ ์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค. Internet Explorer์— ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ์ฐพ๊ณ  ์‹ถ๋‹ค๋ฉด ์— ๋ฐฉ๋ฌธํ•ด ๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. - - ์œ„์—์„œ ์†Œ๊ฐœํ•œ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๊ฒ€์ƒ‰ ์—”์ง„์„ ์ผœ์„œ ๊ฒ€์ƒ‰์–ด์— "MSDN"์„ ๋ถ™์ด๋ฉด ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "RegExp MSDN", "RegExp MSDN jscript" ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . + ์œ„ ์‚ฌ์ดํŠธ์— ๋“ค์–ด๊ฐ€์„œ ์›ํ•˜๋Š” ๋‚ด์šฉ์„ ์ง์ ‘ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ, ๊ฐ€๋”์€ ๊ฒ€์ƒ‰ ์—”์ง„์„ ์ด์šฉํ•ด ๋‚ด์šฉ์„ ์ฐพ๋Š” ๊ฒŒ ๋” ๋‚˜์„ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Google ๊ฒ€์ƒ‰ ์—”์ง„์— ์ ‘์†ํ•ด 'MDN [์›ํ•˜๋Š” ์šฉ์–ด]'๋ฅผ ์ž…๋ ฅํ•ด ๋ด…์‹œ๋‹ค. `parseInt` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ™์ด ๊ฒ€์ƒ‰ํ•˜๋Š” ์‹์œผ๋กœ ๋ง์ด์ฃ . ## ํ˜ธํ™˜์„ฑ ํ‘œ @@ -37,6 +32,6 @@ ECMA-262๋ช…์„ธ์„œ๋Š” ์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ๋งค๋…„ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฒ„์ „์ด - ์—์„  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํŠน์ • ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š”์ง€ (ํ‘œ ํ˜•ํƒœ๋กœ) ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•”ํ˜ธํ™” ๊ด€๋ จ ๊ธฐ๋Šฅ์ธ cryptography๋ฅผ ํŠน์ • ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ ๋ณด๋ ค๋ฉด ๋ฅผ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. - ์—์„  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์žˆ๊ณ , ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ํŠน์ • ์—”์ง„์ด ์ง€์›ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฑฐ๋Œ€ํ•œ ํ‘œ๋ฅผ ํ†ตํ•ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. -์‹ค์ œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์œ„์— ์–ธ๊ธ‰ ๋“œ๋ฆฐ ์ž๋ฃŒ๊ฐ€ ์•„์ฃผ ์œ ์šฉํ•  ๊ฒ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋‚˜ ํ•จ์ˆ˜ ๊ด€๋ จ ์ •๋ณด, ๋ธŒ๋ผ์šฐ์ € ์ง€์› ์—ฌ๋ถ€ ๋“ฑ์€ ์˜์‚ฌ๊ฒฐ์ •์„ ๋‚ด๋ฆด๋•Œ ๊ผญ ํ•„์š”ํ•œ ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์‹ค์ œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์œ„์— ์–ธ๊ธ‰ ๋“œ๋ฆฐ ์ž๋ฃŒ๊ฐ€ ์•„์ฃผ ์œ ์šฉํ•  ๊ฒ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋‚˜ ํ•จ์ˆ˜ ๊ด€๋ จ ์ •๋ณด, ๋ธŒ๋ผ์šฐ์ € ์ง€์› ์—ฌ๋ถ€ ๋“ฑ์€ ์˜์‚ฌ๊ฒฐ์ •์„ ๋‚ด๋ฆด ๋•Œ ๊ผญ ํ•„์š”ํ•œ ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -๋ง์”€๋“œ๋ฆฐ ์‚ฌ์ดํŠธ๋‚˜ ์ด ํŽ˜์ด์ง€๋ฅผ ๊ธฐ์–ตํ•ด ๋†“์•˜๋‹ค๊ฐ€ ํŠน์ • ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๋ฐฉ๋ฌธํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +๋ง์”€๋“œ๋ฆฐ ์‚ฌ์ดํŠธ๋‚˜ ์ด ํŽ˜์ด์ง€๋ฅผ ๊ธฐ์–ตํ•ด ๋†“์•˜๋‹ค๊ฐ€ ํŠน์ • ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๋ฐฉ๋ฌธํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md index 02cc865231..e8ee348f0d 100644 --- a/1-js/01-getting-started/3-code-editors/article.md +++ b/1-js/01-getting-started/3-code-editors/article.md @@ -6,26 +6,26 @@ ## ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ -[ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ](https://en.wikipedia.org/wiki/Integrated_development_environment) (Integrated Development Environment, IDE)์€ ๊ฐ•๋ ฅํ•œ ์—๋””ํ„ฐ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต "ํ”„๋กœ์ ํŠธ ์ „์ฒด"๋ฅผ ๊ด€์žฅํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด IDE๋Š” ๋‹จ์ˆœํ•œ ์—๋””ํ„ฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. "๊ฐœ๋ฐœ ํ™˜๊ฒฝ"์„ ์พŒ์ ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ†ตํ•ฉ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +[ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ](https://en.wikipedia.org/wiki/Integrated_development_environment) (Integrated Development Environment, IDE)์€ ๊ฐ•๋ ฅํ•œ ์—๋””ํ„ฐ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต 'ํ”„๋กœ์ ํŠธ ์ „์ฒด'๋ฅผ ๊ด€์žฅํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด IDE๋Š” ๋‹จ์ˆœํ•œ ์—๋””ํ„ฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. '๊ฐœ๋ฐœ ํ™˜๊ฒฝ'์„ ์พŒ์ ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ†ตํ•ฉ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -IDE๋ฅผ ์ด์šฉํ•˜๋ฉด ์ˆ˜๋งŽ์€ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ํŒŒ์ผ ๊ฐ„์˜ ํƒ์ƒ‰ ์ž‘์—…์ด ์ˆ˜์›”ํ•ด์ง‘๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์—ด๋ ค์žˆ๋Š” ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ํ”„๋กœ์ ํŠธ์— ๊ธฐ๋ฐ˜ํ•œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ [git](https://git-scm.com/)๊ณผ ๊ฐ™์€ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ, ํ…Œ์ŠคํŒ… ํ™˜๊ฒฝ ๋“ฑ, "ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€"์˜ ์ž‘์—…๋„ IDE์—์„œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +IDE๋ฅผ ์ด์šฉํ•˜๋ฉด ์ˆ˜๋งŽ์€ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ํŒŒ์ผ ๊ฐ„์˜ ํƒ์ƒ‰ ์ž‘์—…์ด ์ˆ˜์›”ํ•ด์ง‘๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์—ด๋ ค์žˆ๋Š” ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ํ”„๋กœ์ ํŠธ์— ๊ธฐ๋ฐ˜ํ•œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ [git](https://git-scm.com/)๊ณผ ๊ฐ™์€ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ, ํ…Œ์ŠคํŒ… ํ™˜๊ฒฝ ๋“ฑ, 'ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€'์˜ ์ž‘์—…๋„ IDE์—์„œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„์ง ์–ด๋–ค IDE๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด, ์•„๋ž˜ ๋‘ ์—๋””ํ„ฐ๋ฅผ ๊ณ ๋ คํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +์•„์ง ์–ด๋–ค IDE๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด, ์•„๋ž˜ ๋‘ ์˜ต์…˜์„ ๊ณ ๋ คํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. - [Visual Studio Code](https://code.visualstudio.com/) (ํฌ๋กœ์Šค ํ”Œ๋žซํผ, ๋ฌด๋ฃŒ) - [WebStorm](http://www.jetbrains.com/webstorm/) (ํฌ๋กœ์Šค ํ”Œ๋žซํผ, ์œ ๋ฃŒ) -Windows ์‚ฌ์šฉ์ž๋ผ๋ฉด "Visual Studio"๋ผ๋Š” IDE๋ฅผ ๋“ค์–ด๋ณด์…จ์„ ๊ฒ๋‹ˆ๋‹ค. Visual Studio๋Š” "Visual Studio Code"์™€๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. "Visual Studio"๋Š” .NET ํ”Œ๋žซํผ ๊ฐœ๋ฐœ์— ์“ฐ์ด๋Š” ์œ ๋ฃŒ ์—๋””ํ„ฐ๋กœ, Windows์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Visual Studio์˜ ๋ฌด๋ฃŒ ๋ฒ„์ „์ธ [Visual Studio Community](https://www.visualstudio.com/vs/community/)๋„ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +Windows ์‚ฌ์šฉ์ž๋ผ๋ฉด 'Visual Studio'๋ผ๋Š” IDE๋ฅผ ๋“ค์–ด๋ณด์…จ์„ ๊ฒ๋‹ˆ๋‹ค. Visual Studio๋Š” 'Visual Studio Code'์™€๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. 'Visual Studio'๋Š” .NET ํ”Œ๋žซํผ ๊ฐœ๋ฐœ์— ์“ฐ์ด๋Š” ์œ ๋ฃŒ ์—๋””ํ„ฐ๋กœ, Windows์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Visual Studio์˜ ๋ฌด๋ฃŒ ๋ฒ„์ „์ธ [Visual Studio Community](https://www.visualstudio.com/vs/community/)๋„ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -์ƒ๋‹น์ˆ˜์˜ IDE๊ฐ€ ์œ ๋ฃŒ์ด๊ธด ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž ์—ฐ๋ด‰ ๋Œ€๋น„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์„ ๋งŒํ•œ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ์ฒดํ—˜ ๊ธฐ๊ฐ„์„ ์ด์šฉํ•ด ์ž์‹ ์—๊ฒŒ ๋งž๋Š” IDE๋ฅผ ์ฐพ์•„ ๊ตฌ๋งคํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์œ  ๋“œ๋ฆฝ๋‹ˆ๋‹ค. +์ƒ๋‹น์ˆ˜์˜ IDE๊ฐ€ ์œ ๋ฃŒ์ด๊ธด ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž ์—ฐ๋ด‰ ๋Œ€๋น„ ๋ฌด์‹œํ•  ๋งŒํ•œ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ์ฒดํ—˜ ๊ธฐ๊ฐ„์„ ์ด์šฉํ•ด ์ž์‹ ์—๊ฒŒ ๋งž๋Š” IDE๋ฅผ ์ฐพ์•„ ๊ตฌ๋งคํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์œ  ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ## ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ -"๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ(lightweight editor)"๋Š” IDE๋งŒํผ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง„ ์•Š์ง€๋งŒ, ์†๋„๊ฐ€ ๋น ๋ฅด๊ณ  ๋‹จ์ˆœํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +'๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ(lightweight editor)'๋Š” IDE๋งŒํผ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง„ ์•Š์ง€๋งŒ, ์†๋„๊ฐ€ ๋น ๋ฅด๊ณ  ๋‹จ์ˆœํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ๋Š” ํŒŒ์ผ์„ ์—ด๊ณ  ์ฆ‰์‹œ ์ˆ˜์ •ํ•˜๊ณ ์ž ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ๋Š” ํŒŒ์ผ์„ ์—ด๊ณ  ๋ฐ”๋กœ ์ˆ˜์ •ํ•˜๊ณ ์ž ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -"๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ"์™€ "IDE"์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ IDE๋Š” ํ”„๋กœ์ ํŠธ ๋ ˆ๋ฒจ์—์„œ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. IDE๋Š” ๊ตฌ๋™ ์‹œ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ๊ณ , ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ตฌ๋™ ์‹œ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ๋ถ„์„ํ•˜๋Š” ์ผ ๋“ฑ๋„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค. +'๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ'์™€ 'IDE'์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ IDE๋Š” ํ”„๋กœ์ ํŠธ ๋ ˆ๋ฒจ์—์„œ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. IDE๋Š” ๊ตฌ๋™ ์‹œ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ๊ณ , ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ตฌ๋™ ์‹œ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ๋ถ„์„ํ•˜๋Š” ์ผ ๋“ฑ๋„ ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค. ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ๋Š” ๋‹ค์–‘ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ ˆ๋ฒจ ๋ฌธ๋ฒ• ๋ถ„์„๊ธฐ๋‚˜ ์ž๋™์™„์„ฑ๊ธฐ๋Šฅ ๋“ฑ์„ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ์—์„œ๋„ IDE ๋ชป์ง€์•Š๊ฒŒ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . ์š”์ฆ˜์—” ๊ฒฝ๋Ÿ‰ ์—๋””ํ„ฐ์™€ IDE ์‚ฌ์ด์˜ ์—„๊ฒฉํ•œ ๊ตฌ๋ถ„์ด ์‚ฌ๋ผ์ ธ๊ฐ€๋Š” ์ถ”์„ธ์ž…๋‹ˆ๋‹ค. diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md index 134de20ca9..178866cb38 100644 --- a/1-js/01-getting-started/4-devtools/article.md +++ b/1-js/01-getting-started/4-devtools/article.md @@ -4,9 +4,9 @@ ๊ทธ๋Ÿฐ๋ฐ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋ฆฝํŠธ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ์ด๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ง์ ‘ ๋ณด์—ฌ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€์กฐ์ฐจ ๋ชจ๋ฅด๋ฉด ์—๋Ÿฌ๋ฅผ ๊ณ ์น  ์ˆ˜ ์—†๊ฒ ์ฃ ? -๋ธŒ๋ผ์šฐ์ €์—” "๊ฐœ๋ฐœ์ž ๋„๊ตฌ"๋ผ๋Š” ๊ฒƒ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋ฅผ ์ด์šฉํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ์“ธ๋งŒํ•œ ์ •๋ณด๋„ ์–ป์„ ์ˆ˜ ์žˆ์ฃ . +๋ธŒ๋ผ์šฐ์ €์—” '๊ฐœ๋ฐœ์ž ๋„๊ตฌ'๋ผ๋Š” ๊ฒƒ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋ฅผ ์ด์šฉํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ์“ธ๋งŒํ•œ ์ •๋ณด๋„ ์–ป์„ ์ˆ˜ ์žˆ์ฃ . -๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋Š” Chrome์ด๋‚˜ Firefox๋ฅผ ์ด์šฉํ•ด ๊ฐœ๋ฐœํ•˜๋Š” ๊ฑธ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๊ฐ€ ๊ต‰์žฅํžˆ ํ›Œ๋ฅญํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๊ธฐํƒ€ ๋ธŒ๋ผ์šฐ์ €๋“ค๋„ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋…ํŠนํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ, ๊ฑฐ์˜ Chrome์ด๋‚˜ Firefox ๊ธฐ๋Šฅ์„ "๋”ฐ๋ผ๊ฐ€๋Š”" ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ์ž๋“ค์€ Chrome์ด๋‚˜ Firefox ์ค‘ "์„ ํ˜ธํ•˜๋Š”" ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ•˜๋‚˜ ํƒํ•ด ๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ €์— ์ข…์†๋œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „ํ™˜ํ•ด ๊ฐœ๋ฐœ์„ ์ด์–ด๋‚˜๊ฐ€๊ณค ํ•ฉ๋‹ˆ๋‹ค. +๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋Š” Chrome์ด๋‚˜ Firefox๋ฅผ ์ด์šฉํ•ด ๊ฐœ๋ฐœํ•˜๋Š” ๊ฑธ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๊ฐ€ ๊ต‰์žฅํžˆ ํ›Œ๋ฅญํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๊ธฐํƒ€ ๋ธŒ๋ผ์šฐ์ €๋“ค๋„ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋…ํŠนํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ, ๊ฑฐ์˜ Chrome์ด๋‚˜ Firefox ๊ธฐ๋Šฅ์„ '๋”ฐ๋ผ๊ฐ€๋Š”' ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ์ž๋“ค์€ Chrome์ด๋‚˜ Firefox ์ค‘ '์„ ํ˜ธํ•˜๋Š”' ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ•˜๋‚˜ ํƒํ•ด ๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ €์— ์ข…์†๋œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „ํ™˜ํ•ด ๊ฐœ๋ฐœ์„ ์ด์–ด๋‚˜๊ฐ€๊ณค ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ ํšจ์œจ์ด ์ƒ๋‹นํžˆ ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค. ์ด ์ฑ•ํ„ฐ์—์„  ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์—ด์–ด ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๊ณ , ๋‹ค์–‘ํ•œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ๋ณด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -26,13 +26,18 @@ ํ™”๋ฉด ๊ตฌ์„ฑ์€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” Chrome ๋ฒ„์ „์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ฒ„์ „์ด ๋ฐ”๋€” ๋•Œ ๋งˆ๋‹ค ๊ตฌ์„ฑ์ด ์กฐ๊ธˆ์”ฉ ๋ฐ”๋€Œ๊ธด ํ•˜์ง€๋งŒ ํฐ ํ‹€์€ ๋ฐ”๋€Œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- ๋นจ๊ฐ„์ƒ‰ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณด์ผ ๊ฒ๋‹ˆ๋‹ค. "lalala"๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์•˜๋‹ค(not defined)๋ผ๋Š” ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค. +- ๋นจ๊ฐ„์ƒ‰ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณด์ผ ๊ฒ๋‹ˆ๋‹ค. 'lalala'๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์•˜๋‹ค(not defined)๋ผ๋Š” ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค. - ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์šฐ์ธก์— ๋งํฌ `bug.html:12`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. bug.html์€ ํ•ด๋‹น ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ํŒŒ์ผ, 12๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ค„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์•„๋ž˜์— ํŒŒ๋ž€์ƒ‰ ๊ธฐํ˜ธ `>`๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด ๊ธฐํ˜ธ๊ฐ€ ์žˆ๋Š” ๊ณณ์—” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…๋ น์–ด(command)๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ "์ปค๋งจ๋“œ ๋ผ์ธ(command line)"์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ปค๋งจ๋“œ ๋ผ์ธ์— ๋ช…๋ น์–ด(command)๋ฅผ ์ž…๋ ฅํ•œ ํ›„ `key:Enter`๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ช…๋ น์–ด๋ฅผ ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `key:Shift+Enter`๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š๊ณ  ์ค„ ๋ฐ”๊ฟˆ๋งŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์•„๋ž˜์— ํŒŒ๋ž€์ƒ‰ ๊ธฐํ˜ธ `>`๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด ๊ธฐํ˜ธ๊ฐ€ ์žˆ๋Š” ๊ณณ์—” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…๋ น์–ด(command)๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ '์ปค๋งจ๋“œ ๋ผ์ธ(command line)'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ปค๋งจ๋“œ ๋ผ์ธ์— ๋ช…๋ น์–ด(command)๋ฅผ ์ž…๋ ฅํ•œ ํ›„ `key:Enter`๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ž ์ด์ œ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘์น˜๊ณค ๋‚˜์˜์ง€ ์•Š๋„ค์š”. ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ณ ์น˜๋Š” ๋ฐฉ๋ฒ•(๋””๋ฒ„๊น…)์€ ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +```smart header="Multi-line input" +๋ณดํ†ต์€ ํ•œ์ค„ ์งœ๋ฆฌ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  `key:Enter`๋ฅผ ๋ˆŒ๋Ÿฌ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ž‘์—…์„ ๋งŽ์ด ํ•ฉ๋‹ˆ๋‹ค. + +๋ช…๋ น์–ด๋ฅผ ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `key:Shift+Enter`๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ฉ๋‹ˆ๋‹ค. `key:Shift+Enter`๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š๊ณ  ์ค„ ๋ฐ”๊ฟˆ๋งŒ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ์กฐ๊ฐ์„ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. +``` ## Firefox, Edge ๋ฐ ๊ธฐํƒ€ ๋ธŒ๋ผ์šฐ์ € @@ -42,23 +47,17 @@ ## Safari -Mac ์ „์šฉ ๋ธŒ๋ผ์šฐ์ €์ธ Safari์—์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด "๊ฐœ๋ฐœ์ž ๋ฉ”๋‰ด(Develop menu)"๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +Mac ์ „์šฉ ๋ธŒ๋ผ์šฐ์ €์ธ Safari์—์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด '๊ฐœ๋ฐœ์ž ๋ฉ”๋‰ด(Develop menu)'๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -ํ™˜๊ฒฝ์„ค์ •(Preferences)์˜ "๊ณ ๊ธ‰(Advanced)" ํŒจ๋„์„ ํด๋ฆญํ•œ ํ›„ '๋ฉ”๋‰ด ๋ง‰๋Œ€์—์„œ ๊ฐœ๋ฐœ์ž์šฉ ๋ฉ”๋‰ด ๋ณด๊ธฐ' ์ฒดํฌ ๋ฐ•์Šค๋ฅผ ์ฒดํฌํ•ด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ™œ์„ฑํ™”ํ•ด๋ด…์‹œ๋‹ค. +ํ™˜๊ฒฝ์„ค์ •(Preferences)์˜ '๊ณ ๊ธ‰(Advanced)' ํŒจ๋„์„ ํด๋ฆญํ•œ ํ›„ '๋ฉ”๋‰ด ๋ง‰๋Œ€์—์„œ ๊ฐœ๋ฐœ์ž์šฉ ๋ฉ”๋‰ด ๋ณด๊ธฐ' ์ฒดํฌ ๋ฐ•์Šค๋ฅผ ์ฒดํฌํ•ด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ™œ์„ฑํ™”ํ•ด๋ด…์‹œ๋‹ค. ![safari](safari.png) -์ด์ œ `key:Cmd+Opt+C`๋ฅผ ๋ˆŒ๋Ÿฌ ๊ฐœ๋ฐœ์ž ์ฝ˜์†”์„ ์—ฌ๋‹ซ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Safari ์ƒ๋‹จ์— "๊ฐœ๋ฐœ์ž์šฉ(Develop)" ๋ฉ”๋‰ด๊ฐ€ ์ƒˆ๋กœ ์ƒ๊ธด ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์šฉ ๋ฉ”๋‰ด์—” ๋‹ค์–‘ํ•œ ๋ช…๋ น์–ด์™€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. - -````smart header="์—ฌ๋Ÿฌ ์ค„ ์ž…๋ ฅํ•˜๊ธฐ" -์šฐ๋ฆฌ๋Š” ๋Œ€๋ถ€๋ถ„ ํ•œ ์ค„์งœ๋ฆฌ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  `key:Enter`๋ฅผ ๋ˆŒ๋Ÿฌ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ž‘์—…์„ ๋งŽ์ด ํ•ฉ๋‹ˆ๋‹ค. - -์—ฌ๋Ÿฌ ์ค„ ์งœ๋ฆฌ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `key:Shift+Enter`๋ฅผ ๋ˆ„๋ฅด์„ธ์š”. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ์กฐ๊ฐ์„ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. -```` +์ด์ œ `key:Cmd+Opt+C`๋ฅผ ๋ˆŒ๋Ÿฌ ๊ฐœ๋ฐœ์ž ์ฝ˜์†”์„ ์—ฌ๋‹ซ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Safari ์ƒ๋‹จ์— '๊ฐœ๋ฐœ์ž์šฉ(Develop)' ๋ฉ”๋‰ด๊ฐ€ ์ƒˆ๋กœ ์ƒ๊ธด ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์šฉ ๋ฉ”๋‰ด์—” ๋‹ค์–‘ํ•œ ๋ช…๋ น์–ด์™€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ## ์š”์•ฝ - ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ด์šฉํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๊ณ , ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ๋ณ€์ˆ˜๋ฅผ ๋ถ„์„ํ•ด๋ณด๋Š” ๋“ฑ์˜ ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - Windows ์‚ฌ์šฉ์ž๋Š” `key:F12`๋ฅผ ๋ˆŒ๋Ÿฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Mac ์‚ฌ์šฉ์ž๋Š” Chrome์—์„  `key:Cmd+Opt+J`, Safari์—์„  `key:Cmd+Opt+C`๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ฉ๋‹ˆ๋‹ค. Safari๋Š” ๊ฐœ๋ฐœ์ž ๋ฉ”๋‰ด๋ฅผ ํ™œ์„ฑํ™” ํ•ด ์ค˜์•ผ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด์ œ ํ•™์Šต ํ™˜๊ฒฝ์€ ์ž˜ ๊ฐ–์ถฐ์กŒ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜๋ถ€ํ„ฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•ด ๋ณธ๊ฒฉ์ ์œผ๋กœ ํ•™์Šตํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. \ No newline at end of file +์ด์ œ ํ•™์Šต ํ™˜๊ฒฝ์€ ์ž˜ ๊ฐ–์ถฐ์กŒ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜๋ถ€ํ„ฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•ด ๋ณธ๊ฒฉ์ ์œผ๋กœ ํ•™์Šตํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html new file mode 100644 index 0000000000..ff1d871b08 --- /dev/null +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md index e69de29bb2..81552913b9 100644 --- a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md +++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md @@ -0,0 +1,2 @@ + +[html src="index.html"] diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md index 06de6bfb3b..a242ecef2d 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -4,12 +4,12 @@ ์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ๊ธด ํ•˜์ง€๋งŒ, ํ•™์Šต์„ ์œ„ํ•ด์„  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์€ ์˜จ๋ผ์ธ์œผ๋กœ ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ํ™˜๊ฒฝ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. Node.js์™€ ๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ € ์ด์™ธ์˜ ํ™˜๊ฒฝ์— ์ฃผ๋ ฅํ•˜๋Š” ํ•™์Šต์ž๋ฅผ ์œ„ํ•ด, ๋ธŒ๋ผ์šฐ์ € ํ•œ์ • ๋ช…๋ น์–ด(`alert` ๋“ฑ)๋Š” ์ตœ์†Œํ•œ์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ช…๋ น์–ด๋ฅผ ํ•™์Šตํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ๋ณด๋‚ด์ง€ ์•Š๋„๋ก ๋ง์ด์ฃ . ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” [๋‹ค์Œ ํŒŒํŠธ](/ui)์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -๋จผ์ €, ์›น ํŽ˜์ด์ง€์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. Node.js์™€ ๊ฐ™์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ํ™˜๊ฒฝ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `"node my.js"`์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +๋จผ์ €, ์›น ํŽ˜์ด์ง€์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. ์ฐธ๊ณ ๋กœ Node.js์™€ ๊ฐ™์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ํ™˜๊ฒฝ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `'node my.js'`์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -## "script" ํƒœ๊ทธ +## 'script' ํƒœ๊ทธ -` + ``` ๋ณต์ˆ˜์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ HTML์— ์‚ฝ์ž…ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์Šคํฌ๋ฆฝํŠธ ํƒœ๊ทธ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. @@ -96,11 +96,11 @@ HTML ์•ˆ์— ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์€ ๋Œ€๊ฐœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ๋™์ผํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒˆ๋กœ ๋‹ค์šด๋ฐ›์ง€ ์•Š๊ณ  ์บ์‹œ๋กœ๋ถ€ํ„ฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ํ•œ ๋ฒˆ๋งŒ ๋‹ค์šด๋ฐ›์œผ๋ฉด ๋˜์ฃ . -์ด๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์ด ์ ˆ์•ฝ๋˜๊ณ  ์›น ํŽ˜์ด์ง€์˜ ์‹ค ์†๋„๊ฐ€ ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค. +์ด๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์ด ์ ˆ์•ฝ๋˜๊ณ  ์›น ํŽ˜์ด์ง€์˜ ์‹ค์ œ ์†๋„๊ฐ€ ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค. ``` -````warn header="`src` ์†์„ฑ์ด ์žˆ์œผ๋ฉด, ํƒœ๊ทธ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค." -` + +Function handler is called on this input: +
+ + +

+ +Debounced function debounce(handler, 1000) is called on this input: +
+ + +

+ + + \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md index 4f5867ded9..83e75f3158 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md @@ -1,28 +1,13 @@ ```js demo -function debounce(f, ms) { - - let isCooldown = false; - +function debounce(func, ms) { + let timeout; return function() { - if (isCooldown) return; - - f.apply(this, arguments); - - isCooldown = true; - - setTimeout(() => isCooldown = false, ms); + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, arguments), ms); }; - } -``` - -A call to `debounce` returns a wrapper. There may be two states: -- `isCooldown = false` -- ready to run. -- `isCooldown = true` -- waiting for the timeout. - -In the first call `isCooldown` is falsy, so the call proceeds, and the state changes to `true`. +``` -While `isCooldown` is true, all other calls are ignored. +A call to `debounce` returns a wrapper. When called, it schedules the original function call after given `ms` and cancels the previous such timeout. -Then `setTimeout` reverts it to `false` after the given delay. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 2620f1c712..347a5e64f2 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -4,21 +4,48 @@ importance: 5 # Debounce decorator -The result of `debounce(f, ms)` decorator should be a wrapper that passes the call to `f` at maximum once per `ms` milliseconds. +The result of `debounce(f, ms)` decorator is a wrapper that suspends calls to `f` until there's `ms` milliseconds of inactivity (no calls, "cooldown period"), then invokes `f` once with the latest arguments. -In other words, when we call a "debounced" function, it guarantees that all future calls to the function made less than `ms` milliseconds after the previous call will be ignored. +In other words, `debounce` is like a secretary that accepts "phone calls", and waits until there's `ms` milliseconds of being quiet. And only then it transfers the latest call information to "the boss" (calls the actual `f`). -For instance: +For instance, we had a function `f` and replaced it with `f = debounce(f, 1000)`. -```js no-beautify -let f = debounce(alert, 1000); +Then if the wrapped function is called at 0ms, 200ms and 500ms, and then there are no calls, then the actual `f` will be only called once, at 1500ms. That is: after the cooldown period of 1000ms from the last call. -f(1); // runs immediately -f(2); // ignored +![](debounce.svg) -setTimeout( () => f(3), 100); // ignored ( only 100 ms passed ) -setTimeout( () => f(4), 1100); // runs -setTimeout( () => f(5), 1500); // ignored (less than 1000 ms from the last run) +...And it will get the arguments of the very last call, other calls are ignored. + +Here's the code for it (uses the debounce decorator from the [Lodash library](https://lodash.com/docs/4.17.15#debounce)): + +```js +let f = _.debounce(alert, 1000); + +f("a"); +setTimeout( () => f("b"), 200); +setTimeout( () => f("c"), 500); +// debounced function waits 1000ms after the last call and then runs: alert("c") +``` + +Now a practical example. Let's say, the user types something, and we'd like to send a request to the server when the input is finished. + +There's no point in sending the request for every character typed. Instead we'd like to wait, and then process the whole result. + +In a web-browser, we can setup an event handler -- a function that's called on every change of an input field. Normally, an event handler is called very often, for every typed key. But if we `debounce` it by 1000ms, then it will be only called once, after 1000ms after the last input. + +```online + +In this live example, the handler puts the result into a box below, try it: + +[iframe border=1 src="debounce" height=200] + +See? The second input calls the debounced function, so its content is processed after 1000ms from the last input. ``` -In practice `debounce` is useful for functions that retrieve/update something when we know that nothing new can be done in such a short period of time, so it's better not to waste resources. +So, `debounce` is a great way to process a sequence of events: be it a sequence of key presses, mouse movements or something else. + +It waits the given time after the last call, and then runs its function, that can process the result. + +The task is to implement `debounce` decorator. + +Hint: that's just a few lines if you think about it :) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js index 5339c8d117..e671438f6f 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js @@ -7,8 +7,8 @@ describe("throttle(f, 1000)", function() { } before(function() { - f1000 = throttle(f, 1000); this.clock = sinon.useFakeTimers(); + f1000 = throttle(f, 1000); }); it("the first call runs now", function() { @@ -44,4 +44,20 @@ describe("throttle(f, 1000)", function() { this.clock.restore(); }); -}); \ No newline at end of file +}); + +describe('throttle', () => { + + it('runs a forwarded call once', done => { + let log = ''; + const f = str => log += str; + const f10 = throttle(f, 10); + f10('once'); + + setTimeout(() => { + assert.equal(log, 'once'); + done(); + }, 20); + }); + +}); diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md index c844016d3b..cf851f771f 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md @@ -33,7 +33,7 @@ function throttle(func, ms) { A call to `throttle(func, ms)` returns `wrapper`. 1. During the first call, the `wrapper` just runs `func` and sets the cooldown state (`isThrottled = true`). -2. In this state all calls memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call. -3. ...Then after `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`). And if we had ignored calls, then `wrapper` is executed with last memorized arguments and context. +2. In this state all calls are memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call. +3. After `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`) and, if we had ignored calls, `wrapper` is executed with the last memorized arguments and context. The 3rd step runs not `func`, but `wrapper`, because we not only need to execute `func`, but once again enter the cooldown state and setup the timeout to reset it. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 567c9ce7a1..6df7af1327 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -4,16 +4,21 @@ importance: 5 # Throttle decorator -Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper, passing the call to `f` at maximum once per `ms` milliseconds. Those calls that fall into the "cooldown" period, are ignored. +Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper. -**The difference with `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.** +When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds. + +The difference with debounce is that it's completely different decorator: +- `debounce` runs the function once after the "cooldown" period. Good for processing the final result. +- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often. + +In other words, `throttle` is like a secretary that accepts phone calls, but bothers the boss (calls the actual `f`) not more often than once per `ms` milliseconds. Let's check the real-life application to better understand that requirement and to see where it comes from. **For instance, we want to track mouse movements.** -In browser we can setup a function to run at every mouse movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms). - +In a browser we can setup a function to run at every mouse movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms). **We'd like to update some information on the web-page when the pointer moves.** ...But updating function `update()` is too heavy to do it on every micro-movement. There is also no sense in updating more often than once per 100ms. @@ -31,8 +36,8 @@ A code example: ```js function f(a) { - console.log(a) -}; + console.log(a); +} // f1000 passes calls to f at maximum once per 1000 ms let f1000 = throttle(f, 1000); diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md index 8536cf3142..78b9b05dff 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md @@ -1,21 +1,21 @@ -# Decorators and forwarding, call/apply +# call/apply์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, ํฌ์›Œ๋”ฉ -JavaScript gives exceptional flexibility when dealing with functions. They can be passed around, used as objects, and now we'll see how to *forward* calls between them and *decorate* them. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ํƒ์›”ํ•œ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ์ด๊ณณ์ €๊ณณ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๊ณ , ๊ฐ์ฒด๋กœ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ํ•จ์ˆ˜ ๊ฐ„์— ํ˜ธ์ถœ์„ ์–ด๋–ป๊ฒŒ *ํฌ์›Œ๋”ฉ(forwarding)* ํ•˜๋Š”์ง€, ํ•จ์ˆ˜๋ฅผ ์–ด๋–ป๊ฒŒ *๋ฐ์ฝ”๋ ˆ์ดํŒ…(decorating)* ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -## Transparent caching +## ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ์บ์‹ฑ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•˜๊ธฐ -Let's say we have a function `slow(x)` which is CPU-heavy, but its results are stable. In other words, for the same `x` it always returns the same result. +CPU๋ฅผ ๋งŽ์ด ์žก์•„๋จน์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” ์•ˆ์ •์ ์ธ ํ•จ์ˆ˜ `slow(x)`๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ ์•ˆ์ •์ ์ด๋ผ๋Š” ๋ง์€ `x`๊ฐ€ ๊ฐ™์œผ๋ฉด ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋„ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -If the function is called often, we may want to cache (remember) the results to avoid spending extra-time on recalculations. +`slow(x)`๊ฐ€ ์ž์ฃผ ํ˜ธ์ถœ๋œ๋‹ค๋ฉด, ๊ฒฐ๊ณผ๋ฅผ ์–ด๋”˜๊ฐ€์— ์ €์žฅ(์บ์‹ฑ)ํ•ด ์žฌ์—ฐ์‚ฐ์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ค„์ด๊ณ  ์‹ถ์„ ๊ฒ๋‹ˆ๋‹ค. -But instead of adding that functionality into `slow()` we'll create a wrapper function, that adds caching. As we'll see, there are many benefits of doing so. +์•„๋ž˜ ์˜ˆ์‹œ์—์„  `slow()` ์•ˆ์— ์บ์‹ฑ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹ , ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ณง ์ •๋ฆฌํ•˜๊ฒ ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋ฉด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -Here's the code, and explanations follow: +์ฝ”๋“œ๋ฅผ ๋จผ์ € ์‚ดํŽด๋ด…์‹œ๋‹ค. ์„ค๋ช…์€ ์•„๋ž˜์ชฝ์— ์ ์–ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ```js run function slow(x) { - // there can be a heavy CPU-intensive job here - alert(`Called with ${x}`); + // CPU ์ง‘์•ฝ์ ์ธ ์ž‘์—…์ด ์—ฌ๊ธฐ์— ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + alert(`slow(${x})์„/๋ฅผ ํ˜ธ์ถœํ•จ`); return x; } @@ -23,65 +23,65 @@ function cachingDecorator(func) { let cache = new Map(); return function(x) { - if (cache.has(x)) { // if there's such key in cache - return cache.get(x); // read the result from it + if (cache.has(x)) { // cache์— ํ•ด๋‹น ํ‚ค๊ฐ€ ์žˆ์œผ๋ฉด + return cache.get(x); // ๋Œ€์‘ํ•˜๋Š” ๊ฐ’์„ cache์—์„œ ์ฝ์–ด์˜ต๋‹ˆ๋‹ค. } - let result = func(x); // otherwise call func + let result = func(x); // ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—” func๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , - cache.set(x, result); // and cache (remember) the result + cache.set(x, result); // ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑ(์ €์žฅ)ํ•ฉ๋‹ˆ๋‹ค. return result; }; } slow = cachingDecorator(slow); -alert( slow(1) ); // slow(1) is cached -alert( "Again: " + slow(1) ); // the same +alert( slow(1) ); // slow(1)์ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +alert( "๋‹ค์‹œ ํ˜ธ์ถœ: " + slow(1) ); // ๋™์ผํ•œ ๊ฒฐ๊ณผ -alert( slow(2) ); // slow(2) is cached -alert( "Again: " + slow(2) ); // the same as the previous line +alert( slow(2) ); // slow(2)๊ฐ€ ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +alert( "๋‹ค์‹œ ํ˜ธ์ถœ: " + slow(2) ); // ์œ—์ค„๊ณผ ๋™์ผํ•œ ๊ฒฐ๊ณผ ``` -In the code above `cachingDecorator` is a *decorator*: a special function that takes another function and alters its behavior. +`cachingDecorator`๊ฐ™์ด ์ธ์ˆ˜๋กœ ๋ฐ›์€ ํ•จ์ˆ˜์˜ ํ–‰๋™์„ ๋ณ€๊ฒฝ์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ *๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(decorator)* ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -The idea is that we can call `cachingDecorator` for any function, and it will return the caching wrapper. That's great, because we can have many functions that could use such a feature, and all we need to do is to apply `cachingDecorator` to them. +๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋Œ€์ƒ์œผ๋กœ `cachingDecorator`๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์€ ์บ์‹ฑ ๋ž˜ํผ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜์— `cachingDecorator`๋ฅผ ์ ์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์บ์‹ฑ์ด ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜๋ฅผ ์›ํ•˜๋Š” ๋งŒํผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋Š” ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -By separating caching from the main function code we also keep the main code simpler. +์บ์‹ฑ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜ ์ฝ”๋“œ์™€ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -The result of `cachingDecorator(func)` is a "wrapper": `function(x)` that "wraps" the call of `func(x)` into caching logic: +์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด `cachingDecorator(func)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด '๋ž˜ํผ(wrapper)', `function(x)`์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๋ž˜ํผ `function(x)`๋Š” `func(x)`์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑ ๋กœ์ง์œผ๋กœ ๊ฐ์Œ‰๋‹ˆ๋‹ค(wrapping). ![](decorator-makecaching-wrapper.svg) -From an outside code, the wrapped `slow` function still does the same. It just got a caching aspect added to its behavior. +๋ฐ”๊นฅ ์ฝ”๋“œ์—์„œ ๋ดค์„ ๋•Œ, ํ•จ์ˆ˜ `slow`๋Š” ๋ž˜ํผ๋กœ ๊ฐ์‹ผ ์ด์ „์ด๋‚˜ ์ดํ›„๋‚˜ ๋™์ผํ•œ ์ผ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ–‰๋™ ์–‘์‹์— ์บ์‹ฑ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. -To summarize, there are several benefits of using a separate `cachingDecorator` instead of altering the code of `slow` itself: +`slow` ๋ณธ๋ฌธ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค ๋…๋ฆฝ๋œ ๋ž˜ํผ ํ•จ์ˆ˜ `cachingDecorator`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ƒ๊ธฐ๋Š” ์ด์ ์„ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- The `cachingDecorator` is reusable. We can apply it to another function. -- The caching logic is separate, it did not increase the complexity of `slow` itself (if there was any). -- We can combine multiple decorators if needed (other decorators will follow). +- `cachingDecorator`๋ฅผ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ํ•จ์ˆ˜ ์–ด๋””์—๋“  `cachingDecorator`๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ์บ์‹ฑ ๋กœ์ง์ด ๋ถ„๋ฆฌ๋˜์–ด `slow` ์ž์ฒด์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- ํ•„์š”ํ•˜๋‹ค๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(์ถ”๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” `cachingDecorator` ๋’ค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค). -## Using "func.call" for the context +## 'func.call'๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ ์ง€์ •ํ•˜๊ธฐ -The caching decorator mentioned above is not suited to work with object methods. +์œ„์—์„œ ๊ตฌํ˜„ํ•œ ์บ์‹ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์— ์‚ฌ์šฉํ•˜๊ธฐ์—” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -For instance, in the code below `worker.slow()` stops working after the decoration: +๊ฐ์ฒด ๋ฉ”์„œ๋“œ `worker.slow()`๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ ํ›„ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์ฃ . ```js run -// we'll make worker.slow caching +// worker.slow์— ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด๋ด…์‹œ๋‹ค. let worker = { someMethod() { return 1; }, slow(x) { - // actually, there can be a scary CPU-heavy task here - alert("Called with " + x); + // CPU ์ง‘์•ฝ์ ์ธ ์ž‘์—…์ด๋ผ ๊ฐ€์ • + alert(`slow(${x})์„/๋ฅผ ํ˜ธ์ถœํ•จ`); return x * this.someMethod(); // (*) } }; -// same code as before +// ์ด์ „๊ณผ ๋™์ผํ•œ ์ฝ”๋“œ function cachingDecorator(func) { let cache = new Map(); return function(x) { @@ -96,49 +96,49 @@ function cachingDecorator(func) { }; } -alert( worker.slow(1) ); // the original method works +alert( worker.slow(1) ); // ๊ธฐ์กด ๋ฉ”์„œ๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -worker.slow = cachingDecorator(worker.slow); // now make it caching +worker.slow = cachingDecorator(worker.slow); // ์บ์‹ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ *!* -alert( worker.slow(2) ); // Whoops! Error: Cannot read property 'someMethod' of undefined +alert( worker.slow(2) ); // ์—๋Ÿฌ ๋ฐœ์ƒ!, Error: Cannot read property 'someMethod' of undefined */!* ``` -The error occurs in the line `(*)` that tries to access `this.someMethod` and fails. Can you see why? +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `this.someMethod` ์ ‘๊ทผ์— ์‹คํŒจํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. -The reason is that the wrapper calls the original function as `func(x)` in the line `(**)`. And, when called like that, the function gets `this = undefined`. +์›์ธ์€ `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ๋ž˜ํผ๊ฐ€ ๊ธฐ์กด ํ•จ์ˆ˜ `func(x)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `this`๊ฐ€ `undefined`๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -We would observe a similar symptom if we tried to run: +์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋„ ๋น„์Šทํ•œ ์ฆ์ƒ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ```js let func = worker.slow; func(2); ``` -So, the wrapper passes the call to the original method, but without the context `this`. Hence the error. +๋ž˜ํผ๊ฐ€ ๊ธฐ์กด ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ „๋‹ฌํ•˜๋ ค ํ–ˆ์ง€๋งŒ `this`์˜ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‚ฌ๋ผ์กŒ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด์ฃ . -Let's fix it. +์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด ๋ด…์‹œ๋‹ค. -There's a special built-in function method [func.call(context, ...args)](mdn:js/Function/call) that allows to call a function explicitly setting `this`. +๋จผ์ €, `this`๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๊ณ ์ •ํ•ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŠน๋ณ„ํ•œ ๋‚ด์žฅ ํ•จ์ˆ˜ ๋ฉ”์„œ๋“œ [func.call(context, ...args)](mdn:js/Function/call)์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. -The syntax is: +๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js func.call(context, arg1, arg2, ...) ``` -It runs `func` providing the first argument as `this`, and the next as the arguments. +๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ `this`, ์ด์–ด์ง€๋Š” ์ธ์ˆ˜๊ฐ€ `func`์˜ ์ธ์ˆ˜๊ฐ€ ๋œ ํ›„, `func`์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -To put it simply, these two calls do almost the same: +์•„๋ž˜ ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฑฐ์˜ ๋™์ผํ•œ ์ผ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ```js func(1, 2, 3); func.call(obj, 1, 2, 3) ``` -They both call `func` with arguments `1`, `2` and `3`. The only difference is that `func.call` also sets `this` to `obj`. +๋‘˜ ๋‹ค ์ธ์ˆ˜๋กœ `1`, `2`, `3`์„ ๋ฐ›์ฃ . ์œ ์ผํ•œ ์ฐจ์ด์ ์€ `func.call`์—์„  `this`๊ฐ€ `obj`๋กœ ๊ณ ์ •๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. -As an example, in the code below we call `sayHi` in the context of different objects: `sayHi.call(user)` runs `sayHi` providing `this=user`, and the next line sets `this=admin`: +๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ(๋‹ค๋ฅธ ๊ฐ์ฒด) ํ•˜์— `sayHi`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. `sayHi.call(user)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `sayHi`์˜ ์ปจํ…์ŠคํŠธ๊ฐ€ `this=user`๋กœ, `sayHi.call(admin)`์„ ํ˜ธ์ถœํ•˜๋ฉด `sayHi`์˜ ์ปจํ…์ŠคํŠธ๊ฐ€ `this=admin`๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ```js run function sayHi() { @@ -148,12 +148,12 @@ function sayHi() { let user = { name: "John" }; let admin = { name: "Admin" }; -// use call to pass different objects as "this" +// call์„ ์‚ฌ์šฉํ•ด ์›ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ 'this'๊ฐ€ ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. sayHi.call( user ); // this = John sayHi.call( admin ); // this = Admin ``` -And here we use `call` to call `say` with the given context and phrase: +์•„๋ž˜ ์˜ˆ์‹œ์—์„  `call`์„ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ์™€ `phrase`์— ์›ํ•˜๋Š” ๊ฐ’์„ ์ง€์ •ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ```js run @@ -163,11 +163,11 @@ function say(phrase) { let user = { name: "John" }; -// user becomes this, and "Hello" becomes the first argument +// this์—” user๊ฐ€ ๊ณ ์ •๋˜๊ณ , "Hello"๋Š” ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. say.call( user, "Hello" ); // John: Hello ``` -In our case, we can use `call` in the wrapper to pass the context to the original function: +๋ž˜ํผ ์•ˆ์—์„œ `call`์„ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ๋ฅผ ์›๋ณธ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js run let worker = { @@ -176,7 +176,7 @@ let worker = { }, slow(x) { - alert("Called with " + x); + alert(`slow(${x})์„/๋ฅผ ํ˜ธ์ถœํ•จ`); return x * this.someMethod(); // (*) } }; @@ -188,62 +188,62 @@ function cachingDecorator(func) { return cache.get(x); } *!* - let result = func.call(this, x); // "this" is passed correctly now + let result = func.call(this, x); // ์ด์   'this'๊ฐ€ ์ œ๋Œ€๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. */!* cache.set(x, result); return result; }; } -worker.slow = cachingDecorator(worker.slow); // now make it caching +worker.slow = cachingDecorator(worker.slow); // ์บ์‹ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ -alert( worker.slow(2) ); // works -alert( worker.slow(2) ); // works, doesn't call the original (cached) +alert( worker.slow(2) ); // ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +alert( worker.slow(2) ); // ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ์›๋ณธ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ  ์บ์‹œ ๋œ ๊ฐ’์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ``` -Now everything is fine. +์ด์ œ ์—๋Ÿฌ ์—†์ด ๋ชจ๋“  ๊ฒŒ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -To make it all clear, let's see more deeply how `this` is passed along: +๋ช…ํ™•ํ•œ ์ดํ•ด๋ฅผ ์œ„ํ•ด `this`๊ฐ€ ์–ด๋–ค ๊ณผ์ •์„ ๊ฑฐ์ณ ์ „๋‹ฌ๋˜๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -1. After the decoration `worker.slow` is now the wrapper `function (x) { ... }`. -2. So when `worker.slow(2)` is executed, the wrapper gets `2` as an argument and `this=worker` (it's the object before dot). -3. Inside the wrapper, assuming the result is not yet cached, `func.call(this, x)` passes the current `this` (`=worker`) and the current argument (`=2`) to the original method. +1. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•œ ํ›„์— `worker.slow`๋Š” ๋ž˜ํผ `function (x) { ... }`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +2. `worker.slow(2)`๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ž˜ํผ๋Š” `2`๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๊ณ , `this=worker`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค(์  ์•ž์˜ ๊ฐ์ฒด). +3. ๊ฒฐ๊ณผ๊ฐ€ ์บ์‹œ๋˜์ง€ ์•Š์€ ์ƒํ™ฉ์ด๋ผ๋ฉด `func.call(this, x)`์—์„œ ํ˜„์žฌ `this` (`=worker`)์™€ ์ธ์ˆ˜(`=2`)๋ฅผ ์›๋ณธ ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. -## Going multi-argument with "func.apply" +## ์—ฌ๋Ÿฌ ์ธ์ˆ˜ ์ „๋‹ฌํ•˜๊ธฐ -Now let's make `cachingDecorator` even more universal. Till now it was working only with single-argument functions. +`cachingDecorator`๋ฅผ ์ข€ ๋” ๋‹ค์ฑ„๋กญ๊ฒŒ ํ•ด๋ด…์‹œ๋‹ค. ์ง€๊ธˆ ์ƒํƒœ๋ก  ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜๋ฟ์ธ ํ•จ์ˆ˜์—๋งŒ `cachingDecorator`๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Now how to cache the multi-argument `worker.slow` method? +๋ณต์ˆ˜ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง„ ๋ฉ”์„œ๋“œ, `worker.slow`๋ฅผ ์บ์‹ฑํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ์ง€ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค. ```js let worker = { slow(min, max) { - return min + max; // scary CPU-hogger is assumed + return min + max; // CPU๋ฅผ ์•„์ฃผ ๋งŽ์ด ์“ฐ๋Š” ์ž‘์—…์ด๋ผ๊ณ  ๊ฐ€์ • } }; -// should remember same-argument calls +// ๋™์ผํ•œ ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. worker.slow = cachingDecorator(worker.slow); ``` -Previously, for a single argument `x` we could just `cache.set(x, result)` to save the result and `cache.get(x)` to retrieve it. But now we need to remember the result for a *combination of arguments* `(min,max)`. The native `Map` takes single value only as the key. +์ง€๊ธˆ๊นŒ์ง„ ์ธ์ˆ˜๊ฐ€ `x` ํ•˜๋‚˜๋ฟ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— `cache.set(x, result)`์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ  `cache.get(x)`์œผ๋กœ ์ €์žฅ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด ๋์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด์ œ๋ถ€ํ„ด `(min,max)`๊ฐ™์ด *์ธ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ*์ด๊ณ , ์ด ์ธ์ˆ˜๋“ค์„ ๋„˜๊ฒจ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ `๋งต`์€ ๋‹จ์ผ ํ‚ค๋งŒ ๋ฐ›์ง€๋งŒ ๋ง์ด์ฃ . -There are many solutions possible: +ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. -1. Implement a new (or use a third-party) map-like data structure that is more versatile and allows multi-keys. -2. Use nested maps: `cache.set(min)` will be a `Map` that stores the pair `(max, result)`. So we can get `result` as `cache.get(min).get(max)`. -3. Join two values into one. In our particular case we can just use a string `"min,max"` as the `Map` key. For flexibility, we can allow to provide a *hashing function* for the decorator, that knows how to make one value from many. +1. ๋ณต์ˆ˜ ํ‚ค๋ฅผ ์ง€์›ํ•˜๋Š” ๋งต๊ณผ ์œ ์‚ฌํ•œ ์ž๋ฃŒ ๊ตฌ์กฐ ๊ตฌํ˜„ํ•˜๊ธฐ(์„œ๋“œ ํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์„ ์‚ฌ์šฉํ•ด๋„ ๋จ) +2. ์ค‘์ฒฉ ๋งต์„ ์‚ฌ์šฉํ•˜๊ธฐ. `(max, result)` ์Œ ์ €์žฅ์€ `cache.set(min)`์œผ๋กœ, `result`๋Š” `cache.get(min).get(max)`์„ ์‚ฌ์šฉํ•ด ์–ป์Šต๋‹ˆ๋‹ค. +3. ๋‘ ๊ฐ’์„ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๊ธฐ. `๋งต`์˜ ํ‚ค๋กœ ๋ฌธ์ž์—ด `"min,max"`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐ’์„ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๋Š” ์ฝ”๋“œ๋Š” *ํ•ด์‹ฑ ํ•จ์ˆ˜(hashing function)* ์— ๊ตฌํ˜„ํ•ด ์œ ์—ฐ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. -For many practical applications, the 3rd variant is good enough, so we'll stick to it. +์„ธ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -Also we need to replace `func.call(this, x)` with `func.call(this, ...arguments)`, to pass all arguments to the wrapped function call, not just the first one. +์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ `func.call(this, x)`๋ฅผ `func.call(this, ...arguments)`๋กœ ๊ต์ฒดํ•ด, ๋ž˜ํผ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ผ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๋ณต์ˆ˜ ์ธ์ˆ˜ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -Here's a more powerful `cachingDecorator`: +๋” ๊ฐ•๋ ฅํ•ด์ง„ `cachingDecorator`๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run let worker = { slow(min, max) { - alert(`Called with ${min},${max}`); + alert(`slow(${min},${max})์„/๋ฅผ ํ˜ธ์ถœํ•จ`); return min + max; } }; @@ -273,48 +273,50 @@ function hash(args) { worker.slow = cachingDecorator(worker.slow, hash); -alert( worker.slow(3, 5) ); // works -alert( "Again " + worker.slow(3, 5) ); // same (cached) +alert( worker.slow(3, 5) ); // ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +alert( "๋‹ค์‹œ ํ˜ธ์ถœ: " + worker.slow(3, 5) ); // ๋™์ผํ•œ ๊ฒฐ๊ณผ ์ถœ๋ ฅ(์บ์‹œ๋œ ๊ฒฐ๊ณผ) ``` -Now it works with any number of arguments (though the hash function would also need to be adjusted to allow any number of arguments. An interesting way to handle this will be covered below). +์ด์ œ ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜์— ๊ด€๊ณ„์—†์ด ๋ž˜ํผ๊ฐ€ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ•ด์‹œ ํ•จ์ˆ˜๊ฐ€ ๋ณต์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์ž์œ ์ž์žฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •์„ ํ•ด์•ผ ํ•˜๊ธด ํ•˜์ง€๋งŒ ๋ง์ด์ฃ . ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํฅ๋ฏธ๋กœ์šด ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์—์„œ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. -There are two changes: +๊ฐœ์„  ํ›„, ๋ฐ”๋€ ๊ฒƒ์€ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. -- In the line `(*)` it calls `hash` to create a single key from `arguments`. Here we use a simple "joining" function that turns arguments `(3, 5)` into the key `"3,5"`. More complex cases may require other hashing functions. -- Then `(**)` uses `func.call(this, ...arguments)` to pass both the context and all arguments the wrapper got (not just the first one) to the original function. +- `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `hash`๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ `arguments`๋ฅผ ์‚ฌ์šฉํ•œ ๋‹จ์ผ ํ‚ค๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„  ๊ฐ„๋‹จํ•œ '๊ฒฐํ•ฉ' ํ•จ์ˆ˜๋กœ ์ธ์ˆ˜ `(3, 5)`๋ฅผ ํ‚ค `"3,5"`๋กœ ๋ฐ”๊ฟจ๋Š”๋ฐ, ์ข€ ๋” ๋ณต์žกํ•œ ๊ฒฝ์šฐ๋ผ๋ฉด ๋˜ ๋‹ค๋ฅธ ํ•ด์‹ฑ ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„  `func.call(this, ...arguments)`๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ(`this`)์™€ ๋ž˜ํผ๊ฐ€ ๊ฐ€์ง„ ์ธ์ˆ˜ ์ „๋ถ€(`...arguments`)๋ฅผ ๊ธฐ์กด ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. -Instead of `func.call(this, ...arguments)` we could use `func.apply(this, arguments)`. +## func.apply -The syntax of built-in method [func.apply](mdn:js/Function/apply) is: +๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ `func.call(this, ...arguments)` ๋Œ€์‹ , `func.apply(this, arguments)`๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. + +๋‚ด์žฅ ๋ฉ”์„œ๋“œ [func.apply](mdn:js/Function/apply)์˜ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js func.apply(context, args) ``` -It runs the `func` setting `this=context` and using an array-like object `args` as the list of arguments. +`apply`๋Š” `func`์˜ `this`๋ฅผ `context`๋กœ ๊ณ ์ •ํ•ด์ฃผ๊ณ , ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ธ `args`๋ฅผ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -The only syntax difference between `call` and `apply` is that `call` expects a list of arguments, while `apply` takes an array-like object with them. +`call`๊ณผ `apply`์˜ ๋ฌธ๋ฒ•์  ์ฐจ์ด๋Š” `call`์ด ๋ณต์ˆ˜ ์ธ์ˆ˜๋ฅผ ๋”ฐ๋กœ๋”ฐ๋กœ ๋ฐ›๋Š” ๋Œ€์‹  `apply`๋Š” ์ธ์ˆ˜๋ฅผ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋กœ ๋ฐ›๋Š”๋‹ค๋Š” ์ ๋ฟ์ž…๋‹ˆ๋‹ค. -So these two calls are almost equivalent: +๋”ฐ๋ผ์„œ ์•„๋ž˜ ์ฝ”๋“œ ๋‘ ์ค„์€ ๊ฑฐ์˜ ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ```js -func.call(context, ...args); // pass an array as list with spread operator -func.apply(context, args); // is same as using apply +func.call(context, ...args); // ์ „๊ฐœ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ์ธ์ˆ˜๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ +func.apply(context, args); // call์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ``` -There's only a minor difference: +๊ทธ๋Ÿฐ๋ฐ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค. -- The spread operator `...` allows to pass *iterable* `args` as the list to `call`. -- The `apply` accepts only *array-like* `args`. +- ์ „๊ฐœ ๊ตฌ๋ฌธ `...`์€ *์ดํ„ฐ๋Ÿฌ๋ธ”* `args`์„ ๋ถ„ํ•ด ํ•ด `call`์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. +- `apply`๋Š” ์˜ค์ง *์œ ์‚ฌ ๋ฐฐ์—ด* ํ˜•ํƒœ์˜ `args`๋งŒ ๋ฐ›์Šต๋‹ˆ๋‹ค. -So, these calls complement each other. Where we expect an iterable, `call` works, where we expect an array-like, `apply` works. +์ด ์ฐจ์ด๋งŒ ๋นผ๋ฉด ๋‘ ๋ฉ”์„œ๋“œ๋Š” ์™„์ „ํžˆ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์ดํ„ฐ๋Ÿฌ๋ธ” ํ˜•ํƒœ๋ผ๋ฉด `call`์„, ์œ ์‚ฌ ๋ฐฐ์—ด ํ˜•ํƒœ๋ผ๋ฉด `apply`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -And for objects that are both iterable and array-like, like a real array, we technically could use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better. +๋ฐฐ์—ด๊ฐ™์ด ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์œ ์‚ฌ ๋ฐฐ์—ด์ธ ๊ฐ์ฒด์—” ๋‘˜ ๋‹ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ๋‚ด๋ถ€์—์„œ `apply`๋ฅผ ์ตœ์ ํ™” ํ•˜๊ธฐ ๋•Œ๋ฌธ์— `apply`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ข€ ๋” ๋น ๋ฅด๊ธด ํ•ฉ๋‹ˆ๋‹ค. -Passing all arguments along with the context to another function is called *call forwarding*. +์ด๋ ‡๊ฒŒ ์ปจํ…์ŠคํŠธ์™€ ํ•จ๊ป˜ ์ธ์ˆ˜ ์ „์ฒด๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ *์ฝœ ํฌ์›Œ๋”ฉ(call forwarding)* ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. -That's the simplest form of it: +๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ ์ฝœ ํฌ์›Œ๋”ฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let wrapper = function() { @@ -322,11 +324,11 @@ let wrapper = function() { }; ``` -When an external code calls such `wrapper`, it is indistinguishable from the call of the original function `func`. +์ด๋Ÿฐ ์‹์œผ๋กœ ์™ธ๋ถ€์—์„œ `wrapper`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๊ธฐ์กด ํ•จ์ˆ˜์ธ `func`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -## Borrowing a method [#method-borrowing] +## ๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ [#method-borrowing] -Now let's make one more minor improvement in the hashing function: +์œ„์—์„œ ๊ตฌํ˜„ํ•œ ํ•ด์‹ฑ ํ•จ์ˆ˜๋ฅผ ๊ฐœ์„ ํ•ด๋ด…์‹œ๋‹ค. ```js function hash(args) { @@ -334,9 +336,9 @@ function hash(args) { } ``` -As of now, it works only on two arguments. It would be better if it could glue any number of `args`. +์ง€๊ธˆ ์ƒํƒœ์—์„  ์ธ์ˆ˜ ๋‘ ๊ฐœ๋งŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `args`์˜ ์š”์†Œ ๊ฐœ์ˆ˜์— ์ƒ๊ด€์—†์ด ์š”์†Œ๋“ค์„ ํ•ฉ์น  ์ˆ˜ ์žˆ์œผ๋ฉด ๋” ์ข‹๊ฒ ๋„ค์š”. -The natural solution would be to use [arr.join](mdn:js/Array/join) method: +๊ฐ€์žฅ ์ž์—ฐ์Šค๋Ÿฌ์šด ํ•ด๊ฒฐ์ฑ…์€ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ [arr.join](mdn:js/Array/join)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ```js function hash(args) { @@ -344,9 +346,9 @@ function hash(args) { } ``` -...Unfortunately, that won't work. Because we are calling `hash(arguments)` and `arguments` object is both iterable and array-like, but not a real array. +๊ทธ๋Ÿฐ๋ฐ ์•„์‰ฝ๊ฒŒ๋„ ์ด ๋ฐฉ๋ฒ•์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `hash(arguments)`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋Š” `arguments`๋Š” ์ง„์งœ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๊ณ  ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋‚˜ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -So calling `join` on it would fail, as we can see below: +๋ฐฐ์—ด์ด ์•„๋‹Œ ๊ฒƒ์— `join`์„ ํ˜ธ์ถœํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ```js run function hash() { @@ -358,7 +360,7 @@ function hash() { hash(1, 2); ``` -Still, there's an easy way to use array join: +๊ทธ๋Ÿฐ๋ฐ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ `join`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run function hash() { @@ -372,46 +374,46 @@ hash(1, 2); The trick is called *method borrowing*. -We take (borrow) a join method from a regular array `[].join`. And use `[].join.call` to run it in the context of `arguments`. +์ผ๋ฐ˜ ๋ฐฐ์—ด์—์„œ `join` ๋ฉ”์„œ๋“œ๋ฅผ ๋นŒ๋ ค์˜ค๊ณ (`[].join`), `[].join.call`๋ฅผ ์‚ฌ์šฉํ•ด `arguments`๋ฅผ ์ปจํ…์ŠคํŠธ๋กœ ๊ณ ์ •ํ•œ ํ›„ `join`๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด์ฃ . -Why does it work? +์ด๊ฒŒ ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”? -That's because the internal algorithm of the native method `arr.join(glue)` is very simple. +๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์„œ๋“œ `arr.join(glue)`์˜ ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -Taken from the specification almost "as-is": +์ŠคํŽ™์„ '๊ทธ๋Œ€๋กœ' ์ฐจ์šฉํ•ด ์„ค๋ช…ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -1. Let `glue` be the first argument or, if no arguments, then a comma `","`. -2. Let `result` be an empty string. -3. Append `this[0]` to `result`. -4. Append `glue` and `this[1]`. -5. Append `glue` and `this[2]`. -6. ...Do so until `this.length` items are glued. -7. Return `result`. +1. `glue`๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด `","`๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +2. `result`๋Š” ๋นˆ ๋ฌธ์ž์—ด์ด ๋˜๋„๋ก ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. +3. `this[0]`์„ `result`์— ๋ง๋ถ™์ž…๋‹ˆ๋‹ค. +4. `glue`์™€ `this[1]`๋ฅผ `result`์— ๋ง๋ถ™์ž…๋‹ˆ๋‹ค. +5. `glue`์™€ `this[2]`๋ฅผ `result`์— ๋ง๋ถ™์ž…๋‹ˆ๋‹ค. +6. `this.length`๊ฐœ์˜ ํ•ญ๋ชฉ์ด ๋ชจ๋‘ ์ถ”๊ฐ€๋  ๋•Œ๊นŒ์ง€ ์ด ์ผ์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. +7. `result`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -So, technically it takes `this` and joins `this[0]`, `this[1]` ...etc together. It's intentionally written in a way that allows any array-like `this` (not a coincidence, many methods follow this practice). That's why it also works with `this=arguments`. +๊ธฐ์กด์— `call`์„ ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ์‹์ฒ˜๋Ÿผ `this`๋ฅผ ๋ฐ›๊ณ  `this[0]`, `this[1]` ๋“ฑ์ด ํ•ฉ์ณ์ง‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๊ตฌํ˜„๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ์œ ์‚ฌ ๋ฐฐ์—ด์ด๋“  `this`๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ๋‹น์ˆ˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋Ÿฐ ๊ด€์Šต์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์ฃ . `this`์— `arguments`๊ฐ€ ํ• ๋‹น๋˜๋”๋ผ๋„ ์ž˜ ๋™์ž‘ํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -## Decorators and function properties +## ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ -It is generally safe to replace a function or a method with a decorated one, except for one little thing. If the original function had properties on it, like `func.calledCount` or whatever, then the decorated one will not provide them. Because that is a wrapper. So one needs to be careful if one uses them. +ํ•จ์ˆ˜ ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ๊ฐ์‹ธ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์€ ๋Œ€์ฒด์ ์œผ๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์›๋ณธ ํ•จ์ˆ˜์— `func.calledCount` ๋“ฑ์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•œ ํ•จ์ˆ˜์—์„  ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -E.g. in the example above if `slow` function had any properties on it, then `cachingDecorator(slow)` is a wrapper without them. +์œ„ ์˜ˆ์‹œ์—์„œ ํ•จ์ˆ˜ `slow`์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์—ˆ๋‹ค๋ฉด `cachingDecorator(slow)` ํ˜ธ์ถœ ๊ฒฐ๊ณผ์ธ ๋ž˜ํผ์—” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๊ฒ ์ฃ . -Some decorators may provide their own properties. E.g. a decorator may count how many times a function was invoked and how much time it took, and expose this information via wrapper properties. +๋ช‡๋ช‡ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ž์‹ ๋งŒ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ์„ธ๊ฑฐ๋‚˜ ํ˜ธ์ถœ ์‹œ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ๋ชจ๋˜์—ˆ๋Š”์ง€ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ๋ž˜ํผ์˜ ํ”„๋กœํผํ‹ฐ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -There exists a way to create decorators that keep access to function properties, but this requires using a special `Proxy` object to wrap a function. We'll discuss it later in the article . +ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๊ฑธ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด `Proxy`๋ผ๋Š” ํŠน๋ณ„ํ•œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. `Proxy`์— ๋Œ€ํ•ด์„  ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -*Decorator* is a wrapper around a function that alters its behavior. The main job is still carried out by the function. +*๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ๋Š” ๋ž˜ํผ๋กœ ํ•จ์ˆ˜์˜ ํ–‰๋™์„ ๋ณ€ํ™”์‹œํ‚ต๋‹ˆ๋‹ค. ์ฃผ์š” ์ž‘์—…์€ ์—ฌ์ „ํžˆ ํ•จ์ˆ˜์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -Decorators can be seen as "features" or "aspects" that can be added to a function. We can add one or add many. And all this without changing its code! +๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜์— ์ถ”๊ฐ€๋œ '๊ธฐ๋Šฅ' ํ˜น์€ '์ƒ(็›ธ, aspect)' ์ •๋„๋กœ ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜ ํ˜น์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -To implement `cachingDecorator`, we studied methods: +`cachingDecorator`๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. -- [func.call(context, arg1, arg2...)](mdn:js/Function/call) -- calls `func` with given context and arguments. -- [func.apply(context, args)](mdn:js/Function/apply) -- calls `func` passing `context` as `this` and array-like `args` into a list of arguments. +- [func.call(context, arg1, arg2...)](mdn:js/Function/call) -- ์ฃผ์–ด์ง„ ์ปจํ…์ŠคํŠธ์™€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด `func`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. +- [func.apply(context, args)](mdn:js/Function/apply) -- `this`์— `context`๊ฐ€ ํ• ๋‹น๋˜๊ณ , ์œ ์‚ฌ ๋ฐฐ์—ด `args`๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋˜์–ด `func`์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -The generic *call forwarding* is usually done with `apply`: +*์ฝœ ํฌ์›Œ๋”ฉ*์€ ๋Œ€๊ฐœ `apply`๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ```js let wrapper = function() { @@ -419,6 +421,6 @@ let wrapper = function() { }; ``` -We also saw an example of *method borrowing* when we take a method from an object and `call` it in the context of another object. It is quite common to take array methods and apply them to `arguments`. The alternative is to use rest parameters object that is a real array. +ํŠน์ • ๊ฐ์ฒด์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ปจํ…์ŠคํŠธ๋กœ ๊ณ ์ •ํ•œ ํ›„ ํ•จ์ˆ˜๋ฅผ `ํ˜ธ์ถœ(call)`ํ•˜๋Š” ํ˜•ํƒœ์ธ *๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ*์— ๋Œ€ํ•œ ์˜ˆ์ œ๋„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ๋Š” ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ๋นŒ๋ ค์„œ ์ด๋ฅผ `arguments`์— ์ ์šฉํ•  ๋•Œ ํ”ํžˆ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐฐ์—ด์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -There are many decorators there in the wild. Check how well you got them by solving the tasks of this chapter. +๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ์‚ฌ๋ก€๋“ค์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ฌธ์ œ๋“ค์„ ํ’€์–ด๋ณด๋ฉด์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ์–ผ๋งˆ๋‚˜ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg b/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg index 258fcfdfc7..9b63cb982b 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg +++ b/1-js/06-advanced-functions/09-call-apply-decorators/decorator-makecaching-wrapper.svg @@ -1 +1 @@ -wrapperaround the function \ No newline at end of file +wrapperaround the function \ No newline at end of file diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md index 737a14481f..480c6659f5 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `null`. +์ •๋‹ต: `null` ```js run @@ -13,6 +13,6 @@ let user = { user.g(); ``` -The context of a bound function is hard-fixed. There's just no way to further change it. +bind๋ฅผ ์ ์šฉํ•œ ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ๋Š” ์™„์ „ํžˆ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ํ•œ๋ฒˆ ๊ณ ์ •๋˜๋ฉด ๋ฐ”๊ฟ€ ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. -So even while we run `user.g()`, the original function is called with `this=null`. +๋”ฐ๋ผ์„œ `user.g()`๋ฅผ ์‹คํ–‰ํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ธฐ์กด ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ๋Š” `null`์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— `null`์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md index 6d7e1fb245..5a88d50bc4 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Bound function as a method +# bind๋ฅผ ์ ์šฉํ•œ ํ•จ์ˆ˜๋ฅผ ๋ฉ”์„œ๋“œ์— ์ •์˜ํ•˜๊ธฐ -What will be the output? +์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ์š”? ```js function f() { diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md index 97e1c28098..f398c18b62 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md @@ -1,4 +1,4 @@ -The answer: **John**. +์ •๋‹ต: **John** ```js run no-beautify function f() { @@ -10,6 +10,6 @@ f = f.bind( {name: "John"} ).bind( {name: "Pete"} ); f(); // John ``` -The exotic [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) object returned by `f.bind(...)` remembers the context (and arguments if provided) only at creation time. +`f.bind(...)`๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํŠน์ˆ˜ ๊ฐ์ฒด์ธ [๋ฌถ์ธ ํ•จ์ˆ˜(bound function)](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects)๋Š” ํ•จ์ˆ˜ ์ƒ์„ฑ ์‹œ์ ์˜ ์ปจํ…์ŠคํŠธ๋งŒ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์ œ๊ณต๋˜์—ˆ๋‹ค๋ฉด ๊ทธ ์ธ์ˆ˜ ๋˜ํ•œ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. -A function cannot be re-bound. +ํ•œ๋ฒˆ bind๋ฅผ ์ ์šฉํ•˜๋ฉด bind๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ •์˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md index 5daf053c65..74ad1b9d27 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Second bind +# bind ๋‘ ๋ฒˆ ์ ์šฉํ•˜๊ธฐ -Can we change `this` by additional binding? +ํ•จ์ˆ˜์— bind๋ฅผ ์ ์šฉํ•˜๊ณ , ์ด์–ด์„œ ํ•œ ๋ฒˆ ๋” bind๋ฅผ ์ ์šฉํ•˜๋ฉด `this`๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์„๊นŒ์š”? -What will be the output? +์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ์š”? ```js no-beautify function f() { diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md index 181555d95f..683802389e 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `undefined`. +์ •๋‹ต: `undefined` -The result of `bind` is another object. It does not have the `test` property. +`bind`๋ฅผ ์ ์šฉํ•˜๋ฉด ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ์ฒด์—” `test` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์œผ๋ฏ€๋กœ `undefined`๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md index d6cfb44bf8..616084e53d 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Function property after bind +# bind๋ฅผ ์ ์šฉํ•œ ํ•จ์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ -There's a value in the property of a function. Will it change after `bind`? Why, or why not? +ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ•˜๋‚˜ ํ• ๋‹นํ•ด๋ด…์‹œ๋‹ค. ์ด ํ•จ์ˆ˜์— `bind` ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ ๋ฐ”๋€”๊นŒ์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ํ˜น์€ ๊ทธ๋ ‡์ง€์•Š๋‹ค๋ฉด ๊ทธ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ```js run function sayHi() { @@ -17,7 +17,7 @@ let bound = sayHi.bind({ name: "John" }); -alert( bound.test ); // what will be the output? why? +alert( bound.test ); // ์–ผ๋Ÿฟ ์ฐฝ์—” ์–ด๋–ค ๊ฐ’์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? ๊ฐ’์ด ๋‚˜์˜จ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? */!* ``` diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md index 403107ca68..36a6b6bdea 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md @@ -1,13 +1,13 @@ -The error occurs because `ask` gets functions `loginOk/loginFail` without the object. +์—๋Ÿฌ๋Š” `ask`๊ฐ€ ํ•จ์ˆ˜ `loginOk`, `loginFail`์„ ๊ฐ์ฒด ์—†์ด ๊ฐ€์ง€๊ณ  ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -When it calls them, they naturally assume `this=undefined`. +ask๋Š” `loginOk`, `loginFail`์„ ํ˜ธ์ถœํ•  ๋•Œ `this=undefined`๋ผ๊ณ  ์ž์—ฐ์Šค๋ ˆ ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. -Let's `bind` the context: +`bind` ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณ ์ •์‹œ์ผœ ๋ด…์‹œ๋‹ค. ```js run function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", ''); if (password == "rockstar") ok(); else fail(); } @@ -16,11 +16,11 @@ let user = { name: 'John', loginOk() { - alert(`${this.name} logged in`); + alert(`${this.name}๋‹˜์ด ๋กœ๊ทธ์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.`); }, loginFail() { - alert(`${this.name} failed to log in`); + alert(`${this.name}๋‹˜์ด ๋กœ๊ทธ์ธ์— ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.`); }, }; @@ -30,14 +30,14 @@ askPassword(user.loginOk.bind(user), user.loginFail.bind(user)); */!* ``` -Now it works. +์ด์ œ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -An alternative solution could be: +์ด ์™ธ์—๋„ ๋‹ค๋ฅธ ๋‹ต์ด ์žˆ๋Š”๋ฐ, ์•„๋ž˜์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ```js //... askPassword(() => user.loginOk(), () => user.loginFail()); ``` -Usually that also works and looks good. +์ด๋ ‡๊ฒŒ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ๋˜ํ•œ ๋Œ€๊ฐœ ์ž˜ ๋™์ž‘ํ•˜๋ฉฐ ๊ฐ€๋…์„ฑ๋„ ์ข‹์Šต๋‹ˆ๋‹ค. -It's a bit less reliable though in more complex situations where `user` variable might change *after* `askPassword` is called, but *before* the visitor answers and calls `() => user.loginOk()`. +๋‹ค๋งŒ ์ด ๋ฐฉ๋ฒ•์€ `askPassword`๊ฐ€ ํ˜ธ์ถœ*๋์œผ๋‚˜* ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กฌํ”„ํŠธ ๋Œ€ํ™”์ƒ์ž์— ๊ฐ’์„ ์ œ์ถœํ•˜๊ณ  `() => user.loginOk()`๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ *์ „*์— `user` ๋ณ€์ˆ˜๊ฐ€ ๋ฐ”๋€Œ๋Š” ๋“ฑ์˜ ๋ณต์žกํ•œ ์ƒํ™ฉ์—์„œ๋Š” ์˜ค์ž‘๋™ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md index fe6a9b4eb9..f5862c8e7a 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Fix a function that loses "this" +# this ๊ฐ’์ด undefined์ธ ํ•จ์ˆ˜ ๊ณ ์น˜๊ธฐ -The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer. +์•„๋ž˜ ํ•จ์ˆ˜ `askPassword()`๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋จผ์ € ํ™•์ธํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ `user.loginOk`๋‚˜ `user.loginFail`์„ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -But it leads to an error. Why? +๊ทธ๋Ÿฐ๋ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ๋Š” ์™œ ๋ฐœ์ƒํ–ˆ์„๊นŒ์š”? -Fix the highlighted line for everything to start working right (other lines are not to be changed). +์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์ƒ‰์น ๋œ ์ค„์„ ๊ณ ์ณ๋ณด์„ธ์š”. ๋‹ค๋ฅธ ์ค„์€ ๋ฐ”๊พธ์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", ''); if (password == "rockstar") ok(); else fail(); } @@ -21,11 +21,11 @@ let user = { name: 'John', loginOk() { - alert(`${this.name} logged in`); + alert(`${this.name}๋‹˜์ด ๋กœ๊ทธ์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.`); }, loginFail() { - alert(`${this.name} failed to log in`); + alert(`${this.name}๋‹˜์ด ๋กœ๊ทธ์ธ์— ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.`); }, }; diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md index 3284c943b0..8ed37ff297 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md @@ -1,14 +1,14 @@ -1. Either use a wrapper function, an arrow to be concise: +1. ๋ž˜ํผ ํ•จ์ˆ˜๋‚˜ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js askPassword(() => user.login(true), () => user.login(false)); ``` - Now it gets `user` from outer variables and runs it the normal way. + ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด askPassword๋Š” ์™ธ๋ถ€ ๋ณ€์ˆ˜์—์„œ `user`๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -2. Or create a partial function from `user.login` that uses `user` as the context and has the correct first argument: +2. ์ปจํ…์ŠคํŠธ๊ฐ€ `user`์ด๋ฉด์„œ ์˜ฌ๋ฐ”๋ฅธ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋ฉด ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md index f8b83d7a20..a119bcdd91 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Partial application for login +# ๋กœ๊ทธ์ธ์— ๋ถ€๋ถ„ ์ ์šฉํ•˜๊ธฐ -The task is a little more complex variant of . +์ด ๊ณผ์ œ๋Š” ๋ฅผ ๋ณ€ํ˜•ํ•œ ์ข€ ๋” ๋ณต์žกํ•œ ๊ณผ์ œ์ž…๋‹ˆ๋‹ค. -The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`. +์—ฌ๊ธฐ์„œ๋Š” `user` ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•ด user๊ฐ€ `loginOk`, `loginFail` ๋Œ€์‹ ์— ์˜ค์ง ํ•˜๋‚˜์˜ ํ•จ์ˆ˜ `user.login(trueยทfalse)`๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๋†“์•˜์Šต๋‹ˆ๋‹ค. -What to pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`? +`user.login(true)`๋Š” `ok`, `user.login(false)`์€ `fail`์„ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด `askPassword`์— ๋ฌด์—‡์„ ๋„˜๊ฒจ์ค˜์•ผ ํ• ๊นŒ์š”? ```js function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", ''); if (password == "rockstar") ok(); else fail(); } @@ -21,7 +21,7 @@ let user = { name: 'John', login(result) { - alert( this.name + (result ? ' logged in' : ' failed to log in') ); + alert( this.name + (result ? ' ๋กœ๊ทธ์ธ ์„ฑ๊ณต' : ' ๋กœ๊ทธ์ธ ์‹คํŒจ') ); } }; @@ -30,5 +30,5 @@ askPassword(?, ?); // ? */!* ``` -Your changes should only modify the highlighted fragment. +์ƒ‰์น ๋œ ์ค„์˜ ๋ฌผ์Œํ‘œ ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 628907fa78..2d87339856 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -5,15 +5,15 @@ libs: # ํ•จ์ˆ˜ ๋ฐ”์ธ๋”ฉ -When passing object methods as callbacks, for instance to `setTimeout`, there's a known problem: "losing `this`". +`setTimeout`์— ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ์ฒ˜๋Ÿผ, ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•  ๋•Œ '`this` ์ •๋ณด๊ฐ€ ์‚ฌ๋ผ์ง€๋Š”' ๋ฌธ์ œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. -In this chapter we'll see the ways to fix it. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -## "this"๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฌ๋Š” ๊ฒƒ +## ์‚ฌ๋ผ์ง„ 'this' -We've already seen examples of losing `this`. Once a method is passed somewhere separately from the object -- `this` is lost. +์•ž์„œ ๋‹ค์–‘ํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด `this` ์ •๋ณด๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐ์ฒด ๋‚ด๋ถ€๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ณณ์— ์ „๋‹ฌ๋˜์–ด ํ˜ธ์ถœ๋˜๋ฉด `this`๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ๊ทธ ํ˜„์ƒ์ด `setTimeout`์—์„œ ์–ด๋–ป๊ฒŒ ์ผ์–ด๋‚˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +`setTimeout`์„ ์‚ฌ์šฉํ•œ ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `this`๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ๋ผ์ง€๋Š”์ง€ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run let user = { @@ -28,22 +28,22 @@ setTimeout(user.sayHi, 1000); // Hello, undefined! */!* ``` -์œ„์— ์˜ˆ์‹œ์ฒ˜๋Ÿผ, ๊ฒฐ๊ณผ๋Š” "John"์ด `this.firstName` ์ด ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ `undefined` ์ž…๋‹ˆ๋‹ค! +`this.firstName`์ด "John"์ด ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ์–ผ๋Ÿฟ์ฐฝ์—” `undefined`๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. -๊ทธ ์ด์œ ๋Š” `setTimeout` ์ด `user.sayHi`ํ•จ์ˆ˜๋ฅผ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐ€์ ธ์™”๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ๋ผ์ธ์„ ๋‹ค์‹œ ์“ฐ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ๋œ ์ด์œ ๋Š” `setTimeout`์— ๊ฐ์ฒด์—์„œ ๋ถ„๋ฆฌ๋œ ํ•จ์ˆ˜์ธ `user.sayHi`๊ฐ€ ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์˜ ๋งˆ์ง€๋ง‰ ์ค„์€ ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let f = user.sayHi; -setTimeout(f, 1000); // user ์ปจํ…์ŠคํŠธ๋ฅผ ์žƒ์–ด๋ฒ„๋ ธ์Œ +setTimeout(f, 1000); // user ์ปจํ…์ŠคํŠธ๋ฅผ ์žƒ์–ด๋ฒ„๋ฆผ ``` -The method `setTimeout` in-browser is a little special: it sets `this=window` for the function call (for Node.js, `this` becomes the timer object, but doesn't really matter here). So for `this.firstName` it tries to get `window.firstName`, which does not exist. In other similar cases, usually `this` just becomes `undefined`. +๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ `setTimeout` ๋ฉ”์„œ๋“œ๋Š” ์กฐ๊ธˆ ํŠน๋ณ„ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, `this`์— `window`๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค(Node.js ํ™˜๊ฒฝ์—์„  `this`๊ฐ€ ํƒ€์ด๋จธ ๊ฐ์ฒด๊ฐ€ ๋˜๋Š”๋ฐ, ์—ฌ๊ธฐ์„  ์ค‘์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค). ๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์‹œ์˜ `this.firstName`์€ `window.firstName`๊ฐ€ ๋˜๋Š”๋ฐ, `window` ๊ฐ์ฒด์—” `firstName`์ด ์—†์œผ๋ฏ€๋กœ `undefined`๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์œ ์‚ฌํ•œ ์‚ฌ๋ก€์—์„œ๋„ ๋Œ€๋ถ€๋ถ„ `this`๋Š” `undefined`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -ํ˜ธ์ถœ๋  ๊ณณ์—์„œ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ (์—ฌ๊ธฐ์„œ๋Š” ์Šค์ผ€์ค„๋Ÿฌ์—) ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ „ํ˜•์ ์ธ ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์˜ฌ๋ฐ”๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? +๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์‹ค์ œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ณณ(์˜ˆ์‹œ์—์„  `setTimeout` ์Šค์ผ€์ค„๋Ÿฌ)์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์•„์ฃผ ํ”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ, ์ปจํ…์ŠคํŠธ๋„ ์ œ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? -## ์ฒซ ๋ฒˆ์งธ ํ•ด๊ฒฐ์ฑ…: a wrapper +## ๋ฐฉ๋ฒ• 1: ๋ž˜ํผ -๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€ wrapping ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ```js run let user = { @@ -60,17 +60,17 @@ setTimeout(function() { */!* ``` -์œ„์˜ ์˜ˆ์‹œ๋Š” ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค, ์™œ๋ƒํ•˜๋ฉด `user`๋ฅผ ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์œผ๋กœ ๋ฐ›์•„์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณดํ†ต ๋•Œ์ฒ˜๋Ÿผ ํ˜ธ์ถœํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” ์ด์œ ๋Š” ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์—์„œ `user`๋ฅผ ๋ฐ›์•„์„œ ๋ณดํ†ต ๋•Œ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์œ„ ์˜ˆ์‹œ์™€ ๊ฐ™์ง€๋งŒ, ์งง๊ฒŒ ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +๊ฐ•์กฐ ํ‘œ์‹œํ•œ ์ค„์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js setTimeout(() => user.sayHi(), 1000); // Hello, John! ``` -์œ„์˜ ์ฝ”๋“œ๋Š” ๋ณด๊ธฐ์—๋Š” ๊ดœ์ฐฎ์ง€๋งŒ, ์ฝ”๋“œ ๊ตฌ์กฐ์—๋Š” ์•ฝ๊ฐ„ ์ทจ์•ฝํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ฐ„๊ฒฐํ•ด์ ธ์„œ ๋ณด๊ธฐ๋Š” ์ข‹์ง€๋งŒ, ์•ฝ๊ฐ„์˜ ์ทจ์•ฝ์„ฑ์ด ์ƒ๊น๋‹ˆ๋‹ค. -`setTimeout`์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— (1์ดˆ์˜ ์ง€์—ฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค!) `user`๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ๊ฐ‘์ž๊ธฐ ์ž˜๋ชป๋œ ๊ฐœ์ฒด๋ฅผ ํ˜ธ์ถœํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค! +`setTimeout`์ด ํŠธ๋ฆฌ๊ฑฐ ๋˜๊ธฐ ์ „์—(1์ดˆ๊ฐ€ ์ง€๋‚˜๊ธฐ ์ „์—) `user`๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ๋ณ€๊ฒฝ๋œ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ```js run @@ -83,30 +83,30 @@ let user = { setTimeout(() => user.sayHi(), 1000); -// ...1์ดˆ ์•ˆ์— -user = { sayHi() { alert("Another user in setTimeout!"); } }; +// 1์ดˆ๊ฐ€ ์ง€๋‚˜๊ธฐ ์ „์— user์˜ ๊ฐ’์ด ๋ฐ”๋€œ +user = { sayHi() { alert("๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž!"); } }; -// setTimeout์— ๋˜ ๋‹ค๋ฅธ user ๊ฐ€?!? +// setTimeout์— ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž! ``` -๋‘ ๋ฒˆ์งธ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€ ๊ฐ‘์ž๊ธฐ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋Š” ํ˜„์ƒ์ด ์ผ์–ด๋‚˜๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. +๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -## ๋‘ ๋ฒˆ์งธ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•: bind +## ๋ฐฉ๋ฒ• 2: bind -ํ•จ์ˆ˜๋“ค์€ `this`๋ฅผ ์ˆ˜์ •ํ•˜๋„๋ก ํ•˜๋Š” ๋‚ด์žฅ ๋งค์„œ๋“œ [bind](mdn:js/Function/bind) ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +๋ชจ๋“  ํ•จ์ˆ˜๋Š” `this`๋ฅผ ์ˆ˜์ •ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋‚ด์žฅ ๋ฉ”์„œ๋“œ [bind](mdn:js/Function/bind)๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -๊ธฐ๋ณธ ๋ฌธ๋ฒ•: +๊ธฐ๋ณธ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js -// ๋” ๋ณต์žกํ•œ ๋ฌธ๋ฒ•์€ ๋‚˜์ค‘์— ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค +// ๋” ๋ณต์žกํ•œ ๋ฌธ๋ฒ•์€ ๋’ค์— ๋‚˜์˜ต๋‹ˆ๋‹ค. let boundFunc = func.bind(context); -```` +``` -`func.bind(context)`์˜ ๊ฒฐ๊ณผ๋Š” "exotic object" ๊ฐ™์€ ํŠน๋ณ„ํ•œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค, ์ด๊ฒƒ์€ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉด์„œ `func`์— `this = context`๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. +`func.bind(context)`๋Š” ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ 'ํŠน์ˆ˜ ๊ฐ์ฒด(exotic object)'๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `this`๊ฐ€ `context`๋กœ ๊ณ ์ •๋œ ํ•จ์ˆ˜ `func`๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. -์ฆ‰,`boundFunc`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ `this`๊ฐ€ ๊ณ ์ •๋œ `func`์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ `boundFunc`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `this`๊ฐ€ ๊ณ ์ •๋œ `func`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ๋ด…๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `funcUser`๋Š” `this = user`๋ฅผ ๊ฐ€์ง€๊ณ  `func` ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ `funcUser`์—๋Š” `this`๊ฐ€ `user`๋กœ ๊ณ ์ •๋œ `func`์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ```js run let user = { @@ -123,9 +123,9 @@ funcUser(); // John */!* ``` -์œ„์˜ ์˜ˆ์‹œ์—์„œ `func.bind (user)`๋Š”`func`์˜ "๋ฐ”์šด๋“œ ๋ณ€์ˆ˜"๋กœ ๊ณ ์ •๋œ `this = user`๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์„œ `func.bind(user)`๋Š” `func`์˜ `this`๋ฅผ `user`๋กœ '๋ฐ”์ธ๋”ฉํ•œ ๋ณ€ํ˜•'์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -๋ชจ๋“  ์ธ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ "์žˆ๋Š” ๊ทธ๋Œ€๋กœ" `func` ์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค: +์ธ์ˆ˜๋Š” ์›๋ณธ ํ•จ์ˆ˜ `func`์— '๊ทธ๋Œ€๋กœ' ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ```js run let user = { @@ -136,15 +136,15 @@ function func(phrase) { alert(phrase + ', ' + this.firstName); } -// bind this to user +// this๋ฅผ user๋กœ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. let funcUser = func.bind(user); *!* -funcUser("Hello"); // Hello, John ("Hello" ์ธ์ˆ˜๊ฐ€ ๋„˜๊ฒจ์กŒ๊ณ  this=user์ž…๋‹ˆ๋‹ค) +funcUser("Hello"); // Hello, John (์ธ์ˆ˜ "Hello"๊ฐ€ ๋„˜๊ฒจ์ง€๊ณ  this๋Š” user๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.) */!* ``` -์ด์ œ ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด์ œ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์— `bind`๋ฅผ ์ ์šฉํ•ด ๋ด…์‹œ๋‹ค. ```js run @@ -159,14 +159,21 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* +// ์ด์ œ ๊ฐ์ฒด ์—†์ด๋„ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. sayHi(); // Hello, John! setTimeout(sayHi, 1000); // Hello, John! + +// 1์ดˆ ์ด๋‚ด์— user ๊ฐ’์ด ๋ณ€ํ™”ํ•ด๋„ +// sayHi๋Š” ๊ธฐ์กด ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +user = { + sayHi() { alert("๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž!"); } +}; ``` -`(*)`์ค„์—์„œ `user.sayHi` ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ `user`์— ๋ฐ”์ธ๋“œํ•ฉ๋‹ˆ๋‹ค. `sayHi`๋Š” ๋‹จ๋…์œผ๋กœ ํ˜ธ์ถœ๋˜๊ฑฐ๋‚˜ `setTimeout`์— ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋Š” "๋ฐ”์šด๋“œ (bound)"ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค - ์ปจํ…์ŠคํŠธ๋Š” ๋งž๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ๋ฉ”์„œ๋“œ `user.sayHi`๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๋ฉ”์„œ๋“œ์— `user`๋ฅผ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. `sayHi`๋Š” ์ด์ œ '๋ฌถ์ธ(bound)' ํ•จ์ˆ˜๊ฐ€ ๋˜์–ด ๋‹จ๋…์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ณ  `setTimeout`์— ์ „๋‹ฌํ•˜์—ฌ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฐฉ์‹์ด๋“  ์ปจํƒ์ŠคํŠธ๋Š” ์›ํ•˜๋Š” ๋Œ€๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. -์ธ์ˆ˜๋Š” "์žˆ๋Š” ๊ทธ๋Œ€๋กœ" ์ „๋‹ฌ๋˜๊ณ , ๋‹จ์ง€ "this"๋งŒ์ด `bind`์— ์˜ํ•ด ๊ณ ์ •๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ธ์ˆ˜๋Š” '๊ทธ๋Œ€๋กœ' ์ „๋‹ฌ๋˜๊ณ  `bind`์— ์˜ํ•ด `this`๋งŒ ๊ณ ์ •๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let user = { @@ -178,12 +185,12 @@ let user = { let say = user.say.bind(user); -say("Hello"); // Hello, John ("Hello"์ธ์ˆ˜๊ฐ€ say๋กœ ๋„˜๊ฒจ์กŒ์Œ) -say("Bye"); // Bye, John ("Bye"๊ฐ€ say ๋กœ ๋„˜๊ฒจ์กŒ์Œ) +say("Hello"); // Hello, John (์ธ์ˆ˜ "Hello"๊ฐ€ say๋กœ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.) +say("Bye"); // Bye, John ("Bye"๊ฐ€ say๋กœ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.) ``` -````smart header="Convenience method: `bindAll`" -๊ฐ์ฒด๊ฐ€ ๋งŽ์€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ๊ทธ๊ฒƒ์„ ๋Šฅ๋™์ ์œผ๋กœ ์ „๋‹ฌํ•  ๊ณ„ํš์ด๋ผ๋ฉด, ๋ชจ๋“  ๊ฒƒ์„ ๋ฃจํ”„๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +````smart header="`bindAll`๋กœ ๋ฉ”์„œ๋“œ ์ „์ฒด ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ" +๊ฐ์ฒด์— ๋ณต์ˆ˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๊ณ  ์ด ๋ฉ”์„œ๋“œ ์ „์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ ค ํ•  ๋•, ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js for (let key in user) { @@ -193,24 +200,24 @@ for (let key in user) { } ``` -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ํŽธ๋ฆฌํ•œ ๋งค์Šค ๋ฐ”์ธ๋”ฉ(mass binding) ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. lodash๋ฅผ ์˜ˆ๋กœ ๋“ค๋ฉด [_.bindAll(obj)](http://lodash.com/docs#bindAll) ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋Œ€๊ทœ๋ชจ ๋ฐ”์ธ๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll)์ด ๊ทธ ์˜ˆ์ž…๋‹ˆ๋‹ค. ```` -## Partial functions +## ๋ถ€๋ถ„ ์ ์šฉ -Until now we have only been talking about binding `this`. Let's take it a step further. +์ง€๊ธˆ๊นŒ์ง„ `this` ๋ฐ”์ธ๋”ฉ์— ๋Œ€ํ•ด์„œ๋งŒ ์ด์•ผ๊ธฐํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ•œ ๋‹จ๊ณ„ ๋” ๋‚˜์•„๊ฐ€ ๋ด…์‹œ๋‹ค. -We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy. +`this` ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ธ์ˆ˜๋„ ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜ ๋ฐ”์ธ๋”ฉ์€ ์ž˜ ์“ฐ์ด์ง„ ์•Š์ง€๋งŒ ๊ฐ€๋” ์œ ์šฉํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -The full syntax of `bind`: +`bind`์˜ ์ „์ฒด ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let bound = func.bind(context, [arg1], [arg2], ...); ``` -It allows to bind context as `this` and starting arguments of the function. +`bind`๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ `this`๋กœ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋„ ๊ณ ์ •ํ•ด์ค๋‹ˆ๋‹ค. -For instance, we have a multiplication function `mul(a, b)`: +๊ณฑ์…ˆ์„ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ `mul(a, b)`๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js function mul(a, b) { @@ -218,7 +225,7 @@ function mul(a, b) { } ``` -Let's use `bind` to create a function `double` on its base: +`bind`๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ `double`์„ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run function mul(a, b) { @@ -234,13 +241,13 @@ alert( double(4) ); // = mul(2, 4) = 8 alert( double(5) ); // = mul(2, 5) = 10 ``` -The call to `mul.bind(null, 2)` creates a new function `double` that passes calls to `mul`, fixing `null` as the context and `2` as the first argument. Further arguments are passed "as is". +`mul.bind(null, 2)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ `double`์ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. `double`์—” ์ปจํ…์ŠคํŠธ๊ฐ€ `null`, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” `2`์ธ `mul`์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ธ์ˆ˜๋Š” '๊ทธ๋Œ€๋กœ' ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. -That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one. +์ด๋Ÿฐ ๋ฐฉ์‹์„ [๋ถ€๋ถ„ ์ ์šฉ(partial application)](https://en.wikipedia.org/wiki/Partial_application)์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ๋ถ€๋ถ„ ์ ์šฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ณ ์ •ํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Please note that here we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`. +์œ„ ์˜ˆ์‹œ์—์„  `this`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. `bind`์—” ์ปจํ…์ŠคํŠธ๋ฅผ ํ•ญ์ƒ ๋„˜๊ฒจ์ค˜์•ผ ํ•˜๋ฏ€๋กœ `null`์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. -The function `triple` in the code below triples the value: +๋ถ€๋ถ„ ์ ์šฉ์„ ์‚ฌ์šฉํ•ด 3์„ ๊ณฑํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ `triple`์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run function mul(a, b) { @@ -256,23 +263,23 @@ alert( triple(4) ); // = mul(3, 4) = 12 alert( triple(5) ); // = mul(3, 5) = 15 ``` -Why do we usually make a partial function? +๊ทธ๋Ÿฐ๋ฐ ๋ถ€๋ถ„ ํ•จ์ˆ˜๋Š” ์™œ ๋งŒ๋“œ๋Š” ๊ฑธ๊นŒ์š”? -The benefit is that we can create an independent function with a readable name (`double`, `triple`). We can use it and not provide the first argument every time as it's fixed with `bind`. +๊ฐ€๋…์„ฑ์ด ์ข‹์€ ์ด๋ฆ„(`double`, `triple`)์„ ๊ฐ€์ง„ ๋…๋ฆฝ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์  ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ `bind`๋ฅผ ์‚ฌ์šฉํ•ด ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๊ณ ์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋ฒˆ ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”๋„ ์—†์–ด์ง€์ฃ . -In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience. +์ด ์™ธ์—๋„ ๋ถ€๋ถ„ ์ ์šฉ์€ ๋งค์šฐ ํฌ๊ด„์ ์ธ ํ•จ์ˆ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋œ ํฌ๊ด„์ ์ธ ๋ณ€ํ˜• ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -For instance, we have a function `send(from, to, text)`. Then, inside a `user` object we may want to use a partial variant of it: `sendTo(to, text)` that sends from the current user. +ํ•จ์ˆ˜ `send(from, to, text)`๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ๊ฐ์ฒด `user` ์•ˆ์—์„œ ๋ถ€๋ถ„ ์ ์šฉ์„ ํ™œ์šฉํ•˜๋ฉด, ์ „์†ก ์ฃผ์ฒด๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉ์ž์ธ ํ•จ์ˆ˜ `sendTo(to, text)`๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Going partial without context +## ์ปจํ…์ŠคํŠธ ์—†๋Š” ๋ถ€๋ถ„ ์ ์šฉ -What if we'd like to fix some arguments, but not the context `this`? For example, for an object method. +์ธ์ˆ˜ ์ผ๋ถ€๋Š” ๊ณ ์ •ํ•˜๊ณ  ์ปจํ…์ŠคํŠธ `this`๋Š” ๊ณ ์ •ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? -The native `bind` does not allow that. We can't just omit the context and jump to arguments. +๋„ค์ดํ‹ฐ๋ธŒ `bind`๋งŒ์œผ๋กœ๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ๋žตํ•˜๊ณ  ์ธ์ˆ˜๋กœ ๋ฐ”๋กœ ๋›ฐ์–ด๋„˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. -Fortunately, a helper function `partial` for binding only arguments can be easily implemented. +๋‹คํ–‰ํžˆ๋„ ์ธ์ˆ˜๋งŒ ๋ฐ”์ธ๋”ฉํ•ด์ฃผ๋Š” ํ—ฌํผ ํ•จ์ˆ˜ `partial`๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฑด ์‰ฝ์Šต๋‹ˆ๋‹ค. -Like this: +์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . ```js run *!* @@ -283,7 +290,7 @@ function partial(func, ...argsBound) { } */!* -// Usage: +// ์‚ฌ์šฉ๋ฒ•: let user = { firstName: "John", say(time, phrase) { @@ -291,29 +298,29 @@ let user = { } }; -// add a partial method with fixed time +// ์‹œ๊ฐ„์„ ๊ณ ์ •ํ•œ ๋ถ€๋ถ„ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•จ user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes()); user.sayNow("Hello"); -// Something like: +// ์ถœ๋ ฅ๊ฐ’ ์˜ˆ์‹œ: // [10:00] John: Hello! ``` -The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with: -- Same `this` as it gets (for `user.sayNow` call it's `user`) -- Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`) -- Then gives it `...args` -- arguments given to the wrapper (`"Hello"`) +`partial(func[, arg1, arg2...])`์„ ํ˜ธ์ถœํ•˜๋ฉด ๋ž˜ํผ(`(*)`)๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๋ž˜ํผ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `func`์ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +- ๋™์ผํ•œ `this`๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค(`user.sayNow`๋Š” `user`๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค). +- `partial`์„ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐ›์€ ์ธ์ˆ˜(`"10:00"`)๋Š” `...argsBound`์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. +- ๋ž˜ํผ์— ์ „๋‹ฌ๋œ ์ธ์ˆ˜(`"Hello"`)๋Š” `...args`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -So easy to do it with the spread operator, right? +์ „๊ฐœ ๊ตฌ๋ฌธ ๋•๋ถ„์— ์ด ๋ชจ๋“  ๊ณผ์ •์ด ์‰ฌ์›Œ์กŒ์Šต๋‹ˆ๋‹ค. -Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library. +lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ [_.partial](https://lodash.com/docs#partial)์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ์—†๋Š” ๋ถ€๋ถ„ ์ ์šฉ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -๋ฉ”์„œ๋“œ`func.bind (context, ... args)`๋Š” ์ปจํ…์ŠคํŠธ์˜ `this`์™€ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์ˆ˜์ •๋˜๋Š” `func` ํ•จ์ˆ˜์˜ "๋ฐ”์šด๋“œ ๋ณ€์ˆ˜"๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +`func.bind(context, ...args)`๋Š” `this`๊ฐ€ `context`๋กœ ๊ณ ์ •๋˜๊ณ  ์ธ์ˆ˜๋„ ๊ณ ์ •๋œ ํ•จ์ˆ˜ `func`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -Usually we apply `bind` to fix `this` for an object method, so that we can pass it somewhere. For example, to `setTimeout`. +`bind`๋Š” ๋ณดํ†ต ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์˜ `this`๋ฅผ ๊ณ ์ •ํ•ด ์–ด๋”˜๊ฐ€์— ๋„˜๊ธฐ๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. `setTimeout`์— ๋„˜๊ธธ ๋•Œ ๊ฐ™์ด ๋ง์ด์ฃ . -When we fix some arguments of an existing function, the resulting (less universal) function is called *partially applied* or *partial*. +๊ธฐ์กด ํ•จ์ˆ˜์˜ ์ธ์ˆ˜ ๋ช‡ ๊ฐœ๋ฅผ ๊ณ ์ •ํ•œ ํ•จ์ˆ˜๋ฅผ *๋ถ€๋ถ„ ์ ์šฉ(partially applied)* ํ•จ์ˆ˜ ๋˜๋Š” *๋ถ€๋ถ„(partial)* ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -Partials are convenient when we don't want to repeat the same argument over and over again. Like if we have a `send(from, to)` function, and `from` should always be the same for our task, we can get a partial and go on with it. +๋ถ€๋ถ„ ์ ์šฉ์€ ๊ฐ™์€ ์ธ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณตํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. `send(from, to)`๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ `from`์„ ๊ณ ์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `send(from, to)`์˜ ๋ถ€๋ถ„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ด ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. diff --git a/1-js/06-advanced-functions/12-arrow-functions/article.md b/1-js/06-advanced-functions/12-arrow-functions/article.md index 3f60d730a1..e1ec18ce3e 100644 --- a/1-js/06-advanced-functions/12-arrow-functions/article.md +++ b/1-js/06-advanced-functions/12-arrow-functions/article.md @@ -1,31 +1,31 @@ -# ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์žฌ๊ณ  +# ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋‹ค์‹œ ์‚ดํŽด๋ณด๊ธฐ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜(arrow function)์— ๋Œ€ํ•ด ๋‹ค์‹œ ๋…ผ์˜ํ•ด๋ด…์‹œ๋‹ค. -ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋“ค์€ ๋‹จ์ง€ "์งง๊ฒŒ ์“ฐ๊ธฐ ์œ„ํ•œ" ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ๋ช‡๊ฐ€์ง€ ๋…ํŠนํ•˜๊ณ  ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ๋‹จ์ˆœํžˆ ํ•จ์ˆ˜๋ฅผ '์งง๊ฒŒ' ์“ฐ๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋…ํŠนํ•˜๊ณ  ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‹คํ–‰๋˜๋Š” ์ž‘์€ ํ•จ์ˆ˜๋ฅผ ์จ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ์žฆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์ € ๋ฉ€๋ฆฌ ๋™๋–จ์–ด์ง„ ๊ณณ์—์„œ ์‹คํ–‰๋  ์ž‘์€ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์„ ์ž์ฃผ ๋งŒ๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์˜ˆ์‹œ : +์˜ˆ์‹œ: -- `arr.forEach(func)` -- `func`์€ `forEach`๋ฅผ ์“ฐ๋Š” `arr`์˜ ๋ฐฐ์—ด ์•„์ดํ…œ์„ ์ˆœํšŒํ•  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -- `setTimeout(func)` -- `func` ์€ `setTimeout`์— ๋‚ด์žฅ๋œ ์‹œ๊ฐ„์ด ๋˜๋ฉด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -- ๊ทธ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์‚ฌ๋ก€๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. +- `arr.forEach(func)` -- `func`๋Š” `forEach`๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๋ฐฐ์—ด `arr`์˜ ์š”์†Œ ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +- `setTimeout(func)` -- `func`๋Š” ๋‚ด์žฅ ์Šค์ผ€์ค„๋Ÿฌ์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +- ๊ธฐํƒ€ ๋“ฑ๋“ฑ... -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์–ด๋”˜๊ฐ€๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด์ฒ˜๋Ÿผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ํ•จ์ˆ˜๋ฅผ ์–ด๋”˜๊ฐ€์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์•„์ฃผ ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. -์ด๋ ‡๊ฒŒ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๋“ค์€ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ๋– ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ ์„ ์‘์šฉํ•˜๋ฉด ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์–ด๋”˜๊ฐ€์— ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ฒŒ ๋˜๋ฉด ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ์žƒ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ ์ปจํ…์ŠคํŠธ๋ฅผ ์žƒ์ง€ ์•Š์•„ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -## ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—๋Š” 'this'๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +## ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—๋Š” 'this'๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค - ์ฑ•ํ„ฐ๋ฅผ ๊ธฐ์–ตํ•˜์‹ ๋‹ค๋ฉด, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `this`๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์Œ์„ ์•„์‹ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ `this`์— ์ ‘๊ทผํ•˜๋ฉด, ์ด๊ฒƒ์€ ์™ธ๋ถ€๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. + ์ฑ•ํ„ฐ์—์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—” `this`๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์šด ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์—์„œ `this`์— ์ ‘๊ทผํ•˜๋ฉด, ์™ธ๋ถ€์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค๋ฉด, ์•„๋ž˜๋Š” ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ this๋ฅผ ์ด์šฉํ•ด ์™ธ๋ถ€ ๋ฐฐ์—ด students๋ฅผ ์ˆœํšŒ ํ•˜๊ณ  ์žˆ๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ํŠน์ง•์€ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ(`showList()`) ์•ˆ์—์„œ ๋™์ผ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ(`students`)๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ˆœํšŒ๋ฅผ ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let group = { - title: "Our Group", - students: ["John", "Pete", "Alice"], + title: "1๋ชจ๋‘ ", + students: ["๋ณด๋ผ", "ํ˜ธ์ง„", "์ง€๋ฏผ"], showList() { *!* @@ -39,19 +39,19 @@ let group = { group.showList(); ``` -์—ฌ๊ธฐ์˜ `forEach`์—์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `this.title`์€ ๋ฐ”๊นฅ ๋ฉ”์„œ๋“œ `showList`๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ๊ณผ ๋˜‘๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฆ‰ `this.title`์€ `group.title`์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +์˜ˆ์‹œ์˜ `forEach`์—์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์— ์žˆ๋Š” `this.title`์€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ฐ”๊นฅ์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ์ธ `showList`๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ๊ณผ ๋™์ผํ•ด์ง‘๋‹ˆ๋‹ค. ์ฆ‰ `this.title`์€ `group.title`๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ "์ผ๋ฐ˜์ ์ธ", `function` ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ํ•จ์ˆ˜๋กœ ์“ด๋‹ค๋ฉด ํ•ด๋‹น ๊ตฌ๋ฌธ์€ ์˜ค๋ฅ˜๊ฐ€ ๋‚ฉ๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋Œ€์‹  '์ผ๋ฐ˜' ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค. ```js run let group = { - title: "Our Group", - students: ["John", "Pete", "Alice"], + title: "1๋ชจ๋‘ ", + students: ["๋ณด๋ผ", "ํ˜ธ์ง„", "์ง€๋ฏผ"], showList() { *!* this.students.forEach(function(student) { - // Error: Cannot read property 'title' of undefined + // TypeError: Cannot read property 'title' of undefined alert(this.title + ': ' + student) }); */!* @@ -61,28 +61,28 @@ let group = { group.showList(); ``` -์ด ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ์ด์œ ๋Š” `forEach`์˜ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” `this`๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” `undefined`์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ํ’€์–ด ์จ๋ณด๋ฉด, `undefinde.title`์ด๋ฏ€๋กœ, `undefinde`์— ์ ‘๊ทผ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. +์—๋Ÿฌ๋Š” `forEach`์— ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜์˜ `this`๊ฐ€ `undefined` ์ด์–ด์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. `alert` ํ•จ์ˆ˜์—์„œ `undefined.title`์— ์ ‘๊ทผํ•˜๋ ค ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ผ๋Ÿฟ ์ฐฝ์—” ์—๋Ÿฌ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. -ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `this` ๊ฐ€ ์—†์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, `this`๋กœ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๊ธฐ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `this` ์ž์ฒด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -``` ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `new`์™€ ํ•จ๊ป˜ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -`this`๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋˜ ๋‹ค๋ฅธ ํ•œ๊ณ„๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `new`๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +```warn header="ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `new`์™€ ํ•จ๊ป˜ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." +`this`๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ œ์•ฝ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `new`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ``` -``` ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ VS bind -ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ `=>`์™€ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜์ธ `.bind(this)` ์‚ฌ์ด์—๋Š” ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +```smart header="ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ vs. bind" +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์™€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ `.bind(this)`๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ ์‚ฌ์ด์—๋Š” ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- `.bind(this)`๋Š” ํ•จ์ˆ˜ ์•ˆ์˜ "ํ•œ์ •๋œ ๋ฒ„์ „"์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. -- ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ `=>`๋Š” ์–ด๋–ค ๋ฐ”์ธ๋”ฉ๋„ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋‹จ์ˆœํžˆ `this`๊ฐ€ ์—†๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. `this`์˜ ๊ฒ€์ƒ‰์€ ์™ธ๋ถ€ ํ™˜๊ฒฝ์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ผ๋ฐ˜์ ์ธ ๋ณ€์ˆ˜ ๊ฒ€์ƒ‰๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค: ์ƒ์œ„ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์—์„œ +- `.bind(this)`๋Š” ํ•จ์ˆ˜์˜ 'ํ•œ์ •๋œ ๋ฒ„์ „(bound version)'์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +- ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์–ด๋–ค ๊ฒƒ๋„ ๋ฐ”์ธ๋”ฉ์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—” ๋‹จ์ง€ `this`๊ฐ€ ์—†์„ ๋ฟ์ž…๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ `this`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ฐ˜ ๋ณ€์ˆ˜ ์„œ์นญ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `this`์˜ ๊ฐ’์„ ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์—์„œ ์ฐพ์Šต๋‹ˆ๋‹ค. ``` -## ํ™”์‚ดํ‘œ๋“ค์€ '์ธ์ˆ˜'๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค +## ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—” 'arguments'๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค -๋˜ํ•œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋“ค์€ `์ธ์ˆ˜`๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋ชจ๋“  ์ธ์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด `arguments`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(decorator)์—์„œ ํ˜„์žฌ์˜ `this`์™€ `arguments`๋ฅผ ํ•จ์ˆ˜ ํฌ์›Œ๋”ฉํ•ด์•ผํ•  ๋•Œ, ์ธ์ˆ˜๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์€ ์ข‹์€ ์ผ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ํŠน์ง•์€ ํ˜„์žฌ `this` ๊ฐ’๊ณผ `arguments` ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ์‹ค์–ด ํ˜ธ์ถœ์„ ํฌ์›Œ๋”ฉํ•ด ์ฃผ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -์•„๋ž˜์˜ ์˜ˆ์ œ์—์„œ `defer(f, ms)` ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›์œผ๋ฉฐ, `ms` ๋ฐ€๋ฆฌ์ดˆ ๋’ค์— ์‹คํ–‰๋˜๋Š” ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ `defer(f, ms)`๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ณ  ์ด ํ•จ์ˆ˜๋ฅผ ๋ž˜ํผ๋กœ ๊ฐ์‹ธ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ, ํ•จ์ˆ˜ `f`๋Š” `ms` ๋ฐ€๋ฆฌ์ดˆ ํ›„์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ```js run function defer(f, ms) { @@ -92,14 +92,14 @@ function defer(f, ms) { } function sayHi(who) { - alert('Hello, ' + who); + alert('์•ˆ๋…•, ' + who); } let sayHiDeferred = defer(sayHi, 2000); -sayHiDeferred("John"); // 2000 ๋ฐ€๋ฆฌ ์ดˆ ๋’ค Hello, John๊ฐ€ ์–ผ๋Ÿฟ์œผ๋กœ ๋œน๋‹ˆ๋‹ค. +sayHiDeferred("์ฒ ์ˆ˜"); // 2์ดˆ ํ›„ "์•ˆ๋…•, ์ฒ ์ˆ˜"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ``` -์•„๋ž˜๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์—†๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js function defer(f, ms) { @@ -112,15 +112,15 @@ function defer(f, ms) { } ``` -์ด ํ•จ์ˆ˜๋Š” `setTimeout` ๋‚ด๋ถ€์—์„œ `this`์™€ ์ „๋‹ฌ๋ฐ›์€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก, `args`์™€ `ctx`๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ ์ƒ์„ฑํ•ด ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ผ๋ฐ˜ ํ•จ์ˆ˜์—์„  `setTimeout`์— ๋„˜๊ฒจ์ฃผ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜ `ctx`์™€ `args`๋ฅผ ๋ฐ˜๋“œ์‹œ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ## ์š”์•ฝ -ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. - `this`๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- `new` ํ‚ค์›Œ๋“œ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -- (ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋“ค์€ ๋ฌผ๋ก  `super`๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค๋งŒ, ์•„์ง ํ•ด๋‹น ๋ถ€๋ถ„์€ ๋‹ค๋ฃจ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์€ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ๊ฒƒ์ž…๋‹ˆ๋‹ค.) +- `arguments`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- `new`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +- ์ด ์™ธ์—๋„ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `super`๊ฐ€ ์—†๋‹ค๋Š” ํŠน์ง•๋„ ์žˆ๋Š”๋ฐ, ์•„์ง `super`์— ๋Œ€ํ•ด ๋ฐฐ์šฐ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ํ•ด๋‹น ๋‚ด์šฉ์„ ๋‹ค๋ฃจ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์™€ `super`์˜ ๊ด€๊ณ„๋Š” ์ฑ•ํ„ฐ์—์„œ ํ•™์Šตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋“ค์€ ์ž์‹ ์˜ "์ปจํ…์ŠคํŠธ"๊ฐ€ ์—†๊ณ , ์˜คํžˆ๋ ค ํ˜„์žฌ ์ปจํ…์ŠคํŠธ์—์„œ ์ž‘๋™ํ•˜๋Š” ์งง์€ ์ฝ”๋“œ๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชฉ์ ์— ๋งค์šฐ ํ•ฉ์น˜ํ•ฉ๋‹ˆ๋‹ค. +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ๋Š” ๊ธด ์ฝ”๋“œ๋ณด๋‹ค๋Š” ์ž์ฒด '์ปจํ…์ŠคํŠธ'๊ฐ€ ์—†๋Š” ์งง์€ ์ฝ”๋“œ๋ฅผ ๋‹ด์„ ์šฉ๋„๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชฉ์ ์— ์ž˜ ๋“ค์–ด๋งž๋Š” ํŠน์ง•์„ ๋ณด์ž…๋‹ˆ๋‹ค. diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md index 7b84a829f5..6cbcc9d577 100644 --- a/1-js/07-object-properties/01-property-descriptors/article.md +++ b/1-js/07-object-properties/01-property-descriptors/article.md @@ -3,9 +3,9 @@ ์•„์‹œ๋‹ค์‹œํ”ผ ๊ฐ์ฒด์—” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. -์ง€๊ธˆ๊นŒ์ง„ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹จ์ˆœํžˆ "ํ‚ค-๊ฐ’" ์Œ์˜ ๊ด€์ ์—์„œ๋งŒ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค ํ”„๋กœํผํ‹ฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง„ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹จ์ˆœํžˆ 'ํ‚ค-๊ฐ’' ์Œ์˜ ๊ด€์ ์—์„œ๋งŒ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค ํ”„๋กœํผํ‹ฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. -์ด ์ฑ•ํ„ฐ์—์„  ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์˜ต์…˜ ๋ช‡ ๊ฐ€์ง€๋ฅผ ๋‹ค๋ฃฐ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„  ์ด ์˜ต์…˜๋“ค์„ ์ด์šฉํ•ด ์†์‰ฝ๊ฒŒ getter๋‚˜ setter ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด ์ฑ•ํ„ฐ์—์„  ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์˜ต์…˜ ๋ช‡ ๊ฐ€์ง€๋ฅผ ๋‹ค๋ฃจ๊ณ , ์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„  ์ด ์˜ต์…˜๋“ค์„ ์ด์šฉํ•ด ์†์‰ฝ๊ฒŒ getter๋‚˜ setter ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ## ํ”„๋กœํผํ‹ฐ ํ”Œ๋ž˜๊ทธ @@ -15,7 +15,7 @@ - **`enumerable`** -- `true`์ด๋ฉด ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋‚˜์—ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - **`configurable`** -- `true`์ด๋ฉด ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋‚˜ ํ”Œ๋ž˜๊ทธ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ์™€ ํ”Œ๋ž˜๊ทธ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -ํ”„๋กœํผํ‹ฐ ํ”Œ๋ž˜๊ทธ๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๊ณ ์„  ๋‹ค๋ฃฐ ์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ์ฒ˜์Œ ์†Œ๊ฐœํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ํ•ด์™”๋˜ "ํ‰๋ฒ”ํ•œ ๋ฐฉ์‹"์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๋ฉด ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์˜ ํ”Œ๋ž˜๊ทธ๋Š” ๋ชจ๋‘ `true`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ `true`๋กœ ์„ค์ •๋œ ํ”Œ๋ž˜๊ทธ๋Š” ์–ธ์ œ๋“  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ”„๋กœํผํ‹ฐ ํ”Œ๋ž˜๊ทธ๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๊ณ ์„  ๋‹ค๋ฃฐ ์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ์ฒ˜์Œ ์†Œ๊ฐœํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ํ•ด์™”๋˜ 'ํ‰๋ฒ”ํ•œ ๋ฐฉ์‹'์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๋ฉด ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์˜ ํ”Œ๋ž˜๊ทธ๋Š” ๋ชจ๋‘ `true`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ `true`๋กœ ์„ค์ •๋œ ํ”Œ๋ž˜๊ทธ๋Š” ์–ธ์ œ๋“  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ํ”„๋กœํผํ‹ฐ ํ”Œ๋ž˜๊ทธ์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ด…์‹œ๋‹ค. ๋จผ์ € ํ”Œ๋ž˜๊ทธ๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -66,7 +66,7 @@ Object.defineProperty(obj, propertyName, descriptor) : ์„ค๋ช…์ž๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฐ์ฒด์™€ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ `descriptor` -: ์ ์šฉํ•˜๊ณ ์žํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž +: ์ ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž `defineProperty`๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด์— ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์œผ๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ๋ฐ›์€ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋•Œ ํ”Œ๋ž˜๊ทธ ์ •๋ณด๊ฐ€ ์—†์œผ๋ฉด ํ”Œ๋ž˜๊ทธ ๊ฐ’์€ ์ž๋™์œผ๋กœ `false`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. @@ -96,7 +96,7 @@ alert( JSON.stringify(descriptor, null, 2 ) ); */ ``` -"ํ‰๋ฒ”ํ•œ ๋ฐฉ์‹์œผ๋กœ" ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ `user.name`์„ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์™€ `defineProperty`๋ฅผ ์ด์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ํ”Œ๋ž˜๊ทธ์— ์žˆ์Šต๋‹ˆ๋‹ค. `defineProperty`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ, `descriptor`์— ํ”Œ๋ž˜๊ทธ ๊ฐ’์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ํ”Œ๋ž˜๊ทธ ๊ฐ’์ด ์ž๋™์œผ๋กœ `false`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ”Œ๋ž˜๊ทธ ๊ฐ’์„ `true`๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด `descriptor`์— `true`๋ผ๊ณ  ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ํ”Œ๋ž˜๊ทธ์˜ ํšจ๊ณผ์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. +'ํ‰๋ฒ”ํ•œ ๋ฐฉ์‹์œผ๋กœ' ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ `user.name`์„ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์™€ `defineProperty`๋ฅผ ์ด์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ํ”Œ๋ž˜๊ทธ์— ์žˆ์Šต๋‹ˆ๋‹ค. `defineProperty`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ, `descriptor`์— ํ”Œ๋ž˜๊ทธ ๊ฐ’์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ํ”Œ๋ž˜๊ทธ ๊ฐ’์ด ์ž๋™์œผ๋กœ `false`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ”Œ๋ž˜๊ทธ ๊ฐ’์„ `true`๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด `descriptor`์— `true`๋ผ๊ณ  ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ํ”Œ๋ž˜๊ทธ์˜ ํšจ๊ณผ์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. ## writable ํ”Œ๋ž˜๊ทธ @@ -241,7 +241,7 @@ Object.defineProperty(user, "name", { // ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. // user.name = "Pete" // delete user.name -// defineProperty(user, "name", { value: "Pete" }) +// Object.defineProperty(user, "name", { value: "Pete" }) Object.defineProperty(user, "name", {writable: true}); // Error */!* ``` @@ -249,7 +249,7 @@ Object.defineProperty(user, "name", {writable: true}); // Error ```smart header="\"non-configurable\"์€ \"non-writable\"๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค." `configurable` ํ”Œ๋ž˜๊ทธ๊ฐ€ `false`์ด๋”๋ผ๋„ `writable` ํ”Œ๋ž˜๊ทธ๊ฐ€ `true`์ด๋ฉด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`configurable: false`๋Š” ํ”Œ๋ž˜๊ทธ ๊ฐ’ ๋ณ€๊ฒฝ์ด๋‚˜ ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์ง€, ํ”„๋กœํผํ‹ฐ ๊ฐ’ ๋ณ€๊ฒฝ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด ์ง„ ๊ฒŒ ์•„๋‹™๋‹ˆ๋‹ค. +`configurable: false`๋Š” ํ”Œ๋ž˜๊ทธ ๊ฐ’ ๋ณ€๊ฒฝ์ด๋‚˜ ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์ง€, ํ”„๋กœํผํ‹ฐ ๊ฐ’ ๋ณ€๊ฒฝ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฒŒ ์•„๋‹™๋‹ˆ๋‹ค. ``` ## Object.defineProperties diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md index dc541b6da0..a150831247 100644 --- a/1-js/07-object-properties/02-property-accessors/article.md +++ b/1-js/07-object-properties/02-property-accessors/article.md @@ -1,31 +1,31 @@ -# Property getters and setters +# ํ”„๋กœํผํ‹ฐ getter์™€ setter -There are two kinds of properties. +๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋Š” ๋‘ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. -The first kind is *data properties*. We already know how to work with them. All properties that we've been using till now were data properties. +์ฒซ ๋ฒˆ์งธ ์ข…๋ฅ˜๋Š” *๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ(data property)* ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ ์กฐ์ž‘ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„  ๋ชจ๋‘ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. -The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code. +๋‘ ๋ฒˆ์งธ๋Š” *์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(accessor property)* ๋ผ ๋ถˆ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์˜ ๋ณธ์งˆ์€ ํ•จ์ˆ˜์ธ๋ฐ, ์ด ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ํš๋“(get)ํ•˜๊ณ  ์„ค์ •(set)ํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœํผํ‹ฐ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. -## Getters and setters +## getter์™€ setter -Accessor properties are represented by "getter" and "setter" methods. In an object literal they are denoted by `get` and `set`: +์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” 'getter(ํš๋“์ž)'์™€ 'setter(์„ค์ •์ž)' ๋ฉ”์„œ๋“œ๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ์•ˆ์—์„œ getter์™€ setter ๋ฉ”์„œ๋“œ๋Š” `get`๊ณผ `set`์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js let obj = { *!*get propName()*/!* { - // getter, the code executed on getting obj.propName + // getter, obj.propName์„ ์‹คํ–‰ํ•  ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ }, *!*set propName(value)*/!* { - // setter, the code executed on setting obj.propName = value + // setter, obj.propName = value๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ } }; ``` -The getter works when `obj.propName` is read, the setter -- when it is assigned. +getter ๋ฉ”์„œ๋“œ๋Š” `obj.propName`์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค๊ณ  ํ•  ๋•Œ ์‹คํ–‰๋˜๊ณ , setter ๋ฉ”์„œ๋“œ๋Š” `obj.propName = value`์œผ๋กœ ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ ค ํ•  ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -For instance, we have a `user` object with `name` and `surname`: +ํ”„๋กœํผํ‹ฐ `name`๊ณผ `surname`์ด ์žˆ๋Š” ๊ฐ์ฒด `user`๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ```js let user = { @@ -34,7 +34,7 @@ let user = { }; ``` -Now we want to add a `fullName` property, that should be `"John Smith"`. Of course, we don't want to copy-paste existing information, so we can implement it as an accessor: +์ด ๊ฐ์ฒด์— `fullName` ์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด `fullName`์ด `'John Smith'`๊ฐ€ ๋˜๋„๋ก ํ•ด๋ด…์‹œ๋‹ค. ๊ธฐ์กด ๊ฐ’์„ ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜์ง€ ์•Š๊ณ  `fullName`์ด `'John Smith'`๊ฐ€ ๋˜๋„๋ก ํ•˜๋ ค๋ฉด ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```js run let user = { @@ -53,9 +53,9 @@ alert(user.fullName); // John Smith */!* ``` -From outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes. +๋ฐ”๊นฅ ์ฝ”๋“œ์—์„  ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ์ด๋Ÿฐ ์•„์ด๋””์–ด์—์„œ ์ถœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜์ฒ˜๋Ÿผ *ํ˜ธ์ถœ* ํ•˜์ง€ ์•Š๊ณ , ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์—์„œ ๊ฐ’์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ‰๋ฒ”ํ•˜๊ฒŒ `user.fullName`์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ *์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค*. ๋‚˜๋จธ์ง€ ์ž‘์—…์€ getter ๋ฉ”์„œ๋“œ๊ฐ€ ๋’ท๋‹จ์—์„œ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค. -As of now, `fullName` has only a getter. If we attempt to assign `user.fullName=`, there will be an error: +ํ•œํŽธ, ์œ„ ์˜ˆ์‹œ์˜ `fullName`์€ getter ๋ฉ”์„œ๋“œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `user.fullName=`์„ ์‚ฌ์šฉํ•ด ๊ฐ’์„ ํ• ๋‹นํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ```js run let user = { @@ -65,11 +65,11 @@ let user = { }; *!* -user.fullName = "Test"; // Error (property has only a getter) +user.fullName = "Test"; // Error (ํ”„๋กœํผํ‹ฐ์— getter ๋ฉ”์„œ๋“œ๋งŒ ์žˆ์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.) */!* ``` -Let's fix it by adding a setter for `user.fullName`: +`user.fullName`์— setter ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๊ณ ์ณ๋ด…์‹œ๋‹ค. ```js run let user = { @@ -87,33 +87,29 @@ let user = { */!* }; -// set fullName is executed with the given value. +// ์ฃผ์–ด์ง„ ๊ฐ’์„ ์‚ฌ์šฉํ•ด set fullName์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. user.fullName = "Alice Cooper"; alert(user.name); // Alice alert(user.surname); // Cooper ``` -As the result, we have a "virtual" property `fullName`. It is readable and writable, but in fact does not exist. +์ด๋ ‡๊ฒŒ getter์™€ setter ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ์ฒด์—” `fullName`์ด๋ผ๋Š” '๊ฐ€์ƒ'์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ๊ฐ€์ƒ์˜ ํ”„๋กœํผํ‹ฐ๋Š” ์ฝ๊ณ  ์“ธ ์ˆœ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -```smart header="No way to handle `delete`" -There's no similar method to handle deletion of an accessor property. Only getter/setter methods may exist. -``` - -## Accessor descriptors +## ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž -Descriptors for accessor properties are different from those for data properties. +๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ ์„ค๋ช…์ž์™€ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์˜ ์„ค๋ช…์ž๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -For accessor properties, there is no `value` or `writable`, but instead there are `get` and `set` functions. +์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์—” ์„ค๋ช…์ž `value`์™€ `writable`๊ฐ€ ์—†๋Š” ๋Œ€์‹ ์— `get`๊ณผ `set`์ด๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -That is, an accessor descriptor may have: +๋”ฐ๋ผ์„œ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ค๋ช…์ž๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. -- **`get`** -- a function without arguments, that works when a property is read, -- **`set`** -- a function with one argument, that is called when the property is set, -- **`enumerable`** -- same as for data properties, -- **`configurable`** -- same as for data properties. +- **`get`** -- ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜๋กœ, ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋•Œ ๋™์ž‘ํ•จ +- **`set`** -- ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜๋กœ, ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ์“ธ ๋•Œ ํ˜ธ์ถœ๋จ +- **`enumerable`** -- ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์™€ ๋™์ผํ•จ +- **`configurable`** -- ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์™€ ๋™์ผํ•จ -For instance, to create an accessor `fullName` with `defineProperty`, we can pass a descriptor with `get` and `set`: +์•„๋ž˜์™€ ๊ฐ™์ด `defineProperty`์— ์„ค๋ช…์ž `get`๊ณผ `set`์„ ์ „๋‹ฌํ•˜๋ฉด `fullName`์„ ์œ„ํ•œ ์ ‘๊ทผ์ž๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let user = { @@ -138,9 +134,9 @@ alert(user.fullName); // John Smith for(let key in user) alert(key); // name, surname ``` -Please note once again that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both. +ํ”„๋กœํผํ‹ฐ๋Š” ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(`get/set` ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง)๋‚˜ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ(`value`๋ฅผ ๊ฐ€์ง) ์ค‘ ํ•œ ์ข…๋ฅ˜์—๋งŒ ์†ํ•˜๊ณ  ๋‘˜ ๋‹ค์— ์†ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ ์„ ํ•ญ์ƒ ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -If we try to supply both `get` and `value` in the same descriptor, there will be an error: +ํ•œ ํ”„๋กœํผํ‹ฐ์— `get`๊ณผ `value`๋ฅผ ๋™์‹œ์— ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ```js run *!* @@ -155,11 +151,11 @@ Object.defineProperty({}, 'prop', { }); ``` -## Smarter getters/setters +## getter์™€ setter ๋˜‘๋˜‘ํ•˜๊ฒŒ ํ™œ์šฉํ•˜๊ธฐ -Getters/setters can be used as wrappers over "real" property values to gain more control over operations with them. +getter์™€ setter๋ฅผ '์‹ค์ œ' ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๊ฐ์‹ธ๋Š” ๋ž˜ํผ(wrapper)์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด, ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, if we want to forbid too short names for `user`, we can have a setter `name` and keep the value in a separate property `_name`: +์•„๋ž˜ ์˜ˆ์‹œ์—์„  `name`์„ ์œ„ํ•œ setter๋ฅผ ๋งŒ๋“ค์–ด `user`์˜ ์ด๋ฆ„์ด ๋„ˆ๋ฌด ์งง์•„์ง€๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ๊ฐ’์€ ๋ณ„๋„์˜ ํ”„๋กœํผํ‹ฐ `_name`์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ```js run let user = { @@ -169,7 +165,7 @@ let user = { set name(value) { if (value.length < 4) { - alert("Name is too short, need at least 4 characters"); + alert("์ž…๋ ฅํ•˜์‹  ๊ฐ’์ด ๋„ˆ๋ฌด ์งง์Šต๋‹ˆ๋‹ค. ๋„ค ๊ธ€์ž ์ด์ƒ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”."); return; } this._name = value; @@ -179,19 +175,19 @@ let user = { user.name = "Pete"; alert(user.name); // Pete -user.name = ""; // Name is too short... +user.name = ""; // ๋„ˆ๋ฌด ์งง์€ ์ด๋ฆ„์„ ํ• ๋‹นํ•˜๋ ค ํ•จ ``` -So, the name is stored in `_name` property, and the access is done via getter and setter. +`user`์˜ ์ด๋ฆ„์€ `_name`์— ์ €์žฅ๋˜๊ณ , ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ getter์™€ setter๋ฅผ ํ†ตํ•ด ์ด๋ค„์ง‘๋‹ˆ๋‹ค. -Technically, external code is able to access the name directly by using `user._name`. But there is a widely known convention that properties starting with an underscore `"_"` are internal and should not be touched from outside the object. +๊ธฐ์ˆ ์ ์œผ๋ก  ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ `user._name`์„ ์‚ฌ์šฉํ•ด ์ด๋ฆ„์— ๋ฐ”๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐ‘์ค„ `"_"` ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ๋งŒ ํ™œ์šฉํ•˜๊ณ , ์™ธ๋ถ€์—์„œ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ด€์Šต์ž…๋‹ˆ๋‹ค. -## Using for compatibility +## ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ -One of the great uses of accessors -- they allow to take control over a "regular" data property at any moment by replacing it with getter and setter and tweak its behavior. + ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ์–ธ์ œ ์–ด๋А ๋•Œ๋‚˜ getter์™€ setter๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ ํ–‰๋™๊ณผ ๊ฐ’์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๋Š” ์ ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -Imagine, we started implementing user objects using data properties `name` and `age`: +๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ `name`๊ณผ `age`๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์šฉ์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ```js function User(name, age) { @@ -204,7 +200,7 @@ let john = new User("John", 25); alert( john.age ); // 25 ``` -...But sooner or later, things may change. Instead of `age` we may decide to store `birthday`, because it's more precise and convenient: +๊ทธ๋Ÿฐ๋ฐ ๊ณง ์š”๊ตฌ์‚ฌํ•ญ์ด ๋ฐ”๋€Œ์–ด์„œ `age` ๋Œ€์‹ ์— `birthday`๋ฅผ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. `age`๋ณด๋‹ค๋Š” `birthday`๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ณ  ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ```js function User(name, birthday) { @@ -215,13 +211,13 @@ function User(name, birthday) { let john = new User("John", new Date(1992, 6, 1)); ``` -Now what to do with the old code that still uses `age` property? +์ด๋ ‡๊ฒŒ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๊ธฐ์กด ์ฝ”๋“œ ์ค‘ ํ”„๋กœํผํ‹ฐ `age`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฝ”๋“œ๋„ ์ˆ˜์ •ํ•ด ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. -We can try to find all such places and fix them, but that takes time and can be hard to do if that code is used by many other people. And besides, `age` is a nice thing to have in `user`, right? +`age`๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๋ถ„์„ ๋ชจ๋‘ ์ฐพ์•„์„œ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด `age`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋ชจ๋‘ ์ฐพ์•„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ํž˜๋“ค์ฃ . ๊ฒŒ๋‹ค๊ฐ€ `age`๋Š” `user` ์•ˆ์— ์žˆ์–ด๋„ ๋‚˜์  ๊ฒƒ์ด ์—†๋Š” ํ”„๋กœํผํ‹ฐ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. -Let's keep it. +๊ธฐ์กด ์ฝ”๋“œ๋“ค์€ ๊ทธ๋Œ€๋กœ ๋‘๋„๋ก ํ•ฉ์‹œ๋‹ค. -Adding a getter for `age` solves the problem: +๋Œ€์‹  `age`๋ฅผ ์œ„ํ•œ getter๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ๋ด…์‹œ๋‹ค. ```js run no-beautify function User(name, birthday) { @@ -229,7 +225,7 @@ function User(name, birthday) { this.birthday = birthday; *!* - // age is calculated from the current date and birthday + // age๋Š” ํ˜„์žฌ ๋‚ ์งœ์™€ ์ƒ์ผ์„ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. Object.defineProperty(this, "age", { get() { let todayYear = new Date().getFullYear(); @@ -241,8 +237,8 @@ function User(name, birthday) { let john = new User("John", new Date(1992, 6, 1)); -alert( john.birthday ); // birthday is available -alert( john.age ); // ...as well as the age +alert( john.birthday ); // birthday๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +alert( john.age ); // age ์—ญ์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -Now the old code works too and we've got a nice additional property. +์ด์ œ ๊ธฐ์กด ์ฝ”๋“œ๋„ ์ž˜ ์ž‘๋™ํ•˜๊ณ , ๋ฉ‹์ง„ ํ”„๋กœํผํ‹ฐ๋„ ์ƒˆ๋กœ ์ƒ๊ฒผ๋„ค์š”. diff --git a/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/solution.md b/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/solution.md index 6d25a462ae..7e3aced468 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/solution.md +++ b/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/solution.md @@ -1,4 +1,4 @@ -1. `true`, taken from `rabbit`. -2. `null`, taken from `animal`. -3. `undefined`, there's no such property any more. +1. `true` -- `rabbit`์—์„œ ๊ฐ€์ ธ์˜ด. +2. `null` -- `animal`์—์„œ ๊ฐ€์ ธ์˜ด. +3. `undefined` -- ๋” ์ด์ƒ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ. diff --git a/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/task.md b/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/task.md index f38fb6f97a..a9df75ce65 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/1-property-after-delete/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Working with prototype +# ํ”„๋กœํ† ํƒ€์ž… ์ดํ•ดํ•˜๊ธฐ -Here's the code that creates a pair of objects, then modifies them. +๊ฐ์ฒด ๋‘ ๊ฐœ๋ฅผ ์ด์šฉํ•ด ์Œ์„ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค. -Which values are shown in the process? +์–ผ๋Ÿฟ์ฐฝ์— ์–ด๋–ค ๊ฐ’์ด ๋‚˜์˜ฌ์ง€ ์˜ˆ์ธกํ•ด๋ณด์„ธ์š”. ```js let animal = { @@ -28,4 +28,4 @@ delete animal.jumps; alert( rabbit.jumps ); // ? (3) ``` -There should be 3 answers. +์„ธ ๊ฐœ์˜ ๋‹ต์„ ์ œ์ถœํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/solution.md b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/solution.md index a16796f9cc..395ad480a6 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/solution.md +++ b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/solution.md @@ -1,5 +1,5 @@ -1. Let's add `__proto__`: +1. `__proto__`๋ฅผ ์ถ”๊ฐ€ํ•ด๋ด…์‹œ๋‹ค. ```js run let head = { @@ -27,6 +27,6 @@ alert( table.money ); // undefined ``` -2. In modern engines, performance-wise, there's no difference whether we take a property from an object or its prototype. They remember where the property was found and reuse it in the next request. +2. ๋ชจ๋˜ ์—”์ง„์—์„  ๊ฐ์ฒด์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๊ณผ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ ์‚ฌ์ด์— ์„ฑ๋Šฅ์ ์ธ ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋˜ ์—”์ง„์€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์–ด๋””์„œ ๋ฐœ๊ฒฌ๋๋Š”์ง€ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๋‹ค์Œ ์š”์ฒญ ์‹œ ์ด ์ •๋ณด๋ฅผ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. - For instance, for `pockets.glasses` they remember where they found `glasses` (in `head`), and next time will search right there. They are also smart enough to update internal caches if something changes, so that optimization is safe. + `pockets.glasses`์„ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ด…์‹œ๋‹ค. ์—”์ง„์€ `glasses`๊ฐ€ ๋ฐœ๊ฒฌ๋œ ๊ณณ(`head`)์„ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, ๋‹ค์Œ ์š”์ฒญ๋ถ€ํ„ด ์ด ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฐœ๊ฒฌ๋œ ๊ณณ์—์„œ ๊ฒ€์ƒ‰์„ ์‹œ์ž‘ํ•  ๊ฒ๋‹ˆ๋‹ค. ๋ชจ๋˜ ์—”์ง„์€ ๋ญ”๊ฐ€ ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋‚ด๋ถ€ ์บ์‹œ๋ฅผ ๋ณ€๊ฒฝํ•ด์ค„ ์ •๋„๋กœ ๋˜‘๋˜‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ ํ™”๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•ด์ค๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md index 421b57e0ae..95a943174a 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/2-search-algorithm/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Searching algorithm +# ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ -The task has two parts. +์ด๋ฒˆ์— ํ’€ ๊ณผ์ œ๋Š” ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. -We have objects: +๋จผ์ €, ์•„๋ž˜ ๊ฐ์ฒด๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js let head = { @@ -27,5 +27,5 @@ let pockets = { }; ``` -1. Use `__proto__` to assign prototypes in a way that any property lookup will follow the path: `pockets` -> `bed` -> `table` -> `head`. For instance, `pockets.pen` should be `3` (found in `table`), and `bed.glasses` should be `1` (found in `head`). -2. Answer the question: is it faster to get `glasses` as `pockets.glasses` or `head.glasses`? Benchmark if needed. +1. `__proto__`๋ฅผ ์‚ฌ์šฉํ•ด์„œ, ํ”„๋กœํผํ‹ฐ ์กฐํšŒ๊ฐ€ `pockets` -> `bed` -> `table` -> `head`์˜ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ฅด๋„๋ก ํ•˜์„ธ์š”. `pockets.pen`์€ `table`์— ์žˆ๋Š” `3`, `bed.glasses`๋Š” `head`์— ์žˆ๋Š” `1`์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +2. `pockets.glasses`๋กœ `glasses`๋ฅผ ์–ป๋Š” ๊ฒƒ์ด ๋น ๋ฅผ๊นŒ์š”? ์•„๋‹ˆ๋ฉด `head.glasses`๋กœ ์–ป๋Š” ๊ฒƒ์ด ๋น ๋ฅผ๊นŒ์š”? ํ•„์š”ํ•˜๋‹ค๋ฉด ๋ฒค์น˜๋งˆํฌ๋ฅผ ์‚ฌ์šฉํ•ด ์„ฑ๋Šฅ์„ ์ธก์ •ํ•ด ๋ณด์„ธ์š”. diff --git a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/solution.md b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/solution.md index 4d6ea2653c..64de4e999c 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/solution.md +++ b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/solution.md @@ -1,7 +1,7 @@ -**The answer: `rabbit`.** +**์ •๋‹ต: `rabbit`** -That's because `this` is an object before the dot, so `rabbit.eat()` modifies `rabbit`. +์  ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด๋Š” `this`์ด๊ธฐ ๋•Œ๋ฌธ์—, `rabbit.eat()`์€ `rabbit`์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. -Property lookup and execution are two different things. +ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ๋Š” ๊ฒƒ๊ณผ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ผ์ž…๋‹ˆ๋‹ค. -The method `rabbit.eat` is first found in the prototype, then executed with `this=rabbit`. +๋ฉ”์„œ๋“œ `eat`์€ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋• `this`๊ฐ€ `rabbit`์ด ๋˜์–ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md index b37499bad5..85149b1ebf 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/3-proto-and-this/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Where it writes? +# ์–ด๋””์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ถ”๊ฐ€๋ ๊นŒ์š” -We have `rabbit` inheriting from `animal`. +`animal`์„ ์ƒ์†๋ฐ›๋Š” `rabbit`์ด ์žˆ์Šต๋‹ˆ๋‹ค. -If we call `rabbit.eat()`, which object receives the `full` property: `animal` or `rabbit`? +`rabbit.eat()`์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, `animal`๊ณผ `rabbit` ์ค‘ ์–ด๋–ค ๊ฐ์ฒด์— `full` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ๊ธธ๊นŒ์š”? ```js let animal = { diff --git a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md index c141b2ecdc..00df1dfb1a 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md +++ b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/solution.md @@ -1,18 +1,18 @@ -Let's look carefully at what's going on in the call `speedy.eat("apple")`. +`speedy.eat("apple")`์„ ํ˜ธ์ถœํ•˜๋ฉด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์ฃผ์˜ ๊นŠ๊ฒŒ ์•Œ์•„๋ณด์•„์•ผ ์›์ธ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -1. The method `speedy.eat` is found in the prototype (`=hamster`), then executed with `this=speedy` (the object before the dot). +1. ๋ฉ”์„œ๋“œ `speedy.eat`์€ ํ”„๋กœํ† ํƒ€์ž… `hamster`์—์„œ ๋ฐœ๊ฒฌ๋˜๋Š”๋ฐ, ์  ์•ž์—” ๊ฐ์ฒด `speedy`๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ `this`์—” `speedy`๊ฐ€ ํ• ๋‹น๋˜์–ด ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -2. Then `this.stomach.push()` needs to find `stomach` property and call `push` on it. It looks for `stomach` in `this` (`=speedy`), but nothing found. +2. `this.stomach.push()`๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ํ”„๋กœํผํ‹ฐ `stomach`์„ ์ฐพ์•„์„œ ์—ฌ๊ธฐ์— `push`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `this`์ธ `speedy`์—” ํ”„๋กœํผํ‹ฐ `stomach`์ด ์—†์Šต๋‹ˆ๋‹ค. -3. Then it follows the prototype chain and finds `stomach` in `hamster`. +3. `stomach`์„ ์ฐพ๊ธฐ์œ„ํ•ด ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ณด๋‹ˆ `hamster`์— `stomach`์ด ์žˆ๋Š”๊ฒƒ์„ ๋ฐœ๊ฒฌํ•ฉ๋‹ˆ๋‹ค. -4. Then it calls `push` on it, adding the food into *the stomach of the prototype*. +4. `push` ๋ฉ”์„œ๋“œ๋Š” *ํ”„๋กœํ† ํƒ€์ž… `hamster`์— ์žˆ๋Š” stomach* ์„ ๋Œ€์ƒ์œผ๋กœ ๋™์ž‘ํ•˜์—ฌ ํ”„๋กœํ† ํƒ€์ž…์— food๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. -So all hamsters share a single stomach! +๋ชจ๋“  ํ–„์Šคํ„ฐ๊ฐ€ ํ•˜๋‚˜์˜ stomach๋ฅผ ๊ณต์œ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฐ”๋กœ ์ด๋Ÿฐ ๋™์ž‘๋ฐฉ์‹ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -Both for `lazy.stomach.push(...)` and `speedy.stomach.push()`, the property `stomach` is found in the prototype (as it's not in the object itself), then the new data is pushed into it. +`lazy.stomach.push(...)`, `speedy.stomach.push()`๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๋ชจ๋‘ ํ”„๋กœํผํ‹ฐ `stomach`์€ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๋ฐœ๊ฒฌ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋Š” `stomach`์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. -Please note that such thing doesn't happen in case of a simple assignment `this.stomach=`: +๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด `push` ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ `this.stomach=`์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```js run let hamster = { @@ -20,7 +20,7 @@ let hamster = { eat(food) { *!* - // assign to this.stomach instead of this.stomach.push + // this.stomach.push(food) ๋Œ€์‹ ์— food๋ฅผ this.stomach์— ํ• ๋‹น this.stomach = [food]; */!* } @@ -34,17 +34,17 @@ let lazy = { __proto__: hamster }; -// Speedy one found the food +// ํ–„์Šคํ„ฐ speedy๊ฐ€ ์Œ์‹์„ ๋จน์Šต๋‹ˆ๋‹ค. speedy.eat("apple"); alert( speedy.stomach ); // apple -// Lazy one's stomach is empty -alert( lazy.stomach ); // +// lazy๋Š” ์Œ์‹์„ ๋จน์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค. +alert( lazy.stomach ); // (์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ ์•ˆ๋จ) ``` -Now all works fine, because `this.stomach=` does not perform a lookup of `stomach`. The value is written directly into `this` object. +`this.stomach=`์€ ๊ฐ์ฒด ์ž์ฒด์— ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์—์„œ `stomach`์„ ์ฐพ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. -Also we can totally avoid the problem by making sure that each hamster has their own stomach: +์ด ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ ํ–„์Šคํ„ฐ๊ฐ€ ๊ฐ์ž์˜ stomach๋ฅผ ๊ฐ€์ง€๊ฒŒ ํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ์‚ฌ์ „์— ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let hamster = { @@ -69,12 +69,12 @@ let lazy = { */!* }; -// Speedy one found the food +// ํ–„์Šคํ„ฐ speedy๊ฐ€ ์Œ์‹์„ ๋จน์Šต๋‹ˆ๋‹ค. speedy.eat("apple"); alert( speedy.stomach ); // apple -// Lazy one's stomach is empty -alert( lazy.stomach ); // +// lazy๋Š” ์Œ์‹์„ ๋จน์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค. +alert( lazy.stomach ); // (์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ ์•ˆ๋จ) ``` -As a common solution, all properties that describe the state of a particular object, like `stomach` above, should be written into that object. That prevents such problems. +๋ฌธ์ œ์˜ `stomach`์ฒ˜๋Ÿผ ํŠน์ • ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์กฐ์ƒ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด ์ž์ฒด์— ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md index 6f9fb279ec..03c5c51d55 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md +++ b/1-js/08-prototypes/01-prototype-inheritance/4-hamster-proto/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Why two hamsters are full? +# ์™œ ํ–„์Šคํ„ฐ ๋‘ ๋งˆ๋ฆฌ ๋ชจ๋‘ ๋ฐฐ๊ฐ€ ๊ฝ‰ ์ฐผ์„๊นŒ์š” -We have two hamsters: `speedy` and `lazy` inheriting from the general `hamster` object. +`hamster` ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›๋Š” ํ–„์Šคํ„ฐ `speedy`์™€ `lazy`๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. -When we feed one of them, the other one is also full. Why? How to fix it? +๋‘˜ ์ค‘ ํ•œ ๋งˆ๋ฆฌ์—๊ฒŒ๋งŒ ๋จน์ด๋ฅผ ์ค˜๋„, ๋‹ค๋ฅธ ํ•œ ๋งˆ๋ฆฌ์˜ ๋ฐฐ ์—ญ์‹œ ๊ฝ‰ ์ฐน๋‹ˆ๋‹ค. ์™œ ๊ทธ๋Ÿด๊นŒ์š”? ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ด๋Ÿฐ ์ด์ƒํ•œ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ```js run let hamster = { @@ -25,11 +25,11 @@ let lazy = { __proto__: hamster }; -// This one found the food +// ํ–„์Šคํ„ฐ speedy๊ฐ€ ์Œ์‹์„ ๋จน์Šต๋‹ˆ๋‹ค. speedy.eat("apple"); alert( speedy.stomach ); // apple -// This one also has it, why? fix please. +// ํ–„์Šคํ„ฐ lazy๋Š” ์Œ์‹์„ ๋จน์ง€ ์•Š์•˜๋Š”๋ฐ ๋ฐฐ์— apple์ด ์žˆ๋‹ค๊ณ  ๋‚˜์˜ค๋„ค์š”. ์™œ ๊ทธ๋Ÿด๊นŒ์š”? lazy๋Š” ๋ฐฐ๊ฐ€ ๋น„์–ด์žˆ๋„๋ก ๊ณ ์ณ์ฃผ์„ธ์š”. alert( lazy.stomach ); // apple ``` diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md index 167e54cc62..eada70304b 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/article.md +++ b/1-js/08-prototypes/01-prototype-inheritance/article.md @@ -2,23 +2,23 @@ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ๊ธฐ์กด์— ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ์™€ ํ™•์žฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. -์‚ฌ๋žŒ์— ๊ด€ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„ `user`๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”๋ฐ, `user`์™€ ์ƒ๋‹นํžˆ ์œ ์‚ฌํ•˜์ง€๋งŒ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” `admin`๊ณผ `guest` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ด๋•Œ `user`์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  `user`์— ์•ฝ๊ฐ„์˜ ๊ธฐ๋Šฅ์„ ์–น์–ด `admin`๊ณผ `guest` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊ฒ๋‹ˆ๋‹ค. +์‚ฌ๋žŒ์— ๊ด€ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„ `user`๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”๋ฐ, `user`์™€ ์ƒ๋‹นํžˆ ์œ ์‚ฌํ•˜์ง€๋งŒ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” `admin`๊ณผ `guest` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ด๋•Œ "`user`์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  `user`์— ์•ฝ๊ฐ„์˜ ๊ธฐ๋Šฅ์„ ์–น์–ด `admin`๊ณผ `guest` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ?"๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค ๊ฒ๋‹ˆ๋‹ค. -*ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†(prototypal inheritance)* ์€ ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด์˜ ๊ณ ์œ  ๊ธฐ๋Šฅ์ธ *ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†(prototypal inheritance)* ์„ ์ด์šฉํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ์ƒ๊ฐ์„ ์‹คํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## [[Prototype]] -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ฐ์ฒด๋Š” ๋ช…์„ธ์„œ์—์„œ ๋ช…๋ช…ํ•œ `[[Prototype]]`์ด๋ผ๋Š” ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ๊ทธ ๊ฐ’์€ `null`์ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์ฐธ์กฐ ๋Œ€์ƒ์„ 'ํ”„๋กœํ† ํƒ€์ž…(prototype)'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ์ฒด๋Š” ๋ช…์„ธ์„œ์—์„œ ๋ช…๋ช…ํ•œ `[[Prototype]]`์ด๋ผ๋Š” ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์ด ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ `null`์ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋˜๋Š”๋ฐ, ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ ์ฐธ์กฐ ๋Œ€์ƒ์„ 'ํ”„๋กœํ† ํƒ€์ž…(prototype)'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ![prototype](object-prototype-empty.svg) -ํ”„๋กœํ† ํƒ€์ž…์˜ ๋™์ž‘ ๋ฐฉ์‹์€ '์‹ ๋น„์Šค๋Ÿฌ์šด'๋ฉด์ด ์žˆ์Šต๋‹ˆ๋‹ค. `object`์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค๊ณ  ํ•˜๋Š”๋ฐ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋™์œผ๋กœ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„  ์ด๋Ÿฐ ๋™์ž‘ ๋ฐฉ์‹์„ 'ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์–ธ์–ด ์ฐจ์›์—์„œ ์ง€์›ํ•˜๋Š” ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์ด๋‚˜ ๊ฐœ๋ฐœ ํ…Œํฌ๋‹‰ ์ค‘ ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†์— ๊ธฐ๋ฐ˜ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ๋“ค์ด ๋งŽ์Šต๋‹ˆ๋‹ค. +ํ”„๋กœํ† ํƒ€์ž…์˜ ๋™์ž‘ ๋ฐฉ์‹์€ '์‹ ๋น„์Šค๋Ÿฌ์šด' ๋ฉด์ด ์žˆ์Šต๋‹ˆ๋‹ค. `object`์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค๊ณ  ํ•˜๋Š”๋ฐ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋™์œผ๋กœ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„  ์ด๋Ÿฐ ๋™์ž‘ ๋ฐฉ์‹์„ 'ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์–ธ์–ด ์ฐจ์›์—์„œ ์ง€์›ํ•˜๋Š” ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์ด๋‚˜ ๊ฐœ๋ฐœ ํ…Œํฌ๋‹‰ ์ค‘ ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†์— ๊ธฐ๋ฐ˜ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ๋“ค์ด ๋งŽ์Šต๋‹ˆ๋‹ค. -`[[Prototype]]` ํ”„๋กœํผํ‹ฐ๋Š” ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ด๋ฉด์„œ ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ์ด์ง€๋งŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`[[Prototype]]` ํ”„๋กœํผํ‹ฐ๋Š” ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ด๋ฉด์„œ ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ์ด์ง€๋งŒ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ `__proto__`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ํŠน๋ณ„ํ•œ ์ด๋ฆ„์ธ `__proto__`์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```js run +```js let animal = { eats: true }; @@ -31,20 +31,20 @@ rabbit.__proto__ = animal; */!* ``` -```smart header="`__proto__`๋Š” `[[Prototype]]`์šฉ getter/setter์ž…๋‹ˆ๋‹ค." -`__proto__`๋Š” `[[Prototype]]`๊ณผ *๋‹ค๋ฆ…๋‹ˆ๋‹ค*. `__proto__`๋Š” `[[Prototype]]`์˜ getter(ํš๋“์ž)/setter(์„ค์ •์ž) ์ž…๋‹ˆ๋‹ค. +```smart header="`__proto__`๋Š” `[[Prototype]]`์šฉ getterยทsetter์ž…๋‹ˆ๋‹ค." +`__proto__`๋Š” `[[Prototype]]`๊ณผ *๋‹ค๋ฆ…๋‹ˆ๋‹ค*. `__proto__`๋Š” `[[Prototype]]`์˜ getter(ํš๋“์ž)์ด์ž setter(์„ค์ •์ž) ์ž…๋‹ˆ๋‹ค. -ํ•˜์œ„ ํ˜ธํ™˜์„ฑ ๋•Œ๋ฌธ์— `__proto__`๋ฅผ ์—ฌ์ „ํžˆ ์“ธ ์ˆœ ์žˆ์ง€๋งŒ ๋น„๊ต์  ๊ทผ๋ž˜์— ์ž‘์„ฑ๋œ ์Šคํฌ๋ฆฝํŠธ์—์„  `__proto__`๋Œ€์‹  ํ•จ์ˆ˜ `Object.getPrototypeOf`๋‚˜ `Object.setPrototypeOf`์„ ์จ์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ํš๋“(get)ํ•˜๊ฑฐ๋‚˜ ์„ค์ •(set)ํ•ฉ๋‹ˆ๋‹ค. ๊ทผ๋ž˜์—” ์™œ `__proto__`๋ฅผ ์“ฐ์ง€ ์•Š๋Š”์ง€์™€ ๋‘ ํ•จ์ˆ˜์˜ ์ž์„ธํ•œ ์„ค๋ช…์— ๋Œ€ํ•ด์„  ์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +ํ•˜์œ„ ํ˜ธํ™˜์„ฑ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ `__proto__`๋ฅผ ์‚ฌ์šฉํ•  ์ˆœ ์žˆ์ง€๋งŒ ๋น„๊ต์  ๊ทผ๋ž˜์— ์ž‘์„ฑ๋œ ์Šคํฌ๋ฆฝํŠธ์—์„  `__proto__` ๋Œ€์‹  ํ•จ์ˆ˜ `Object.getPrototypeOf`๋‚˜ `Object.setPrototypeOf`์„ ์จ์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ํš๋“(get)ํ•˜๊ฑฐ๋‚˜ ์„ค์ •(set)ํ•ฉ๋‹ˆ๋‹ค. ๊ทผ๋ž˜์—” ์™œ `__proto__`๋ฅผ ์“ฐ์ง€ ์•Š๋Š”์ง€์™€ ๋‘ ํ•จ์ˆ˜์˜ ์ž์„ธํ•œ ์„ค๋ช…์— ๋Œ€ํ•ด์„  ์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -`__proto__`๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ์ง€์›ํ•˜๋„๋ก ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์—์„œ ๊ทœ์ •ํ•˜์˜€๋Š”๋ฐ, -์‹ค์ƒ์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ `__proto__`๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. `[[Prototype]]`๋ณด๋‹ค๋Š” `__proto__`๊ฐ€ ์กฐ๊ธˆ ๋” ์ง๊ด€์ ์ด์–ด์„œ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ๋ฏ€๋กœ, ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„  `__proto__`๋ฅผ ์‚ฌ์šฉํ•ด ์˜ˆ์‹œ๋ฅผ ๋งŒ๋“ค๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +`__proto__`๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ์ง€์›ํ•˜๋„๋ก ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์—์„œ ๊ทœ์ •ํ•˜์˜€๋Š”๋ฐ, +์‹ค์ƒ์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ `__proto__`๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. `[[Prototype]]`๋ณด๋‹ค๋Š” `__proto__`๊ฐ€ ์กฐ๊ธˆ ๋” ์ง๊ด€์ ์ด์–ด์„œ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ๋ฏ€๋กœ, ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์˜ ์˜ˆ์‹œ์—์„  `__proto__`๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ``` ๊ฐ์ฒด `rabbit`์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์–ป๊ณ ์‹ถ์€๋ฐ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋‹ค๋ฉด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋™์œผ๋กœ `animal`์ด๋ผ๋Š” ๊ฐ์ฒด์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: -```js +```js run let animal = { eats: true }; @@ -65,15 +65,15 @@ alert( rabbit.jumps ); // true `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„  `animal`์ด `rabbit`์˜ ํ”„๋กœํ† ํƒ€์ž…์ด ๋˜๋„๋ก ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. -`(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `alert` ํ•จ์ˆ˜๊ฐ€ `rabbit.eats` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค ํ–ˆ๋Š”๋ฐ, `rabbit`์—” `eats`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” `[[Prototype]]`์ด ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ธ `animal`์—์„œ `eats`๋ฅผ ์–ป์–ด๋ƒ…๋‹ˆ๋‹ค(์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ฐ‘์—์„œ๋ถ€ํ„ฐ ์œ„๋กœ ์‚ดํŽด๋ณด์„ธ์š”). +`(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `alert` ํ•จ์ˆ˜๊ฐ€ `rabbit.eats` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค ํ–ˆ๋Š”๋ฐ, `rabbit`์—” `eats`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” `[[Prototype]]`์ด ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ธ `animal`์—์„œ `eats`๋ฅผ ์–ป์–ด๋ƒ…๋‹ˆ๋‹ค. ๋‹ค์Œ ๊ทธ๋ฆผ์„ ๋ฐ‘์—์„œ๋ถ€ํ„ฐ ์œ„๋กœ ์‚ดํŽด๋ณด์„ธ์š”. ![](proto-animal-rabbit.svg) -์ด์ œ "`rabbit`์˜ ํ”„๋กœํ† ํƒ€์ž…์€ `animal`์ž…๋‹ˆ๋‹ค."๋‚˜ "`rabbit`์€ `animal`์„ ์ƒ์†๋ฐ›๋Š”๋‹ค."๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋„ค์š”. +์ด์ œ "`rabbit`์˜ ํ”„๋กœํ† ํƒ€์ž…์€ `animal`์ž…๋‹ˆ๋‹ค." ํ˜น์€ "`rabbit`์€ `animal`์„ ์ƒ์†๋ฐ›๋Š”๋‹ค."๋ผ๊ณ  ๋ง ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -๋•๋ถ„์— `rabbit`์—์„œ๋„ `animal`์— ๊ตฌํ˜„๋œ ์œ ์šฉํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋Š” "์ƒ์†๋ฐ›์€(inherited)" ํ”„๋กœํผํ‹ฐ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +ํ”„๋กœํ† ํƒ€์ž…์„ ์„ค์ •ํ•ด ์ค€ ๋•๋ถ„์— `rabbit`์—์„œ๋„ `animal`์— ๊ตฌํ˜„๋œ ์œ ์šฉํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋„ค์š”. ์ด๋ ‡๊ฒŒ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋ฅผ '์ƒ์† ํ”„๋กœํผํ‹ฐ(inherited property)'๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. -`animal`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ `rabbit`์—์„œ ํ˜ธ์ถœํ•ด ๋ด…์‹œ๋‹ค. +์ƒ์† ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด `animal`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ `rabbit`์—์„œ ํ˜ธ์ถœํ•ด ๋ด…์‹œ๋‹ค. ```js run let animal = { @@ -90,17 +90,17 @@ let rabbit = { __proto__: animal }; -// ๋ฉ”์„œ๋“œ walk๋Š” rabbit์˜ ํ”„๋กœํ† ํƒ€์ž…์ธ animal์—์„œ ์ƒ์†๋ฐ›์Œ +// ๋ฉ”์„œ๋“œ walk๋Š” rabbit์˜ ํ”„๋กœํ† ํƒ€์ž…์ธ animal์—์„œ ์ƒ์†๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. *!* rabbit.walk(); // ๋™๋ฌผ์ด ๊ฑท์Šต๋‹ˆ๋‹ค. */!* ``` -์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ํ”„๋กœํ† ํƒ€์ž…(`animal`)์—์„œ `walk`๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์†๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์— `rabbit`์—์„œ๋„ `walk`๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ํ”„๋กœํ† ํƒ€์ž…(`animal`)์—์„œ `walk`๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์†๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์— `rabbit`์—์„œ๋„ `walk`๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ![](proto-animal-rabbit-walk.svg) -ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์€ ์œ„ ์˜ˆ์‹œ๋ณด๋‹ค ๋” ๊ธธ์–ด์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์€ ์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ์˜ˆ์‹œ๋“ค๋ณด๋‹ค ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let animal = { @@ -124,7 +124,7 @@ let longEar = { */!* }; -// ๋ฉ”์„œ๋“œ walk๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์—์„œ ์–ป์–ด์˜ต +// ๋ฉ”์„œ๋“œ walk๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ํ†ตํ•ด ์ƒ์†๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. longEar.walk(); // ๋™๋ฌผ์ด ๊ฑท์Šต๋‹ˆ๋‹ค. alert(longEar.jumps); // true (rabbit์—์„œ ์ƒ์†๋ฐ›์Œ) ``` @@ -136,15 +136,15 @@ alert(longEar.jumps); // true (rabbit์—์„œ ์ƒ์†๋ฐ›์Œ) 1. ์ˆœํ™˜ ์ฐธ์กฐ(circular reference)๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `__proto__`๋ฅผ ์ด์šฉํ•ด ๋‹ซํžŒ ํ˜•ํƒœ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. 2. `__proto__`์˜ ๊ฐ’์€ ๊ฐ์ฒด๋‚˜ `null`๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. -์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๊ฐ์ฒด์—” ์˜ค์ง ํ•˜๋‚˜์˜ `[[Portotype]]`๋งŒ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹น์—ฐํ•œ ์ œ์•ฝ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๊ฐ์ฒด์—” ์˜ค์ง ํ•˜๋‚˜์˜ `[[Prototype]]`๋งŒ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹น์—ฐํ•œ ์ œ์•ฝ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. -## ์“ธ ๋•Œ๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +## ํ”„๋กœํ† ํƒ€์ž…์€ ์ฝ๊ธฐ ์ „์šฉ์ด๋‹ค ํ”„๋กœํ† ํƒ€์ž…์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋•Œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -ํ”„๋กœํผํ‹ฐ๋ฅผ ์“ฐ๊ฑฐ๋‚˜(์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜) ์ง€์šฐ๋Š” ์—ฐ์‚ฐ์€ ๊ฐ์ฒด์— ์ง์ ‘ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€, ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ง€์šฐ๋Š” ์—ฐ์‚ฐ์€ ๊ฐ์ฒด์— ์ง์ ‘ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ๊ฐ์ฒด `rabbit`์— ๋ฉ”์„œ๋“œ `walk`๋ฅผ ์ง์ ‘ ํ• ๋‹นํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. +๊ฐ์ฒด `rabbit`์— ๋ฉ”์„œ๋“œ `walk`๋ฅผ ์ง์ ‘ ํ• ๋‹นํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let animal = { @@ -167,13 +167,13 @@ rabbit.walk = function() { rabbit.walk(); // ํ† ๋ผ๊ฐ€ ๊นก์ถฉ๊นก์ถฉ ๋œ๋‹ˆ๋‹ค. ``` -`rabbit.walk()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ด์   ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด `rabbit`์— ์„ค์ •๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +`rabbit.walk()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ๊ฐ์ฒด `rabbit`์— ์ง์ ‘ ์ถ”๊ฐ€ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ![](proto-animal-rabbit-walk-2.svg) -๊ทธ๋Ÿฐ๋ฐ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(accessor property)๋Š” setter ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฏ€๋กœ ์˜ˆ์™ธ์— ์†ํ•ฉ๋‹ˆ๋‹ค. ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(accessor property)๋Š” setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฏ€๋กœ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹น(`(**)`)ํ•˜๋ฉด ๊ฐ์ฒด(`admin`)์— ํ”„๋กœํผํ‹ฐ(`fullName`)๊ฐ€ ์ถ”๊ฐ€๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ setter ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ์œ„ ์˜ˆ์‹œ์™€๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `admin.fullName`์ด ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `admin.fullName`์ด ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. ```js run let user = { @@ -198,25 +198,29 @@ alert(admin.fullName); // John Smith (*) // setter ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค! admin.fullName = "Alice Cooper"; // (**) + +alert(admin.fullName); // Alice Cooper, setter์— ์˜ํ•ด ์ถ”๊ฐ€๋œ admin์˜ ํ”„๋กœํผํ‹ฐ(name, surname)์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด +alert(user.fullName); // John Smith, ๋ณธ๋ž˜ user์— ์žˆ์—ˆ๋˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’ ``` -`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `admin.fullName`์€ ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” getter ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ , `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์˜ ํ• ๋‹น ์—ฐ์‚ฐ์€ ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” setter ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ต๋‹ˆ๋‹ค. +ํ”„๋กœํ† ํƒ€์ž… `user`์—” getter ํ•จ์ˆ˜ `get fullName`์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„  `get fullName`์ด ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ”„๋กœํ† ํƒ€์ž…์— ์ด๋ฏธ setter ํ•จ์ˆ˜(`set fullName`)๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์˜ ํ• ๋‹น ์—ฐ์‚ฐ์ด ์‹คํ–‰๋˜๋ฉด ๊ฐ์ฒด `user`์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” setter ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + -## 'this'๊ฐ€ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ +## this๊ฐ€ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ -์œ„ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด์„œ "`set fullName(value)`์•ˆ `this`์˜ ๊ฐ’์€ ๋ฌด์—‡์ด์ง€?"๋ผ๋Š” ์˜๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "ํ”„๋กœํผํ‹ฐ `this.name`๊ณผ `this.surname`์— ๊ฐ’์„ ์“ฐ๋ฉด ๊ทธ ๊ฐ’์ด `user`์— ์ €์žฅ๋ ๊นŒ, ์•„๋‹ˆ๋ฉด `admin`์— ์ €์žฅ๋ ๊นŒ?"๋ผ๋Š” ์˜๋ฌธ๋„ ์ƒ๊ธธ ์ˆ˜ ์žˆ์ฃ . +์œ„ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด "`set fullName(value)` ๋ณธ๋ฌธ์˜ `this`์—” ์–ด๋–ค ๊ฐ’์ด ๋“ค์–ด๊ฐ€์ง€?"๋ผ๋Š” ์˜๋ฌธ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "ํ”„๋กœํผํ‹ฐ `this.name`๊ณผ `this.surname`์— ๊ฐ’์„ ์“ฐ๋ฉด ๊ทธ ๊ฐ’์ด `user`์— ์ €์žฅ๋ ๊นŒ, ์•„๋‹ˆ๋ฉด `admin`์— ์ €์žฅ๋ ๊นŒ?"๋ผ๋Š” ์˜๋ฌธ๋„ ์ƒ๊ธธ ์ˆ˜ ์žˆ์ฃ . -๋‹ต์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. `this`๋Š” ํ”„๋กœํ† ํƒ€์ž…์— ์ „ํ˜€ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋‹ต์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. `this`๋Š” ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -**๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ–ˆ๋“  ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ˜ธ์ถœํ–ˆ๋“  ์ƒ๊ด€์—†์ด `this`๋Š” ์–ธ์ œ๋‚˜ `.` ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.** +**๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ–ˆ๋“  ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ˜ธ์ถœํ–ˆ๋“  ์ƒ๊ด€์—†์ด `this`๋Š” ์–ธ์ œ๋‚˜ `.` ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.** -์œ„ ์˜ˆ์‹œ์—์„œ `admin.fullName=`์œผ๋กœ setter ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, `this`๋Š” `user`๊ฐ€ ์•„๋‹Œ `admin`์ด ๋˜์ฃ . +`admin.fullName=`์œผ๋กœ setter ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, `this`๋Š” `user`๊ฐ€ ์•„๋‹Œ `admin`์ด ๋˜์ฃ . -๋ฉ”์„œ๋“œ๊ฐ€ ๋งŽ์ด ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ์ค‘์‹ฌ ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋‹ค์–‘ํ•œ ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ํŠน์ง•์„ ์ž˜ ์•Œ์•„๋‘์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด ์•„๋‹Œ ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. +๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค๊ณ  ์—ฌ๊ธฐ์— ๋ฉ”์„œ๋“œ๋ฅผ ๋งŽ์ด ๊ตฌํ˜„ํ•ด ๋†“์€ ๋‹ค์Œ, ์—ฌ๋Ÿฌ ๊ฐ์ฒด์—์„œ ์ด ์ปค๋‹ค๋ž€ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ํŠน์ง•์„ ์ž˜ ์•Œ์•„๋‘์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด ์•„๋‹Œ ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. -์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์•Œ์•„๋ด…์‹œ๋‹ค. '๋ฉ”์„œ๋“œ ์ €์žฅ์†Œ' ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด `animal`์„ `rabbit`์ด ์ƒ์†๋ฐ›๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. +์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์•Œ์•„๋ด…์‹œ๋‹ค. '๋ฉ”์„œ๋“œ ์ €์žฅ์†Œ' ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด `animal`์„ `rabbit`์ด ์ƒ์†๋ฐ›๊ฒŒ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -`rabbit.sleep()`์„ ํ˜ธ์ถœํ•˜๋ฉด `this.isSleeping`์ด ๊ฐ์ฒด `rabbit`์— ์„ค์ •๋˜๊ฒ ์ฃ . +`rabbit.sleep()`์„ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด `rabbit`์— `isSleeping`ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ```js run // animal์—” ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -236,24 +240,24 @@ let rabbit = { __proto__: animal }; -// rabbit์˜ ํ”„๋กœํผํ‹ฐ isSleeping์„ true๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. +// rabbit์— ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ isSleeping์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ทธ ๊ฐ’์„ true๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. rabbit.sleep(); alert(rabbit.isSleeping); // true alert(animal.isSleeping); // undefined (ํ”„๋กœํ† ํƒ€์ž…์—๋Š” isSleeping์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.) ``` -์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ํ›„, ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ํ›„, ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](proto-animal-rabbit-walk-3.svg) -`rabbit` ๋ง๊ณ ๋„ `bird`, `snake` ๋“ฑ์ด `animal`์„ ์ƒ์†๋ฐ›๋Š”๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ์ด ๊ฐ์ฒด๋“ค๋„ `rabbit`์ฒ˜๋Ÿผ `animal`์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . ์ด๋•Œ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ์˜ `this`๋Š” `animal`์ด ์•„๋‹Œ ์‹ค์ œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์˜ ์ (`.`) ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `this`์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋ฉด `animal`์ด ์•„๋‹Œ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”ํ•ฉ๋‹ˆ๋‹ค. +`rabbit` ๋ง๊ณ ๋„ `bird`, `snake` ๋“ฑ์ด `animal`์„ ์ƒ์†๋ฐ›๋Š”๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ์ด ๊ฐ์ฒด๋“ค๋„ `rabbit`์ฒ˜๋Ÿผ `animal`์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ์˜ `this`๋Š” `animal`์ด ์•„๋‹Œ ์‹ค์ œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์˜ ์ (`.`) ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `this`์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋ฉด `animal`์ด ์•„๋‹Œ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”ํ•ฉ๋‹ˆ๋‹ค. -๊ฒฐ๋ก ์„ ๋ง์”€๋“œ๋ฆฌ์ž๋ฉด ๋ฉ”์„œ๋“œ๋Š” ๊ณต์œ ๋˜์ง€๋งŒ, ๊ฐ์ฒด์˜ ์ƒํƒœ๋Š” ๊ณต์œ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์ด๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ๋Š” ๊ณต์œ ๋˜์ง€๋งŒ, ๊ฐ์ฒด์˜ ์ƒํƒœ๋Š” ๊ณต์œ ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฒฐ๋ก  ๋‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## for..in ๋ฐ˜๋ณต๋ฌธ -`for..in`์€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋„ ์ˆœํšŒ๋Œ€์ƒ์— ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. +`for..in`์€ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋„ ์ˆœํšŒ๋Œ€์ƒ์— ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -273,14 +277,14 @@ alert(Object.keys(rabbit)); // jumps */!* *!* -// for..in์€ ๊ฐ์ฒด ์ž์‹ ์˜ ํ‚ค์™€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ์˜ ํ‚ค ๋ชจ๋‘๋ฅผ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. +// for..in์€ ๊ฐ์ฒด ์ž์‹ ์˜ ํ‚ค์™€ ์ƒ์† ํ”„๋กœํผํ‹ฐ์˜ ํ‚ค ๋ชจ๋‘๋ฅผ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. for(let prop in rabbit) alert(prop); // jumps, eats */!* ``` -[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty)๋ฅผ ์ด์šฉํ•˜๋ฉด ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋Š” `key`์— ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๊ณ  `obj`์— ์ง์ ‘ ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ผ๋ฉด `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty)๋ฅผ ์ด์šฉํ•˜๋ฉด ์ƒ์† ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋Š” `key`์— ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์† ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๊ณ  `obj`์— ์ง์ ‘ ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ํ”„๋กœํผํ‹ฐ์ผ ๋•Œ๋งŒ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -`obj.hasOwnProperty(key)`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์ฒ˜๋Ÿผ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜๋„ ์žˆ๊ณ , ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`obj.hasOwnProperty(key)`๋ฅผ ์‘์šฉํ•˜๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์ฒ˜๋Ÿผ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๊ณ , ์ƒ์† ํ”„๋กœํผํ‹ฐ๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let animal = { @@ -298,33 +302,33 @@ for(let prop in rabbit) { if (isOwn) { alert(`๊ฐ์ฒด ์ž์‹ ์˜ ํ”„๋กœํผํ‹ฐ: ${prop}`); // ๊ฐ์ฒด ์ž์‹ ์˜ ํ”„๋กœํผํ‹ฐ: jumps } else { - alert(`์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ: ${prop}`); // ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ: eats + alert(`์ƒ์† ํ”„๋กœํผํ‹ฐ: ${prop}`); // ์ƒ์† ํ”„๋กœํผํ‹ฐ: eats } } ``` -์œ„ ์˜ˆ์‹œ์˜ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `rabbit`์€ `animal`์„, `animal`์€ `Object.prototype`์„, `Object.prototype`์€ `null`์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค(`animal`์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋ฐฉ์‹์œผ๋กœ ์„ ์–ธํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— `Object.prototype`๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค). +์œ„ ์˜ˆ์‹œ์˜ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `rabbit`์€ `animal`์„, `animal`์€ `Object.prototype`์„, `Object.prototype`์€ `null`์„ ์ƒ์†๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ `animal`์ด `Object.prototype`๋ฅผ ์ƒ์†๋ฐ›๋Š” ์ด์œ ๋Š” `animal`์„ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋ฐฉ์‹์œผ๋กœ ์„ ์–ธํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ![](rabbit-animal-object.svg) -`for..in` ์•ˆ์— ์“ฐ์ธ ๋ฉ”์„œ๋“œ `hasOwnProperty`๋Š” `Object.prototype.hasOwnProperty`์—์„œ ์™”๋‹ค๋Š” ๊ฒƒ์„ ๊ทธ๋ฆผ์„ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋ฆผ์„ ๋ณด๋ฉด `for..in` ์•ˆ์—์„œ ์‚ฌ์šฉํ•œ ๋ฉ”์„œ๋“œ `hasOwnProperty`๊ฐ€ `Object.prototype.hasOwnProperty`์—์„œ ์™”๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์—‡? ๊ทธ๋Ÿฐ๋ฐ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ์ธ `eats`๋Š” ์–ผ๋Ÿฟ ์ฐฝ์— ์ถœ๋ ฅ๋˜๋Š”๋ฐ, `hasOwnProperty`๋Š” ์ถœ๋ ฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฌด์Šจ ์ผ์ด ์žˆ๋Š” ๊ฑธ๊นŒ์š”? +์—‡? ๊ทธ๋Ÿฐ๋ฐ ์ƒ์† ํ”„๋กœํผํ‹ฐ์ธ `eats`๋Š” ์–ผ๋Ÿฟ ์ฐฝ์— ์ถœ๋ ฅ๋˜๋Š”๋ฐ, `hasOwnProperty`๋Š” ์ถœ๋ ฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฌด์Šจ ์ผ์ด ์žˆ๋Š” ๊ฑธ๊นŒ์š”? -์ด์œ ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. `hasOwnProperty`๋Š” ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ(enumerable) ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `Object.prototype`์— ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ์˜ `enumerable` ํ”Œ๋ž˜๊ทธ๋Š” `false`์ธ๋ฐ, `for..in`์€ ์˜ค์ง ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋งŒ ์ˆœํšŒ ๋Œ€์ƒ์— ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. +์ด์œ ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. `hasOwnProperty`๋Š” ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ(enumerable) ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `Object.prototype`์— ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ์˜ `enumerable` ํ”Œ๋ž˜๊ทธ๋Š” `false`์ธ๋ฐ, `for..in`์€ ์˜ค์ง ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋งŒ ์ˆœํšŒ ๋Œ€์ƒ์— ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์— `hasOwnProperty`๋Š” ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -```smart header="ํ‚ค-๊ฐ’์„ ์ˆœํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." -`Object.keys`, `Object.values`์™€ ๊ฐ™์ด ๊ฐ์ฒด์˜ ํ‚ค-๊ฐ’์„ ๋Œ€์ƒ์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +```smart header="ํ‚ค-๊ฐ’์„ ์ˆœํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." +`Object.keys`, `Object.values` ๊ฐ™์ด ๊ฐ์ฒด์˜ ํ‚ค-๊ฐ’์„ ๋Œ€์ƒ์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋Š” *์ œ์™ธํ•˜๊ณ * ํ•ด๋‹น ๊ฐ์ฒด์—์„œ ์ •์˜ํ•œ ํ”„๋กœํผํ‹ฐ๋งŒ ์—ฐ์‚ฐ ๋Œ€์ƒ์— ํฌํ•จํ•˜์ฃ . +ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋Š” *์ œ์™ธํ•˜๊ณ *, ํ•ด๋‹น ๊ฐ์ฒด์—์„œ ์ •์˜ํ•œ ํ”„๋กœํผํ‹ฐ๋งŒ ์—ฐ์‚ฐ ๋Œ€์ƒ์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ``` ## ์š”์•ฝ - ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“  ๊ฐ์ฒด์—” ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ `[[Prototype]]`์ด ์žˆ๋Š”๋ฐ, ์ด ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด๋‚˜ `null`์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `obj.__proto__`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `__proto__`๋Š” `[[Prototype]]`์˜ getter/setter๋กœ ์“ฐ์ด๋Š”๋ฐ, ์š”์ฆ˜์—” ์ž˜ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ๋’ค์ชฝ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -- `[[Prototype]]`์ด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋Š” 'ํ”„๋กœํ† ํƒ€์ž…'์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -- `obj`์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ ค ํ•˜๋Š”๋ฐ ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. +- `obj.__proto__`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `__proto__`๋Š” `[[Prototype]]`์˜ getterยทsetter๋กœ ์“ฐ์ด๋Š”๋ฐ, ์š”์ฆ˜์—” ์ž˜ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ๋’ค์ชฝ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +- `[[Prototype]]`์ด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋ฅผ 'ํ”„๋กœํ† ํƒ€์ž…'์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +- ๊ฐ์ฒด์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๋Š”๋ฐ ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. - ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ๋‹ค๋ฉด, ์“ฐ๊ธฐ๋‚˜ ์ง€์šฐ๊ธฐ์™€ ๊ด€๋ จ ์—ฐ์‚ฐ์€ ํ”„๋กœํ† ํƒ€์ž…์„ ํ†ตํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด์— ์ง์ ‘ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. - ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์ƒ์†๋ฐ›์€ `method`๋ผ๋„ `obj.method()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `method` ์•ˆ์˜ `this`๋Š” ํ˜ธ์ถœ ๋Œ€์ƒ ๊ฐ์ฒด์ธ `obj`๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `for..in` ๋ฐ˜๋ณต๋ฌธ์€ ๊ฐ์ฒด ์ž์ฒด์—์„œ ์ •์˜ํ•œ ํ”„๋กœํผํ‹ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋„ ์ˆœํšŒ ๋Œ€์ƒ์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ํ‚ค-๊ฐ’๊ณผ ๊ด€๋ จ๋œ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ๋Š” ์ œ์™ธํ•˜๊ณ  ๊ฐ์ฒด ์ž์ฒด ํ”„๋กœํผํ‹ฐ๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. \ No newline at end of file +- `for..in` ๋ฐ˜๋ณต๋ฌธ์€ ๊ฐ์ฒด ์ž์ฒด์—์„œ ์ •์˜ํ•œ ํ”„๋กœํผํ‹ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋„ ์ˆœํšŒ ๋Œ€์ƒ์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ํ‚ค-๊ฐ’๊ณผ ๊ด€๋ จ๋œ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ ์ƒ์† ํ”„๋กœํผํ‹ฐ๋Š” ์ œ์™ธํ•˜๊ณ  ๊ฐ์ฒด ์ž์ฒด ํ”„๋กœํผํ‹ฐ๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg b/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg index da48a7ccd9..eb79c19ffd 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/object-prototype-empty.svg @@ -1 +1 @@ -prototype objectobject[[Prototype]] \ No newline at end of file +prototype objectobject[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg index 520bf87edc..4bf580ae77 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-chain.svg @@ -1 +1 @@ -eats: true walk: functionanimaljumps: truerabbit[[Prototype]]earLength: 10longEar[[Prototype]] \ No newline at end of file +eats: true walk: functionanimaljumps: truerabbit[[Prototype]]earLength: 10longEar[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg index 8b6573574d..838c78395b 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-2.svg @@ -1 +1 @@ -eats: true walk: functionanimalwalk: functionrabbit[[Prototype]] \ No newline at end of file +eats: true walk: functionanimalwalk: functionrabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg index 6e3b6f5554..d791e5390d 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk-3.svg @@ -1 +1 @@ -walk: function sleep: functionanimalrabbit[[Prototype]]name: "White Rabbit" isSleeping: true \ No newline at end of file +walk: function sleep: functionanimalrabbit[[Prototype]]name: "White Rabbit" isSleeping: true \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg index b83933a87d..b324710286 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit-walk.svg @@ -1 +1 @@ -eats: true walk: functionanimaljumps: truerabbit[[Prototype]] \ No newline at end of file +eats: true walk: functionanimaljumps: truerabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg index 538f5afb36..4f3c1bc0ec 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-animal-rabbit.svg @@ -1 +1 @@ -eats: trueanimaljumps: truerabbit[[Prototype]] \ No newline at end of file +eats: trueanimaljumps: truerabbit[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg b/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg index ed9fea4a04..bf0baf013a 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/proto-user-admin.svg @@ -1 +1 @@ -name: "John" surname: "Smith" set fullName: functionisAdmin: true name: "Alice" surname: "Cooper"useradmin[[Prototype]] \ No newline at end of file +name: "John" surname: "Smith" set fullName: functionisAdmin: true name: "Alice" surname: "Cooper"useradmin[[Prototype]] \ No newline at end of file diff --git a/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg b/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg index 782a858bdb..32a9858f83 100644 --- a/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg +++ b/1-js/08-prototypes/01-prototype-inheritance/rabbit-animal-object.svg @@ -1 +1 @@ -toString: function hasOwnProperty: function ...Object.prototypeanimal[[Prototype]][[Prototype]][[Prototype]]nulleats: truerabbitjumps: true \ No newline at end of file +toString: function hasOwnProperty: function ...Object.prototypeanimal[[Prototype]][[Prototype]][[Prototype]]nulleats: truerabbitjumps: true \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md index ebbdf3a7c1..9f3c7b76d2 100644 --- a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md +++ b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md @@ -1,20 +1,20 @@ -Answers: +์ •๋‹ต: -1. `true`. +1. `true` - The assignment to `Rabbit.prototype` sets up `[[Prototype]]` for new objects, but it does not affect the existing ones. + `Rabbit.prototype`์— ๋ฌด์–ธ๊ฐ€๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๊ทธ ๊ฐ’์ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ `[[Prototype]]`์ด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์—” ์ด ๊ทœ์น™์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -2. `false`. +2. `false` - Objects are assigned by reference. The object from `Rabbit.prototype` is not duplicated, it's still a single object referenced both by `Rabbit.prototype` and by the `[[Prototype]]` of `rabbit`. + ๊ฐ์ฒด๋Š” ์ฐธ์กฐ์— ์˜ํ•ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. `Rabbit.prototype`์ด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋Š” ๋‹จ ํ•˜๋‚˜๋ฟ์ธ๋ฐ, ์ด ๊ฐ์ฒด๋Š” `Rabbit.prototype`๊ณผ `rabbit`์˜ `[[Prototype]]`์„ ์‚ฌ์šฉํ•ด ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - So when we change its content through one reference, it is visible through the other one. + ๋”ฐ๋ผ์„œ ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋‹ค๋ฅธ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด์„œ๋„ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -3. `true`. +3. `true` - All `delete` operations are applied directly to the object. Here `delete rabbit.eats` tries to remove `eats` property from `rabbit`, but it doesn't have it. So the operation won't have any effect. + `delete` ์—ฐ์‚ฐ์€ ๊ฐ์ฒด์— ์ง์ ‘ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. `delete rabbit.eats`๋Š” `rabbit`์—์„œ `eats` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ฑฐํ•˜๋Š”๋ฐ, `rabbit`์—” `eats`๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `delete`๋Š” ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -4. `undefined`. +4. `undefined` - The property `eats` is deleted from the prototype, it doesn't exist any more. + ํ”„๋กœํผํ‹ฐ `eats`๊ฐ€ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ์‚ญ์ œ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— `eats`๋Š” ๋”์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md index 4b8522d3dd..2d58d029f4 100644 --- a/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md +++ b/1-js/08-prototypes/02-function-prototype/1-changing-prototype/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Changing "prototype" +# 'prototype' ๋ณ€๊ฒฝํ•˜๊ธฐ -In the code below we create `new Rabbit`, and then try to modify its prototype. +์•„๋ž˜ ์ฝ”๋“œ์—์„  `new Rabbit`๋ฅผ ๋งŒ๋“ค๊ณ  `Rabbit`์˜ `"prototype"`์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. -In the start, we have this code: +์‹œ์ž‘ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js run function Rabbit() {} @@ -20,7 +20,7 @@ alert( rabbit.eats ); // true ``` -1. We added one more string (emphasized), what `alert` shows now? +1. ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€(๊ฐ•์กฐ๋œ ์ค„)ํ•˜๋ฉด ์–ผ๋Ÿฟ์ฐฝ์—” ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? ```js function Rabbit() {} @@ -37,7 +37,7 @@ alert( rabbit.eats ); // true alert( rabbit.eats ); // ? ``` -2. ...And if the code is like this (replaced one line)? +2. ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์–ผ๋Ÿฟ์ฐฝ์—” ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? ```js function Rabbit() {} @@ -54,7 +54,7 @@ alert( rabbit.eats ); // true alert( rabbit.eats ); // ? ``` -3. Like this (replaced one line)? +3. ์•„๋ž˜์™€ ๊ฐ™์ด `delete`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ผ๋Ÿฟ์ฐฝ์—” ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? ```js function Rabbit() {} @@ -71,7 +71,7 @@ alert( rabbit.eats ); // true alert( rabbit.eats ); // ? ``` -4. The last variant: +4. ๋งˆ์ง€๋ง‰ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ผ๋Ÿฟ์ฐฝ์—” ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? ```js function Rabbit() {} diff --git a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md index 0073e252ea..08bd62393a 100644 --- a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md +++ b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md @@ -1,6 +1,6 @@ -We can use such approach if we are sure that `"constructor"` property has the correct value. +`"constructor"` ํ”„๋กœํผํ‹ฐ์— ์ œ๋Œ€๋กœ ๋œ ๊ฐ’์ด ์ €์žฅ๋˜์–ด์žˆ๋‹ค๋ฉด ์œ„์™€ ๊ฐ™์€ ์ ‘๊ทผ๋ฒ•์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -For instance, if we don't touch the default `"prototype"`, then this code works for sure: +๊ธฐ๋ณธ `"prototype"`๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ๋Š” ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```js run function User(name) { @@ -10,14 +10,14 @@ function User(name) { let user = new User('John'); let user2 = new user.constructor('Pete'); -alert( user2.name ); // Pete (worked!) +alert( user2.name ); // Pete (์ž˜ ๋™์ž‘ํ•˜๋„ค์š”!) ``` -It worked, because `User.prototype.constructor == User`. +`User.prototype.constructor == User`์ด๊ธฐ ๋•Œ๋ฌธ์— ์œ„ ์˜ˆ์‹œ๋Š” ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -..But if someone, so to speak, overwrites `User.prototype` and forgets to recreate `constructor` to reference `User`, then it would fail. +๊ทธ๋Ÿฐ๋ฐ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ `User.prototype`๋ฅผ ๋ฎ์–ด์“ฐ๊ณ  `User`๋ฅผ ์ฐธ์กฐํ•˜๋Š” `constructor`๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฑธ ์žŠ์—ˆ๋‹ค๋ฉด ๋ฌธ์ œ์˜ ์ ‘๊ทผ๋ฒ•์€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js run function User(name) { @@ -33,12 +33,12 @@ let user2 = new user.constructor('Pete'); alert( user2.name ); // undefined ``` -Why `user2.name` is `undefined`? +์™œ `user2.name`์ด `undefined`๊ฐ€ ๋ ๊นŒ์š”? -Here's how `new user.constructor('Pete')` works: +๊ทธ ์ด์œ ๋Š” `new user.constructor('Pete')`๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -1. First, it looks for `constructor` in `user`. Nothing. -2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has nothing. -3. The value of `User.prototype` is a plain object `{}`, its prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used. +1. `new user.constructor('Pete')`๋Š” `user`์—์„œ `constructor`๋ฅผ ์ฐพ๋Š”๋ฐ ์•„๋ฌด๊ฒƒ๋„ ์ฐพ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. +2. ๊ฐ์ฒด์—์„œ ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๊ฒ€์ƒ‰์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `user`์˜ ํ”„๋กœํ† ํƒ€์ž…์€ `User.prototype`์ธ๋ฐ, `User.prototype`์€ ๋นˆ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. +3. `User.prototype`์€ ์ผ๋ฐ˜ ๊ฐ์ฒด `{}`์ด๊ณ , ์ผ๋ฐ˜ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์€ `Object.prototype`์ž…๋‹ˆ๋‹ค. `Object.prototype.constructor == Object`์ด๋ฏ€๋กœ `Object`๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object, similar to `let user2 = {}`, that's what we have in `user2` after all. +๊ฒฐ๊ตญ์— `let user2 = new user.constructor('Pete');`๋Š” `let user2 = new Object('Pete')`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `Object`์˜ ์ƒ์„ฑ์ž๋Š” ์ธ์ˆ˜๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ํ•ญ์ƒ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `let user2 = new Object('Pete')`๋Š” `let user2 = {}`์™€ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `user2.name`์ด `undefined`์ธ ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/task.md b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/task.md index 934f3470b9..d45b530210 100644 --- a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/task.md +++ b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/task.md @@ -2,14 +2,14 @@ importance: 5 --- -# Create an object with the same constructor +# ๋™์ผํ•œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ -Imagine, we have an arbitrary object `obj`, created by a constructor function -- we don't know which one, but we'd like to create a new object using it. +์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ํ•˜๋‚˜ ์žˆ๊ณ , ์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ์ž„์˜์˜ ๊ฐ์ฒด `obj`๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ์ง€๊ธˆ์€ ์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. -Can we do it like that? +์ •์ฒด๋ฅผ ๋ชจ๋ฅด๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š”๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”? ```js let obj2 = new obj.constructor(); ``` -Give an example of a constructor function for `obj` which lets such code work right. And an example that makes it work wrong. +์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ์˜ˆ์‹œ๋„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/article.md b/1-js/08-prototypes/02-function-prototype/article.md index 871ab8e2d2..963e08fe78 100644 --- a/1-js/08-prototypes/02-function-prototype/article.md +++ b/1-js/08-prototypes/02-function-prototype/article.md @@ -1,16 +1,16 @@ # ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ -`new F()`์™€ ๊ฐ™์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ์•ž์„œ ๋ฐฐ์šด ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” ๋ฆฌํ„ฐ๋Ÿด ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `new F()`์™€ ๊ฐ™์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ๋„ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ๋ฐฐ์šด ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -`F.prototype`์ด ๊ฐ์ฒด๋ผ๋ฉด `new` ์—ฐ์‚ฐ์ž๋Š” `F.prototype`์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ [[Prototype]]์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +์ด๋ฒˆ ๊ธ€์—์„  ์ƒ์„ฑ์ž 'ํ•จ์ˆ˜'๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ์— ํ”„๋กœํ† ํƒ€์ž…์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ ๋ฆฌํ„ฐ๋Ÿด ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅธ์ ์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž…์ด ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ์— `new` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž… ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ด [[Prototype]]์„ ์„ค์ •ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ```smart -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฒ˜์Œ ๋งŒ๋“ค์–ด์กŒ์„ ๋• ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ์ƒ์†์ด ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์„ ๋‹น์‹œ์—” ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ์ƒ์†์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. -๊ทธ๋Ÿฐ๋ฐ ๊ณผ๊ฑฐ์—” ํ”„๋กœ๋กœํƒ€์ž…์— ์ง์ ‘ ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋‚˜๋งˆ ๋ฏฟ๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๋ฐฉ๋ฒ•์€ ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•  ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ `"prototype"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋ฟ์ด์—ˆ์ฃ . ๋งŽ์€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„์ง ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ๊ณผ๊ฑฐ์—” ํ”„๋กœํ† ํƒ€์ž…์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋‚˜๋งˆ ๋ฏฟ๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๋ฐฉ๋ฒ•์€ ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•  ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ `"prototype"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋ฟ์ด์—ˆ์ฃ . ๋งŽ์€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„์ง ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. ``` -`F.prototype`์—์„œ `"prototype"`์€ `F`์— ์ •์˜๋œ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ๋ผ๋Š” ์ ์— ์ฃผ์˜ํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์•ž์„œ ๋ฐฐ์› ๋˜ 'ํ”„๋กœํ† ํƒ€์ž…' ๊ฐ์ฒด์™€ ๊ฐ™์•„ ๋ณด์ด์ง€๋งŒ `F.prototype`์—์„œ `"prototype"`์€ ์ด๋ฆ„๋งŒ ๊ฐ™์€ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. +์ƒ์„ฑ์ž ํ•จ์ˆ˜(`F`)์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์˜๋ฏธํ•˜๋Š” `F.prototype`์—์„œ `"prototype"`์€ `F`์— ์ •์˜๋œ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ๋ผ๋Š” ์ ์— ์ฃผ์˜ํ•ด ๊ธ€์„ ์ฝ์–ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. `F.prototype`์—์„œ `"prototype"`์€ ๋ฐ”๋กœ ์•ž์—์„œ ๋ฐฐ์šด 'ํ”„๋กœํ† ํƒ€์ž…'๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋“ค๋ฆฌ๊ฒ ์ง€๋งŒ ์ด๋ฆ„๋งŒ ๊ฐ™์„ ๋ฟ ์‹ค์ œ๋ก  ๋‹ค๋ฅธ ์šฐ๋ฆฌ๊ฐ€ ์ตํžˆ ์•Œ๊ณ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -27,68 +27,68 @@ function Rabbit(name) { Rabbit.prototype = animal; */!* -let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal +let rabbit = new Rabbit("ํฐ ํ† ๋ผ"); // rabbit.__proto__ == animal alert( rabbit.eats ); // true ``` -`Rabbit.prototype = animal`์€ "`new Rabbit`์ด ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ, ์ด๊ฒƒ์˜ `[[Prototype]]`์„ `animal`๋กœ ํ• ๋‹นํ•˜๋ผ."๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +`Rabbit.prototype = animal`์€ "`new Rabbit`์„ ํ˜ธ์ถœํ•ด ๋งŒ๋“  ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ `[[Prototype]]`์„ `animal`๋กœ ์„ค์ •ํ•˜๋ผ."๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -์ด๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ด…์‹œ๋‹ค. +๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](proto-constructor-animal-rabbit.svg) -๊ทธ๋ฆผ์—์„œ ๊ฐ€๋กœ ํ™”์‚ดํ‘œ๋Š” ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์ธ `"prototype"`์„, ์„ธ๋กœ ํ™”์‚ดํ‘œ๋Š” `[[Prototype]]`์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์„ธ๋กœ ํ™”์‚ดํ‘œ๋Š” `rabbit`์ด `animal`์„ ์ƒ์†๋ฐ›์•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์„œ ๊ฐ€๋กœ ํ™”์‚ดํ‘œ๋Š” ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์ธ `"prototype"`์„, ์„ธ๋กœ ํ™”์‚ดํ‘œ๋Š” `[[Prototype]]`์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์„ธ๋กœ ํ™”์‚ดํ‘œ๋Š” `rabbit`์ด `animal`์„ ์ƒ์†๋ฐ›์•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -```smart header="`F.prototype`์€ `new F`์ด ํ˜ธ์ถœ๋  ๋•Œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค." -`F.prototype` ํ”„๋กœํผํ‹ฐ๋Š” `new F`๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งŒ ์‚ฌ์šฉ๋˜์–ด ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ํ• ๋‹นํ•ด์ค๋‹ˆ๋‹ค. ์ด ์ž‘์—… ์ดํ›„์—” `F.prototype`๊ณผ ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ ์—ฐ๊ด€ ๊ด€๊ณ„๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. `F.prototype`๋Š” 'ํ•œ ๋ฒˆ๋งŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ์„ ๋ฌผ'์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. +```smart header="`F.prototype`์€ `new F`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค." +`F.prototype` ํ”„๋กœํผํ‹ฐ๋Š” `new F`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. `new F`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งŒ๋“ค์–ด์ง€๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ํ• ๋‹นํ•ด ์ฃผ์ฃ . -์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ์ดํ›„์— `F.prototype` ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฐ”๋€๋‹ค๋ฉด(`F.prototype = `) `new F`๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ `[[Prototype]]`์œผ๋กœ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ๊ธฐ์กด์— ์žˆ๋˜ ๊ฐ์ฒด์˜ `[[Prototype]]`์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ํ›„์— `F.prototype` ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด(`F.prototype = `) `new F`๋ฅผ ํ˜ธ์ถœํ•ด ๋งŒ๋“œ๋Š” ๋˜ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋Š” another object๋ฅผ `[[Prototype]]`์œผ๋กœ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ๊ธฐ์กด์— ์žˆ๋˜ ๊ฐ์ฒด์˜ `[[Prototype]]`์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ``` -## ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์™€ constructor ํ”„๋กœํผํ‹ฐ +## ํ•จ์ˆ˜์˜ ๋””ํดํŠธ ํ”„๋กœํผํ‹ฐ prototype๊ณผ constructor ํ”„๋กœํผํ‹ฐ -๊ฐœ๋ฐœ์ž๊ฐ€ ํŠน๋ณ„ํžˆ ํ• ๋‹นํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” "prototype" ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. +๊ฐœ๋ฐœ์ž๊ฐ€ ํŠน๋ณ„ํžˆ ํ• ๋‹นํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ `"prototype"` ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. -๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ์ธ `"prototype"`์€ `constructor` ํ”„๋กœํผํ‹ฐ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ, `constructor` ํ”„๋กœํผํ‹ฐ๋Š” ํ•จ์ˆ˜ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +๋””ํดํŠธ(์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ ์ž๋™์œผ๋กœ ์„ ํƒ๋˜๋Š” ๋ฌด์–ธ๊ฐ€ โ€“ ์˜ฎ๊ธด์ด) ํ”„๋กœํผํ‹ฐ `"prototype"`์€ `constructor` ํ”„๋กœํผํ‹ฐ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ `constructor` ํ”„๋กœํผํ‹ฐ๋Š” ํ•จ์ˆ˜ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ์ด ๊ด€๊ณ„๋ฅผ ์ฝ”๋“œ์™€ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js function Rabbit() {} -/* ๊ธฐ๋ณธ prototype +/* ๋””ํดํŠธ prototype Rabbit.prototype = { constructor: Rabbit }; */ ``` ![](function-prototype-constructor.svg) -์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด ์ด๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•ด ์ง์ ‘ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. ```js run function Rabbit() {} -// ๊ธฐ๋ณธ prototype: +// ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ธฐ๋งŒ ํ•ด๋„ ๋””ํดํŠธ ํ”„๋กœํผํ‹ฐ์ธ prototype์ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค. // Rabbit.prototype = { constructor: Rabbit } alert( Rabbit.prototype.constructor == Rabbit ); // true ``` -ํŠน๋ณ„ํ•œ ์กฐ์ž‘์„ ๊ฐ€ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด `Rabbit`์„ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด ๋ชจ๋‘์—์„œ `[[Prototype]]`์„ ๊ฑฐ์ณ `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํŠน๋ณ„ํ•œ ์กฐ์ž‘์„ ๊ฐ€ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด `new Rabbit`์„ ์‹คํ–‰ํ•ด ๋งŒ๋“  ํ† ๋ผ ๊ฐ์ฒด ๋ชจ๋‘์—์„œ `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋•Œ `[[Prototype]]`์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. ```js run function Rabbit() {} -// ๊ธฐ๋ณธ prototype: +// ๋””ํดํŠธ prototype: // Rabbit.prototype = { constructor: Rabbit } -let rabbit = new Rabbit(); // {constructor: Rabbit}์—์„œ ์ƒ์† +let rabbit = new Rabbit(); // {constructor: Rabbit}์„ ์ƒ์†๋ฐ›์Œ -alert(rabbit.constructor == Rabbit); // true (ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฑฐ์ณ ์ ‘๊ทผํ•จ) +alert(rabbit.constructor == Rabbit); // true ([[Prototype]]์„ ๊ฑฐ์ณ ์ ‘๊ทผํ•จ) ``` ![](rabbit-prototype-constructor.svg) -`constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด์— ์žˆ๋˜ ๊ฐ์ฒด์˜ `constructor`๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`constructor` ํ”„๋กœํผํ‹ฐ๋Š” ๊ธฐ์กด์— ์žˆ๋˜ ๊ฐ์ฒด์˜ `constructor`๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . @@ -98,22 +98,22 @@ function Rabbit(name) { alert(name); } -let rabbit = new Rabbit("White Rabbit"); +let rabbit = new Rabbit("ํฐ ํ† ๋ผ"); *!* -let rabbit2 = new rabbit.constructor("Black Rabbit"); +let rabbit2 = new rabbit.constructor("๊ฒ€์ • ํ† ๋ผ"); */!* ``` -๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”๋ฐ ์ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์–ด๋–ค ์ƒ์„ฑ์ž๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ(์˜ˆ: ๊ฐ์ฒด๊ฐ€ ์„œ๋“œ ํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜จ ๊ฒฝ์šฐ)์— ์ด ๋ฐฉ์‹์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ด ๋ฐฉ๋ฒ•์€ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”๋ฐ ์ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์–ด๋–ค ์ƒ์„ฑ์ž๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ(๊ฐ์ฒด๊ฐ€ ์„œ๋“œ ํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜จ ๊ฒฝ์šฐ ๋“ฑ) ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์–ด๋А ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋“  `"constructor"`์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +`"constructor"`๋ฅผ ์ด์•ผ๊ธฐ ํ•  ๋•Œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ ์€ -**์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์•Œ๋งž์€ `"constructor"` ๊ฐ’์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** +**์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์•Œ๋งž์€ `"constructor"` ๊ฐ’์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค**๋Š” ์ ์ž…๋‹ˆ๋‹ค. -ํ•จ์ˆ˜์— ๊ธฐ๋ณธ์œผ๋กœ `"prototype"` ๊ฐ’์ด ์„ค์ •๋˜๊ธด ํ•˜์ง€๋งŒ ๊ทธ๊ฒŒ ์ „๋ถ€ ์ž…๋‹ˆ๋‹ค. `"constructor"`์— ๋ฒŒ์–ด์ง€๋Š” ์ผ ๋ชจ๋‘๋Š” ์ „์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋‹ฌ๋ ค์žˆ์Šต๋‹ˆ๋‹ค. +ํ•จ์ˆ˜์—” ๊ธฐ๋ณธ์œผ๋กœ `"prototype"`์ด ์„ค์ •๋œ๋‹ค๋ผ๋Š” ์‚ฌ์‹ค ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. `"constructor"`์™€ ๊ด€๋ จํ•ด์„œ ๋ฒŒ์–ด์ง€๋Š” ๋ชจ๋“  ์ผ์€ ์ „์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋‹ฌ๋ ค์žˆ์Šต๋‹ˆ๋‹ค. -ํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ `"prototype"` ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๋ฉด ์ด ๊ฐ์ฒด์—” `"constructor"`๊ฐ€ ์—†์„ ๊ฒ๋‹ˆ๋‹ค. +ํ•จ์ˆ˜์— ๊ธฐ๋ณธ์œผ๋กœ ์„ค์ •๋˜๋Š” `"prototype"` ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ” ๋ฌด์Šจ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์‚ดํŽด๋ด…์‹œ๋‹ค. new๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์—ˆ์ง€๋งŒ ์ด ๊ฐ์ฒด์— `"constructor"`๊ฐ€ ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -129,18 +129,18 @@ alert(rabbit.constructor === Rabbit); // false */!* ``` -์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์•Œ๋งž์€ `constructor`๋ฅผ ์œ ์ง€ํ•˜๋ ค๋ฉด `"prototype"` ์ „์ฒด๋ฅผ ๋ฎ์–ด์“ฐ์ง€ ๋ง๊ณ  ๊ธฐ๋ณธ `"prototype"`์— ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€/์ œ๊ฑฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ณ  `constructor`์˜ ๊ธฐ๋ณธ ์„ฑ์งˆ์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋ ค๋ฉด `"prototype"`์— ๋ญ”๊ฐ€๋ฅผ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ `"prototype"` ์ „์ฒด๋ฅผ ๋ฎ์–ด์“ฐ์ง€ ๋ง๊ณ  ๋””ํดํŠธ `"prototype"`์— ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€, ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js function Rabbit() {} // Rabbit.prototype ์ „์ฒด๋ฅผ ๋ฎ์–ด์“ฐ์ง€ ๋ง๊ณ  -// ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๊ทธ๋ƒฅ ์ถ”๊ฐ€ํ•˜์„ธ์š”. +// ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๋ƒฅ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Rabbit.prototype.jumps = true -// ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ๋ณธ Rabbit.prototype.constructor๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. +// ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋””ํดํŠธ ํ”„๋กœํผํ‹ฐ Rabbit.prototype.constructor๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ``` -`constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ๋„ ๋Œ€์•ˆ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์‹ค์ˆ˜๋กœ `"prototype"`์„ ๋ฎ์–ด์ผ๋‹ค ํ•˜๋”๋ผ๋„ `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ฃผ๋ฉด `constructor`๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js Rabbit.prototype = { @@ -150,21 +150,21 @@ Rabbit.prototype = { */!* }; -// ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•Œ๋งž์€ constructor๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. +// ์ˆ˜๋™์œผ๋กœ constructor๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋˜ constructor์˜ ํŠน์ง•์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` ## ์š”์•ฝ -์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด์— `[[Prototype]]`์„ ์„ค์ •ํ•ด ์ฃผ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ„๋žตํžˆ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๊ณ ๊ธ‰ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด์— ๋Œ€ํ•ด์„  ์ถ”ํ›„ ํ•™์Šตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด์˜ `[[Prototype]]`์ด ์–ด๋–ป๊ฒŒ ์„ค์ •๋˜๋Š”์ง€ ๊ฐ„๋žตํžˆ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๊ณ ๊ธ‰ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด์— ๋Œ€ํ•ด์„  ์ถ”ํ›„ ํ•™์Šตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์‚ฌํ•ญ๋งŒ ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฉด ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๊ฒƒ๋“ค์€ ๋ณต์žกํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- `F.prototype` ํ”„๋กœํผํ‹ฐ(`[[prototype]]`๊ณผ๋Š” ๋‹ค๋ฆ„)๋Š” `new F()`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งŒ๋“ค์–ด์ง€๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +- ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ๊ธฐ๋ณธ์œผ๋กœ ์„ธํŒ…๋˜๋Š” ํ”„๋กœํผํ‹ฐ(`F.prototype`)๋Š” `[[Prototype]]`๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. `F.prototype`์€ `new F()`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งŒ๋“ค์–ด์ง€๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - `F.prototype`์˜ ๊ฐ’์€ ๊ฐ์ฒด๋‚˜ null๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฐ’์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. -- `"prototype"` ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์„ค์ •ํ•˜๊ณ  `new`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ์œ„์™€ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ฐœํœ˜ํ•ฉ๋‹ˆ๋‹ค. +- ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ `new`๋ฅผ ์‚ฌ์šฉํ•ด ํ˜ธ์ถœํ•  ๋•Œ๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. -์ผ๋ฐ˜ ๊ฐ์ฒด์— `"prototype"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ฌด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ ์ผ๋ฐ˜ ๊ฐ์ฒด์—” `"prototype"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ ์•„๋ฌด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js let user = { name: "John", @@ -172,4 +172,4 @@ let user = { }; ``` -๋ชจ๋“  ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ `F.prototype = { constructor : F }`๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ํ•จ์ˆ˜์˜ `"constructor"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ชจ๋“  ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ `F.prototype = { constructor : F }`๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ `"constructor"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg b/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg index 187b899e48..59d60b397a 100644 --- a/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg +++ b/1-js/08-prototypes/02-function-prototype/function-prototype-constructor.svg @@ -1 +1 @@ -Rabbitprototypeconstructordefault "prototype" \ No newline at end of file +Rabbitprototypeconstructordefault "prototype" \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg b/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg index a2c19d8505..ede4e1227e 100644 --- a/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg +++ b/1-js/08-prototypes/02-function-prototype/proto-constructor-animal-rabbit.svg @@ -1 +1 @@ -eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file +eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg b/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg index 4d6b10e303..54b3d79804 100644 --- a/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg +++ b/1-js/08-prototypes/02-function-prototype/rabbit-prototype-constructor.svg @@ -1 +1 @@ -default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file +default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/solution.md b/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/solution.md index ebd2f44e9c..3423ba52f8 100644 --- a/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/solution.md +++ b/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/solution.md @@ -9,5 +9,5 @@ function f() { alert("Hello!"); } -f.defer(1000); // shows "Hello!" after 1 sec +f.defer(1000); // 1์ดˆ ํ›„ "Hello!" ์ถœ๋ ฅ ``` diff --git a/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/task.md b/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/task.md index d3b3a51c2a..04dc36230f 100644 --- a/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/task.md +++ b/1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/task.md @@ -2,16 +2,18 @@ importance: 5 --- -# Add method "f.defer(ms)" to functions +# ๋ฉ”์„œ๋“œ"f.defer(ms)"๋ฅผ ํ•จ์ˆ˜์— ์ถ”๊ฐ€ํ•˜๊ธฐ -Add to the prototype of all functions the method `defer(ms)`, that runs the function after `ms` milliseconds. +๋ชจ๋“  ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž…์— `ms`๋ฐ€๋ฆฌ์ดˆ ํ›„์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” `defer(ms)`ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. -After you do it, such code should work: +ํ•จ์ˆ˜๋ฅผ ํ”„๋กœํ† ํƒ€์ž…์— ์ถ”๊ฐ€ํ•œ ์ดํ›„ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js function f() { alert("Hello!"); } -f.defer(1000); // shows "Hello!" after 1 second +f.defer(1000); // 1์ดˆ ํ›„ "Hello!" ์ถœ๋ ฅ ``` + +์ธ์ˆ˜๋“ค์€ ๊ธฐ์กด ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘์„ธ์š”. diff --git a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md index 99c358c9b0..1a6958f1ce 100644 --- a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md +++ b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md @@ -8,17 +8,17 @@ Function.prototype.defer = function(ms) { } }; -// check it +// ํ™•์ธํ•ด ๋ณด์„ธ์š”. function f(a, b) { alert( a + b ); } -f.defer(1000)(1, 2); // shows 3 after 1 sec +f.defer(1000)(1, 2); // 1์ดˆ ํ›„ 3 ์ถœ๋ ฅ ``` -Please note: we use `this` in `f.apply` to make our decoration work for object methods. +๊ฐ์ฒด ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋ฐ์ฝ”๋ ˆ์ด์…˜ ๋™์ž‘์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ `this`๋ฅผ `f.apply`์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘์„ธ์š”. -So if the wrapper function is called as an object method, then `this` is passed to the original method `f`. +๊ทธ๋ž˜์„œ ๋ž˜ํผ ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋กœ์จ ํ˜ธ์ถœ๋œ๋‹ค๋ฉด `this`๋Š” ๊ธฐ์กด ๋ฉ”์„œ๋“œ `f`์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ```js run Function.prototype.defer = function(ms) { diff --git a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/task.md b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/task.md index 4d3823bb85..140d0b0678 100644 --- a/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/task.md +++ b/1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/task.md @@ -2,18 +2,18 @@ importance: 4 --- -# Add the decorating "defer()" to functions +# ๋ฐ์ฝ”๋ ˆ์ดํŒ… "defer()"๋ฅผ ํ•จ์ˆ˜์— ์ถ”๊ฐ€ํ•˜๊ธฐ -Add to the prototype of all functions the method `defer(ms)`, that returns a wrapper, delaying the call by `ms` milliseconds. +๋ชจ๋“  ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž…์— `ms` ๋ฐ€๋ฆฌ์„ธ์ปจ์ดˆ ์ง€์—ฐ ํ˜ธ์ถœ ๋ž˜ํผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” `defer(ms)` ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. -Here's an example of how it should work: +์•„๋ž˜๋Š” ๋™์ž‘์˜ˆ์‹œ ์ž…๋‹ˆ๋‹ค. ```js function f(a, b) { alert( a + b ); } -f.defer(1000)(1, 2); // shows 3 after 1 second +f.defer(1000)(1, 2); // 1์ดˆ ํ›„ 3์„ ์ถœ๋ ฅ ``` -Please note that the arguments should be passed to the original function. +์ธ์ˆ˜๋“ค์€ ๊ธฐ์กด ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘์„ธ์š”. diff --git a/1-js/08-prototypes/03-native-prototypes/article.md b/1-js/08-prototypes/03-native-prototypes/article.md index b50e779ecf..d655f06df7 100644 --- a/1-js/08-prototypes/03-native-prototypes/article.md +++ b/1-js/08-prototypes/03-native-prototypes/article.md @@ -1,115 +1,117 @@ -# Native prototypes +# ๋‚ด์žฅ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… -The `"prototype"` property is widely used by the core of JavaScript itself. All built-in constructor functions use it. +`prototype` ํ”„๋กœํผํ‹ฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์—์„œ๋„ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋‚ด์žฅ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์—์„œ `prototype` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -First we'll see at the details, and then how to use it for adding new capabilities to built-in objects. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ๋‚ด์žฅ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์‚ดํŽด๋ณธ ํ›„, ์–ด๋–ป๊ฒŒ ๋‚ด์žฅ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋ฅผ ์‘์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ## Object.prototype -Let's say we output an empty object: +๋นˆ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ```js run let obj = {}; alert( obj ); // "[object Object]" ? ``` -Where's the code that generates the string `"[object Object]"`? That's a built-in `toString` method, but where is it? The `obj` is empty! +`"[object Object]"` ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋Š” ์–ด๋””์— ์žˆ์„๊นŒ์š”? `toString` ๋ฉ”์„œ๋“œ์—์„œ ์ด ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•ž์„œ ๋ฐฐ์›Œ์„œ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๋„๋Œ€์ฒด ์ฝ”๋“œ๋Š” ์–ด๋””์— ์žˆ๋Š” ๊ฑธ๊นŒ์š”? `obj`๋Š” ๋น„์–ด ์žˆ๋Š”๋ฐ ๋ง์ด์ฃ . -...But the short notation `obj = {}` is the same as `obj = new Object()`, where `Object` is a built-in object constructor function, with its own `prototype` referencing a huge object with `toString` and other methods. +`obj = new Object()`๋ฅผ ์ค„์ด๋ฉด `obj = {}`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ `Object`๋Š” ๋‚ด์žฅ ๊ฐ์ฒด ์ƒ์„ฑ์ž ํ•จ์ˆ˜์ธ๋ฐ, ์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ `prototype`์€ `toString`์„ ๋น„๋กฏํ•œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ๊ฑฐ๋Œ€ํ•œ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. -Here's what's going on: +๊ทธ๋ฆผ์„ ์ด์šฉํ•ด ์‚ดํŽด๋ด…์‹œ๋‹ค. ![](object-prototype.svg) -When `new Object()` is called (or a literal object `{...}` is created), the `[[Prototype]]` of it is set to `Object.prototype` according to the rule that we discussed in the previous chapter: +`new Object()`๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ๋ฒ• `{...}`์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ, ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ `[[Prototype]]`์€ ๋ฐ”๋กœ ์•ž ์ฑ•ํ„ฐ์—์„œ ์–ธ๊ธ‰ํ•œ ๊ทœ์น™์— ๋”ฐ๋ผ `Object.prototype`์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ![](object-prototype-1.svg) -So then when `obj.toString()` is called the method is taken from `Object.prototype`. +๋”ฐ๋ผ์„œ `obj.toString()`์„ ํ˜ธ์ถœํ•˜๋ฉด `Object.prototype`์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -We can check it like this: +์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. ```js run let obj = {}; alert(obj.__proto__ === Object.prototype); // true -// obj.toString === obj.__proto__.toString == Object.prototype.toString + +alert(obj.toString === obj.__proto__.toString); //true +alert(obj.toString === Object.prototype.toString); //true ``` -Please note that there is no more `[[Prototype]]` in the chain above `Object.prototype`: +๊ทธ๋Ÿฐ๋ฐ ์ด๋•Œ `Object.prototype` ์œ„์ชฝ์—” `[[Prototype]]` ์ฒด์ธ์ด ์—†๋‹ค๋Š” ์ ์„ ์ฃผ์˜ํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run alert(Object.prototype.__proto__); // null ``` -## Other built-in prototypes +## ๋‹ค์–‘ํ•œ ๋‚ด์žฅ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… -Other built-in objects such as `Array`, `Date`, `Function` and others also keep methods in prototypes. +`Array`, `Date`, `Function`์„ ๋น„๋กฏํ•œ ๋‚ด์žฅ ๊ฐ์ฒด๋“ค ์—ญ์‹œ ํ”„๋กœํ† ํƒ€์ž…์— ๋ฉ”์„œ๋“œ๋ฅผ ์ €์žฅํ•ด ๋†“์Šต๋‹ˆ๋‹ค. -For instance, when we create an array `[1, 2, 3]`, the default `new Array()` constructor is used internally. So `Array.prototype` becomes its prototype and provides methods. That's very memory-efficient. +๋ฐฐ์—ด `[1, 2, 3]`์„ ๋งŒ๋“ค๋ฉด `new Array()`์˜ ๋””ํดํŠธ ์ƒ์„ฑ์ž๊ฐ€ ๋‚ด๋ถ€์—์„œ ๋™์ž‘ํ•˜์—ฌ `Array.prototype`์ด ๋ฐฐ์—ด `[1, 2, 3]`์˜ ํ”„๋กœํ† ํƒ€์ž…์ด ๋˜๊ณ  ๊ฐœ๋ฐœ์ž๋Š” `Array.prototype`์„ ํ†ตํ•ด ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋‚ด๋ถ€ ๋™์ž‘์€ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ ๋†’์—ฌ์ฃผ๋Š” ์žฅ์ ์„ ๊ฐ€์ ธ๋‹ค์ค๋‹ˆ๋‹ค. -By specification, all of the built-in prototypes have `Object.prototype` on the top. That's why some people say that "everything inherits from objects". +๋ช…์„ธ์„œ์—์„  ๋ชจ๋“  ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์˜ ์ƒ์† ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์—” `Object.prototype`์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ทœ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ช…์„ธ ๋•Œ๋ฌธ์— ๋ช‡๋ช‡ ์‚ฌ๋žŒ๋“ค์€ "๋ชจ๋“  ๊ฒƒ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค."๋ผ๋Š” ๋ง์„ ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. -Here's the overall picture (for 3 built-ins to fit): +์„ธ ๋‚ด์žฅ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ์ง€๊ธˆ๊นŒ์ง€ ์„ค๋ช…ํ•œ ๋‚ด์šฉ์„ ๊ทธ๋ ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](native-prototypes-classes.svg) -Let's check the prototypes manually: +์ด๋ฒˆ์—” ์ฝ”๋“œ๋กœ ๊ฐ ๋‚ด์žฅ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์ง์ ‘ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. ```js run let arr = [1, 2, 3]; -// it inherits from Array.prototype? +// arr์€ Array.prototype์„ ์ƒ์†๋ฐ›์•˜๋‚˜์š”? alert( arr.__proto__ === Array.prototype ); // true -// then from Object.prototype? +// arr์€ Object.prototype์„ ์ƒ์†๋ฐ›์•˜๋‚˜์š”? alert( arr.__proto__.__proto__ === Object.prototype ); // true -// and null on the top. +// ์ฒด์ธ ๋งจ ์œ„์—” null์ด ์žˆ์Šต๋‹ˆ๋‹ค. alert( arr.__proto__.__proto__.__proto__ ); // null ``` -Some methods in prototypes may overlap, for instance, `Array.prototype` has its own `toString` that lists comma-delimited elements: +์ฒด์ธ ์ƒ์˜ ํ”„๋กœํ† ํƒ€์ž…์—” ์ค‘๋ณต ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `Array.prototype`์—” ์š”์†Œ ์‚ฌ์ด์— ์‰ผํ‘œ๋ฅผ ๋„ฃ์–ด ์š”์†Œ ์ „์ฒด๋ฅผ ํ•ฉ์นœ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ž์ฒด ๋ฉ”์„œ๋“œ `toString`์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let arr = [1, 2, 3] -alert(arr); // 1,2,3 <-- the result of Array.prototype.toString +alert(arr); // 1,2,3 <-- Array.prototype.toString์˜ ๊ฒฐ๊ณผ ``` -As we've seen before, `Object.prototype` has `toString` as well, but `Array.prototype` is closer in the chain, so the array variant is used. +๊ทธ๋Ÿฐ๋ฐ `Object.prototype`์—๋„ ๋ฉ”์„œ๋“œ `toString`์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ค‘๋ณต ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์„ ๋•Œ๋Š” ์ฒด์ธ ์ƒ์—์„œ ๊ฐ€๊นŒ์šด ๊ณณ์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. `Array.prototype`์ด ์ฒด์ธ ์ƒ์—์„œ ๋” ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์‹œ์—์„  `Array.prototype`์˜ `toString`์ด ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ![](native-prototypes-array-tostring.svg) -In-browser tools like Chrome developer console also show inheritance (`console.dir` may need to be used for built-in objects): +Chrome ๊ฐœ๋ฐœ์ž ์ฝ˜์†”๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์† ๊ด€๊ณ„๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `console.dir`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด์žฅ ๊ฐ์ฒด์˜ ์ƒ์† ๊ด€๊ณ„๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ![](console_dir_array.png) -Other built-in objects also work the same way. Even functions -- they are objects of a built-in `Function` constructor, and their methods (`call`/`apply` and others) are taken from `Function.prototype`. Functions have their own `toString` too. +๋ฐฐ์—ด์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๋‚ด์žฅ ๊ฐ์ฒด๋“ค ๋˜ํ•œ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋‚ด์žฅ ๊ฐ์ฒด `Function`์˜ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค์–ด์ง€๋Š”๋ฐ `call`, `apply`๋ฅผ ๋น„๋กฏํ•œ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋Š” `Fuction.prototype`์—์„œ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ํ•จ์ˆ˜์—๋„ `toString`์ด ๊ตฌํ˜„๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ```js run function f() {} alert(f.__proto__ == Function.prototype); // true -alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects +alert(f.__proto__.__proto__ == Object.prototype); // true, ๊ฐ์ฒด์—์„œ ์ƒ์†๋ฐ›์Œ ``` -## Primitives +## ์›์‹œ๊ฐ’ -The most intricate thing happens with strings, numbers and booleans. +๋ฌธ์ž์—ด๊ณผ ์ˆซ์ž, ๋ถˆ๋ฆฐ๊ฐ’์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ์—„์ฒญ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. -As we remember, they are not objects. But if we try to access their properties, then temporary wrapper objects are created using built-in constructors `String`, `Number`, `Boolean`, they provide the methods and disappear. +๋ฌธ์ž์—ด๊ณผ ์ˆซ์ž, ๋ถˆ๋ฆฐ๊ฐ’์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ์›์‹œ ํƒ€์ž… ๊ฐ’์˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋‚ด์žฅ ์ƒ์„ฑ์ž `String`, `Number`, `Boolean`์„ ์‚ฌ์šฉํ•˜๋Š” ์ž„์‹œ ๋ž˜ํผ(wrapper) ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ž„์‹œ ๋ž˜ํผ ๊ฐ์ฒด๋Š” ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋‚œ ํ›„์— ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -These objects are created invisibly to us and most engines optimize them out, but the specification describes it exactly this way. Methods of these objects also reside in prototypes, available as `String.prototype`, `Number.prototype` and `Boolean.prototype`. +๋ž˜ํผ ๊ฐ์ฒด๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์—์„œ ๋งŒ๋“ค์–ด์ง€๋Š”๋ฐ ์—”์ง„์— ์˜ํ•ด ์ตœ์ ํ™”๊ฐ€ ์ด๋ค„์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ช…์„ธ์„œ์—” ๊ฐ ์ž๋ฃŒํ˜•์— ํ•ด๋‹นํ•˜๋Š” ๋ž˜ํผ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ”„๋กœํ† ํƒ€์ž… ์•ˆ์— ๊ตฌํ˜„ํ•ด ๋†“๊ณ  `String.prototype`, `Number.prototype`, `Boolean.prototype`์„ ์‚ฌ์šฉํ•ด ์“ฐ๋„๋ก ๊ทœ์ •ํ•ฉ๋‹ˆ๋‹ค. -```warn header="Values `null` and `undefined` have no object wrappers" -Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes too. +```warn header="`null`๊ณผ `undefined`์— ๋Œ€์‘ํ•˜๋Š” ๋ž˜ํผ ๊ฐ์ฒด๋Š” ์—†์Šต๋‹ˆ๋‹ค." +ํŠน์ˆ˜ ๊ฐ’์ธ `null`๊ณผ `undefined`๋Š” ๋ฌธ์ž์—ด๊ณผ ์ˆซ์ž, ๋ถˆ๋ฆฐ๊ฐ’๊ณผ๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. `null`๊ณผ `undefined`์— ๋Œ€์‘ํ•˜๋Š” ๋ž˜ํผ ๊ฐ์ฒด๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `null`๊ณผ `undefined`์—์„  ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœํ† ํƒ€์ž…๋„ ๋ฌผ๋ก  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ``` -## Changing native prototypes [#native-prototype-change] +## ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž… ๋ณ€๊ฒฝํ•˜๊ธฐ [#native-prototype-change] -Native prototypes can be modified. For instance, if we add a method to `String.prototype`, it becomes available to all strings: +๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž…์€ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `String.prototype`์— ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ชจ๋“  ๋ฌธ์ž์—ด์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run String.prototype.show = function() { @@ -119,51 +121,51 @@ String.prototype.show = function() { "BOOM!".show(); // BOOM! ``` -During the process of development, we may have ideas for new built-in methods we'd like to have, and we may be tempted to add them to native prototypes. But that is generally a bad idea. +๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์ƒˆ๋กœ์šด ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด ์ข‹์ง€ ์•Š์„๊นŒ ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ค ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž…์— ์ƒˆ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ์œ ํ˜น์ด ์ž๊พธ ์ƒ๊ธฐ์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์ด๋Š” ์ข‹์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ```warn -Prototypes are global, so it's easy to get a conflict. If two libraries add a method `String.prototype.show`, then one of them will be overwriting the method of the other. +ํ”„๋กœํ† ํƒ€์ž…์€ ์ „์—ญ์œผ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœํ† ํƒ€์ž…์„ ์กฐ์ž‘ํ•˜๋ฉด ๊ธฐ์กด ์ฝ”๋“œ์™€ ์ถฉ๋Œ์ด ๋‚  ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋™์‹œ์— `String.prototype.show` ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฎ์–ด์“ฐ์ฃ . -So, generally, modifying a native prototype is considered a bad idea. +์ด๋Ÿฐ ์ด์œ ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž…์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์€ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` -**In modern programming, there is only one case where modifying native prototypes is approved. That's polyfilling.** +**๋ชจ๋˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž… ๋ณ€๊ฒฝ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋”ฑ ํ•˜๋‚˜๋ฟ์ž…๋‹ˆ๋‹ค. ๋ฐ”๋กœ ํด๋ฆฌํ•„์„ ๋งŒ๋“ค ๋•Œ์ž…๋‹ˆ๋‹ค.** -Polyfilling is a term for making a substitute for a method that exists in JavaScript specification, but is not yet supported by current JavaScript engine. +ํด๋ฆฌํ•„์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ฒด๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ช…์„ธ์„œ์—๋Š” ์ •์˜๋˜์–ด ์žˆ์œผ๋‚˜ ํŠน์ • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์—์„œ๋Š” ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š์„ ๋•Œ ํด๋ฆฌํ•„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -Then we may implement it manually and populate the built-in prototype with it. +ํด๋ฆฌํ•„์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ณ  ๋‚œ ํ›„, ํด๋ฆฌํ•„์„ ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์— ์ถ”๊ฐ€ํ•  ๋•Œ๋งŒ ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž…์„ ๋ณ€๊ฒฝํ•ฉ์‹œ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js run -if (!String.prototype.repeat) { // if there's no such method - // add it to the prototype +if (!String.prototype.repeat) { // repeat์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค + // ํ”„๋กœํ† ํƒ€์ž…์— repeat๋ฅผ ์ถ”๊ฐ€ String.prototype.repeat = function(n) { - // repeat the string n times + // string์„ nํšŒ ๋ฐ˜๋ณต(repeat)ํ•ฉ๋‹ˆ๋‹ค. - // actually, the code should be a little bit more complex than that - // (the full algorithm is in the specification) - // but even an imperfect polyfill is often considered good enough for use + // ์‹ค์ œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ๋” ๋ณต์žกํ•œ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + // ์ „์ฒด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ช…์„ธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, + // ๋ช…์„ธ์„œ๋ฅผ ์™„๋ฒฝํžˆ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์€ ํด๋ฆฌํ•„์ด๋ผ๋„ ์ถฉ๋ถ„ํžˆ ์“ธ๋งŒํ•˜๋‹ˆ ์˜ˆ์‹œ๋Š” ์ด ์ •๋„๋กœ๋งŒ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. return new Array(n + 1).join(this); }; } -alert( "La".repeat(3) ); // LaLaLa +alert( "๋ผ".repeat(3) ); // ๋ผ๋ผ๋ผ ``` -## Borrowing from prototypes +## ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๋ฉ”์„œ๋“œ ๋นŒ๋ ค์˜ค๊ธฐ -In the chapter we talked about method borrowing. +์—์„œ ๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ํ•™์Šตํ•œ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -That's when we take a method from one object and copy it into another. +ํ•œ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ณต์‚ฌํ•  ๋•Œ ์ด ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -Some methods of native prototypes are often borrowed. +๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœํ† ํƒ€์ž…์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋ฅผ ๋นŒ๋ ค์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์ƒ๊น๋‹ˆ๋‹ค. -For instance, if we're making an array-like object, we may want to copy some `Array` methods to it. +์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์—ฌ๊ธฐ์— `Array` ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•ด๋ด…์‹œ๋‹ค. -E.g. +์˜ˆ์‹œ: ```js run let obj = { @@ -179,18 +181,18 @@ obj.join = Array.prototype.join; alert( obj.join(',') ); // Hello,world! ``` -It works, because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property, it doesn't check that the object is indeed the array. And many built-in methods are like that. - -Another possibility is to inherit by setting `obj.__proto__` to `Array.prototype`, so all `Array` methods are automatically available in `obj`. +๋‚ด์žฅ ๋ฉ”์„œ๋“œ `join`์˜ ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ œ๋Œ€๋กœ ๋œ ์ธ๋ฑ์Šค๊ฐ€ ์žˆ๋Š”์ง€์™€ `length` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”์ง€๋งŒ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์‹œ๋Š” ์—๋Ÿฌ ์—†์ด ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœ ๋Œ€์ƒ์ด ์ง„์งœ ๋ฐฐ์—ด์ธ์ง€๋Š” ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๋‹ค์ˆ˜์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -But that's impossible if `obj` already inherits from another object. Remember, we only can inherit from one object at a time. +๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ ๋ง๊ณ ๋„ `obj.__proto__`๋ฅผ `Array.prototype`์œผ๋กœ ์„ค์ •ํ•ด ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `obj`์—์„œ ๋ชจ๋“  `Array` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹จ์ผ ์ƒ์†๋งŒ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฐฉ๋ฒ•์€ `obj`๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์žˆ์„ ๋•Œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -Borrowing methods is flexible, it allows to mix functionality from different objects if needed. +๋ฉ”์„œ๋“œ ๋นŒ๋ฆฌ๊ธฐ๋Š” ์—ฌ๋Ÿฌ ๊ฐ์ฒด์—์„œ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ์™€ ์„ž๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์—ฐํ•œ ๊ฐœ๋ฐœ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -- All built-in objects follow the same pattern: - - The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype` etc). - - The object itself stores only the data (array items, object properties, the date). -- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype`, `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects. -- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. Probably the only allowable case is when we add-in a new standard, but not yet supported by the engine JavaScript method. +- ๋ชจ๋“  ๋‚ด์žฅ ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. + - ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํ† ํƒ€์ž…์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค(`Array.prototype`, `Object.prototype`, `Date.prototype` ๋“ฑ). + - ๊ฐ์ฒด ์ž์ฒด์—” ๋ฐ์ดํ„ฐ๋งŒ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค(๋ฐฐ์—ด์˜ ์š”์†Œ, ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ, ๋‚ ์งœ ๋“ฑ). +- ์›์‹œ๊ฐ’ ๋˜ํ•œ ๋ž˜ํผ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์— `Number.prototype`, `String.prototype`, `Boolean.prototype` ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ `undefined`์™€ `null`์€ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. +- ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์€ ์ˆ˜์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋นŒ๋ ค์™€ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ ์—ญ์‹œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž… ๋ณ€๊ฒฝ์€ ๋˜๋„๋ก ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒˆ๋กœ ๋ช…์„ธ์„œ์— ๋“ฑ๋ก๋œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์—” ์ด ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š์„ ๋•Œ๋งŒ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg b/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg index 187b899e48..59d60b397a 100644 --- a/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg +++ b/1-js/08-prototypes/03-native-prototypes/function-prototype-constructor.svg @@ -1 +1 @@ -Rabbitprototypeconstructordefault "prototype" \ No newline at end of file +Rabbitprototypeconstructordefault "prototype" \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg b/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg index 8475560b3f..ebb4f32051 100644 --- a/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg +++ b/1-js/08-prototypes/03-native-prototypes/native-prototypes-array-tostring.svg @@ -1 +1 @@ -toString: function ...Array.prototypetoString: function ...Object.prototype[[Prototype]][[Prototype]][1, 2, 3] \ No newline at end of file +toString: function ...Array.prototypetoString: function ...Object.prototype[[Prototype]][[Prototype]][1, 2, 3] \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg index caa5ec04b3..4d6129e0a0 100644 --- a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg +++ b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg @@ -1 +1 @@ -toString: function other object methodsObject.prototypenullslice: function other array methods[[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]]Array.prototypecall: function other function methodsFunction.prototypetoFixed: function other number methodsNumber.prototype[1, 2, 3]function f(args) { ... }5 \ No newline at end of file +toString: function other object methodsObject.prototypenullslice: function other array methods[[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]][[Prototype]]Array.prototypecall: function other function methodsFunction.prototypetoFixed: function other number methodsNumber.prototype[1, 2, 3]function f(args) { ... }5 \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg index c111e07255..9630e68e27 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype-1.svg @@ -1 +1 @@ -constructor: Object toString: function ...Object.prototypeObjectobj = new Object()[[Prototype]]prototype \ No newline at end of file +constructor: Object toString: function ...Object.prototypeObjectobj = new Object()[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg index 8b802eb442..9ccb342299 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype-null.svg @@ -1 +1 @@ -obj[[Prototype]]null \ No newline at end of file +obj[[Prototype]]null \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/object-prototype.svg b/1-js/08-prototypes/03-native-prototypes/object-prototype.svg index b5014f9f00..024dd30213 100644 --- a/1-js/08-prototypes/03-native-prototypes/object-prototype.svg +++ b/1-js/08-prototypes/03-native-prototypes/object-prototype.svg @@ -1 +1 @@ -constructor: Object toString: function ...Object.prototypeObjectprototype \ No newline at end of file +constructor: Object toString: function ...Object.prototypeObjectprototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg b/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg index a2c19d8505..ede4e1227e 100644 --- a/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg +++ b/1-js/08-prototypes/03-native-prototypes/proto-constructor-animal-rabbit.svg @@ -1 +1 @@ -eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file +eats: truename: "White Rabbit"animalRabbitrabbit[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg b/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg index 4d6b10e303..54b3d79804 100644 --- a/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg +++ b/1-js/08-prototypes/03-native-prototypes/rabbit-prototype-constructor.svg @@ -1 +1 @@ -default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file +default "prototype"Rabbitrabbit[[Prototype]]prototypeconstructor \ No newline at end of file diff --git a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md index a92e17900e..7758d6092c 100644 --- a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md +++ b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md @@ -1,13 +1,13 @@ -The method can take all enumerable keys using `Object.keys` and output their list. +์ด ๋ฉ”์„œ๋“œ๋Š” `Object.keys`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํ‚ค๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ชฉ๋ก์œผ๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -To make `toString` non-enumerable, let's define it using a property descriptor. The syntax of `Object.create` allows us to provide an object with property descriptors as the second argument. +`toString`์„ ์—ด๊ฑฐํ•  ์ˆ˜ ์—†๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `toString`์„ ์ •์˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. `Object.create` ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run *!* let dictionary = Object.create(null, { - toString: { // define toString property - value() { // the value is a function + toString: { // toString ํ”„๋กœํผํ‹ฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. + value() { // value๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. return Object.keys(this).join(); } } @@ -17,15 +17,15 @@ let dictionary = Object.create(null, { dictionary.apple = "Apple"; dictionary.__proto__ = "test"; -// apple and __proto__ is in the loop +// apple๊ณผ __proto__๋Š” ๋ฐ˜๋ณต๋ฌธ ์•ˆ์— ์žˆ์Šต๋‹ˆ๋‹ค. for(let key in dictionary) { - alert(key); // "apple", then "__proto__" + alert(key); // "apple" ๋‹ค์Œ "__proto__"๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. } -// comma-separated list of properties by toString +// toString์— ์˜ํ•ด ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก alert(dictionary); // "apple,__proto__" ``` -When we create a property using a descriptor, its flags are `false` by default. So in the code above, `dictionary.toString` is non-enumerable. +์„ค๋ช…์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ”Œ๋ž˜๊ทธ๊ฐ€ `false`์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ์ฝ”๋“œ์—์„œ `dictionary.toString`์€ ์—ด๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -See the the chapter [](info:property-descriptors) for review. +๋‹ค์Œ ์ฑ•ํ„ฐ [](info:property-descriptors)๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/task.md b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/task.md index 0d831f2cc5..0174ca11b4 100644 --- a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/task.md +++ b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/task.md @@ -2,30 +2,30 @@ importance: 5 --- -# Add toString to the dictionary +# ์‚ฌ์ „์— toString ์ถ”๊ฐ€ํ•˜๊ธฐ -There's an object `dictionary`, created as `Object.create(null)`, to store any `key/value` pairs. +`key/value` ์Œ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด `Object.create(null)`๋กœ ์ƒ์„ฑ๋œ `dictionary` ๊ฐ์ฒด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -Add method `dictionary.toString()` into it, that should return a comma-delimited list of keys. Your `toString` should not show up in `for..in` over the object. +๊ทธ ์•ˆ์— ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ํ‚ค ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋Š” `dictionary.toString()`๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค. `toString`์€ ๊ฐ์ฒด ์œ„์˜ `for..in`์— ๋‚˜ํƒ€๋‚˜์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. -Here's how it should work: +์ž‘๋™ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let dictionary = Object.create(null); *!* -// your code to add dictionary.toString method +// dictionary.toString ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ฝ”๋“œ */!* -// add some data +// ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. dictionary.apple = "Apple"; -dictionary.__proto__ = "test"; // __proto__ is a regular property key here +dictionary.__proto__ = "test"; // __proto__๋Š” ์—ฌ๊ธฐ์„œ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœํผํ‹ฐ ํ‚ค์ž…๋‹ˆ๋‹ค. -// only apple and __proto__ are in the loop +// ๋ฐ˜๋ณต๋ฌธ์—๋Š” apple๊ณผ __proto__ ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. for(let key in dictionary) { - alert(key); // "apple", then "__proto__" + alert(key); // "apple" ๋‹ค์Œ "__proto__"์ž…๋‹ˆ๋‹ค. } -// your toString in action +// toString์ด ๋™์ž‘ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. alert(dictionary); // "apple,__proto__" ``` diff --git a/1-js/08-prototypes/04-prototype-methods/3-compare-calls/solution.md b/1-js/08-prototypes/04-prototype-methods/3-compare-calls/solution.md index 90d3118bfd..637d15f878 100644 --- a/1-js/08-prototypes/04-prototype-methods/3-compare-calls/solution.md +++ b/1-js/08-prototypes/04-prototype-methods/3-compare-calls/solution.md @@ -1,7 +1,7 @@ -The first call has `this == rabbit`, the other ones have `this` equal to `Rabbit.prototype`, because it's actually the object before the dot. +`this`๋Š” ์‹ค์ œ ์  ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์—, ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์—์„  `this`๊ฐ€ `rabbit`์ด๊ณ , ๋‹ค๋ฅธ ํ˜ธ์ถœ์—์„  `Rabbit.prototype`์ž…๋‹ˆ๋‹ค. -So only the first call shows `Rabbit`, other ones show `undefined`: +๋”ฐ๋ผ์„œ ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ๋งŒ์ด `Rabbit`์„ ์ถœ๋ ฅํ•˜๊ณ  ๋‹ค๋ฅธ ํ˜ธ์ถœ์€ `undefined`๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ```js run function Rabbit(name) { diff --git a/1-js/08-prototypes/04-prototype-methods/3-compare-calls/task.md b/1-js/08-prototypes/04-prototype-methods/3-compare-calls/task.md index 09bb7f1ed8..d6c38a9833 100644 --- a/1-js/08-prototypes/04-prototype-methods/3-compare-calls/task.md +++ b/1-js/08-prototypes/04-prototype-methods/3-compare-calls/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# The difference between calls +# ํ˜ธ์ถœ ๊ฐ„์˜ ์ฐจ์ด์  -Let's create a new `rabbit` object: +์ƒˆ๋กœ์šด `rabbit` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. ```js function Rabbit(name) { @@ -17,7 +17,7 @@ Rabbit.prototype.sayHi = function() { let rabbit = new Rabbit("Rabbit"); ``` -These calls do the same thing or not? +์•„๋ž˜์™€ ๊ฐ™์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ• ์ง€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ• ์ง€ ์˜ˆ์ƒํ•ด ๋ณด์„ธ์š”. ```js rabbit.sayHi(); diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md index fc32cbb89f..42fdd142ee 100644 --- a/1-js/08-prototypes/04-prototype-methods/article.md +++ b/1-js/08-prototypes/04-prototype-methods/article.md @@ -3,15 +3,15 @@ ์ด ์ ˆ์˜ ์ฒซ ๋ฒˆ์งธ ์ฑ•ํ„ฐ์—์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋˜ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. -`__proto__`๋Š” ๋‹ค์†Œ ๊ตฌ์‹์ด๊ณ  ๋”๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•  ๊ฒƒ์œผ๋กœ ๋ด…๋‹ˆ๋‹ค(์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ ์ค‘ ๋ธŒ๋ผ์šฐ์ € ๋ถ€๋ถ„์—์„œ). +`__proto__`๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋‹ค์†Œ ๊ตฌ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ํ‘œ์ค€์—๋„ ๊ด€๋ จ ๋‚ด์šฉ์ด ๋ช…์‹œ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. -๋ชจ๋˜ํ•œ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +๋Œ€์‹  ์•„๋ž˜์™€ ๊ฐ™์€ ๋ชจ๋˜ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. -- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- ์ธ์ž๋กœ ๋„˜๊ธด `proto`๋ฅผ `[[Prototype]]`๋กœ ํ•˜๋Š” ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์ถ”๊ฐ€๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- `[[Prototype]]`์ด `proto`๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋•Œ ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์ถ”๊ฐ€๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- `obj`์˜ `[[Prototype]]`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- `obj`์˜ `[[Prototype]]`์„ `proto` ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- `obj`์˜ `[[Prototype]]`์ด `proto`๊ฐ€ ๋˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. -`__proto__` ๋Œ€์‹  ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. +์•ž์œผ๋ก  ์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ `__proto__` ๋Œ€์‹  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค. ์˜ˆ์‹œ: @@ -36,7 +36,7 @@ Object.setPrototypeOf(rabbit, {}); // rabbit์˜ ํ”„๋กœํ† ํƒ€์ž…์„ {}์œผ๋กœ ๋ฐ” */!* ``` -`Object.create`์— ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช…์ž๋ฅผ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ฉ”์„œ๋“œ๋ฅผ ์†Œ๊ฐœํ•  ๋•Œ ์ž ์‹œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ `Object.create`์—๋Š” ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…์ž๋ฅผ ์ด์šฉํ•ด ์ƒˆ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let animal = { @@ -52,116 +52,115 @@ let rabbit = Object.create(animal, { alert(rabbit.jumps); // true ``` -์„ค๋ช…์ž๋Š” ์—์„œ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +์„ค๋ช…์ž๋Š” ์—์„œ ๋ฐฐ์šด ๊ฒƒ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -`Object.create`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `for..in`์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณต์‚ฌํ•  ๋•Œ๋ณด๋‹ค ๋” ํšจ๊ณผ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ณต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Object.create`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `for..in`์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํšจ๊ณผ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ณต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js -// obj์™€ ์™„๋ฒฝํ•˜๊ฒŒ ๋™์ผํ•œ ์–•์€ ์‚ฌ๋ณธ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); ``` -์ด ํ˜ธ์ถœ์€ `obj`์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ํฌํ•จํ•œ ์™„๋ฒฝํ•œ ์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด๋ƒ…๋‹ˆ๋‹ค. ์‚ฌ๋ณธ์€ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ถˆ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ, ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ, getter, setter ๋“ฑ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์™€ ์˜ฌ๋ฐ”๋ฅธ `[[Prototype]]`์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +`Object.create`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `obj`์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ํฌํ•จํ•œ ์™„๋ฒฝํ•œ ์‚ฌ๋ณธ์ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค, ์‚ฌ๋ณธ์—” ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ถˆ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ, ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ, getter, setter ๋“ฑ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณต์ œ๋ฉ๋‹ˆ๋‹ค. `[[Prototype]]`๋„ ๋ณต์ œ๋˜์ฃ . -## ๊ฐ„๋žตํ•œ ์—ญ์‚ฌ +## ๋น„ํ•˜์ธ๋“œ ์Šคํ† ๋ฆฌ -`[[Prototype]]`์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๋งŽ์Šต๋‹ˆ๋‹ค! ๊ฐ™์€ ๊ฒƒ์„ ํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค! +`[[Prototype]]`์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ํ•˜๋‚˜์ธ๋ฐ ๋ชฉํ‘œ๋ฅผ ์ด๋ฃจ๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€์ด์ฃ . ์™œ ๊ทธ๋Ÿด๊นŒ์š”? ์—ญ์‚ฌ์ ์ธ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- ์ƒ์„ฑ์ž์˜ `"prototype"` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„์ฃผ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. -- ํ›„์— 2012๋…„์— ์ด๋ฅด๋Ÿฌ `Object.create`๊ฐ€ ํ‘œ์ค€์— ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด ์ฃผ์–ด์ง„ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์—ˆ์ง€๋งŒ, ํ”„๋กœํ† ํƒ€์ž…์„ get/setํ•  ์ˆ˜๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์–ธ์ œ๋“ ์ง€ ํ”„๋กœํ† ํƒ€์ž…์„ get/set ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋น„ํ‘œ์ค€ `__proto__` ์ ‘๊ทผ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -- 2015๋…„์—๋Š” `Object.setPrototypeOf`์™€ `Object.getPrototypeOf`๊ฐ€ ํ‘œ์ค€์— ์ถ”๊ฐ€๋˜์—ˆ๊ณ  `__proto__`์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค์ƒ `__proto__`๊ฐ€ ๋ชจ๋“  ๊ณณ์— ๊ตฌํ˜„๋˜์–ด์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, `__proto__`๋Š” ์•ž์œผ๋กœ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ๋งํ•˜์•ผ ํ•  ๊ฒƒ์œผ๋กœ ๋ณด๊ณ  ํ‘œ์ค€์˜ ๋ถ€๋ก B(Annex B)์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ํ™˜๊ฒฝ์—์„œ `__proto__`๋Š” ์„ ํƒ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. +- ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ `"prototype"` ํ”„๋กœํผํ‹ฐ๋Š” ์•„์ฃผ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +- ๊ทธ๋Ÿฐ๋ฐ 2012๋…„, ๋ช…์„ธ์„œ์— `Object.create`๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `Object.create`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฃผ์–ด์ง„ ํ”„๋กœํ† ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธด ํ•˜์ง€๋งŒ, ํ”„๋กœํ† ํƒ€์ž…์„ ์–ป๊ฑฐ๋‚˜ ์„ค์ •ํ•˜๋Š”๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋น„ํ‘œ์ค€ ์ ‘๊ทผ์ž์ธ `__proto__`๋ฅผ ๊ตฌํ˜„ํ•ด ์–ธ์ œ๋‚˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์–ป๊ฑฐ๋‚˜ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. +- ์ดํ›„ 2015๋…„์— `Object.setPrototypeOf`์™€ `Object.getPrototypeOf`๊ฐ€ ํ‘œ์ค€์— ์ถ”๊ฐ€๋˜๋ฉด์„œ `__proto__`์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ์‹œ์ ์—” `__proto__`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์ด ๋„ˆ๋ฌด ๋งŽ์•„์„œ `__proto__`๋Š” ์‚ฌ์‹ค์ƒ ํ‘œ์ค€(de-facto standard)์ด ๋˜์–ด๋ฒ„๋ ธ์ฃ . ์ด ๋‚ด์šฉ์€ ๋ช…์„ธ์„œ์˜ ๋ถ€๋ก B(Annex B)์— ์ถ”๊ฐ€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ€๋ก B์˜ ๋‚ด์šฉ์€ ๋ธŒ๋ผ์šฐ์ € ์ด์™ธ์˜ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์—์„  ์„ ํƒ์‚ฌํ•ญ์ด๋ผ๋Š”๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -์˜ค๋Š˜๋‚ ์—๋Š” ์ด ๋ชจ๋“  ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์—ญ์‚ฌ์ ์ธ ์ด์œ  ๋•Œ๋ฌธ์— ์ง€๊ธˆ์€ ์—ฌ๋Ÿฌ ๋ฐฉ์‹์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -์™œ `__proto__`๋ฅผ ํ•จ์ˆ˜ `getPrototypeOf/setPrototypeOf`๋กœ ๋Œ€์ฒดํ–ˆ์„๊นŒ์š”? ํฅ๋ฏธ๋กœ์šด ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต์€ `__proto__`๊ฐ€ ์™œ ๋‚˜์œ์ง€ ์ดํ•ดํ•˜๋ฉด ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ต์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ณ„์† ์ฝ์–ด ๋ด…์‹œ๋‹ค. +์ด์ฏค๋˜๋ฉด "์™œ `__proto__`๊ฐ€ ํ•จ์ˆ˜ `getPrototypeOf`, `setPrototypeOf`๋กœ ๋Œ€์ฒด๋˜์—ˆ์„๊นŒ?"๋ผ๋Š” ์˜๋ฌธ์ด ๋– ์˜ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กœ์šด ์งˆ๋ฌธ์ด์ฃ . ๋‹ต์€ `__proto__`๊ฐ€ ์™œ ๋‚˜์œ์ง€ ์ดํ•ดํ•˜๋ฉด ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋‚ด์šฉ์„ ๊ณ„์† ์ฝ์œผ๋ฉด์„œ ๋‹ต์„ ์ฐพ์•„๋ด…์‹œ๋‹ค. -```warn header="์†๋„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋ฉด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ๋ฐ”๊พธ์ง€ ๋งˆ์„ธ์š”." -๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” `[[Prototype]]`์„ ์–ธ์ œ๋“ ์ง€ get/setํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒ์„ฑ ์‹œ์ ์—๋งŒ `[[Prototype]]`์„ ์„ค์ •ํ•˜๊ณ  ์ดํ›„์—” ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `rabbit`์€ `animal`์„ ์ƒ์†ํ•˜๊ณ  ๊ทธ ์‚ฌ์‹ค์€ ๋ณ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +```warn header="์†๋„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋ฉด ๊ธฐ์กด ๊ฐ์ฒด์˜ `[[Prototype]]`์„ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”." +์›ํ•œ๋‹ค๋ฉด ์–ธ์ œ๋‚˜ `[[Prototype]]`์„ ์–ป๊ฑฐ๋‚˜ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์  ์ œ์•ฝ์ด ์žˆ๋Š” ๊ฑด ์•„๋‹ˆ์ฃ . ํ•˜์ง€๋งŒ ๋Œ€๊ฐœ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งŒ `[[Prototype]]`์„ ์„ค์ •ํ•˜๊ณ  ์ดํ›„์—” ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `rabbit`์ด `animal`์„ ์ƒ์†๋ฐ›๋„๋ก ์„ค์ •ํ•˜๊ณ  ๋‚œ ์ดํ›„์—” ์ƒ์† ๊ด€๊ณ„๋ฅผ ์ž˜ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์ด๋ฅผ ํ† ๋Œ€๋กœ ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. `Object.setPrototypeOf`๋‚˜ `obj.__proto__=`๋ฅผ ์จ์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ทธ๋•Œ๊ทธ๋•Œ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋А๋ฆฝ๋‹ˆ๋‹ค. ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋Š” ๋™์ž‘์˜ ์ตœ์ ํ™”๋ฅผ ๊นจ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ `[[Prototype]]`์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ• ์ง€ ํ™•์‹คํžˆ ์•Œ๊ฑฐ๋‚˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์†๋„๊ฐ€ ์ „ํ˜€ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด `[[Prototype]]`์„ ๋ฐ”๊พธ์ง€ ๋งˆ์„ธ์š”. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์ด๋Ÿฐ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ† ๋Œ€๋กœ ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. `Object.setPrototypeOf`๋‚˜ `obj.__proto__=`๋ฅผ ์จ์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ทธ๋•Œ๊ทธ๋•Œ ๋ฐ”๊พธ๋Š” ์—ฐ์‚ฐ์€ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ ๊ด€๋ จ ์ตœ์ ํ™”๋ฅผ ๋ง์น˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์— ๋‚˜์œ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ `[[Prototype]]`์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ• ์ง€ ํ™•์‹คํžˆ ์•Œ๊ฑฐ๋‚˜ ์†๋„๊ฐ€ ์ „ํ˜€ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด `[[Prototype]]`์„ ๋ฐ”๊พธ์ง€ ๋งˆ์„ธ์š”. ``` -## '๋งค์šฐ ๋‹จ์ˆœํ•œ' ๊ฐ์ฒด [#very-plain] +## ์•„์ฃผ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด [#very-plain] -์•Œ๋‹ค์‹œํ”ผ ๊ฐ์ฒด๋Š” ํ‚ค/๊ฐ’ ์Œ์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์—ฐ๊ด€ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค. +์•Œ๋‹ค์‹œํ”ผ ๊ฐ์ฒด๋Š” ํ‚ค-๊ฐ’ ์Œ์ด ์žˆ๋Š” ์—ฐ๊ด€ ๋ฐฐ์—ด๋กœ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ํ‚ค๋ฅผ ์ €์žฅํ•˜๋ ค๊ณ  ํ•  ๋•Œ(์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ „์„ ๋งŒ๋“ค ๋•Œ), ์‚ฌ์†Œํ•œ ๊ฒฐํ•จ์„ ํ•˜๋‚˜ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ๋ฌธ์ž์—ด์€ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ `"__proto__"`๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ปค์Šคํ…€ ์‚ฌ์ „์„ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ž…๋ ฅํ•œ ํ‚ค๋ฅผ ๊ฐ€์ง€๊ณ  ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋‹ค ๋ณด๋ฉด ์‚ฌ์†Œํ•œ ๊ฒฐํ•จ์ด ๋ฐœ๊ฒฌ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฌธ์ž์—ด์€ ๊ดœ์ฐฎ์ง€๋งŒ `"__proto__"`๋ผ๋Š” ๋ฌธ์ž์—ด์€ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒฐํ•จ์ด์ฃ . -๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run let obj = {}; -let key = prompt("What's the key?", "__proto__"); -obj[key] = "some value"; +let key = prompt("์ž…๋ ฅํ•˜๊ณ ์ž ํ•˜๋Š” key๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?", "__proto__"); +obj[key] = "...๊ฐ’..."; -alert(obj[key]); // "some value"๊ฐ€ ์•„๋‹ˆ๋ผ [object Object]์ž…๋‹ˆ๋‹ค! +alert(obj[key]); // "...๊ฐ’..."์ด ์•„๋‹Œ [object Object]๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ``` -์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ์ž๊ฐ€ `__proto__`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ• ๋‹น์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +ํ”„๋กฌํ”„ํŠธ ์ฐฝ์— `__proto__`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๊ฐ’์ด ์ œ๋Œ€๋กœ ํ• ๋‹น๋˜์ง€ ์•Š๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์‚ฌ์‹ค ๋†€๋ž„ ์ผ์€ ์•„๋‹™๋‹ˆ๋‹ค. `__proto__` ํ”„๋กœํผํ‹ฐ๋Š” ํŠน๋ณ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `__proto__`๋Š” ํ•ญ์ƒ ๊ฐ์ฒด์ด๊ฑฐ๋‚˜ `null`์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ํƒ€์ž…์€ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +`__proto__` ํ”„๋กœํผํ‹ฐ๋Š” ํŠน๋ณ„ํ•œ ํ”„๋กœํผํ‹ฐ๋ผ๋Š” ๊ฒƒ์„ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ๋†€๋ž„๋งŒํ•œ ์ผ์€ ์•„๋‹ˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ `__proto__`๋Š” ํ•ญ์ƒ ๊ฐ์ฒด์ด๊ฑฐ๋‚˜ `null`์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด์€ ํ”„๋กœํ† ํƒ€์ž…์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ *์˜๋„์น˜ ์•Š๊ฒŒ* ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ฃ ? ํ‚ค/๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๋ ค๋Š”๋ฐ ํ‚ค์˜ ์ด๋ฆ„์ด `"__proto__"`์ด๋ฉด ์ œ๋Œ€๋กœ ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ด๊ฑด ๋ฒ„๊ทธ๊ฐ€ ๋งž์Šต๋‹ˆ๋‹ค. +๊ฐœ๋ฐœ์ž๊ฐ€ ์œ„ ์˜ˆ์‹œ์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋• ์ด๋Ÿฐ ๊ฒฐ๊ณผ๋ฅผ ์˜๋„ํ•˜๋ฉด์„œ ๊ตฌํ˜„ํ•˜์ง„ ์•Š์•˜์„ ๊ฒ๋‹ˆ๋‹ค. ํ‚ค๊ฐ€ ๋ฌด์—‡์ด ๋˜์—ˆ๋“ , ํ‚ค-๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ํ‚ค๊ฐ€ `__proto__`์ผ ๋•Œ ๊ฐ’์ด ์ œ๋Œ€๋กœ ์ €์žฅ๋˜์ง€ ์•Š๋Š” ๊ฑด ๋ช…๋ฐฑํ•œ ๋ฒ„๊ทธ์ด์ฃ . -์—ฌ๊ธฐ์„  ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ๊ทธ๋ฆฌ ์น˜๋ช…์ ์ด์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ ๊ฐ์ฒด๋ฅผ ๊ฐ’์œผ๋กœ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ์—” ํ”„๋กœํ† ํƒ€์ž…์ด ์ •๋ง ๋ฐ”๋€” ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ์™„์ „ํžˆ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜ˆ์‹œ์—์„  ์ด ๋ฒ„๊ทธ๊ฐ€ ๊ทธ๋ฆฌ ์น˜๋ช…์ ์ด์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ• ๋‹น ๊ฐ’์ด ๊ฐ์ฒด์ผ ๋•Œ๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด ๋ฐ”๋€” ์ˆ˜ ์žˆ๋‹ค๋Š” ์น˜๋ช…์ ์ธ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํ† ํƒ€์ž…์ด ๋ฐ”๋€Œ๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ผ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์„ค์ƒ๊ฐ€์ƒ์œผ๋กœ ๊ฐœ๋ฐœ์ž๋“ค์€ ๋Œ€๊ฒŒ ํ”„๋กœํ† ํƒ€์ž…์ด ๋ฐ”๋€” ๊ฐ€๋Šฅ์„ฑ์„ ์ „ํ˜€ ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ”„๋กœํ† ํƒ€์ž…์ด ๋ฐ”๋€ ๊ฒƒ์€ ๋ˆˆ์น˜์ฑ„๊ธฐ๋„ ํž˜๋“ค๊ณ , ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉ์ค‘์ผ ๋• ์‹ฌ์ง€์–ด ์ทจ์•ฝ์ ์ด ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. +๊ฐœ๋ฐœ์ž๋“ค์€ ๋Œ€๊ฐœ ํ”„๋กœํ† ํƒ€์ž…์ด ์ค‘๊ฐ„์— ๋ฐ”๋€Œ๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋ฐฐ์ œํ•œ ์ฑ„ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ณ ์ •๊ด€๋… ๋•Œ๋ฌธ์— ํ”„๋กœํ† ํƒ€์ž…์ด ์ค‘๊ฐ„์— ๋ฐ”๋€Œ๋ฉด์„œ ๋ฐœ์ƒํ•œ ๋ฒ„๊ทธ๋Š” ๊ทธ ์›์ธ์„ ์‰ฝ๊ฒŒ ์ฐพ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉ ํ•  ๋• ์ด๋Ÿฐ ๋ฒ„๊ทธ๊ฐ€ ์ทจ์•ฝ์ ์ด ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์€ ๋™์ž‘์€ ์›๋ž˜ ํ•จ์ˆ˜์ธ `toString`์ด๋‚˜ ๋‹ค๋ฅธ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ์— ํ• ๋‹น์„ ํ•  ๋•Œ๋„ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`toString`์„ ๋น„๋กฏํ•œ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ์— ํ• ๋‹น์„ ํ•  ๋•Œ๋„ ๊ฐ™์€ ์ด์œ  ๋•Œ๋ฌธ์— ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ผ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ”ผํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? +๊ทธ๋Ÿผ ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? -์šฐ์„  `๋งต`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. +๊ฐ์ฒด ๋Œ€์‹  `๋งต`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ `๊ฐ์ฒด`๋ฅผ ์จ๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์–ธ์–ด๋ฅผ ๋งŒ๋“  ์‚ฌ๋žŒ๋“ค์ด ์˜ค๋ž˜์ „์— ์ด ๋ฌธ์ œ๋ฅผ ๊ณ ๋ คํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“  ์‚ฌ๋žŒ๋“ค์ด ์•„์ฃผ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๊ณ ๋ คํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— `๊ฐ์ฒด`๋ฅผ ์จ๋„ ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ์จ์„œ ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ด…์‹œ๋‹ค. -`__proto__`๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ `Object.prototype`์˜ ์ ‘๊ทผ์ž์ž…๋‹ˆ๋‹ค. +์•„์‹œ๋‹ค์‹œํ”ผ `__proto__`๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ `Object.prototype`์˜ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ![](object-prototype-2.svg) -๊ทธ๋ž˜์„œ `obj.__proto__`๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ๋•Œ, ์ด์— ๋Œ€์‘ํ•˜๋Š” getter/setter๋ฅผ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ˜ธ์ถœํ•ด `[[Prototype]]`์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— `obj.__proto__`๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ๋•Œ๋Š” ์ด์— ๋Œ€์‘ํ•˜๋Š” getter, setter๊ฐ€ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ํ˜ธ์ถœ๋˜๊ณ  `obj`๋Š” `[[Prototype]]`์„ ํ†ตํ•ด getter์™€ setter์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. -์ด ์ ˆ์„ ์‹œ์ž‘ํ•  ๋•Œ ์–ธ๊ธ‰ํ•œ๊ฒƒ ์ฒ˜๋Ÿผ `__proto__`์€ `[[Prototype]]`์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด์ง€ `[[Prototype]]` ๊ทธ ์ž์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. +์ด ์ ˆ์„ ์‹œ์ž‘ํ•  ๋•Œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ `__proto__`๋Š” `[[Prototype]]`์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด์ง€ `[[Prototype]]` ๊ทธ ์ž์ฒด๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด์ฃ . -์ž ์ด์ œ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ด€ ๋ฐฐ์—ด๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ„๋‹จํ•œ ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +์ด์ œ ๊ฐ„๋‹จํ•œ ํŠธ๋ฆญ์„ ์จ ๊ฐ์ฒด๊ฐ€ ์—ฐ๊ด€ ๋ฐฐ์—ด์˜ ์—ญํ• ์„ ๋‹ค ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run *!* let obj = Object.create(null); */!* -let key = prompt("What's the key?", "__proto__"); -obj[key] = "some value"; +let key = prompt("์ž…๋ ฅํ•˜๊ณ ์ž ํ•˜๋Š” key๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?", "__proto__"); +obj[key] = "...๊ฐ’..."; -alert(obj[key]); // "some value" +alert(obj[key]); // "...๊ฐ’..."์ด ์ œ๋Œ€๋กœ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ``` -`Object.create(null)`์€ ํ”„๋กœํ† ํƒ€์ž…์ด ์—†๋Š” ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค(`[[Prototype]]`์ด `null`). +`Object.create(null)`์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํ† ํƒ€์ž…์ด ์—†๋Š” ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. `[[Prototype]]`์ด `null`์ธ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“  ๊ฒƒ์ด์ฃ . ![](object-prototype-null.svg) -๊ทธ๋Ÿฌ๋ฏ€๋กœ `__proto__` getter/setter๋ฅผ ์ƒ์†ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ œ `"__proto__"`๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ์œ„์˜ ์˜ˆ์ œ๋Š” ์ž˜ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +`Object.create(null)`๋กœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋ฉด `__proto__` getter์™€ setter๋ฅผ ์ƒ์†๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ œ `__proto__`๋Š” ํ‰๋ฒ”ํ•œ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ๋ฒ„๊ทธ ์—†์ด ์˜ˆ์‹œ๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ๊ฐ์ฒด๋ฅผ '๋งค์šฐ ๋‹จ์ˆœํ•œ(very plain)' ๊ฐ์ฒด ํ˜น์€ '์ˆœ์ˆ˜ ์‚ฌ์ „์‹ ๊ฐ์ฒด(pure dictionary objects)'๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์ˆœํ•œ ๊ฐ์ฒด `{...}` ๋ณด๋‹ค ํ›จ์”ฌ ๋‹จ์ˆœํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . +์ด๋ ‡๊ฒŒ ํ”„๋กœํ† ํƒ€์ž…์ด ์—†๋Š” ๋นˆ ๊ฐ์ฒด๋Š” '์•„์ฃผ ๋‹จ์ˆœํ•œ(very plain)' ํ˜น์€ '์ˆœ์ˆ˜ ์‚ฌ์ „์‹(pure dictionary)' ๊ฐ์ฒด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ๊ฐ์ฒด `{...}` ๋ณด๋‹ค ํ›จ์”ฌ ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค. -์ด ๋ฐฉ์‹์˜ ๋‹จ์ ์€ ์ด๋Ÿฐ ๊ฐ์ฒด๋“ค์€ ๋‚ด์žฅ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. `toString`์„ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ ์•„์ฃผ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด๋Š” ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. `toString`๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ```js run *!* let obj = Object.create(null); */!* -alert(obj); // Error (toString์ด ์—†์Œ) +alert(obj); // Error: Cannot convert object to primitive value (toString์ด ์—†์Œ) ``` -ํ•˜์ง€๋งŒ ์—ฐ๊ด€ ๋ฐฐ์—ด์ด๋‹ˆ ๋ณดํ†ต์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. +๊ฐ์ฒด๋ฅผ ์—ฐ๊ด€ ๋ฐฐ์—ด๋กœ ์“ธ ๋•Œ๋Š” ์ด๋Ÿฐ ๋‹จ์ ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. -๊ฐ์ฒด์™€ ์—ฐ๊ด€๋œ ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ `Object.keys(obj)`์™€ ๊ฐ™์ด `Object.something(...)`ํ˜•ํƒœ๋ผ๋Š” ์ ์„ ์œ ์˜ํ•˜์„ธ์š”. ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— '๋งค์šฐ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด'์—๋„ ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฐ์ฒด ๊ด€๋ จ ๋ฉ”์„œ๋“œ ๋Œ€๋ถ€๋ถ„์€ `Object.keys(obj)` ๊ฐ™์ด `Object.something(...)` ํ˜•ํƒœ๋ฅผ ๋•๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ํ”„๋กœํ† ํƒ€์ž…์— ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— '์•„์ฃผ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด'์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run @@ -174,32 +173,32 @@ alert(Object.keys(chineseDictionary)); // hello,bye ## ์š”์•ฝ -ํ”„๋กœํ† ํƒ€์ž…์„ ์„ค์ •ํ•˜๊ณ  ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋˜ํ•œ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +ํ”„๋กœํ† ํƒ€์ž…์— ์ง์ ‘ ์ ‘๊ทผํ•  ๋• ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋˜ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- ์ธ์ž๋กœ ๋„˜๊ธด `proto`๋ฅผ `[[Prototype]]`์œผ๋กœ ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค(`null`์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค). ์„ ํƒ์ ์œผ๋กœ ์„ค๋ช…์ž๋ฅผ ๋„˜๊ธธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- `[[Prototype]]`์ด `proto`์ธ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ฐธ์กฐ ๊ฐ’์€ `null`์ผ ์ˆ˜ ์žˆ๊ณ  ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ๋„˜๊ธฐ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - [Object.getPrototypeOf(obj)](mdn:js/Object.getPrototypeOf) -- `obj`์˜ `[[Prototype]]`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค(`__proto__` getter์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค). - [Object.setPrototypeOf(obj, proto)](mdn:js/Object.setPrototypeOf) -- `obj`์˜ `[[Prototype]]`์„ `proto`๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค(`__proto__` setter์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค). -์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ํ‚ค๋ฅผ ๊ฐ์ฒด์— ์ €์žฅํ•  ๋•Œ, ๋‚ด์žฅ `__proto__` getter/setter๋Š” ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ `"__proto__"`๋ฅผ ํ‚ค๋กœ ์ž…๋ ฅํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•œ ์—๋Ÿฌ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ๋ณดํ†ต ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. +์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•˜๋ฉด, ๋‚ด์žฅ `__proto__`์˜ getter, setter ๋•Œ๋ฌธ์— ์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‚ค๊ฐ€ `"__proto__"`์ผ ๋•Œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์ฃ . ๋‹จ์ˆœํ•œ ์—๋Ÿฌ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ๋ณดํ†ต ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. -๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ด๋Ÿด ๋• `Object.create(null)`์„ ์‚ฌ์šฉํ•ด `__proto__`๊ฐ€ ์—†๋Š” '๋งค์šฐ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด'๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, `๋งต` ๊ฐ์ฒด๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. +์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด `Object.create(null)`์„ ์‚ฌ์šฉํ•ด `__proto__`๊ฐ€ ์—†๋Š” '์•„์ฃผ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด'๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, `๋งต`์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. -๋˜ `Object.create`๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด์˜ ๋ชจ๋“  ์„ค๋ช…์ž๋ฅผ ์–•๊ฒŒ ๋ณต์‚ฌ(shallow-copy)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•œํŽธ, `Object.create`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์–•์€ ๋ณต์‚ฌ๋ณธ(shallow-copy)์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); ``` -`__proto__`๋Š” `[[Prototype]]`์˜ getter/setter๋ผ๋Š” ์ ๊ณผ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์™€ ๊ฐ™์ด `Object.prototype`์— ์ •์˜๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๋Š” `__proto__`๋Š” `[[Prototype]]`์˜ getter, setter๋ผ๋Š” ์ ๊ณผ `__proto__`๋Š” ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์ฒ˜๋Ÿผ `Object.prototype`์— ์ •์˜๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. -`Object.create(null)`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํ† ํƒ€์ž…์ด ์—†๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฐ์ฒด๋Š” '์ˆœ์ˆ˜ํžˆ ์‚ฌ์ „์œผ๋กœ' ์‚ฌ์šฉ๋˜๊ณ  `"__proto__"`๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ๋•Œ๋„ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +`Object.create(null)`์„ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž…์ด ์—†๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฐ์ฒด๋Š” `"__proto__"`๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ปค์Šคํ…€ ์‚ฌ์ „์„ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -์‚ดํŽด๋ณผ ๋งŒํ•œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋‚ด์šฉ๊ณผ ๋”๋ถˆ์–ด ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋„ ๊ฐ™์ด ์‚ดํŽด๋ณด๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. -- [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- ๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•œ ์—ด๊ฑฐ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์˜ ์ด๋ฆ„/๊ฐ’/ํ‚ค-๊ฐ’ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- ๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•œ ์‹ฌ๋ณผ ํ‚ค์˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- ๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•œ ๋ชจ๋“  ๋ฌธ์ž์—ด ํ‚ค์˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- ๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•œ ํ‚ค์˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): `obj`๊ฐ€ ์†Œ์œ ํ•œ(์ƒ์†ํ•˜์ง€ ์•Š์€) ํ‚ค ์ค‘ ์ด๋ฆ„์ด `key`์ธ ๊ฒƒ์ด ์žˆ์œผ๋ฉด `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- `obj` ๋‚ด ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ ํ‚ค, ๊ฐ’, ํ‚ค-๊ฐ’ ์Œ์„ ๋‹ด์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- `obj` ๋‚ด ์‹ฌ๋ณผํ˜• ํ‚ค๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- [Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- `obj` ๋‚ด ๋ฌธ์žํ˜• ํ‚ค๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- `obj`๋‚ด ํ‚ค ์ „์ฒด๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty) -- ์ƒ์†๋ฐ›์ง€ ์•Š๊ณ  `obj` ์ž์ฒด์— ๊ตฌํ˜„๋œ ํ‚ค ์ค‘ ์ด๋ฆ„์ด `key`์ธ ๊ฒƒ์ด ์žˆ์œผ๋ฉด `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ(`Object.keys` ๋“ฑ) ์€ '๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•œ' ํ”„๋กœํผํ‹ฐ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์†ํ•œ ํ”„๋กœํผํ‹ฐ๋Š” `for..in`๋ฅผ ์‚ฌ์šฉํ•ด ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Object.keys`๋ฅผ ๋น„๋กฏํ•˜์—ฌ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์€ ๊ฐ์ฒด๊ฐ€ '์ง์ ‘ ์†Œ์œ ํ•œ' ํ”„๋กœํผํ‹ฐ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์† ํ”„๋กœํผํ‹ฐ๋Š” `for..in`์„ ์‚ฌ์šฉํ•ด ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg b/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg index c3717ad509..cf4d3023f8 100644 --- a/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg +++ b/1-js/08-prototypes/04-prototype-methods/object-prototype-2.svg @@ -1 +1 @@ -... get __proto__: function set __proto__: functionObject.prototypeObjectobj[[Prototype]]prototype \ No newline at end of file +... get __proto__: function set __proto__: functionObject.prototypeObjectobj[[Prototype]]prototype \ No newline at end of file diff --git a/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg b/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg index 8b802eb442..9ccb342299 100644 --- a/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg +++ b/1-js/08-prototypes/04-prototype-methods/object-prototype-null.svg @@ -1 +1 @@ -obj[[Prototype]]null \ No newline at end of file +obj[[Prototype]]null \ No newline at end of file diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md index 05365e4104..336aadc05b 100644 --- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md +++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md @@ -2,8 +2,8 @@ importance: 5 --- -# Rewrite to class +# ํด๋ž˜์Šค๋กœ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ธฐ -The `Clock` class is written in functional style. Rewrite it the "class" syntax. +ํ•จ์ˆ˜ ์Šคํƒ€์ผ๋กœ ์ž‘์„ฑ๋œ `Clock` ํด๋ž˜์Šค๋ฅผ 'ํด๋ž˜์Šค' ๋ฌธ๋ฒ•์œผ๋กœ ๋‹ค์‹œ ์จ๋ด…์‹œ๋‹ค. -P.S. The clock ticks in the console, open it to see. +์ฐธ๊ณ : ์ฝ˜์†”์ฐฝ์„ ์—ด์–ด ์‹œ๊ณ„๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•ด๋ณด์„ธ์š”. diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index a7215ea7fb..0e1def2be6 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -2,21 +2,21 @@ # ํด๋ž˜์Šค์™€ ๊ธฐ๋ณธ ๋ฌธ๋ฒ• ```quote author="์œ„ํ‚ค๋ฐฑ๊ณผ" -ํด๋ž˜์Šค(class)๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)์—์„œ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ์ผ์ข…์˜ ํ‹€๋กœ, ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)์™€ ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜)๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. +ํด๋ž˜์Šค๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ์ผ์ข…์˜ ํ‹€๋กœ, ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)์™€ ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜)๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ``` ์‹ค๋ฌด์—์„  ์‚ฌ์šฉ์ž๋‚˜ ๋ฌผ๊ฑด๊ฐ™์ด ๋™์ผํ•œ ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žฆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿด ๋•Œ ์—์„œ ๋ฐฐ์šด `new function`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿด ๋•Œ ์—์„œ ๋ฐฐ์šด `new function`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋„์ž…๋œ `ํด๋ž˜์Šค`๋ผ๋Š” ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋„์ž…๋œ `ํด๋ž˜์Šค(class)`๋ผ๋Š” ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ๊ธฐ๋ณธ ๋ฌธ๋ฒ• ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js class MyClass { - // ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ + // ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Œ constructor() { ... } method1() { ... } method2() { ... } @@ -25,7 +25,7 @@ class MyClass { } ``` -์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , `new MyClass()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์œ„ ์˜ˆ์‹œ์—์„œ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋“ค์–ด์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , `new MyClass()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด๋ถ€์—์„œ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด์˜ ๊ธฐ๋ณธ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•ด์ฃผ๋Š” ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ `constructor()`๋Š” `new`์— ์˜ํ•ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ, ํŠน๋ณ„ํ•œ ์ ˆ์ฐจ ์—†์ด ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -49,28 +49,28 @@ let user = new User("John"); user.sayHi(); ``` -`new User("John")`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ผ์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. +`new User("John")`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. 1. ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. -2. `constructor`๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„  ์ด๋•Œ ์ธ์ˆ˜ `"John"`์ด `this.name`์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. +2. ๋„˜๊ฒจ๋ฐ›์€ ์ธ์ˆ˜์™€ ํ•จ๊ป˜ `constructor`๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ธ์ˆ˜ `"John"`์ด `this.name`์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. -`user.sayHi()`์™€ ๊ฐ™์€ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์ด๋Ÿฐ ๊ณผ์ • ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ๊ณผ์ •์„ ๊ฑฐ์นœ ํ›„์— `user.sayHi()` ๊ฐ™์€ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```warn header="ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ ์‚ฌ์ด์—” ์‰ผํ‘œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค." -์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๋Š” ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์‰ผํ‘œ๋ฅผ ๋„ฃ๋Š” ์‹ค์ˆ˜๋ฅผ ์ €์ง€๋ฅด๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์‰ผํ‘œ๋ฅผ ๋„ฃ๊ฒŒ ๋˜๋ฉด ๋ฌธ๋ฒ• ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +```warn header="๋ฉ”์„œ๋“œ ์‚ฌ์ด์—” ์‰ผํ‘œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค." +์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๋Š” ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์‰ผํ‘œ๋ฅผ ๋„ฃ๋Š” ์‹ค์ˆ˜๋ฅผ ์ €์ง€๋ฅด๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์‰ผํ‘œ๋ฅผ ๋„ฃ์œผ๋ฉด ๋ฌธ๋ฒ• ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -ํด๋ž˜์Šค์™€ ๊ด€๋ จ๋œ ํ‘œ๊ธฐ๋ฒ•์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•๊ณผ ์ฐจ์ด๊ฐ€ ์žˆ์Œ์— ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ํด๋ž˜์Šค์—์„  ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์‰ผํ‘œ๋ฅผ ๋„ฃ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. +ํด๋ž˜์Šค์™€ ๊ด€๋ จ๋œ ํ‘œ๊ธฐ๋ฒ•์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•๊ณผ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์—์„  ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์‰ผํ‘œ๋ฅผ ๋„ฃ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ``` -## ํด๋ž˜์Šค๋ž€? +## ํด๋ž˜์Šค๋ž€ -์ด ์‹œ์ ์—์„œ "`ํด๋ž˜์Šค`๊ฐ€ ์ •ํ™•ํžˆ ๋ญ”๊ฐ€์š”?"๋ผ๋Š” ์˜๋ฌธ์ด ์ƒ๊ธฐ์‹ค ๊ฒ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ์ด ๊ธ€์„ ์ฝ๊ณ  ๊ณ„์‹  ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์ฒ˜๋Ÿผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฐจ์›์—์„œ ์ƒˆ๋กญ๊ฒŒ ์ฐฝ์•ˆ ํ•œ ๊ฐœ์ฒด(entity)๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. +์ด ์‹œ์ ์—์„œ "`ํด๋ž˜์Šค`๊ฐ€ ์ •ํ™•ํžˆ ๋ญ”๊ฐ€์š”?"๋ผ๋Š” ์˜๋ฌธ์ด ์ƒ๊ธฐ์‹ค ๊ฒ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ƒˆ๋กญ๊ฒŒ ์ฐฝ์•ˆํ•œ ๊ฐœ์ฒด(entity)๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. -ํด๋ž˜์Šค๊ฐ€ ๋ณด์—ฌ์ฃผ๋Š” ๋‹ค์–‘ํ•œ ๋งˆ๋ฒ•์˜ ์›๋ฆฌ๋ฅผ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๋ฉฐ ํด๋ž˜์Šค๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. ์ด ๊ณผ์ •์„ ๊ฑฐ์น˜๊ณ  ๋‚˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +ํด๋ž˜์Šค๊ฐ€ ๋ณด์—ฌ์ฃผ๋Š” ๋‹ค์–‘ํ•œ ๋งˆ๋ฒ•์˜ ์›๋ฆฌ๋ฅผ ํ•˜๋‚˜์”ฉ ํŒŒํ—ค์น˜๋ฉด์„œ ํด๋ž˜์Šค๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. ์ด ๊ณผ์ •์„ ๊ฑฐ์น˜๊ณ  ๋‚˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํด๋ž˜์Šค๋Š” ํ•จ์ˆ˜์˜ ํ•œ ์ข…๋ฅ˜์ž…๋‹ˆ๋‹ค. -์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. +์ฝ”๋“œ๋กœ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. ```js run class User { @@ -84,18 +84,18 @@ alert(typeof User); // function */!* ``` -`class User {...}`๋ผ๋Š” ๋ฌธ๋ฒ• ๊ตฌ์กฐ๊ฐ€ ์ง„์งœ ํ•˜๋Š” ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +`class User {...}` ๋ฌธ๋ฒ• ๊ตฌ์กฐ๊ฐ€ ์ง„์งœ ํ•˜๋Š” ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. ํด๋ž˜์Šค ์„ ์–ธ์˜ ๊ฒฐ๊ณผ๋กœ `User`๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋ณธ๋ฌธ์˜ ์ฝ”๋“œ๋Š” ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ `constructor`์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค(์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด ํ•จ์ˆ˜ ๋ณธ๋ฌธ์ด ๋น„์–ด์ง„ ์ฑ„๋กœ ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค). +1. `User`๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋ณธ๋ฌธ์€ ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ `constructor`์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด ๋ณธ๋ฌธ์ด ๋น„์›Œ์ง„ ์ฑ„๋กœ ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. 2. `sayHi`๊ฐ™์€ ํด๋ž˜์Šค ๋‚ด์—์„œ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ `User.prototype`์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. -`new User`๋ฅผ ํ˜ธ์ถœํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด์—์„œ ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`new User`๋ฅผ ํ˜ธ์ถœํ•ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ๋ฅผ prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด์—์„œ ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`class User` ์„ ์–ธ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +`class User` ์„ ์–ธ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](class-user.svg) -์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๋ฉด์„œ ์ง€๊ธˆ๊นŒ์ง€ ์„ค๋ช…ํ•œ ๊ฒƒ๋“ค์„ ๋‹ค์‹œ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ํ–ˆ๋˜ ์„ค๋ช…์„ ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•ด ๋ด…์‹œ๋‹ค. ```js run class User { @@ -112,25 +112,25 @@ alert(User === User.prototype.constructor); // true // ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๋Š” User.prototype์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. alert(User.prototype.sayHi); // alert(this.name); -// ์ด ์˜ˆ์‹œ์—์„œ ํ”„๋กœํ† ํƒ€์ž…์—๋Š” ๋ฉ”์„œ๋“œ ๋‘ ๊ฐœ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. +// ํ˜„์žฌ ํ”„๋กœํ† ํƒ€์ž…์—๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ๋‘ ๊ฐœ์ž…๋‹ˆ๋‹ค. alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ``` -## ํด๋ž˜์Šค๋Š” ๋‹จ์ˆœํ•œ ํŽธ์˜ ๋ฌธ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค. +## ํด๋ž˜์Šค๋Š” ๋‹จ์ˆœํ•œ ํŽธ์˜ ๋ฌธ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค -์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ `class`๋ผ๋Š” ํ‚ค์›Œ๋“œ ์—†์ด๋„ ํด๋ž˜์Šค ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์–ด์„œ `ํด๋ž˜์Šค`๋Š” 'ํŽธ์˜ ๋ฌธ๋ฒ•(syntax sugar, ๊ธฐ์กด ๋ฌธ๋ฒ•์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ฝ๊ธฐ ์œ„ํ•ด ๋งŒ๋“  ๋ฌธ๋ฒ•์œผ๋กœ, ๊ธฐ์กด ๋ฌธ๋ฒ•๊ณผ ๊ธฐ๋Šฅ์€ ๋™์ผํ•จ)'์— ๋ถˆ๊ณผํ•˜๋‹ค๊ณ  ์ด์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. +์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ `class`๋ผ๋Š” ํ‚ค์›Œ๋“œ ์—†์ด๋„ ํด๋ž˜์Šค ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `ํด๋ž˜์Šค`๋Š” 'ํŽธ์˜ ๋ฌธ๋ฒ•'์— ๋ถˆ๊ณผํ•˜๋‹ค๊ณ  ์ด์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๊ธฐ๋Šฅ์€ ๋™์ผํ•˜๋‚˜ ๊ธฐ์กด ๋ฌธ๋ฒ•์„ ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ๋ฌธ๋ฒ•์„ ํŽธ์˜ ๋ฌธ๋ฒ•(syntactic sugar, ๋ฌธ๋ฒ• ์„คํƒ•)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ```js run -// ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋งŒ์œผ๋กœ class User์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +// class User์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. // 1. ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. function User(name) { this.name = name; } -// ๋ชจ๋“  ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž…์€ constructor ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๊ฐ–๊ณ  ์žˆ์œผ๋ฏ€๋กœ +// ๋ชจ๋“  ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž…์€ 'constructor' ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— // constructor ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -// 2. prototype ํ”„๋กœํผํ‹ฐ์— ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. +// 2. prototype์— ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. User.prototype.sayHi = function() { alert(this.name); }; @@ -140,24 +140,24 @@ let user = new User("John"); user.sayHi(); ``` -์œ„ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋กœ ํด๋ž˜์Šค ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ `class` ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๊ฒฐ๊ณผ๋Š” ๊ฑฐ์˜ ๊ฐ™์Šต๋‹ˆ๋‹ค. `class`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‹จ์ˆœํ•œ ํŽธ์˜ ๋ฌธ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋กœ ํด๋ž˜์Šค ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ `class` ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๊ฒฐ๊ณผ๋Š” ๊ฑฐ์˜ ๊ฐ™์Šต๋‹ˆ๋‹ค. `class`๊ฐ€ ๋‹จ์ˆœํ•œ ํŽธ์˜ ๋ฌธ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ๋‘ ๋ฐฉ๋ฒ•์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ์ฐจ์ด์  ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ๋‘ ๋ฐฉ๋ฒ•์—๋Š” ์ค‘์š”ํ•œ ์ฐจ์ด๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค. -1. `class`๋กœ ๋งŒ๋“  ํ•จ์ˆ˜์—” ์ˆ˜๋™์œผ๋กœ ๋งŒ๋“  ํ•จ์ˆ˜์™€๋Š” ๋‹ฌ๋ฆฌ ํŠน์ˆ˜ํ•œ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ธ `[[FunctionKind]]:"classConstructor"`๊ฐ€ ์ด๋ฆ„ํ‘œ์ฒ˜๋Ÿผ ๋ถ™์Šต๋‹ˆ๋‹ค. +1. `class`๋กœ ๋งŒ๋“  ํ•จ์ˆ˜์—” ํŠน์ˆ˜ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ธ `[[IsClassConstructor]]: true`๊ฐ€ ์ด๋ฆ„ํ‘œ์ฒ˜๋Ÿผ ๋ถ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ๋งŒ์œผ๋กœ๋„ ๋‘ ๋ฐฉ๋ฒ•์—” ๋ถ„๋ช…ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋‹ฌ๋ฆฌ ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋Š” ๋ฐ˜๋“œ์‹œ `new`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ์— `[[IsClassConstructor]]: true`๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ `new`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด ๋•Œ `[[IsClassConstructor]]: true`๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ```js run class User { constructor() {} } - alert(typeof User); // function - User(); // Error: Class constructor User cannot be invoked without 'new' + alert(typeof User); // User์˜ ํƒ€์ž…์€ ํ•จ์ˆ˜์ด๊ธด ํ•˜์ง€๋งŒ ๊ทธ๋ƒฅ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + User(); // TypeError: Class constructor User cannot be invoked without 'new' ``` - ๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ๋ฌธ์ž์—ด๋กœ ํ‘œํ˜„ํ•  ๋•Œ 'class...'๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž์—ด๋กœ ํ‘œํ˜„ํ•œ๋‹ค๋Š” ์  ์—ญ์‹œ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. + ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ๋ฌธ์ž์—ด๋กœ ํ˜•๋ณ€ํ™˜ํ•˜๋ฉด 'class...'๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž์—ด์ด ๋˜๋Š”๋ฐ ์ด๋•Œ๋„ `[[IsClassConstructor]]: true`๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ```js run class User { @@ -166,32 +166,33 @@ user.sayHi(); alert(User); // class User { ... } ``` + ๋˜ ๋‹ค๋ฅธ ์ฐจ์ด์ ๋“ค์— ๋Œ€ํ•ด์„  ๊ณง ๋” ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -2. ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋Š” ์—ด๊ฑฐํ˜•์ด ์•„๋‹™๋‹ˆ๋‹ค(non-enumerable). - ํด๋ž˜์Šค์˜ `"prototype"` ํ”„๋กœํผํ‹ฐ์— ์ถ”๊ฐ€๋œ ๋ชจ๋“  ๋ฉ”์„œ๋“œ์˜ `enumerable` ํ”Œ๋ž˜๊ทธ๋Š” `false`์ž…๋‹ˆ๋‹ค. +2. ํด๋ž˜์Šค์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋Š” ์—ด๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(non-enumerable). + ํด๋ž˜์Šค์˜ `prototype` ํ”„๋กœํผํ‹ฐ์— ์ถ”๊ฐ€๋œ ๋ฉ”์„œ๋“œ์˜ `enumerable` ํ”Œ๋ž˜๊ทธ๋Š” `false`์ž…๋‹ˆ๋‹ค. - `for..in`์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ˆœํšŒํ•  ๋•Œ, ๋ฉ”์„œ๋“œ๋Š” ์ˆœํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์œผ๋ฏ€๋กœ ์ด ํŠน์ง•์€ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. + `for..in`์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ˆœํšŒํ•  ๋•Œ, ๋ฉ”์„œ๋“œ๋Š” ์ˆœํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์œผ๋ฏ€๋กœ ์ด ํŠน์ง•์€ ๊ฝค ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. 3. ํด๋ž˜์Šค๋Š” ํ•ญ์ƒ `์—„๊ฒฉ ๋ชจ๋“œ`๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค(`use strict`). - ํด๋ž˜์Šค ์ƒ์„ฑ์ž ์•ˆ์˜ ๋ชจ๋“  ์ฝ”๋“œ์—” ์ž๋™์œผ๋กœ ์—„๊ฒฉ ๋ชจ๋“œ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. + ํด๋ž˜์Šค ์ƒ์„ฑ์ž ์•ˆ ์ฝ”๋“œ ์ „์ฒด์—” ์ž๋™์œผ๋กœ ์—„๊ฒฉ ๋ชจ๋“œ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. -์ด ์™ธ์—๋„ `class`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์ด ๋”ฐ๋ผ์˜ค๋Š”๋ฐ, ์ด์— ๋Œ€ํ•ด์„  ์ถ”ํ›„์— ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด ์™ธ์—๋„ `class`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์ด ๋”ฐ๋ผ์˜ค๋Š”๋ฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฐจ์ฐจ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ## ํด๋ž˜์Šค ํ‘œํ˜„์‹ -ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํด๋ž˜์Šค๋„ ๋˜ ๋‹ค๋ฅธ ํ‘œํ˜„์‹ ๋‚ด๋ถ€์—์„œ ์ •์˜, ์ „๋‹ฌ, ๋ฐ˜ํ™˜, ํ• ๋‹น๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋„ ๋‹ค๋ฅธ ํ‘œํ˜„์‹ ๋‚ด๋ถ€์—์„œ ์ •์˜, ์ „๋‹ฌ, ๋ฐ˜ํ™˜, ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ํด๋ž˜์Šค ํ‘œํ˜„์‹์— ๋Œ€ํ•œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. +๋จผ์ € ํด๋ž˜์Šค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js let User = class { sayHi() { - alert("Hello"); + alert("์•ˆ๋…•ํ•˜์„ธ์š”."); } }; ``` -๊ธฐ๋ช… ํ•จ์ˆ˜ ํ‘œํ˜„์‹(Named Function Expression)๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํด๋ž˜์Šค ํ‘œํ˜„์‹๋„ ์ด๋ฆ„์„ ๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ธฐ๋ช… ํ•จ์ˆ˜ ํ‘œํ˜„์‹(Named Function Expression)๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํด๋ž˜์Šค ํ‘œํ˜„์‹์—๋„ ์ด๋ฆ„์„ ๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ํ‘œํ˜„์‹์— ์ด๋ฆ„์„ ๋ถ™์ด๋ฉด, ์ด ์ด๋ฆ„์€ ์˜ค์ง ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -204,12 +205,11 @@ let User = class *!*MyClass*/!* { } }; -new User().sayHi(); // ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค(MyClass์˜ ์ •์˜๋ฅผ ๋ณด์—ฌ์คŒ). +new User().sayHi(); // ์›ํ•˜๋Š”๋Œ€๋กœ MyClass์˜ ์ •์˜๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. -alert(MyClass); // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. MyClass๋Š” ํด๋ž˜์Šค ๋ฐ–์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +alert(MyClass); // ReferenceError: MyClass is not defined, MyClass๋Š” ํด๋ž˜์Šค ๋ฐ–์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ``` - ์•„๋ž˜์™€ ๊ฐ™์ด 'ํ•„์š”์— ๋”ฐ๋ผ' ํด๋ž˜์Šค๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ```js run @@ -223,17 +223,17 @@ function makeClass(phrase) { } // ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ฆ -let User = makeClass("Hello"); +let User = makeClass("์•ˆ๋…•ํ•˜์„ธ์š”."); -new User().sayHi(); // Hello +new User().sayHi(); // ์•ˆ๋…•ํ•˜์„ธ์š”. ``` -## getter,setter๋ฅผ ๋น„๋กฏํ•œ ๊ธฐํƒ€ ๋‹จ์ถ• ๊ตฌ๋ฌธ +## getter์™€ setter -๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋„ getter๋‚˜ setter, ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ(computed property)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋„ getter๋‚˜ setter, ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ(computed property)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„  `get`๊ณผ`set`์„ ์ด์šฉํ•ด `user.name`์— ๊ฐ’์„ ํ• ๋‹นํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +`get`๊ณผ`set`์„ ์ด์šฉํ•ด `user.name`์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๋ด…์‹œ๋‹ค. ```js run class User { @@ -261,28 +261,17 @@ class User { } -let user = new User("John"); -alert(user.name); // John +let user = new User("๋ณด๋ผ"); +alert(user.name); // ๋ณด๋ผ user = new User(""); // ์ด๋ฆ„์ด ๋„ˆ๋ฌด ์งง์Šต๋‹ˆ๋‹ค. ``` -ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด `User.prototype`์— getter์™€ setter๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋ฏ€๋กœ get๊ณผ set์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ getter์™€ setter๋Š” `User.prototype`์— ์ •์˜๋ฉ๋‹ˆ๋‹ค. -```js -Object.defineProperties(User.prototype, { - name: { - get() { - return this._name - }, - set(name) { - // ... - } - } -}); -``` +## ๊ณ„์‚ฐ๋œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„ [...] -์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ๋Œ€๊ด„ํ˜ธ `[...]`๋ฅผ ์ด์šฉํ•œ ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋Œ€๊ด„ํ˜ธ `[...]`๋ฅผ ์ด์šฉํ•ด ๊ณ„์‚ฐ๋œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„(computed method name)์„ ๋งŒ๋“œ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run class User { @@ -298,33 +287,123 @@ class User { new User().sayHi(); ``` -## ํด๋ž˜์Šค ํ”„๋กœํผํ‹ฐ +๊ณ„์‚ฐ๋œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์€ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ์ฒด์™€ ์œ ์‚ฌํ•œ ํ˜•ํƒœ๋ฅผ ๋ ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ๋ฒ•์„ ์™ธ์šฐ๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. + +## ํด๋ž˜์Šค ํ•„๋“œ -```warn header="๊ตฌ์‹ ๋ธŒ๋ผ์šฐ์ €๋Š” ํด๋ฆฌํ•„์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." -ํด๋ž˜์Šค ๋ ˆ๋ฒจ์˜ ํ”„๋กœํผํ‹ฐ๋Š” ๊ทผ๋ž˜์— ๋”ํ•ด์ง„ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. +```warn header="๊ตฌ์‹ ๋ธŒ๋ผ์šฐ์ €์—์„  ํด๋ฆฌํ•„์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." +ํด๋ž˜์Šค ํ•„๋“œ๋Š” ์ตœ๊ทผ์— ๋”ํ•ด์ง„ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ``` -์œ„ ์˜ˆ์‹œ์˜ `User`์—” ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋งŒ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์— ํ”„๋กœํผํ‹ฐ๋ฅผ ๋”ํ•ด์ค˜ ๋ด…์‹œ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ์˜ˆ์‹œ์—” ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +'ํด๋ž˜์Šค ํ•„๋“œ(class field)'๋ผ๋Š” ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์ข…๋ฅ˜์˜ ํ”„๋กœํผํ‹ฐ๋„ ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํด๋ž˜์Šค `User`์— `name` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ด…์‹œ๋‹ค. + ```js run class User { *!* - name = "Anonymous"; + name = "๋ณด๋ผ"; */!* sayHi() { - alert(`Hello, ${this.name}!`); + alert(`${this.name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`); } } -new User().sayHi(); +new User().sayHi(); // ๋ณด๋ผ๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”! +``` + +ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ '<ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„> = <๊ฐ’>'์„ ์จ์ฃผ๋ฉด ๊ฐ„๋‹จํžˆ ํด๋ž˜์Šค ํ•„๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํด๋ž˜์Šค ํ•„๋“œ์˜ ์ค‘์š”ํ•œ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” `User.prototype`์ด ์•„๋‹Œ ๊ฐœ๋ณ„ ๊ฐ์ฒด์—๋งŒ ํด๋ž˜์Šค ํ•„๋“œ๊ฐ€ ์„ค์ •๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. + +```js run +class User { +*!* + name = "๋ณด๋ผ"; +*/!* +} + +let user = new User(); +alert(user.name); // ๋ณด๋ผ +alert(User.prototype.name); // undefined +``` + +์•„์šธ๋Ÿฌ ํด๋ž˜์Šค ํ•„๋“œ์—” ๋ณต์žกํ•œ ํ‘œํ˜„์‹์ด๋‚˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js run +class User { +*!* + name = prompt("์ด๋ฆ„์„ ์•Œ๋ ค์ฃผ์„ธ์š”.", "๋ณด๋ผ"); +*/!* +} + +let user = new User(); +alert(user.name); // ๋ณด๋ผ +``` + + +### ํด๋ž˜์Šค ํ•„๋“œ๋กœ ๋ฐ”์ธ๋”ฉ ๋œ ๋ฉ”์„œ๋“œ ๋งŒ๋“ค๊ธฐ + + ์ฑ•ํ„ฐ์—์„œ ์‚ดํŽด๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ `this`๋Š” ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๊ธฐ์ €๊ธฐ ์ „๋‹ฌํ•ด ์ „ํ˜€ ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด `this`๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋œ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +๊ด€๋ จ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด `undefined`๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. + +```js run +class Button { + constructor(value) { + this.value = value; + } + + click() { + alert(this.value); + } +} + +let button = new Button("์•ˆ๋…•ํ•˜์„ธ์š”."); + +*!* +setTimeout(button.click, 1000); // undefined +*/!* ``` -`User.prototype`์„ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ `name`์„ ์ •์˜ํ•˜์ง€ ์•Š๊ณ , `new`๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— `name`์ด ๋งŒ๋“ค์–ด์ง€๋„๋ก ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŒ๋“  ํ”„๋กœํผํ‹ฐ๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋งŒ์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ `this`์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ์•Œ ์ˆ˜ ์—†๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ '์žƒ์–ด๋ฒ„๋ฆฐ `this`(losing this)'๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. + +๋ฌธ์ œ๋Š” ๋‘ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์—์„œ ์ด ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. + +1. `setTimeout(() => button.click(), 1000)` ๊ฐ™์ด ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ +2. ์ƒ์„ฑ์ž ์•ˆ ๋“ฑ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ + +์ด ๋‘ ๋ฐฉ๋ฒ• ๋ง๊ณ  ํด๋ž˜์Šค ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์šฐ์•„ํ•˜๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js run +class Button { + constructor(value) { + this.value = value; + } +*!* + click = () => { + alert(this.value); + } +*/!* +} + +let button = new Button("์•ˆ๋…•ํ•˜์„ธ์š”."); + +setTimeout(button.click, 1000); // ์•ˆ๋…•ํ•˜์„ธ์š”. +``` + +ํด๋ž˜์Šค ํ•„๋“œ `click = () => {...}`๋Š” ๊ฐ `Button` ๊ฐ์ฒด๋งˆ๋‹ค ๋…๋ฆฝ์ ์ธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ์ด ํ•จ์ˆ˜์˜ `this`๋ฅผ ํ•ด๋‹น ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ์‹œ์ผœ์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๋Š” `button.click`์„ ์•„๋ฌด ๊ณณ์—๋‚˜ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ , `this`์—” ํ•ญ์ƒ ์˜๋„ํ•œ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + +ํด๋ž˜์Šค ํ•„๋“œ์˜ ์ด๋Ÿฐ ๊ธฐ๋Šฅ์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋กœ ์„ค์ •ํ•ด์•ผ ํ•  ๋•Œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ## ์š”์•ฝ -์•„๋ž˜์™€ ๊ฐ™์€ ๊ธฐ๋ณธ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js class MyClass { @@ -339,11 +418,11 @@ class MyClass { get something(...) {} // getter ๋ฉ”์„œ๋“œ set something(...) {} // setter ๋ฉ”์„œ๋“œ - [Symbol.iterator]() {} // ๊ณ„์‚ฐ๋œ ์ด๋ฆ„(computed name)์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“œ๋Š” ๋ฉ”์„œ๋“œ (์‹ฌ๋ณผ๋„ ๊ฐ€๋Šฅ) + [Symbol.iterator]() {} // ๊ณ„์‚ฐ๋œ ์ด๋ฆ„(computed name)์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“œ๋Š” ๋ฉ”์„œ๋“œ (์‹ฌ๋ณผ) // ... } ``` -`MyClass`๋Š” `constructor`์˜ ์ฝ”๋“œ๋ฅผ ๋ณธ๋ฌธ์œผ๋กœ ๊ฐ–๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. `MyClass`์—์„œ ์ •์˜ํ•œ ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ๋‚˜ getter, setter๋Š” `MyClass.prototype`์— ์“ฐ์—ฌ์ง‘๋‹ˆ๋‹ค. +`MyClass`๋Š” `constructor`์˜ ์ฝ”๋“œ๋ฅผ ๋ณธ๋ฌธ์œผ๋กœ ๊ฐ–๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. `MyClass`์—์„œ ์ •์˜ํ•œ ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ๋‚˜ getter, setter๋Š” `MyClass.prototype`์— ์“ฐ์ž…๋‹ˆ๋‹ค. ์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„  ์ƒ์†์„ ๋น„๋กฏํ•œ ํด๋ž˜์Šค์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/01-class/class-user.svg b/1-js/09-classes/01-class/class-user.svg index 95b58179b6..418d71d187 100644 --- a/1-js/09-classes/01-class/class-user.svg +++ b/1-js/09-classes/01-class/class-user.svg @@ -1 +1 @@ -sayHi: functionUserUser.prototypeprototypeconstructor: User \ No newline at end of file +sayHi: functionUserUser.prototypeprototypeconstructor: User \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md index 4711e48271..b5b8e8718d 100644 --- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md +++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md @@ -1,6 +1,6 @@ -That's because the child constructor must call `super()`. +์ž์‹ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„œ `super()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. -Here's the corrected code: +์ˆ˜์ • ํ›„ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js run class Animal { @@ -21,7 +21,7 @@ class Rabbit extends Animal { } *!* -let rabbit = new Rabbit("White Rabbit"); // ok now +let rabbit = new Rabbit("White Rabbit"); // ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. */!* alert(rabbit.name); // White Rabbit ``` diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md index 380a4720b2..cfd553f953 100644 --- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md +++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Error creating an instance +# ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ์˜ค๋ฅ˜ -Here's the code with `Rabbit` extending `Animal`. +์•„๋ž˜ ์ฝ”๋“œ์—์„œ `Rabbit`์€ `Animal`์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -Unfortunately, `Rabbit` objects can't be created. What's wrong? Fix it. +๊ทธ๋Ÿฐ๋ฐ `Rabbit` ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡์ด ์ž˜๋ชป๋œ ๊ฒƒ์ผ๊นŒ์š”? ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด๋ณด์„ธ์š”. ```js run class Animal { diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js index ca613ca5e5..be2053cfcf 100644 --- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js +++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js @@ -1,7 +1,7 @@ class ExtendedClock extends Clock { constructor(options) { super(options); - let { precision=1000 } = options; + let { precision = 1000 } = options; this.precision = precision; } diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html index c0609858b8..61d229a8e9 100644 --- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html +++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html @@ -7,7 +7,7 @@ clock.start(); - /* Your class should work like this: */ + /* ๋งŒ๋“œ์‹  ํด๋ž˜์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. */ /* diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md index bbc2c6a43c..1150b93473 100644 --- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md +++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md @@ -2,14 +2,14 @@ importance: 5 --- -# Extended clock +# ์‹œ๊ณ„ ํ™•์žฅํ•˜๊ธฐ -We've got a `Clock` class. As of now, it prints the time every second. +๋งค ์ดˆ๋งˆ๋‹ค ์‹œ๊ฐ„์„ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํด๋ž˜์Šค `Clock`์ด ์žˆ์Šต๋‹ˆ๋‹ค. [js src="source.view/clock.js"] -Create a new class `ExtendedClock` that inherits from `Clock` and adds the parameter `precision` -- the number of `ms` between "ticks". Should be `1000` (1 second) by default. +`Clock`์„ ์ƒ์†๋ฐ›๋Š” `ExtendedClock`์„ ๋งŒ๋“ค๊ณ , `precision`(์ •ํ™•๋„)์ด๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”. `precision`์€ '์ดˆ' ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์„ ์˜๋ฏธํ•˜๊ณ , ๊ธฐ๋ณธ๊ฐ’์€ `1000`(1์ดˆ)์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- Your code should be in the file `extended-clock.js` -- Don't modify the original `clock.js`. Extend it. +- ์ƒˆ๋กœ์šด ํŒŒ์ผ(`extended-clock.js`)์„ ๋งŒ๋“ค์–ด ๋‹ต์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”. +- `clock.js`์€ ์ˆ˜์ •ํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ƒ์†์„ ์‚ฌ์šฉํ•˜์„ธ์š”. diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md deleted file mode 100644 index ca9e80601b..0000000000 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md +++ /dev/null @@ -1,81 +0,0 @@ -First, let's see why the latter code doesn't work. - -The reason becomes obvious if we try to run it. An inheriting class constructor must call `super()`. Otherwise `"this"` won't be "defined". - -So here's the fix: - -```js run -class Rabbit extends Object { - constructor(name) { -*!* - super(); // need to call the parent constructor when inheriting -*/!* - this.name = name; - } -} - -let rabbit = new Rabbit("Rab"); - -alert( rabbit.hasOwnProperty('name') ); // true -``` - -But that's not all yet. - -Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`. - -As we know, the "extends" syntax sets up two prototypes: - -1. Between `"prototype"` of the constructor functions (for methods). -2. Between the constructor functions themselves (for static methods). - -In our case, for `class Rabbit extends Object` it means: - -```js run -class Rabbit extends Object {} - -alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true -alert( Rabbit.__proto__ === Object ); // (2) true -``` - -So `Rabbit` now provides access to static methods of `Object` via `Rabbit`, like this: - -```js run -class Rabbit extends Object {} - -*!* -// normally we call Object.getOwnPropertyNames -alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b -*/!* -``` - -But if we don't have `extends Object`, then `Rabbit.__proto__` is not set to `Object`. - -Here's the demo: - -```js run -class Rabbit {} - -alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true -alert( Rabbit.__proto__ === Object ); // (2) false (!) -alert( Rabbit.__proto__ === Function.prototype ); // as any function by default - -*!* -// error, no such function in Rabbit -alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error -*/!* -``` - -So `Rabbit` doesn't provide access to static methods of `Object` in that case. - -By the way, `Function.prototype` has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`. - -Here's the picture: - -![](rabbit-extends-object.svg) - -So, to put it short, there are two differences: - -| class Rabbit | class Rabbit extends Object | -|--------------|------------------------------| -| -- | needs to call `super()` in constructor | -| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` | diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md deleted file mode 100644 index b82a4255e9..0000000000 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md +++ /dev/null @@ -1,42 +0,0 @@ -importance: 5 - ---- - -# Class extends Object? - -As we know, all objects normally inherit from `Object.prototype` and get access to "generic" object methods like `hasOwnProperty` etc. - -For instance: - -```js run -class Rabbit { - constructor(name) { - this.name = name; - } -} - -let rabbit = new Rabbit("Rab"); - -*!* -// hasOwnProperty method is from Object.prototype -alert( rabbit.hasOwnProperty('name') ); // true -*/!* -``` - -But if we spell it out explicitly like `"class Rabbit extends Object"`, then the result would be different from a simple `"class Rabbit"`? - -What's the difference? - -Here's an example of such code (it doesn't work -- why? fix it?): - -```js -class Rabbit extends Object { - constructor(name) { - this.name = name; - } -} - -let rabbit = new Rabbit("Rab"); - -alert( rabbit.hasOwnProperty('name') ); // true -``` diff --git a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg index 2f994f7b73..63b5a18a19 100644 --- a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg +++ b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg @@ -1 +1 @@ -constructor: Animal run: function stop: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitnew Rabbit[[Prototype]][[Prototype]]prototypeprototypename: "White Rabbit"constructorconstructorextends \ No newline at end of file +constructor: Animal run: function stop: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitnew Rabbit[[Prototype]][[Prototype]]prototypeprototypename: "White Rabbit"constructorconstructorextends \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md index d1685f20a8..8c626fa2c2 100644 --- a/1-js/09-classes/02-class-inheritance/article.md +++ b/1-js/09-classes/02-class-inheritance/article.md @@ -1,13 +1,13 @@ -# Class inheritance +# ํด๋ž˜์Šค ์ƒ์† -Class inheritance is a way for one class to extend another class. +ํด๋ž˜์Šค ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -So we can create new functionality on top of the existing. +๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ ๊ธฐ๋Šฅ์„ ํ† ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ . -## The "extends" keyword +## 'extends' ํ‚ค์›Œ๋“œ -Let's say with have class `Animal`: +๋จผ์ €, ํด๋ž˜์Šค `Animal`์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js class Animal { @@ -16,62 +16,62 @@ class Animal { this.name = name; } run(speed) { - this.speed += speed; - alert(`${this.name} runs with speed ${this.speed}.`); + this.speed = speed; + alert(`${this.name} ์€/๋Š” ์†๋„ ${this.speed}๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค.`); } stop() { this.speed = 0; - alert(`${this.name} stands still.`); + alert(`${this.name} ์ด/๊ฐ€ ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค.`); } } -let animal = new Animal("My animal"); +let animal = new Animal("๋™๋ฌผ"); ``` -Here's how we can represent `animal` object and `Animal` class graphically: +๊ฐ์ฒด `animal`๊ณผ ํด๋ž˜์Šค `Animal`์˜ ๊ด€๊ณ„๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](rabbit-animal-independent-animal.svg) -...And we would like to create another `class Rabbit`. +๋˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค `Rabbit`์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -As rabbits are animals, `Rabbit` class should be based on `Animal`, have access to animal methods, so that rabbits can do what "generic" animals can do. +ํ† ๋ผ๋Š” ๋™๋ฌผ์ด๋ฏ€๋กœ `Rabbit`์€ ๋™๋ฌผ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ด๊ธด `Animal`์„ ํ™•์žฅํ•ด์„œ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ† ๋ผ๋„ ๋™๋ฌผ์ด ํ•  ์ˆ˜ ์žˆ๋Š” '์ผ๋ฐ˜์ ์ธ' ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The syntax to extend another class is: `class Child extends Parent`. +ํด๋ž˜์Šค ํ™•์žฅ ๋ฌธ๋ฒ• `class Child extends Parent`๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด ๋ด…์‹œ๋‹ค. -Let's create `class Rabbit` that inherits from `Animal`: +`Animal`์„ ์ƒ์†๋ฐ›๋Š” `class Rabbit`๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js *!* class Rabbit extends Animal { */!* hide() { - alert(`${this.name} hides!`); + alert(`${this.name} ์ด/๊ฐ€ ์ˆจ์—ˆ์Šต๋‹ˆ๋‹ค!`); } } -let rabbit = new Rabbit("White Rabbit"); +let rabbit = new Rabbit("ํฐ ํ† ๋ผ"); -rabbit.run(5); // White Rabbit runs with speed 5. -rabbit.hide(); // White Rabbit hides! +rabbit.run(5); // ํฐ ํ† ๋ผ ์€/๋Š” ์†๋„ 5๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค. +rabbit.hide(); // ํฐ ํ† ๋ผ ์ด/๊ฐ€ ์ˆจ์—ˆ์Šต๋‹ˆ๋‹ค! ``` -Object of `Rabbit` class have access to both `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`. +ํด๋ž˜์Šค `Rabbit`์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๊ฐ์ฒด๋Š” `rabbit.hide()` ๊ฐ™์€ `Rabbit`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , `rabbit.run()` ๊ฐ™์€ `Animal`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Internally, `extends` keyword works using the good old prototype mechanics. It sets `Rabbit.prototype.[[Prototype]]` to `Animal.prototype`. So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`. +ํ‚ค์›Œ๋“œ `extends`๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. `extends`๋Š” `Rabbit.prototype.[[Prototype]]`์„ `Animal.prototype`์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— `Rabbit.prototype`์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด `Animal.prototype`์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ![](animal-rabbit-extends.svg) -For instance, to find `rabbit.run` method, the engine checks (bottom-up on the picture): -1. The `rabbit` object (has no `run`). -2. Its prototype, that is `Rabbit.prototype` (has `hide`, but not `run`). -3. Its prototype, that is (due to `extends`) `Animal.prototype`, that finally has the `run` method. +์—”์ง„์€ ๋‹ค์Œ ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ `rabbit.run`์˜ ์กด์žฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค(๊ทธ๋ฆผ์„ ์•„๋ž˜๋ถ€ํ„ฐ ๋ณด์„ธ์š”). +1. ๊ฐ์ฒด `rabbit`์— `run`์ด ์žˆ๋‚˜ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. `run`์ด ์—†๋„ค์š”. +2. `rabbit`์˜ ํ”„๋กœํ† ํƒ€์ž…์ธ `Rabbit.prototype`์— ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‚˜ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. `hide`๋Š” ์žˆ๋Š”๋ฐ `run`์€ ์—†์Šต๋‹ˆ๋‹ค. +3. `extends`๋ฅผ ํ†ตํ•ด ๊ด€๊ณ„๊ฐ€ ๋งŒ๋“ค์–ด์ง„ `Rabbit.prototype`์˜ ํ”„๋กœํ† ํƒ€์ž…, `Animal.prototype`์— ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‚˜ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋“œ๋””์–ด ๋ฉ”์„œ๋“œ `run`์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. -As we can recall from the chapter , JavaScript itself uses prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`. That's why dates have access to generic object methods. +์—์„œ ์•Œ์•„๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋‚ด์žฅ ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๋งบ์Šต๋‹ˆ๋‹ค. `Date.prototype.[[Prototype]]`์ด `Object.prototype`์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . `Date` ๊ฐ์ฒด์—์„œ ์ผ๋ฐ˜ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -````smart header="Any expression is allowed after `extends`" -Class syntax allows to specify not just a class, but any expression after `extends`. +````smart header="`extends` ๋’ค์— ํ‘œํ˜„์‹์ด ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค." +ํด๋ž˜์Šค ๋ฌธ๋ฒ•์€ `extends` ๋’ค์— ํ‘œํ˜„์‹์ด ์™€๋„ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค. -For instance, a function call that generates the parent class: +์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ `extends` ๋’ค์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์ฃ . ```js run function f(phrase) { @@ -86,34 +86,34 @@ class User extends f("Hello") {} new User().sayHi(); // Hello ``` -Here `class User` inherits from the result of `f("Hello")`. +์—ฌ๊ธฐ์„œ `class User`๋Š” `f("Hello")`์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -That may be useful for advanced programming patterns when we use functions to generate classes depending on many conditions and can inherit from them. +์ด ๋ฐฉ๋ฒ•์€ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์‹ถ์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```` -## Overriding a method +## ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ -Now let's move forward and override a method. By default, all methods that are not specified in `class Rabbit` are taken directly "as is" from `class Animal`. +์ด์ œ ํ•œ๋ฐœ ๋” ๋‚˜์•„๊ฐ€ ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด๋ด…์‹œ๋‹ค. ํŠน๋ณ„ํ•œ ์‚ฌํ•ญ์ด ์—†์œผ๋ฉด `class Rabbit`์€ `class Animal`์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ '๊ทธ๋Œ€๋กœ' ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -But if we specify our own method in `Rabbit`, such as `stop()` then it will be used instead: +๊ทธ๋Ÿฐ๋ฐ `Rabbit`์—์„œ `stop()` ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์ฒด์ ์œผ๋กœ ์ •์˜ํ•˜๋ฉด, ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ ์ž์ฒด ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ```js class Rabbit extends Animal { stop() { - // ...now this will be used for rabbit.stop() - // instead of stop() from class Animal + // rabbit.stop()์„ ํ˜ธ์ถœํ•  ๋•Œ + // Animal์˜ stop()์ด ์•„๋‹Œ, ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. } } ``` -Usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process. +๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ ์ „์ฒด๋ฅผ ๊ต์ฒดํ•˜์ง€ ์•Š๊ณ , ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๋ฅผ ํ† ๋Œ€๋กœ ์ผ๋ถ€ ๊ธฐ๋Šฅ๋งŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋„ ์žˆ์ฃ . ์ด๋Ÿด ๋•Œ ์ปค์Šคํ…€ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ž‘์—…ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ฏธ ์ปค์Šคํ…€ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ๋”๋ผ๋„ ์ด ๊ณผ์ • ์ „ยทํ›„์— ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -Classes provide `"super"` keyword for that. +ํ‚ค์›Œ๋“œ `super`๋Š” ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -- `super.method(...)` to call a parent method. -- `super(...)` to call a parent constructor (inside our constructor only). +- `super.method(...)`๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ, `method`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. +- `super(...)`๋Š” ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ์ž์‹ ์ƒ์„ฑ์ž ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, let our rabbit autohide when stopped: +์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•ด ํ† ๋ผ๊ฐ€ ๋ฉˆ์ถ”๋ฉด ์ž๋™์œผ๋กœ ์ˆจ๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run class Animal { @@ -124,51 +124,51 @@ class Animal { } run(speed) { - this.speed += speed; - alert(`${this.name} runs with speed ${this.speed}.`); + this.speed = speed; + alert(`${this.name}๊ฐ€ ์†๋„ ${this.speed}๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค.`); } stop() { this.speed = 0; - alert(`${this.name} stands still.`); + alert(`${this.name}๊ฐ€ ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค.`); } } class Rabbit extends Animal { hide() { - alert(`${this.name} hides!`); + alert(`${this.name}๊ฐ€ ์ˆจ์—ˆ์Šต๋‹ˆ๋‹ค!`); } *!* stop() { - super.stop(); // call parent stop - this.hide(); // and then hide + super.stop(); // ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ stop์„ ํ˜ธ์ถœํ•ด ๋ฉˆ์ถ”๊ณ , + this.hide(); // ์ˆจ์Šต๋‹ˆ๋‹ค. } */!* } -let rabbit = new Rabbit("White Rabbit"); +let rabbit = new Rabbit("ํฐ ํ† ๋ผ"); -rabbit.run(5); // White Rabbit runs with speed 5. -rabbit.stop(); // White Rabbit stands still. White rabbit hides! +rabbit.run(5); // ํฐ ํ† ๋ผ๊ฐ€ ์†๋„ 5๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค. +rabbit.stop(); // ํฐ ํ† ๋ผ๊ฐ€ ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค. ํฐ ํ† ๋ผ๊ฐ€ ์ˆจ์—ˆ์Šต๋‹ˆ๋‹ค! ``` -Now `Rabbit` has the `stop` method that calls the parent `super.stop()` in the process. +`Rabbit`์€ ์ด์ œ ์‹คํ–‰ ์ค‘๊ฐ„์— ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ `super.stop()`์„ ํ˜ธ์ถœํ•˜๋Š” `stop`์„ ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ๋„ค์š”. -````smart header="Arrow functions have no `super`" -As was mentioned in the chapter , arrow functions do not have `super`. +````smart header="ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—” `super`๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค." +์—์„œ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `super`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -If accessed, it's taken from the outer function. For instance: +`super`์— ์ ‘๊ทผํ•˜๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `super`๋ฅผ ์™ธ๋ถ€ ํ•จ์ˆ˜์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ```js class Rabbit extends Animal { stop() { - setTimeout(() => super.stop(), 1000); // call parent stop after 1sec + setTimeout(() => super.stop(), 1000); // 1์ดˆ ํ›„์— ๋ถ€๋ชจ stop์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. } } ``` -The `super` in the arrow function is the same as in `stop()`, so it works as intended. If we specified a "regular" function here, there would be an error: +ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ `super`๋Š” `stop()`์˜ `super`์™€ ๊ฐ™์•„์„œ ์œ„ ์˜ˆ์‹œ๋Š” ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ `setTimeout`์•ˆ์—์„œ '์ผ๋ฐ˜' ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค. ```js // Unexpected super @@ -177,17 +177,17 @@ setTimeout(function() { super.stop() }, 1000); ```` -## Overriding constructor +## ์ƒ์„ฑ์ž ์˜ค๋ฒ„๋ผ์ด๋”ฉ -With constructors it gets a little bit tricky. +์ƒ์„ฑ์ž ์˜ค๋ฒ„๋ผ์ด๋”ฉ์€ ์ข€ ๋” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. -Till now, `Rabbit` did not have its own `constructor`. +์ง€๊ธˆ๊นŒ์ง„ `Rabbit`์— ์ž์ฒด `constructor`๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. -According to the [specification](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), if a class extends another class and has no `constructor`, then the following "empty" `constructor` is generated: +[๋ช…์„ธ์„œ](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation)์— ๋”ฐ๋ฅด๋ฉด, ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  `constructor`๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—” ์•„๋ž˜์ฒ˜๋Ÿผ '๋น„์–ด์žˆ๋Š”' `constructor`๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ```js class Rabbit extends Animal { - // generated for extending classes without own constructors + // ์ž์ฒด ์ƒ์„ฑ์ž๊ฐ€ ์—†๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉด ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ง *!* constructor(...args) { super(...args); @@ -196,9 +196,9 @@ class Rabbit extends Animal { } ``` -As we can see, it basically calls the parent `constructor` passing it all the arguments. That happens if we don't write a constructor of our own. +๋ณด์‹œ๋‹ค์‹œํ”ผ ์ƒ์„ฑ์ž๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€๋ชจ `constructor`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋ถ€๋ชจ `constructor`์—๋„ ์ธ์ˆ˜๋ฅผ ๋ชจ๋‘ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค์— ์ž์ฒด ์ƒ์„ฑ์ž๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—” ์ด๋Ÿฐ ์ผ์ด ๋ชจ๋‘ ์ž๋™์œผ๋กœ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. -Now let's add a custom constructor to `Rabbit`. It will specify the `earLength` in addition to `name`: +์ด์ œ `Rabbit`์— ์ปค์Šคํ…€ ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์ƒ์„ฑ์ž์—์„œ `name`๊ณผ `earLength`๋ฅผ ์ง€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run class Animal { @@ -223,29 +223,31 @@ class Rabbit extends Animal { } *!* -// Doesn't work! -let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined. +// ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค! +let rabbit = new Rabbit("ํฐ ํ† ๋ผ", 10); // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor */!* ``` -Whoops! We've got an error. Now we can't create rabbits. What went wrong? +์•„์ด์ฝ”! ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋„ค์š”. ํ† ๋ผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡์ด ์ž˜๋ชป๋œ ๊ฑธ๊นŒ์š”? -The short answer is: constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`. +์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -...But why? What's going on here? Indeed, the requirement seems strange. +- **์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„  ๋ฐ˜๋“œ์‹œ `super(...)`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”๋ฐ, `super(...)`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. `super(...)`๋Š” `this`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** -Of course, there's an explanation. Let's get into details, so you'll really understand what's going on. +๊ทธ๋Ÿฐ๋ฐ ์™œ `super(...)`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๊ฑธ๊นŒ์š”? -In JavaScript, there's a distinction between a "constructor function of an inheriting class" and all others. In an inheriting class, the corresponding constructor function is labeled with a special internal property `[[ConstructorKind]]:"derived"`. +๋‹น์—ฐํžˆ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ์•„๋ณด๋ฉฐ ์ด์œ ๋ฅผ ์ฐพ์•„๋ด…์‹œ๋‹ค. -The difference is: +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” '์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜(derived constructor)'์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์—” ํŠน์ˆ˜ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ธ `[[ConstructorKind]]:"derived"`๊ฐ€ ์ด๋ฆ„ํ‘œ์ฒ˜๋Ÿผ ๋ถ™์Šต๋‹ˆ๋‹ค. -- When a normal constructor runs, it creates an empty object and assigns it to `this`. -- But when a derived constructor runs, it doesn't do this. It expects the parent constructor to do this job. +์ผ๋ฐ˜ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ฐ„ ์ฐจ์ด๋Š” `new`์™€ ํ•จ๊ป˜ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. -So if we're making a constructor of our own, then we must call `super`, because otherwise the object for `this` won't be created. And we'll get an error. +- ์ผ๋ฐ˜ ํด๋ž˜์Šค๊ฐ€ `new`์™€ ํ•จ๊ป˜ ์‹คํ–‰๋˜๋ฉด, ๋นˆ ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  `this`์— ์ด ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. +- ๋ฐ˜๋ฉด, ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋ฉด, ์ผ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์ผ์–ด๋‚œ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  `this`์— ์ด ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•˜๋Š” ์ผ์„ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ฒ˜๋ฆฌํ•ด์ฃผ๊ธธ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. -For `Rabbit` constructor to work, it needs to call `super()` before using `this`, like here: +์ด๋Ÿฐ ์ฐจ์ด ๋•Œ๋ฌธ์— ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„  `super`๋ฅผ ํ˜ธ์ถœํ•ด ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ์‹คํ–‰ํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `this`๊ฐ€ ๋  ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + +์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `this`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— `super()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `Rabbit`์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```js run class Animal { @@ -271,76 +273,172 @@ class Rabbit extends Animal { } *!* -// now fine -let rabbit = new Rabbit("White Rabbit", 10); -alert(rabbit.name); // White Rabbit +// ์ด์ œ ์—๋Ÿฌ ์—†์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +let rabbit = new Rabbit("ํฐ ํ† ๋ผ", 10); +alert(rabbit.name); // ํฐ ํ† ๋ผ alert(rabbit.earLength); // 10 */!* ``` -## Super: internals, [[HomeObject]] -```warn header="Advanced information" -If you're reading the tutorial for the first time - this section may be skipped. +### ํด๋ž˜์Šค ํ•„๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ: ๊นŒ๋‹ค๋กœ์šด ๋‚ด์šฉ + +```warn header="์‚ฌ์ „ ๊ณต์ง€" +์ด ๋‚ด์šฉ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด์™ธ์˜ ์–ธ์–ด์—์„œ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๋ณธ ๊ฒฝํ—˜์ด ์žˆ๋‹ค๋Š” ์ „์ œํ•˜์— ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. + +์—ฌ๊ธฐ์„œ ๋‹ค๋ฃฐ ๋‚ด์šฉ์„ ์ž˜ ์Šต๋“ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ ํ†ต์ฐฐ๋ ฅ์ด ๋†’์•„์ง€๊ณ  ๋“œ๋ฌผ์ง€๋งŒ, ๋ฒ„๊ทธ๋ฅผ ๋งŒ๋“œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šต๊ด€์— ๋Œ€ํ•ด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด ์ด ๋ถ€๋ถ„์„ ๊ฑด๋„ˆ๋›ฐ์—ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๋‹ค์‹œ ์ฝ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค. +``` + +์˜ค๋ฒ„๋ผ์ด๋”ฉ์€ ๋ฉ”์„œ๋“œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค ํ•„๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ์•ˆ์— ์žˆ๋Š” ์˜ค๋ฐ”๋ผ์ด๋”ฉํ•œ ํ•„๋“œ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์กฐ๊ธˆ ๊นŒ๋‹ค๋กญ์ง€๋งŒ ๋ง์ด์ฃ . + +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. + +```js run +class Animal { + name = 'animal' + + constructor() { + alert(this.name); // (*) + } +} + +class Rabbit extends Animal { + name = 'rabbit'; +} + +new Animal(); // animal +*!* +new Rabbit(); // animal +*/!* +``` + +`Animal`์„ ์ƒ์†๋ฐ›๋Š” `Rabbit`์—์„œ `name` ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ–ˆ์Šต๋‹ˆ๋‹ค. + +`Rabbit`์—๋Š” ๋”ฐ๋กœ ์ƒ์„ฑ์ž๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— `Rabbit`์„ ์‚ฌ์šฉํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๋ฉด `Animal`์˜ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + +ํฅ๋ฏธ๋กœ์šด ์ ์€ `new Animal()`๊ณผ `new Rabbit()`์„ ์‹คํ–‰ํ•  ๋•Œ ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์— ์žˆ๋Š” `alert` ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ์–ผ๋Ÿฟ ์ฐฝ์— `animal`์ด ์ถœ๋ ฅ๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. + +์ด๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” **'๋ถ€๋ชจ ์ƒ์„ฑ์ž๋Š” ์ž์‹ ํด๋ž˜์Šค์—์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ๊ฐ’์ด ์•„๋‹Œ, ๋ถ€๋ชจ ํด๋ž˜์Šค ์•ˆ์˜ ํ•„๋“œ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค'** ๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ƒ์†์„ ๋ฐ›๊ณ  ํ•„๋“œ ๊ฐ’์„ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๋Š”๋ฐ ์ƒˆ๋กœ์šด ๊ฐ’ ๋Œ€์‹  ๋ถ€๋ชจ ํด๋ž˜์Šค ์•ˆ์— ์žˆ๋Š” ๊ธฐ์กด ํ•„๋“œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋‹ค๋‹ˆ ์ด์ƒํ•˜์ง€ ์•Š๋‚˜์š”? + +์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์ด ์ƒํ™ฉ์„ ๋ฉ”์„œ๋“œ์™€ ๋น„๊ตํ•ด ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. + +์•„๋ž˜ ์˜ˆ์‹œ์—์„  ํ•„๋“œ `this.name` ๋Œ€์‹ ์— ๋ฉ”์„œ๋“œ `this.showName()`์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. + +```js run +class Animal { + showName() { // this.name = 'animal' ๋Œ€์‹  ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ + alert('animal'); + } + + constructor() { + this.showName(); // alert(this.name); ๋Œ€์‹  ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ + } +} + +class Rabbit extends Animal { + showName() { + alert('rabbit'); + } +} + +new Animal(); // animal +*!* +new Rabbit(); // rabbit +*/!* +``` + +ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ์œ„์ชฝ ์˜ˆ์‹œ์™€ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅด๋„ค์š”. + +์œ„์™€ ๊ฐ™์ด ์ž์‹ ํด๋ž˜์Šค์—์„œ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒŒ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋˜ ๊ฒฐ๊ณผ์ฃ . + +๊ทธ๋Ÿฐ๋ฐ ํด๋ž˜์Šค ํ•„๋“œ๋Š” ์ž์‹ ํด๋ž˜์Šค์—์„œ ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด๋„ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๊ฐ€ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ํ•„๋“œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋Š” ํ•ญ์ƒ ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์žˆ๋Š” ํ•„๋“œ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + +์™œ ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ์š”? + +์ด์œ ๋Š” ํ•„๋“œ ์ดˆ๊ธฐํ™” ์ˆœ์„œ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํด๋ž˜์Šค ํ•„๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์— ๋”ฐ๋ผ ์ดˆ๊ธฐํ™” ์ˆœ์„œ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. +- ์•„๋ฌด๊ฒƒ๋„ ์ƒ์†๋ฐ›์ง€ ์•Š๋Š” ๋ฒ ์ด์Šค ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž ์‹คํ–‰ ์ด์ „์— ์ดˆ๊ธฐํ™”๋จ +- ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—” `super()` ์‹คํ–‰ ์งํ›„์— ์ดˆ๊ธฐํ™”๋จ + +์œ„ ์˜ˆ์‹œ์—์„œ `Rabbit`์€ ํ•˜์œ„ ํด๋ž˜์Šค์ด๊ณ  `constructor()`๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์•ž์„œ ์„ค๋ช…ํ•œ ๋ฐ”์™€ ๊ฐ™์ด ์ƒ์„ฑ์ž๋Š” ๋น„์–ด์žˆ๋Š”๋ฐ ๊ทธ ์•ˆ์— `super(...args)`๋งŒ ์žˆ๋‹ค๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ `new Rabbit()`์„ ์‹คํ–‰ํ•˜๋ฉด `super()`๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋•Œ ํ•˜์œ„ ํด๋ž˜์Šค ํ•„๋“œ ์ดˆ๊ธฐํ™” ์ˆœ์„œ์— ๋”ฐ๋ผ ํ•˜์œ„ ํด๋ž˜์Šค `Rabbit`์˜ ํ•„๋“œ๋Š” `super()` ์‹คํ–‰ ํ›„์— ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์— `Rabbit`์˜ ํ•„๋“œ๋Š” ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š์ฃ . ์ด๋Ÿฐ ์ด์œ ๋กœ ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ–ˆ์„ ๋•Œ `Animal`์— ์žˆ๋Š” ํ•„๋“œ๊ฐ€ ์‚ฌ์šฉ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ด๋ ‡๊ฒŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์‹œ ํ•„๋“œ์™€ ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘ ๋ฐฉ์‹์ด ๋ฏธ๋ฌ˜ํ•˜๊ฒŒ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. + +๋‹คํ–‰ํžˆ๋„ ์ด๋Ÿฐ ๋ฌธ์ œ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ํ•„๋“œ๋ฅผ ๋ถ€๋ชจ ์ƒ์„ฑ์ž์—์„œ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์™œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ๋ชจ๋ฅด๋ฉด ๊ฒฐ๊ณผ๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด ํ•„๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์‹œ ๋‚ด๋ถ€์—์„œ ๋ฒŒ์–ด์ง€๋Š” ์ผ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. + +๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ ํ•„๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•„๋“œ ๋Œ€์‹  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ getter๋‚˜ setter๋ฅผ ์‚ฌ์šฉํ•ด ํ•ด๊ฒฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. + + +## super ํ‚ค์›Œ๋“œ์™€ [[HomeObject]] + +```warn header="์–ด๋ ต์Šต๋‹ˆ๋‹ค." +ํŠœํ† ๋ฆฌ์–ผ์„ ์ฒ˜์Œ ์ฝ๋Š” ๋ถ„์ด๋ผ๋ฉด ์ด๋ฒˆ ์ ˆ์€ ๋„˜์–ด๊ฐ€์„œ๋„ ์ข‹์Šต๋‹ˆ๋‹ค. -It's about the internal mechanisms behind inheritance and `super`. +์ด๋ฒˆ ์ ˆ์—์„  ์ƒ์†๊ณผ `super`์˜ ๋‚ด๋ถ€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•ด ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ``` -Let's get a little deeper under the hood of `super`. We'll see some interesting things along the way. +`super`์— ๋Œ€ํ•ด์„œ ์ข€ ๋” ๊นŠ์ด ํŒŒ๋ด…์‹œ๋‹ค. ์ค‘๊ฐ„์ค‘๊ฐ„ ํฅ๋ฏธ๋กœ์šด ์ ์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -First to say, from all that we've learned till now, it's impossible for `super` to work at all! +๋จผ์ € ๋“œ๋ ค์•ผ ํ•  ๋ง์€ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ๋งŒ์œผ๋ก  `super`๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -Yeah, indeed, let's ask ourselves, how it should technically work? When an object method runs, it gets the current object as `this`. If we call `super.method()` then, the engine needs to get the `method` from the prototype of the current object. But how? +๋„ค ์•„์‰ฝ์ง€๋งŒ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. "๋‚ด๋ถ€์—์„œ super๋Š” '์–ด๋–ป๊ฒŒ' ๋™์ž‘ํ• ๊นŒ?"๋ผ๋Š” ์งˆ๋ฌธ์„ ์ž์‹ ์—๊ฒŒ ๋˜์ ธ๋ด…์‹œ๋‹ค. "๊ฐ์ฒด ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ํ˜„์žฌ ๊ฐ์ฒด๊ฐ€ `this`๊ฐ€ ๋œ๋‹ค. ์ด ์ƒํƒœ์—์„œ `super.method()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์—”์ง„์€ ํ˜„์žฌ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์—์„œ `method`๋ฅผ ์ฐพ์•„์•ผ ํ•œ๋‹ค."๊นŒ์ง„ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ๊ณผ์ •์€ '์–ด๋–ป๊ฒŒ' ์ผ์–ด๋‚˜๋Š” ๊ฑธ๊นŒ์š”? -The task may seem simple, but it isn't. The engine knows the current object `this`, so it could get the parent `method` as `this.__proto__.method`. Unfortunately, such a "naive" solution won't work. +์‰ฌ์›Œ ๋ณด์ด๋Š” ์งˆ๋ฌธ ๊ฐ™์ง€๋งŒ ์‹ค์ œ๋ก  ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—”์ง„์€ ํ˜„์žฌ ๊ฐ์ฒด `this`๋ฅผ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— `this.__proto__.method`๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ ๊ฐ์ฒด์˜ `method`๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์ฃ . ํ•˜์ง€๋งŒ ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ์ด๋Ÿฐ '๋‚˜์ด๋ธŒํ•œ' ์ƒ๊ฐ์€ ๋“ค์–ด๋งž์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -Let's demonstrate the problem. Without classes, using plain objects for the sake of simplicity. +๊ตฌ์ฒด์ ์ธ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐ์„ฑ์„ ์œ„ํ•ด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ์˜ˆ์‹œ๋ฅผ ๊ตฌ์„ฑํ•ด ๋ด…์‹œ๋‹ค. -You may skip this part and go below to the `[[HomeObject]]` subsection if you don't want to know the details. That won't harm. Or read on if you're interested in understanding things in-depth. +๊ตฌ์ฒด์ ์ธ ๋‚ด๋ถ€ ๋™์ž‘์— ๊ด€์‹ฌ์ด ์—†์œผ๋ฉด ์ด ๋ถ€๋ถ„์„ ์ง€๋‚˜์น˜๊ณ  `[[HomeObject]]`๋กœ ๋ฐ”๋กœ ๋„˜์–ด๊ฐ€์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๋ถ€ํ„ฐ ๋‹ค๋ฃฐ ๋‚ด์šฉ์„ ๋ชจ๋ฅด๊ณ ๋„ `[[HomeObject]]` ๋‚ด์šฉ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊นŠ๊ฒŒ ์ดํ•ดํ•˜๋ ค๋ฉด ์˜ˆ์‹œ์™€ ๊ด€๋ จ ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. -In the example below, `rabbit.__proto__ = animal`. Now let's try: in `rabbit.eat()` we'll call `animal.eat()`, using `this.__proto__`: +์•„๋ž˜ ์˜ˆ์‹œ์˜ `rabbit.__proto__`์€ `animal`์ž…๋‹ˆ๋‹ค. `rabbit.eat()`์—์„œ `this.__proto__`๋ฅผ ์‚ฌ์šฉํ•ด `animal.eat()`์„ ํ˜ธ์ถœํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let animal = { - name: "Animal", + name: "๋™๋ฌผ", eat() { - alert(`${this.name} eats.`); + alert(`${this.name} ์ด/๊ฐ€ ๋จน์ด๋ฅผ ๋จน์Šต๋‹ˆ๋‹ค.`); } }; let rabbit = { __proto__: animal, - name: "Rabbit", + name: "ํ† ๋ผ", eat() { *!* - // that's how super.eat() could presumably work + // ์˜ˆ์ƒ๋Œ€๋กœ๋ผ๋ฉด super.eat()์ด ๋™์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. this.__proto__.eat.call(this); // (*) */!* } }; -rabbit.eat(); // Rabbit eats. +rabbit.eat(); // ํ† ๋ผ ์ด/๊ฐ€ ๋จน์ด๋ฅผ ๋จน์Šต๋‹ˆ๋‹ค. ``` -At the line `(*)` we take `eat` from the prototype (`animal`) and call it in the context of the current object. Please note that `.call(this)` is important here, because a simple `this.__proto__.eat()` would execute parent `eat` in the context of the prototype, not the current object. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„  `eat`์„ ํ”„๋กœํ† ํƒ€์ž…(`animal`)์—์„œ ๊ฐ€์ ธ์˜ค๊ณ  ํ˜„์žฌ ๊ฐ์ฒด์˜ ์ปจํ…์ŠคํŠธ์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ `eat`์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•ด์„œ ๋ด์•ผ ํ•  ๋ถ€๋ถ„์€ `.call(this)`์ž…๋‹ˆ๋‹ค. `this.__proto__.eat()`๋งŒ ์žˆ์œผ๋ฉด ํ˜„์žฌ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ํ”„๋กœํ† ํƒ€์ž…์˜ ์ปจํ…์ŠคํŠธ์—์„œ ๋ถ€๋ชจ `eat`์„ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— `.call(this)`์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -And in the code above it actually works as intended: we have the correct `alert`. +์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜ˆ์ƒํ•œ ๋‚ด์šฉ์ด ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„ค์š”. -Now let's add one more object to the chain. We'll see how things break: +์ž ์ด์ œ ์ฒด์ธ์— ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์Šฌ์Šฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```js run let animal = { - name: "Animal", + name: "๋™๋ฌผ", eat() { - alert(`${this.name} eats.`); + alert(`${this.name} ์ด/๊ฐ€ ๋จน์ด๋ฅผ ๋จน์Šต๋‹ˆ๋‹ค.`); } }; let rabbit = { __proto__: animal, eat() { - // ...bounce around rabbit-style and call parent (animal) method + // call์„ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ๋ฅผ ์˜ฎ๊ฒจ๊ฐ€๋ฉฐ ๋ถ€๋ชจ(animal) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. this.__proto__.eat.call(this); // (*) } }; @@ -348,71 +446,71 @@ let rabbit = { let longEar = { __proto__: rabbit, eat() { - // ...do something with long ears and call parent (rabbit) method + // longEar๋ฅผ ๊ฐ€์ง€๊ณ  ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๋ฉด์„œ ๋ถ€๋ชจ(rabbit) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. this.__proto__.eat.call(this); // (**) } }; *!* -longEar.eat(); // Error: Maximum call stack size exceeded +longEar.eat(); // RangeError: Maximum call stack size exceeded */!* ``` -The code doesn't work anymore! We can see the error trying to call `longEar.eat()`. +์˜ˆ์ƒ๊ณผ ๋‹ฌ๋ฆฌ `longEar.eat()`๋ฅผ ํ˜ธ์ถœํ•˜๋‹ˆ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋„ค์š”! -It may be not that obvious, but if we trace `longEar.eat()` call, then we can see why. In both lines `(*)` and `(**)` the value of `this` is the current object (`longEar`). That's essential: all object methods get the current object as `this`, not a prototype or something. +์›์ธ์ด ์„์—ฐ์น˜ ์•Š์•„ ๋ณด์ด์ง€๋งŒ `longEar.eat()`์ด ํ˜ธ์ถœ๋  ๋•Œ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ•˜๋‚˜์”ฉ ์ถ”์ฒ™ํ•˜๋‹ค๋ณด๋ฉด ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์‚ดํŽด๋ด์•ผ ํ•  ๊ฒƒ์€ `(*)`๊ณผ `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์ž…๋‹ˆ๋‹ค. ์ด ๋‘ ์ค„์—์„œ `this`๋Š” ํ˜„์žฌ ๊ฐ์ฒด์ธ `longEar`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ํ•ต์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋“ฑ์ด ์•„๋‹Œ ํ˜„์žฌ ๊ฐ์ฒด๋ฅผ `this`๋กœ ๊ฐ–์Šต๋‹ˆ๋‹ค. -So, in both lines `(*)` and `(**)` the value of `this.__proto__` is exactly the same: `rabbit`. They both call `rabbit.eat` without going up the chain in the endless loop. +๋”ฐ๋ผ์„œ `(*)`๊ณผ `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์˜ `this.__proto__`์—” ์ •ํ™•ํžˆ ๊ฐ™์€ ๊ฐ’, `rabbit`์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ์ฒด์ธ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๊ณ  ์–‘์ชฝ ๋ชจ๋‘์—์„œ `rabbit.eat`์„ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌดํ•œ ๋ฃจํ”„์— ๋น ์ง€๊ฒŒ ๋˜์ฃ . -Here's the picture of what happens: +์ด๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](this-super-loop.svg) -1. Inside `longEar.eat()`, the line `(**)` calls `rabbit.eat` providing it with `this=longEar`. +1. `longEar.eat()` ๋‚ด๋ถ€์˜ `(**)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `rabbit.eat`์„ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ์ด๋•Œ `this`๋Š” `longEar`์ž…๋‹ˆ๋‹ค. ```js - // inside longEar.eat() we have this = longEar + // longEar.eat()์•ˆ์˜ this๋Š” longEar์ž…๋‹ˆ๋‹ค. this.__proto__.eat.call(this) // (**) - // becomes + // ๋”ฐ๋ผ์„œ ์œ—์ค„์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. longEar.__proto__.eat.call(this) - // that is + // longEar์˜ ํ”„๋กœํ† ํƒ€์ž…์€ rabbit์ด๋ฏ€๋กœ ์œ—์ค„์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. rabbit.eat.call(this); ``` -2. Then in the line `(*)` of `rabbit.eat`, we'd like to pass the call even higher in the chain, but `this=longEar`, so `this.__proto__.eat` is again `rabbit.eat`! +2. `rabbit.eat` ๋‚ด๋ถ€์˜ `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ์ฒด์ธ ์œ„์ชฝ์— ์žˆ๋Š” ํ˜ธ์ถœ์„ ์ „๋‹ฌํ•˜๋ ค ํ–ˆ์œผ๋‚˜ `this`๊ฐ€ `longEar` ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋˜๋‹ค์‹œ `rabbit.eat`์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ```js - // inside rabbit.eat() we also have this = longEar + // rabbit.eat()์•ˆ์˜ this ์—ญ์‹œ longEar์ž…๋‹ˆ๋‹ค. this.__proto__.eat.call(this) // (*) - // becomes + // ๋”ฐ๋ผ์„œ ์œ—์ค„์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. longEar.__proto__.eat.call(this) - // or (again) + // longEar์˜ ํ”„๋กœํ† ํƒ€์ž…์€ rabbit์ด๋ฏ€๋กœ ์œ—์ค„์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. rabbit.eat.call(this); ``` -3. ...So `rabbit.eat` calls itself in the endless loop, because it can't ascend any further. +3. ์ด๋Ÿฐ ๋‚ด๋ถ€ ๋™์ž‘ ๋•Œ๋ฌธ์— `rabbit.eat`์€ ์ฒด์ธ ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์ง€ ๋ชปํ•˜๊ณ  ์ž๊ธฐ ์ž์‹ ์„ ๊ณ„์† ํ˜ธ์ถœํ•ด ๋ฌดํ•œ ๋ฃจํ”„์— ๋น ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -The problem can't be solved by using `this` alone. +์ด๋Ÿฐ ๋ฌธ์ œ๋Š” `this`๋งŒ์œผ๋ก  ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ### `[[HomeObject]]` -To provide the solution, JavaScript adds one more special internal property for functions: `[[HomeObject]]`. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—” ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ ์ „์šฉ ํŠน์ˆ˜ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ `[[HomeObject]]`์ž…๋‹ˆ๋‹ค. -When a function is specified as a class or object method, its `[[HomeObject]]` property becomes that object. +ํด๋ž˜์Šค์ด๊ฑฐ๋‚˜ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์ธ ํ•จ์ˆ˜์˜ `[[HomeObject]]` ํ”„๋กœํผํ‹ฐ๋Š” ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. -Then `super` uses it to resolve the parent prototype and its methods. +`super`๋Š” `[[HomeObject]]`๋ฅผ ์ด์šฉํ•ด ๋ถ€๋ชจ ํ”„๋กœํ† ํƒ€์ž…๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. -Let's see how it works, first with plain objects: +์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด `[[HomeObject]]`๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ด…์‹œ๋‹ค. ๋จผ์ € ์ผ๋ฐ˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let animal = { - name: "Animal", + name: "๋™๋ฌผ", eat() { // animal.eat.[[HomeObject]] == animal - alert(`${this.name} eats.`); + alert(`${this.name} ์ด/๊ฐ€ ๋จน์ด๋ฅผ ๋จน์Šต๋‹ˆ๋‹ค.`); } }; let rabbit = { __proto__: animal, - name: "Rabbit", + name: "ํ† ๋ผ", eat() { // rabbit.eat.[[HomeObject]] == rabbit super.eat(); } @@ -420,38 +518,38 @@ let rabbit = { let longEar = { __proto__: rabbit, - name: "Long Ear", + name: "๊ท€๊ฐ€ ๊ธด ํ† ๋ผ", eat() { // longEar.eat.[[HomeObject]] == longEar super.eat(); } }; *!* -// works correctly -longEar.eat(); // Long Ear eats. +// ์ด์ œ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค +longEar.eat(); // ๊ท€๊ฐ€ ๊ธด ํ† ๋ผ ์ด/๊ฐ€ ๋จน์ด๋ฅผ ๋จน์Šต๋‹ˆ๋‹ค. */!* ``` -It works as intended, due to `[[HomeObject]]` mechanics. A method, such as `longEar.eat`, knows its `[[HomeObject]]` and takes the parent method from its prototype. Without any use of `this`. +`[[HomeObject]]`์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๋ฉ”์„œ๋“œ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ `longEar.eat`๊ฐ™์€ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋Š” `[[HomeObject]]`๋ฅผ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `this` ์—†์ด๋„ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ๋ถ€ํ„ฐ ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -### Methods are not "free" +### ๋ฉ”์„œ๋“œ๋Š” ์ž์œ ๋กญ์ง€ ์•Š์Šต๋‹ˆ๋‹ค -As we've known before, generally functions are "free", not bound to objects in JavaScript. So they can be copied between objects and called with another `this`. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํ•จ์ˆ˜๋Š” ๋Œ€๊ฐœ ๊ฐ์ฒด์— ๋ฌถ์ด์ง€ ์•Š๊ณ  '์ž์œ ๋กญ์Šต๋‹ˆ๋‹ค'. ์ด๋Ÿฐ ์ž์œ ์„ฑ ๋•Œ๋ฌธ์— `this`๊ฐ€ ๋‹ฌ๋ผ๋„ ๊ฐ์ฒด ๊ฐ„ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜์ฃ . -The very existance of `[[HomeObject]]` violates that principle, because methods remember their objects. `[[HomeObject]]` can't be changed, so this bond is forever. +๊ทธ๋Ÿฐ๋ฐ `[[HomeObject]]`๋Š” ๊ทธ ์กด์žฌ๋งŒ์œผ๋กœ๋„ ํ•จ์ˆ˜์˜ ์ž์œ ๋„๋ฅผ ํŒŒ๊ดดํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐ์ฒด๋ฅผ ๊ธฐ์–ตํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ `[[HomeObject]]`๋ฅผ ๋ณ€๊ฒฝํ•  ๋ฐฉ๋ฒ•์€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ๋ฒˆ ๋ฐ”์ธ๋”ฉ ๋œ ํ•จ์ˆ˜๋Š” ๋” ์ด์ƒ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์ฃ . -The only place in the language where `[[HomeObject]]` is used -- is `super`. So, if a method does not use `super`, then we can still consider it free and copy between objects. But with `super` things may go wrong. +๋‹คํ–‰์ธ ์ ์€ `[[HomeObject]]`๋Š” ์˜ค์ง `super` ๋‚ด๋ถ€์—์„œ๋งŒ ์œ ํšจํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ์—์„œ `super`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—” ๋ฉ”์„œ๋“œ์˜ ์ž์œ ์„ฑ์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด ๊ฐ„ ๋ณต์‚ฌ ์—ญ์‹œ ๊ฐ€๋Šฅํ•˜์ฃ . ํ•˜์ง€๋งŒ ๋ฉ”์„œ๋“œ์—์„œ `super`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์•ผ๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -Here's the demo of a wrong `super` result after copying: +๊ฐ์ฒด ๊ฐ„ ๋ฉ”์„œ๋“œ๋ฅผ ์ž˜๋ชป ๋ณต์‚ฌํ•œ ๊ฒฝ์šฐ์— `super`๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run let animal = { sayHi() { - console.log(`I'm an animal`); + console.log(`๋‚˜๋Š” ๋™๋ฌผ์ž…๋‹ˆ๋‹ค.`); } }; -// rabbit inherits from animal +// rabbit์€ animal์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. let rabbit = { __proto__: animal, sayHi() { @@ -461,11 +559,11 @@ let rabbit = { let plant = { sayHi() { - console.log("I'm a plant"); + console.log("๋‚˜๋Š” ์‹๋ฌผ์ž…๋‹ˆ๋‹ค."); } }; -// tree inherits from plant +// tree๋Š” plant๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. let tree = { __proto__: plant, *!* @@ -474,32 +572,32 @@ let tree = { }; *!* -tree.sayHi(); // I'm an animal (?!?) +tree.sayHi(); // ๋‚˜๋Š” ๋™๋ฌผ์ž…๋‹ˆ๋‹ค. (?!?) */!* ``` -A call to `tree.sayHi()` shows "I'm an animal". Definitevely wrong. +`tree.sayHi()`๋ฅผ ํ˜ธ์ถœํ•˜๋‹ˆ "๋‚˜๋Š” ๋™๋ฌผ์ž…๋‹ˆ๋‹ค."๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๋ญ”๊ฐ€ ์ž˜๋ชป๋œ ๊ฒƒ์ด ๋ถ„๋ช…ํ•ด ๋ณด์ด๋„ค์š”. -The reason is simple: -- In the line `(*)`, the method `tree.sayHi` was copied from `rabbit`. Maybe we just wanted to avoid code duplication? -- Its `[[HomeObject]]` is `rabbit`, as it was created in `rabbit`. There's no way to change `[[HomeObject]]`. -- The code of `tree.sayHi()` has `super.sayHi()` inside. It goes up from `rabbit` and takes the method from `animal`. +์›์ธ์€ ๊ฝค ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค. +- `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ๋ฉ”์„œ๋“œ `tree.sayHi`๋Š” ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด `rabbit`์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์™”์Šต๋‹ˆ๋‹ค. +- ๊ทธ๋Ÿฐ๋ฐ ๋ณต์‚ฌํ•ด์˜จ ๋ฉ”์„œ๋“œ๋Š” `rabbit`์—์„œ ์ƒ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ์˜ `[[HomeObject]]`๋Š” `rabbit`์ž…๋‹ˆ๋‹ค, ๊ฐœ๋ฐœ์ž๋Š” `[[HomeObject]]`๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +- `tree.sayHi()`์˜ ์ฝ”๋“œ ๋‚ด๋ถ€์—” `super.sayHi()`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. `rabbit`์˜ ํ”„๋กœํ† ํƒ€์ž…์€ `animal`์ด๋ฏ€๋กœ `super`๋Š” ์ฒด์ธ ์œ„์—์žˆ๋Š” `animal`๋กœ ์˜ฌ๋ผ๊ฐ€ `sayHi`๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. -Here's the diagram of what happens: +์ผ๋ จ์˜ ๊ณผ์ •์„ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](super-homeobject-wrong.svg) -### Methods, not function properties +### ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹Œ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉํ•˜๊ธฐ -`[[HomeObject]]` is defined for methods both in classes and in plain objects. But for objects, methods must be specified exactly as `method()`, not as `"method: function()"`. +`[[HomeObject]]`๋Š” ํด๋ž˜์Šค์™€ ์ผ๋ฐ˜ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ์—์„œ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ `[[HomeObject]]`๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ˜๋“œ์‹œ `method()` ํ˜•ํƒœ๋กœ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `"method: function()"` ํ˜•ํƒœ๋กœ ์ •์˜ํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. -The difference may be non-essential for us, but it's important for JavaScript. +๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„  ๋‘ ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด๋Š” ๊ทธ๋ฆฌ ์ค‘์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž…์žฅ์—์„  ์•„์ฃผ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. -In the example below a non-method syntax is used for comparison. `[[HomeObject]]` property is not set and the inheritance doesn't work: +๋ฉ”์„œ๋“œ ๋ฌธ๋ฒ•์ด ์•„๋‹Œ(non-method syntax) ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์˜ˆ์‹œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `[[HomeObject]]` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์†์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let animal = { - eat: function() { // intentially writing like this instead of eat() {... + eat: function() { // 'eat() {...' ๋Œ€์‹  'eat: function() {...'์„ ์‚ฌ์šฉํ•ด๋ด…์‹œ๋‹ค. // ... } }; @@ -512,21 +610,21 @@ let rabbit = { }; *!* -rabbit.eat(); // Error calling super (because there's no [[HomeObject]]) +rabbit.eat(); // SyntaxError: 'super' keyword unexpected here ([[HomeObject]]๊ฐ€ ์—†์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ) */!* ``` -## Summary +## ์š”์•ฝ -1. To extend a class: `class Child extends Parent`: - - That means `Child.prototype.__proto__` will be `Parent.prototype`, so methods are inherited. -2. When overriding a constructor: - - We must call parent constructor as `super()` in `Child` constructor before using `this`. -3. When overriding another method: - - We can use `super.method()` in a `Child` method to call `Parent` method. -4. Internals: - - Methods remember their class/object in the internal `[[HomeObject]]` property. That's how `super` resolves parent methods. - - So it's not safe to copy a method with `super` from one object to another. +1. ํด๋ž˜์Šค ํ™•์žฅํ•˜๊ธฐ: `class Child extends Parent` + - `Child.prototype.__proto__`๊ฐ€ `Parent.prototype`์ด ๋˜๋ฏ€๋กœ ๋ฉ”์„œ๋“œ ์ „์ฒด๊ฐ€ ์ƒ์†๋ฉ๋‹ˆ๋‹ค. +2. ์ƒ์„ฑ์ž ์˜ค๋ฒ„๋ผ์ด๋”ฉ: + - `this`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— `Child` ์ƒ์„ฑ์ž ์•ˆ์—์„œ `super()`๋กœ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +3. ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ: + - `Child`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ์—์„œ `super.method()`๋ฅผ ์‚ฌ์šฉํ•ด `Parent`์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +4. super ํ‚ค์›Œ๋“œ์™€ [[HomeObject]] + - ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ `[[HomeObject]]`์— ์ž์‹ ์ด ์ •์˜๋œ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด๋ฅผ ๊ธฐ์–ตํ•ด๋†“์Šต๋‹ˆ๋‹ค. `super`๋Š” `[[HomeObject]]`๋ฅผ ์‚ฌ์šฉํ•ด ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. + - ๋”ฐ๋ผ์„œ `super`๊ฐ€ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด ๊ฐ„ ๋ณต์‚ฌ ์‹œ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Also: -- Arrow functions don't have own `this` or `super`, so they transparently fit into the surrounding context. +์ถ”๊ฐ€ ์‚ฌํ•ญ: +- ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” `this`๋‚˜ `super`๋ฅผ ๊ฐ–์ง€ ์•Š์œผ๋ฏ€๋กœ ์ฃผ๋ณ€ ์ปจํ…์ŠคํŠธ์— ์ž˜ ๋“ค์–ด๋งž์Šต๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg index 10af6c4c23..5ea9bf29ea 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg @@ -1 +1 @@ -slice: function ...Array.prototypearrhasOwnProperty: function ...Object.prototype[1, 2, 3][[Prototype]][[Prototype]] \ No newline at end of file +slice: function ...Array.prototypearrhasOwnProperty: function ...Object.prototype[1, 2, 3][[Prototype]][[Prototype]] \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg index a81676e25c..72e47e34c2 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg @@ -1 +1 @@ -jump: functionRabbit.prototyperabbiteat: functionAnimal.prototypename: "White Rabbit"[[Prototype]][[Prototype]]Rabbit.prototype.__proto__ = Animal.prototype sets thistoString: function hasOwnProperty: function ...Object.prototype[[Prototype]][[Prototype]]null \ No newline at end of file +jump: functionRabbit.prototyperabbiteat: functionAnimal.prototypename: "White Rabbit"[[Prototype]][[Prototype]]Rabbit.prototype.__proto__ = Animal.prototype sets thistoString: function hasOwnProperty: function ...Object.prototype[[Prototype]][[Prototype]]null \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg index 35529aa432..bced3d355e 100644 --- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg +++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg @@ -1 +1 @@ -methods of RabbitRabbit.prototyperabbitmethods of AnimalAnimal.prototype[[Prototype]][[Prototype]]properties of rabbit \ No newline at end of file +methods of RabbitRabbit.prototyperabbitmethods of AnimalAnimal.prototype[[Prototype]][[Prototype]]properties of rabbit \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg index 905efe37a5..f53fc92dee 100644 --- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg +++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg @@ -1 +1 @@ - constructor: Animal run: function stop: functionAnimal.prototypeAnimalnew Animal[[Prototype]]prototypename: "My animal" \ No newline at end of file + constructor: Animal run: function stop: functionAnimal.prototypeAnimalnew Animal[[Prototype]]prototypename: "My animal" \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg index 81bf1850b0..2f30a3a901 100644 --- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg +++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg @@ -1 +1 @@ - constructor: Rabbit hide: functionRabbit.prototypeRabbitnew Rabbit[[Prototype]]prototypename: "My rabbit" \ No newline at end of file + constructor: Rabbit hide: functionRabbit.prototypeRabbitnew Rabbit[[Prototype]]prototypename: "My rabbit" \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg index 8ad09f484d..f6450ddc49 100644 --- a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg +++ b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg @@ -1 +1 @@ -sayHiplantsayHitreesayHianimalrabbit[[HomeObject]]sayHi \ No newline at end of file +sayHiplantsayHitreesayHianimalrabbit[[HomeObject]]sayHi \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/this-super-loop.svg b/1-js/09-classes/02-class-inheritance/this-super-loop.svg index bc200fab33..4f5f45034a 100644 --- a/1-js/09-classes/02-class-inheritance/this-super-loop.svg +++ b/1-js/09-classes/02-class-inheritance/this-super-loop.svg @@ -1 +1 @@ -rabbitlongEarrabbitlongEar \ No newline at end of file +rabbitlongEarrabbitlongEar \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg similarity index 59% rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg index 34d783b4de..915ab9aa64 100644 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg @@ -1 +1 @@ -call: function bind: function ...Function.prototypeconstructorObjectRabbit[[Prototype]][[Prototype]]constructorcall: function bind: function ...Function.prototypeRabbit[[Prototype]]constructorclass Rabbitclass Rabbit extends Object \ No newline at end of file +call: function bind: function ...Function.prototypeconstructorObjectRabbit[[Prototype]][[Prototype]]constructorcall: function bind: function ...Function.prototypeRabbit[[Prototype]]constructorclass Rabbitclass Rabbit extends Object \ No newline at end of file diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md new file mode 100644 index 0000000000..e09872f2e7 --- /dev/null +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md @@ -0,0 +1,81 @@ +๋จผ์ €, ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์™œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”์ง€ ์‚ดํŽด๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ด์œ ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์† ๋ฐ›๋Š” ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋Š” `super()`๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `"this"`๊ฐ€ '์ •์˜'๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +์ˆ˜์ •ํ•œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. + +```js run +class Rabbit extends Object { + constructor(name) { +*!* + super(); // ์ƒ์† ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„  ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +*/!* + this.name = name; + } +} + +let rabbit = new Rabbit("Rab"); + +alert( rabbit.hasOwnProperty('name') ); // true +``` + +๊ทธ๋Ÿฐ๋ฐ ์ด๊ฒŒ ๋์ด ์•„๋‹™๋‹ˆ๋‹ค. + +์œ„์™€ ๊ฐ™์ด ์ˆ˜์ • ํ•ด๋„, ์—ฌ์ „ํžˆ `"class Rabbit extends Object"`์™€ `class Rabbit`๋Š” ๋‹ค๋ฅธ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. + +์•„์‹œ๋‹ค์‹œํ”ผ 'extends' ๋ฌธ๋ฒ•์€ ๋‘ ๊ฐœ์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + +1. ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ `"prototype"` ์‚ฌ์ด(์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ์šฉ) +2. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ž์ฒด ์‚ฌ์ด(์ •์  ๋ฉ”์„œ๋“œ์šฉ) + +์˜ˆ์‹œ์˜ `class Rabbit extends Object`๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค์ฃ . + +```js run +class Rabbit extends Object {} + +alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true +alert( Rabbit.__proto__ === Object ); // (2) true +``` + +๋”ฐ๋ผ์„œ `Rabbit`์€ ์•„๋ž˜์™€ ๊ฐ™์ด `Rabbit`์„ ํ†ตํ•ด `Object`์˜ ์ •์  ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js run +class Rabbit extends Object {} + +*!* +// ๋ณดํ†ต์€ Object.getOwnPropertyNames ๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. +alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b +*/!* +``` + +๊ทธ๋Ÿฐ๋ฐ `extends Object`๊ฐ€ ์—†์œผ๋ฉด, `Rabbit.__proto__`๋Š” `Object`๋กœ ์„ค์ •๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +๋ฐ๋ชจ: + +```js run +class Rabbit {} + +alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true +alert( Rabbit.__proto__ === Object ); // (2) false (!) +alert( Rabbit.__proto__ === Function.prototype ); // true (๋ชจ๋“  ํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ ํ”„๋กœํ† ํƒ€์ž…) + +*!* +// error, no such function in Rabbit +alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error +*/!* +``` + +์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— `Rabbit`์—์„œ `Object`์˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + +ํ•œํŽธ, `Function.prototype`์€ `call`, `bind` ๋“ฑ์˜ '์ผ๋ฐ˜' ํ•จ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋‚ด์žฅ ๊ฐ์ฒด, `Object`์˜ ์ƒ์„ฑ์ž๋Š” `Object.__proto__ === Function.prototype` ๊ด€๊ณ„๋ฅผ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— `Function.prototype`์— ์ •์˜๋œ ์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•œ ๊ทธ๋ฆผ: + +![](rabbit-extends-object.svg) + +๊ทธ๋ƒฅ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๋ช…์‹œ์ ์œผ๋กœ `Object`๋ฅผ ์ƒ์†ํ•ด ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์˜ ์ฐจ์ด๋ฅผ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. + +| class Rabbit | class Rabbit extends Object | +|--------------|------------------------------| +| -- | ์ƒ์„ฑ์ž์—์„œ `super()`๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•จ | +| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` | diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md new file mode 100644 index 0000000000..47ff694487 --- /dev/null +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md @@ -0,0 +1,42 @@ +importance: 3 + +--- + +# Object๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค + +์•„์‹œ๋‹ค์‹œํ”ผ, ๊ฐ์ฒด๋Š” ๋ณดํ†ต `Object.prototype`๋ฅผ ์ƒ์†๋ฐ›๊ณ  `hasOwnProperty`๊ฐ™์€ '์ผ๋ฐ˜' ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์˜ˆ์‹œ: + +```js run +class Rabbit { + constructor(name) { + this.name = name; + } +} + +let rabbit = new Rabbit("Rab"); + +*!* +// ๋ฉ”์„œ๋“œ hasOwnProperty๋Š” Object.prototype์—์„œ ์™”์Šต๋‹ˆ๋‹ค. +alert( rabbit.hasOwnProperty('name') ); // true +*/!* +``` + +๊ทธ๋Ÿฐ๋ฐ `"class Rabbit extends Object"`๊ฐ™์ด ์ƒ์†์„ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด์ฃผ๋Š” ๊ฒฝ์šฐ์™€ ๊ทธ๋ƒฅ `"class Rabbit"`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅผ๊นŒ์š”? + +๋งŒ์•ฝ ๋‹ค๋ฅด๋‹ค๋ฉด ์–ด๋–ค ๊ฒƒ์ด ๋‹ค๋ฅผ๊นŒ์š”? + +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `"class Rabbit extends Object"`๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ, ์‹คํ–‰ํ•ด๋ณด๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋””์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๊ฑธ๊นŒ์š”? ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด๋ณด์„ธ์š”. + +```js +class Rabbit extends Object { + constructor(name) { + this.name = name; + } +} + +let rabbit = new Rabbit("Rab"); + +alert( rabbit.hasOwnProperty('name') ); // Error +``` diff --git a/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg b/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg index 18093d7cfc..3e354b895d 100644 --- a/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg +++ b/1-js/09-classes/03-static-properties-methods/animal-rabbit-static.svg @@ -1 +1 @@ -constructor: Animal run: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitrabbit[[Prototype]][[Prototype]][[Prototype]]prototypeprototypecomparename: "White Rabbit" \ No newline at end of file +constructor: Animal run: functionAnimal.prototypeconstructor: Rabbit hide: functionRabbit.prototypeAnimalRabbitrabbit[[Prototype]][[Prototype]][[Prototype]]prototypeprototypecomparename: "White Rabbit" \ No newline at end of file diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index 8e08514f23..90cd8094c3 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -1,9 +1,9 @@ -# Static properties and methods +# ์ •์  ๋ฉ”์„œ๋“œ์™€ ์ •์  ํ”„๋กœํผํ‹ฐ -We can also assign a method to the class function itself, not to its `"prototype"`. Such methods are called *static*. +`"prototype"`์ด ์•„๋‹Œ ํด๋ž˜์Šค ํ•จ์ˆ˜ ์ž์ฒด์— ๋ฉ”์„œ๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋ฅผ *์ •์ (static)* ๋ฉ”์„œ๋“œ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -In a class, they are prepended by `static` keyword, like this: +์ •์  ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํด๋ž˜์Šค ์•ˆ์—์„œ `static` ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run class User { @@ -17,21 +17,23 @@ class User { User.staticMethod(); // true ``` -That actually does the same as assigning it as a property directly: +์ •์  ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ”„๋กœํผํ‹ฐ ํ˜•ํƒœ๋กœ ์ง์ ‘ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. -```js -class User() { } +```js run +class User { } User.staticMethod = function() { alert(this === User); }; + +User.staticMethod(); // true ``` -The value of `this` in `User.staticMethod()` call is the class constructor `User` itself (the "object before dot" rule). +`User.staticMethod()`๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ `this`์˜ ๊ฐ’์€ ํด๋ž˜์Šค ์ƒ์„ฑ์ž์ธ `User` ์ž์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค(์  ์•ž ๊ฐ์ฒด). -Usually, static methods are used to implement functions that belong to the class, but not to any particular object of it. +์ •์  ๋ฉ”์„œ๋“œ๋Š” ์–ด๋–ค ํŠน์ •ํ•œ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค์— ์†ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -For instance, we have `Article` objects and need a function to compare them. A natural solution would be to add `Article.compare` method, like this: +๊ฐ์ฒด `Article`์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๊ณ  ์ด๋“ค์„ ๋น„๊ตํ•ด์ค„ ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ๊ฐ€์žฅ ๋จผ์ € ์•„๋ž˜์™€ ๊ฐ™์ด `Article.compare`๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋– ์˜ค๋ฅผ ๊ฒ๋‹ˆ๋‹ค. ```js run class Article { @@ -47,7 +49,7 @@ class Article { */!* } -// usage +// ์‚ฌ์šฉ๋ฒ• let articles = [ new Article("HTML", new Date(2019, 1, 1)), new Article("CSS", new Date(2019, 0, 1)), @@ -61,17 +63,17 @@ articles.sort(Article.compare); alert( articles[0].title ); // CSS ``` -Here `Article.compare` stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class. +์—ฌ๊ธฐ์„œ `Article.compare`๋Š” article(๊ธ€)์„ ๋น„๊ตํ•ด์ฃผ๋Š” ์ˆ˜๋‹จ์œผ๋กœ, ๊ธ€ ์ „์ฒด๋ฅผ '์œ„์—์„œ' ๋ฐ”๋ผ๋ณด๋ฉฐ ๋น„๊ต๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. `Article.compare`์ด ๊ธ€ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—ฌ์•ผ ํ•˜๋Š” ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -Another example would be a so-called "factory" method. Imagine, we need few ways to create an article: +์ด๋ฒˆ์— ์‚ดํŽด๋ณผ ์˜ˆ์‹œ๋Š” 'ํŒฉํ† ๋ฆฌ' ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์กฐ๊ฑด์— ๋งž๋Š” article ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. -1. Create by given parameters (`title`, `date` etc). -2. Create an empty article with today's date. -3. ...or else somehow. +1. ๋งค๊ฐœ๋ณ€์ˆ˜(`title`, `date` ๋“ฑ)๋ฅผ ์ด์šฉํ•ด ๊ด€๋ จ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด article ์ƒ์„ฑ +2. ์˜ค๋Š˜ ๋‚ ์งœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋น„์–ด์žˆ๋Š” article ์ƒ์„ฑ +3. ๊ธฐํƒ€ ๋“ฑ๋“ฑ -The first way can be implemented by the constructor. And for the second one we can make a static method of the class. +์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ํด๋ž˜์Šค์— ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Like `Article.createTodays()` here: +์•„๋ž˜ `Article.createTodays()`๊ฐ™์ด ๋ง์ด์ฃ . ```js run class Article { @@ -82,7 +84,7 @@ class Article { *!* static createTodays() { - // remember, this = Article + // this๋Š” Article์ž…๋‹ˆ๋‹ค. return new this("Today's digest", new Date()); } */!* @@ -93,21 +95,21 @@ let article = Article.createTodays(); alert( article.title ); // Today's digest ``` -Now every time we need to create a today's digest, we can call `Article.createTodays()`. Once again, that's not a method of an article, but a method of the whole class. +์ด์ œ Today's digest๋ผ๋Š” ๊ธ€์ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค `Article.createTodays()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `Article.createTodays()`๋Š” article์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ ์ „์ฒด ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. -Static methods are also used in database-related classes to search/save/remove entries from the database, like this: +์ •์  ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ํ•ญ๋ชฉ ๊ฒ€์ƒ‰, ์ €์žฅ, ์‚ญ์ œ ๋“ฑ์„ ์ˆ˜ํ–‰ํ•ด์ฃผ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ํด๋ž˜์Šค์—๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ```js -// assuming Article is a special class for managing articles -// static method to remove the article: +// Article์€ article์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ํŠน๋ณ„ ํด๋ž˜์Šค๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค. +// article ์‚ญ์ œ์— ์“ฐ์ด๋Š” ์ •์  ๋ฉ”์„œ๋“œ Article.remove({id: 12345}); ``` -## Static properties +## ์ •์  ํ”„๋กœํผํ‹ฐ [recent browser=Chrome] -Static properties are also possible, they look like regular class properties, but prepended by `static`: +์ •์  ํ”„๋กœํผํ‹ฐ๋„ ๋ฌผ๋ก  ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์  ํ”„๋กœํผํ‹ฐ๋Š” ์ผ๋ฐ˜ ํด๋ž˜์Šค ํ”„๋กœํผํ‹ฐ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ƒ๊ฒผ๋Š”๋ฐ ์•ž์— `static`์ด ๋ถ™๋Š”๋‹ค๋Š” ์ ๋งŒ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ```js run class Article { @@ -117,20 +119,21 @@ class Article { alert( Article.publisher ); // Ilya Kantor ``` -That is the same as a direct assignment to `Article`: +์œ„ ์˜ˆ์‹œ๋Š” `Article`์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง์ ‘ ํ• ๋‹นํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```js Article.publisher = "Ilya Kantor"; ``` -## Inheritance of static methods +## ์ •์  ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ ์ƒ์† -Static methods are inherited. +์ •์  ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ƒ์†๋ฉ๋‹ˆ๋‹ค. -For instance, `Animal.compare` in the code below is inherited and accessible as `Rabbit.compare`: +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `Animal.compare`์™€ `Animal.planet`์€ ์ƒ์†๋˜์–ด์„œ ๊ฐ๊ฐ `Rabbit.compare`์™€ `Rabbit.planet`์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run class Animal { + static planet = "์ง€๊ตฌ"; constructor(name, speed) { this.speed = speed; @@ -139,7 +142,7 @@ class Animal { run(speed = 0) { this.speed += speed; - alert(`${this.name} runs with speed ${this.speed}.`); + alert(`${this.name}๊ฐ€ ์†๋„ ${this.speed}๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค.`); } *!* @@ -150,62 +153,64 @@ class Animal { } -// Inherit from Animal +// Animal์„ ์ƒ์†๋ฐ›์Œ class Rabbit extends Animal { hide() { - alert(`${this.name} hides!`); + alert(`${this.name}๊ฐ€ ์ˆจ์—ˆ์Šต๋‹ˆ๋‹ค!`); } } let rabbits = [ - new Rabbit("White Rabbit", 10), - new Rabbit("Black Rabbit", 5) + new Rabbit("ํฐ ํ† ๋ผ", 10), + new Rabbit("๊ฒ€์€ ํ† ๋ผ", 5) ]; *!* rabbits.sort(Rabbit.compare); */!* -rabbits[0].run(); // Black Rabbit runs with speed 5. +rabbits[0].run(); // ๊ฒ€์€ ํ† ๋ผ๊ฐ€ ์†๋„ 5๋กœ ๋‹ฌ๋ฆฝ๋‹ˆ๋‹ค. + +alert(Rabbit.planet); // ์ง€๊ตฌ ``` -Now when we can call `Rabbit.compare`, the inherited `Animal.compare` will be called. +์ด์ œ `Rabbit.compare`์„ ํ˜ธ์ถœํ•˜๋ฉด `Animal.compare`๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -How does it work? Again, using prototypes. As you might have already guessed, `extends` gives `Rabbit` the `[[Prototype]]` reference to `Animal`. +์ด๊ฒŒ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ์˜ˆ์ƒํ•˜์…จ๊ฒ ์ง€๋งŒ, `extends` ํ‚ค์›Œ๋“œ๋Š” `Rabbit`์˜ `[[Prototype]]`์ด `Animal`์„ ์ฐธ์กฐํ•˜๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ![](animal-rabbit-static.svg) -So, `Rabbit extends Animal` creates two `[[Prototype]]` references: +๋”ฐ๋ผ์„œ `Rabbit extends Animal`์€ ๋‘ ๊ฐœ์˜ `[[Prototype]]` ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ค์–ด ๋ƒ…๋‹ˆ๋‹ค. -1. `Rabbit` function prototypally inherits from `Animal` function. -2. `Rabbit.prototype` prototypally inherits from `Animal.prototype`. +1. ํ•จ์ˆ˜ `Rabbit`์€ ํ”„๋กœํ† ํƒ€์ž…์„ ํ†ตํ•ด ํ•จ์ˆ˜ `Animal`์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. +2. `Rabbit.prototype`์€ ํ”„๋กœํ† ํƒ€์ž…์„ ํ†ตํ•ด `Animal.prototype`์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -As the result, inheritance works both for regular and static methods. +์ด๋Ÿฐ ๊ณผ์ •์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ ์ƒ์†๊ณผ ์ •์  ๋ฉ”์„œ๋“œ ์ƒ์†์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -Here, let's check that by code: +์ฝ”๋“œ๋กœ ์ง์ ‘ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. ```js run class Animal {} class Rabbit extends Animal {} -// for statics +// ์ •์  ๋ฉ”์„œ๋“œ alert(Rabbit.__proto__ === Animal); // true -// for regular methods +// ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ alert(Rabbit.prototype.__proto__ === Animal.prototype); // true ``` -## Summary +## ์š”์•ฝ -Static methods are used for the functionality that belongs to the class "as a whole", doesn't relate to a concrete class instance. +์ •์  ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค '์ „์ฒด'์— ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For example, a method for comparison `Article.compare(article1, article2)` or a factory method `Article.createTodays()`. +์ธ์Šคํ„ด์Šค๋ผ๋ฆฌ ๋น„๊ตํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ `Article.compare(article1, article2)`์ด๋‚˜ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ `Article.createTodays()`๋ฅผ ๋งŒ๋“ค ๋•Œ ์ •์  ๋ฉ”์„œ๋“œ๊ฐ€ ์“ฐ์ž…๋‹ˆ๋‹ค. -They are labeled by the word `static` in class declaration. +์ •์  ๋ฉ”์„œ๋“œ๋Š” ํด๋ž˜์Šค ์„ ์–ธ๋ถ€ ์•ˆ์— ์œ„์น˜ํ•˜๊ณ  ์•ž์— `static`์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์Šต๋‹ˆ๋‹ค. -Static properties are used when we'd like to store class-level data, also not bound to an instance. +์ •์  ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํด๋ž˜์Šค ์ˆ˜์ค€์— ์ €์žฅํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ •์  ํ”„๋กœํผํ‹ฐ ์—ญ์‹œ ๊ฐœ๋ณ„ ์ธ์Šคํ„ด์Šค์— ๋ฌถ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -The syntax is: +๋ฌธ๋ฒ•: ```js class MyClass { @@ -217,13 +222,13 @@ class MyClass { } ``` -Technically, static declaration is the same as assigning to the class itself: +`static`์„ ์‚ฌ์šฉํ•œ ์„ ์–ธ์€ ๊ธฐ์ˆ ์ ์œผ๋ก  ํด๋ž˜์Šค ์ž์ฒด์— ์ง์ ‘ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ```js MyClass.property = ... MyClass.method = ... ``` -Static properties and methods are inherited. +์ •์  ํ”„๋กœํผํ‹ฐ์™€ ์ •์  ๋ฉ”์„œ๋“œ๋Š” ์ƒ์†์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -For `class B extends A` the prototype of the class `B` itself points to `A`: `B.[[Prototype]] = A`. So if a field is not found in `B`, the search continues in `A`. +`class B extends A`๋Š” ํด๋ž˜์Šค `B`์˜ ํ”„๋กœํ† ํƒ€์ž…์ด ํด๋ž˜์Šค `A`๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค(`B.[[Prototype]] = A`). ๋”ฐ๋ผ์„œ `B`์—์„œ ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด `A`๋กœ ๊ฒ€์ƒ‰์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md index f4a9d0813b..30265bbf51 100644 --- a/1-js/09-classes/04-private-protected-properties-methods/article.md +++ b/1-js/09-classes/04-private-protected-properties-methods/article.md @@ -3,73 +3,73 @@ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์›๋ฆฌ ์ค‘ ํ•˜๋‚˜๋Š” '๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ ์ง“๋Š” ๊ฒƒ'์ž…๋‹ˆ๋‹ค. -๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ ์ง“๋Š” ๊ฒƒ์€ 'hello word'์•ฑ๋ณด๋‹ค ๋” ๋ณต์žกํ•œ ๊ฒƒ์„ ๊ฐœ๋ฐœํ•œ๋‹ค๋ฉด ํ•„์ˆ˜์ ์œผ๋กœ ์—ฐ์Šต๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๋‹จ์ˆœํžˆ 'hello world'๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ณต์žกํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด, ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ '๋ฐ˜๋“œ์‹œ' ์•Œ๊ณ  ๊ณ„์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด, ์ž ์‹œ ๊ฐœ๋ฐœ์—์„œ ๋ฒ—์–ด๋‚˜ ํ˜„์‹ค ์„ธ๊ณ„๋กœ ๋ˆˆ์„ ๋Œ๋ ค๋ด…์‹œ๋‹ค. +์ž ์‹œ ๊ฐœ๋ฐœ์„ ๋ฒ—์–ด๋‚˜ ํ˜„์‹ค ์„ธ๊ณ„๋กœ ๋ˆˆ์„ ๋Œ๋ ค, ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ๋ถ„์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. -๋ณดํ†ต ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์žฅ์น˜๋“ค์€ ๊ฝค ๋ณต์žกํ•˜์ง€๋งŒ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ตฌ๋ถ„ ์ง€์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ผ์ƒ์ƒํ™œ์—์„œ ์ ‘ํ•˜๊ฒŒ ๋˜๋Š” ๊ธฐ๊ณ„๋“ค์€ ๊ฝค ๋ณต์žกํ•œ ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ตฌ๋ถ„๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ์—†์ด ๊ธฐ๊ณ„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์‹ค์ƒํ™œ ์˜ˆ์ œ -์ปคํ”ผ ๋จธ์‹ ์œผ๋กœ ์˜ˆ๋ฅผ ๋“ค์–ด๋ด…์‹œ๋‹ค. ์™ธํ˜•์€ ์‹ฌํ”Œํ•ฉ๋‹ˆ๋‹ค: ๋ฒ„ํŠผ ํ•˜๋‚˜, ํ™”๋ฉด ํ•˜๋‚˜, ๊ตฌ๋ฉ ๋ช‡ ๊ฐœ... ๋ฌผ๋ก , ๊ฒฐ๊ณผ๋ฌผ์ธ ํ›Œ๋ฅญํ•œ ์ปคํ”ผ๋„ ์žˆ์Šต๋‹ˆ๋‹ค! :) +์ปคํ”ผ ๋จธ์‹ ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ด…์‹œ๋‹ค. ์™ธํ˜•์€ ์‹ฌํ”Œํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ ํ•˜๋‚˜, ํ™”๋ฉด ํ•˜๋‚˜, ๊ตฌ๋ฉ ๋ช‡ ๊ฐœ ๋“ฑ์ด ์žˆ์ฃ . ํ›Œ๋ฅญํ•œ ์ปคํ”ผ๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ๋กœ ๋‚˜์˜จ๋‹ค๋Š” ๊ฒƒ ๋˜ํ•œ ๋นผ๋†“์„ ์ˆ˜ ์—†๊ฒ ๋„ค์š”! :) ![](coffee.jpg) -ํ•˜์ง€๋งŒ ์•ˆ์ชฝ์€... (์ˆ˜๋ฆฌ ๋งค๋‰ด์–ผ์— ์žˆ๋Š” ์‚ฌ์ง„) +ํ•˜์ง€๋งŒ ๋‚ด๋ถ€๋Š” ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค(์ˆ˜๋ฆฌ์šฉ ๋งค๋‰ด์–ผ์—์„œ ๊ฐ€์ ธ์˜จ ์‚ฌ์ง„). ![](coffee-inside.jpg) -์„ธ์„ธํ•œ ๊ฒƒ๋“ค์ด ์•„์ฃผ ๋งŽ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ด ์„ธ์„ธํ•œ ๊ฒƒ๋“ค์— ๋Œ€ํ•ด ์•„๋ฌด๊ฒƒ๋„ ๋ชฐ๋ผ๋„ ์ปคํ”ผ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ญ”๊ฐ€ ๋””ํ…Œ์ผํ•œ ๊ฒƒ๋“ค์ด ์•„์ฃผ ๋งŽ๋„ค์š”. ํ•˜์ง€๋งŒ ์ด ๋ชจ๋“  ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•ด๋„ ์ปคํ”ผ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์ง€์žฅ์ด ์—†์Šต๋‹ˆ๋‹ค. -์ปคํ”ผ ๋จธ์‹ ์€ ์ƒ๋‹นํžˆ ๋ฏฟ์„๋งŒํ•˜์ง€ ์•Š๋‚˜์š”? ํ•˜๋‚˜๋ฅผ ์ˆ˜ ๋…„ ๋™์•ˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๊ณ ์žฅ์ด ๋‚œ๋‹ค๋ฉด ์ˆ˜๋ฆฌ๋ฅผ ๋ฐ›์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. +์ปคํ”ผ ๋จธ์‹ ์€ ๊ฝค ๋ฏฟ์Œ์งํ•œ ๊ธฐ๊ณ„์ž…๋‹ˆ๋‹ค. ์ˆ˜๋…„ ๊ฐ„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ค‘๊ฐ„์— ๊ณ ์žฅ์ด ๋‚˜๋„ ์ˆ˜๋ฆฌ๋ฅผ ๋ฐ›์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -์ปคํ”ผ ๋จธ์‹ ์˜ ์‹ ๋ขฐ์„ฑ๊ณผ ๋‹จ์ˆœํ•จ์˜ ๋น„๋ฐ€์€ ๋ชจ๋“  ๋””ํ…Œ์ผ๋“ค์ด ์ž˜ ์กฐ์ •๋˜์–ด ์•ˆ์ชฝ์— *์ˆจ๊ฒจ์ ธ* ์žˆ๋‹ค๋Š” ๊ฒƒ์— ์žˆ์Šต๋‹ˆ๋‹ค. +์™ธํ˜•์€ ๋‹จ์ˆœํ•˜์ง€๋งŒ ์ปคํ”ผ ๋จธ์‹ ์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” ๋ชจ๋“  ์„ธ๋ถ€ ์š”์†Œ๋“ค์ด ๊ธฐ๊ณ„ ๋‚ด๋ถ€์— ์ž˜ ์ •๋ฆฌ๋˜์–ด *์ˆจ๊ฒจ์ ธ* ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์ปคํ”ผ ๋จธ์‹ ์—์„œ ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ์—†์•ค๋‹ค๋ฉด ์ปคํ”ผ๋จธ์‹ ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋ณต์žกํ•ด์ง€๊ณ  ์œ„ํ—˜ํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.(์–ด๋””๋ฅผ ๋ˆŒ๋Ÿฌ์•ผ ํ•˜๋Š”์ง€ ํ—ท๊ฐˆ๋ฆด ๊ฒƒ์ด๊ณ , ๊ฐ์ „์ด ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.) +์ปคํ”ผ ๋จธ์‹ ์—์„œ ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ์‚ฌ์šฉ๋ฒ•์ด ํ›จ์”ฌ ๋ณต์žกํ•ด์ง€๊ณ  ์œ„ํ—˜ํ•œ ์ƒํ™ฉ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋””๋ฅผ ๋ˆŒ๋Ÿฌ์•ผ ํ• ์ง€ ๋ชจ๋ฅด๊ณ  ๊ฐ์ „์ด ๋  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์ด์ œ๋ถ€ํ„ฐ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ฒ˜๋Ÿผ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ฐ์ฒด๋ž€ ์ปคํ”ผ ๋จธ์‹  ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์•ž์œผ๋กœ ํ•™์Šตํ•˜๊ฒ ์ง€๋งŒ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ฐ์ฒด๋Š” ์ปคํ”ผ ๋จธ์‹ ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -๋‹ค๋งŒ, ์•ˆ์ชฝ์˜ ์„ธ์„ธํ•œ ๊ฒƒ๋“ค์„ ์ˆจ๊ธฐ๊ธฐ ์œ„ํ•ด์„œ ๋ณดํ˜ธ ์ปค๋ฒ„๊ฐ€ ์•„๋‹ˆ๋ผ ์–ธ์–ด์™€ ๊ด€์Šต์˜ ํŠน๋ณ„ํ•œ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ํŠน๋ณ„ํ•œ ๋ฌธ๋ฒ•๊ณผ ์ปจ๋ฒค์…˜์„ ์‚ฌ์šฉํ•ด ์•ˆ์ชฝ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ˆจ๊ธด๋‹ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ## ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค -๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง‘๋‹ˆ๋‹ค. +๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ทธ๋ฃน์œผ๋กœ ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค. -- *๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค* -- ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ์— ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋กœ๋ถ€ํ„ฐ๋Š” ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ํด๋ž˜์Šค์˜ ๋ฐ–์—์„œ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -- *์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค* -- ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ์— ํด๋ž˜์Šค์˜ ์™ธ๋ถ€์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- *๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค(internal interface)* -- ๋™์ผํ•œ ํด๋ž˜์Šค ๋‚ด์˜ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์—์„  ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํด๋ž˜์Šค ๋ฐ–์—์„  ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ +- *์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค(external interface)* -- ํด๋ž˜์Šค ๋ฐ–์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ -์ปคํ”ผ ๋จธ์‹ ์œผ๋กœ ๋ถ„์„์„ ์ด์–ด๊ฐ€์ž๋ฉด ๊ฐ€์—ด๋œ ๋ฌผ์ด ์ง€๋‚˜๊ฐ€๋Š” ํŠœ๋ธŒ, ๋ฐœ์—ด ์žฅ์น˜ ๋“ฑ ์•ˆ์ชฝ์— ์ˆจ๊ฒจ์ง„ ๊ฒƒ์ด ๋ฐ”๋กœ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. +์ปคํ”ผ ๋จธ์‹ ์œผ๋กœ ๋น„์œ ํ•˜์ž๋ฉด ๊ธฐ๊ณ„ ์•ˆ์ชฝ์— ์ˆจ์–ด์žˆ๋Š” ๋œจ๊ฑฐ์šด ๋ฌผ์ด ์ง€๋‚˜๊ฐ€๋Š” ๊ด€์ด๋‚˜ ๋ฐœ์—ด ์žฅ์น˜ ๋“ฑ์ด ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ฐ์ฒด๋ฅผ ์ž‘๋™์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๊ณ  ๊ทธ ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์€ ์„œ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๊ฐ€์—ด๋œ ๋ฌผ์ด ์ง€๋‚˜๊ฐ€๋Š” ํŠœ๋ธŒ๋Š” ๋ฐœ์—ด ์žฅ์น˜์— ๋ถ€์ฐฉ๋ฉ๋‹ˆ๋‹ค. +๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์„ธ๋ถ€์‚ฌํ•ญ๋“ค์€ ์„œ๋กœ์˜ ์ •๋ณด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋™์ž‘์‹œํ‚ต๋‹ˆ๋‹ค. ๋ฐœ์—ด ์žฅ์น˜์— ๋ถ€์ฐฉ๋œ ๊ด€์„ ํ†ตํ•ด ๋œจ๊ฑฐ์šด ๋ฌผ์ด ์ด๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . -๊ทธ๋Ÿฌ๋‚˜ ์ปคํ”ผ ๋จธ์‹ ์€ ๋ณดํ˜ธ ์ปค๋ฒ„์— ์˜ํ•ด ๋‹ซํ˜€ ์žˆ์–ด์„œ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์•„๋ฌด๋„ ๋‚ด๋ถ€์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์€ ์ˆจ๊ฒจ์ ธ์žˆ๊ณ  ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ๋‚ด๋ถ€์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ปคํ”ผ ๋จธ์‹ ์€ ๋ณดํ˜ธ ์ปค๋ฒ„์— ๋‘˜๋Ÿฌ์‹ธ์—ฌ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ๋ฒ—๊ธฐ์ง€ ์•Š๊ณ ๋Š” ์ปคํ”ผ๋จธ์‹  ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ–์—์„  ์„ธ๋ถ€ ์š”์†Œ๋ฅผ ์•Œ ์ˆ˜ ์—†๊ณ , ์ ‘๊ทผ๋„ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋Šฅ์€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์•ผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์•Œ์•„์•ผ ํ•  ๊ฒƒ์€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐ์ฒด์˜ ์•ˆ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์™„์ „ํžˆ ์•Œ์ง€ ๋ชปํ•ด๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์•Œ์•„๋„ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด ์•ˆ์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์ง€ ๋ชปํ•ด๋„ ๊ดœ์ฐฎ๋‹ค๋Š” ์ ์€ ํฐ ์žฅ์ ์œผ๋กœ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค. -์ง€๊ธˆ๊นŒ์ง€ ์ผ๋ฐ˜์ ์ธ ์†Œ๊ฐœ์˜€์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง„ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฐœ๊ด€์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด ๋“œ๋ ธ์Šต๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‘ ๊ฐ€์ง€ ํƒ€์ž…์˜ ๊ฐ์ฒด ํ•„๋“œ(ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ํƒ€์ž…์˜ ๊ฐ์ฒด ํ•„๋“œ(ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- public: ์–ด๋””์„œ์—์„œ๋“ ์ง€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๋Š” public ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. -- private: ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +- public: ์–ด๋””์„œ๋“ ์ง€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‹ค๋ฃฌ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋‘ public์ž…๋‹ˆ๋‹ค. +- private: ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ์“ฐ์ž…๋‹ˆ๋‹ค. -๋‹ค๋ฅธ ๋งŽ์€ ์–ธ์–ด๋“ค์—๋Š” 'protected' ํ•„๋“œ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. protected๋Š” ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€์™€ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(private๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ์ƒ์† ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ์˜ ์ ‘๊ทผ ๊ถŒํ•œ์ด ์ถ”๊ฐ€๋œ ๊ฐœ๋…). ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉ๋˜๊ธฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ณดํ†ต ์ƒ์† ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— protected๋Š” ์–ด๋–ค ์˜๋ฏธ์—์„œ๋Š” private๋ณด๋‹ค ๋„๋ฆฌ ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด์™ธ์˜ ๋‹ค์ˆ˜ ์–ธ์–ด์—์„œ ํด๋ž˜์Šค ์ž์‹ ๊ณผ ์ž์† ํด๋ž˜์Šค์—์„œ๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๋Š” 'protected' ํ•„๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. protected ํ•„๋“œ๋Š” private๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ, ์ž์† ํด๋ž˜์Šค์—์„œ๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. protected ํ•„๋“œ๋„ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž์† ํด๋ž˜์Šค์˜ ํ•„๋“œ์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์—, protected ํ•„๋“œ๋Š” private ํ•„๋“œ๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -protected ํ•„๋“œ๋Š” ์–ธ์–ด ์ˆ˜์ค€์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š์ง€๋งŒ ์‹ค์ œ๋กœ protected๋Š” ๊ต‰์žฅํžˆ ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—๋ฎฌ๋ ˆ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” protected ํ•„๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ, protected๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•œ ์ ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๋ชจ๋ฐฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. -์ด์ œ ์šฐ๋ฆฌ๋Š” ํ”„๋กœํผํ‹ฐ์˜ ์ด ๋ชจ๋“  ํƒ€์ž…๋“ค์„ ์ด์šฉํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ปคํ”ผ ๋จธ์‹ ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปคํ”ผ ๋จธ์‹ ์—๋Š” ์•„์ฃผ ๋งŽ์€ ๋””ํ…Œ์ผ์ด ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ฐ„๋‹จํžˆ ํ•˜๊ธฐ ์œ„ํ•ด ์™„์ „ํ•œ ๋ชจ๋ธ์„ ๋งŒ๋“ค์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด์ œ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ํ”„๋กœํผํ‹ฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ์ปคํ”ผ๋จธ์‹ ์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์ปคํ”ผ ๋จธ์‹ ์€ ์•„์ฃผ ๋ณต์žกํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์„  ๊ฐ„๊ฒฐ์„ฑ์„ ์œ„ํ•ด ๊ฐ„์ด ๋ชจ๋ธ์„ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค(์›ํ•œ๋‹ค๋ฉด ๊ตฌํ˜„์€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค). -## protected ํ”„๋กœํผํ‹ฐ +## ํ”„๋กœํผํ‹ฐ ๋ณดํ˜ธํ•˜๊ธฐ -์ฒซ ๋ฒˆ์งธ๋กœ, ๊ฐ„๋‹จํ•œ ์ปคํ”ผ ๋จธ์‹  ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. +๋จผ์ €, ๊ฐ„๋‹จํ•œ ์ปคํ”ผ ๋จธ์‹  ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run class CoffeeMachine { - waterAmount = 0; // ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๋ฌผ์˜ ์–‘ + waterAmount = 0; // ๋ฌผํ†ต์— ์ฐจ ์žˆ๋Š” ๋ฌผ์˜ ์–‘ constructor(power) { this.power = power; - alert( `Created a coffee-machine, power: ${power}` ); + alert( `์ „๋ ฅ๋Ÿ‰์ด ${power}์ธ ์ปคํ”ผ๋จธ์‹ ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.` ); } } @@ -81,15 +81,15 @@ let coffeeMachine = new CoffeeMachine(100); coffeeMachine.waterAmount = 200; ``` -ํ˜„์žฌ `waterAmount`ํ”„๋กœํผํ‹ฐ์™€ `power`ํ”„๋กœํผํ‹ฐ๋Š” public์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€์—์„œ ์‰ฝ๊ฒŒ ๊ทธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์–ด๋А ๊ฐ’์œผ๋กœ๋“  ๋ฐ”๊ฟ€ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ˜„์žฌ ํ”„๋กœํผํ‹ฐ `waterAmount`์™€ `power`๋Š” public์ž…๋‹ˆ๋‹ค. ์†์‰ฝ๊ฒŒ `waterAmount`์™€ `power`๋ฅผ ์ฝ๊ณ  ์›ํ•˜๋Š” ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์‰ฌ์šด ์ƒํƒœ์ด์ฃ . -`waterAmount`ํ”„๋กœํผํ‹ฐ๋ฅผ protected๋กœ ๋ฐ”๊ฟ”์„œ ๋” ํ†ต์ œ์‹œ์ผœ ๋ด…์‹œ๋‹ค. ์•„๋ฌด๋„ ์ด๊ฒƒ์„ 0 ๋ฏธ๋งŒ์œผ๋กœ๋Š” ์„ค์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. +์ด์ œ `waterAmount`๋ฅผ protected๋กœ ๋ฐ”๊ฟ”์„œ `waterAmount`๋ฅผ ํ†ต์ œํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ `waterAmount`๋ฅผ 0 ๋ฏธ๋งŒ์˜ ๊ฐ’์œผ๋กœ๋Š” ์„ค์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋งŒ๋“ค์–ด ๋ณผ ๊ฒ๋‹ˆ๋‹ค. -**protected ํ”„๋กœํผํ‹ฐ๋Š” ๋Œ€๊ฒŒ ํ”„๋กœํผํ‹ฐ๋ช… ์•ž์— ๋ฐ‘์ค„ `_` ์„ ๋ถ™์ž…๋‹ˆ๋‹ค.** +**protected ํ”„๋กœํผํ‹ฐ ๋ช… ์•ž์—” ๋ฐ‘์ค„ `_`์ด ๋ถ™์Šต๋‹ˆ๋‹ค.** -์ด๊ฒƒ์€ ์–ธ์–ด ์ˆ˜์ค€์—์„œ ๊ฐ•์ œ์ ์ธ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค ์‚ฌ์ด์—์„œ๋Š” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•˜๋ฉด ์•ˆ ๋˜๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ž˜ ์•Œ๋ ค์ง„ ๊ด€์Šต์ž…๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ฐ•์ œํ•œ ์‚ฌํ•ญ์€ ์•„๋‹ˆ์ง€๋งŒ, ๋ฐ‘์ค„์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค ์‚ฌ์ด์—์„œ ์™ธ๋ถ€ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋•Œ ์”๋‹ˆ๋‹ค. -๊ทธ๋Ÿฌ๋‹ˆ ์ด์ œ `waterAmount`๋„ `_waterAmount`๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. +`waterAmount`์— ๋ฐ‘์ค„์„ ๋ถ™์—ฌ protected ํ”„๋กœํผํ‹ฐ๋กœ ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค. ```js run class CoffeeMachine { @@ -117,15 +117,15 @@ let coffeeMachine = new CoffeeMachine(100); coffeeMachine.waterAmount = -10; // Error: ๋ฌผ์˜ ์–‘์€ ์Œ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ``` -์ด์ œ ์ ‘๊ทผ์ด ๋” ํ†ต์ œ์ ์ด๋ผ์„œ ๋ฌผ์˜ ์–‘์„ 0 ๋ฏธ๋งŒ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +์ด์ œ ๋ฌผ์˜ ์–‘์„ 0 ๋ฏธ๋งŒ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ## ์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ -`power` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ๋งŒ ๊ฐ’์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์ดํ›„์—๋Š” ์ ˆ๋Œ€ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋Š”๋ฐ, ์ด๋•Œ ์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`power` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งŒ ๊ฐ’์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์ดํ›„์—๋Š” ๊ฐ’์„ ์ ˆ๋Œ€ ์ˆ˜์ •ํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋Š”๋ฐ, ์ด๋Ÿด ๋•Œ ์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ปคํ”ผ ๋จธ์‹ ์˜ ๊ฒฝ์šฐ์—๋Š” ์ „๋ ฅ์ด ๊ทธ๋Ÿฌํ•œ ๊ฒƒ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. +์ปคํ”ผ ๋จธ์‹ ์˜ ๊ฒฝ์šฐ์—๋Š” ์ „๋ ฅ์ด ์ด์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. -์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” setter(์„ค์ •์ž)๋Š” ๋งŒ๋“ค์ง€ ์•Š๊ณ  getter(ํš๋“์ž)๋งŒ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด setter(์„ค์ •์ž)๋Š” ๋งŒ๋“ค์ง€ ์•Š๊ณ  getter(ํš๋“์ž)๋งŒ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run class CoffeeMachine { @@ -144,15 +144,15 @@ class CoffeeMachine { // ์ปคํ”ผ ๋จธ์‹  ์ƒ์„ฑ let coffeeMachine = new CoffeeMachine(100); -alert(`Power is: ${coffeeMachine.power}W`); // Power is: 100W +alert(`์ „๋ ฅ๋Ÿ‰์ด ${coffeeMachine.power}์ธ ์ปคํ”ผ๋จธ์‹ ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.`); // ์ „๋ ฅ๋Ÿ‰์ด 100์ธ ์ปคํ”ผ๋จธ์‹ ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. coffeeMachine.power = 25; // Error (setter ์—†์Œ) ``` -````smart header="getter/setter ํ•จ์ˆ˜" -์—ฌ๊ธฐ์„œ๋Š” getter, setter ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. +````smart header="getter์™€ setter ํ•จ์ˆ˜" +์œ„์—์„œ๋Š” get, set ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ getter์™€ setter ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์€ ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์€ `get.../set...`ํ˜•์‹์˜ ํ•จ์ˆ˜๊ฐ€ ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์€ ์•„๋ž˜์™€ ๊ฐ™์ด `get.../set...` ํ˜•์‹์˜ ํ•จ์ˆ˜๊ฐ€ ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค. ```js class CoffeeMachine { @@ -171,26 +171,26 @@ class CoffeeMachine { new CoffeeMachine().setWaterAmount(100); ``` -๋‹ค์†Œ ๊ธธ๋”๋ผ๋„ ์œ„์˜ ๋ฐฉ์‹์€ ๋‹ค์ˆ˜์˜ ์ธ์ž๋ฅผ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข€ ๋” ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” ๋‹ค์ˆ˜์˜ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.) +๋‹ค์†Œ ๊ธธ์–ด๋ณด์ด๊ธด ํ•˜์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ๋‹ค์ˆ˜์˜ ์ธ์ž๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข€ ๋” ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค(์œ„ ์˜ˆ์‹œ์—์„  ์ธ์ž๊ฐ€ ํ•˜๋‚˜๋ฟ์ด๊ธด ํ•˜์ง€๋งŒ์š”). -์œ„์˜ ๋ฐฉ์‹๊ณผ๋Š” ๋‹ฌ๋ฆฌ get/set ๋ฌธ๋ฒ•์€ ๋” ์งง๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ •ํ•ด์ง„ ์—„๊ฒฉํ•œ ๊ทœ์น™์€ ์—†์œผ๋ฏ€๋กœ ์›ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +๋ฐ˜๋ฉด get, set ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์งง์•„์ง„๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค๊ฑธ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™์€ ์—†์œผ๋ฏ€๋กœ ์›ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•˜์„ธ์š”. ```` -```smart header="Protected ํ•„๋“œ๋Š” ์ƒ์†๋ฉ๋‹ˆ๋‹ค." -๋งŒ์•ฝ `CoffeeMachine`ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” `MegaMachine`ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด, ์ด ์ƒˆ๋กœ์šด ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ `this._waterAmount`๋‚˜ `this._power`์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์— ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +```smart header="protected ํ•„๋“œ๋Š” ์ƒ์†๋ฉ๋‹ˆ๋‹ค." +`class MegaMachine extends CoffeeMachine`๋กœ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉด, ์ƒˆ๋กœ์šด ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ `this._waterAmount`๋‚˜ `this._power`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ทธ๋ž˜์„œ protected ํ•„๋“œ๋Š” ์ž์—ฐ์Šค๋ ˆ ์ƒ์†์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ๋ณด๊ฒŒ ๋  private ๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๋ง์ด์ฃ . +์ด๋ ‡๊ฒŒ protected ํ•„๋“œ๋Š” ์•„๋ž˜์—์„œ ๋ณด๊ฒŒ ๋  private ํ•„๋“œ์™€ ๋‹ฌ๋ฆฌ, ์ž์—ฐ์Šค๋Ÿฌ์šด ์ƒ์†์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ``` ## private ํ”„๋กœํผํ‹ฐ [recent browser=none] -ํ‘œ์ค€์— ๋“ฑ์žฌ๋˜๊ธฐ ์ง์ „์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ œ์•ˆ์„œ์—์„œ private ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ์–ธ์–ด ์ˆ˜์ค€์˜ ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +private ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ œ์•ˆ(proposal) ๋ชฉ๋ก์— ๋“ฑ์žฌ๋œ ๋ฌธ๋ฒ•์œผ๋กœ, ๋ช…์„ธ์„œ์— ๋“ฑ์žฌ๋˜๊ธฐ ์ง์ „ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. -private ํ”„๋กœํผํ‹ฐ๋Š” '#'์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์“ฐ์ธ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋Š” ์˜ค์ง ํด๋ž˜์Šค ์•ˆ์—์„œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +private ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” `#`์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `#`์ด ๋ถ™์œผ๋ฉด ํด๋ž˜์Šค ์•ˆ์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -private ํ”„๋กœํผํ‹ฐ์ธ `#waterLimit`๊ณผ ๋ฌผ์„ ์ฒดํฌํ•˜๋Š” private ๋ฉ”์„œ๋“œ์ธ `#checkWater`๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. +๋ฌผ ์šฉ๋Ÿ‰ ํ•œ๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” private ํ”„๋กœํผํ‹ฐ `#waterLimit`๊ณผ ๋‚จ์•„์žˆ๋Š” ๋ฌผ์˜ ์–‘์„ ํ™•์ธํ•ด์ฃผ๋Š” private ๋ฉ”์„œ๋“œ `#checkWater`๋ฅผ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค. ```js run class CoffeeMachine { @@ -216,11 +216,11 @@ coffeeMachine.#waterLimit = 1000; // Error */!* ``` -์–ธ์–ด ์ˆ˜์ค€์—์„œ `#`์€ private ํ•„๋“œ๋ฅผ ์˜๋ฏธํ•˜๋Š” ํŠน๋ณ„ํ•œ ํ‘œ์‹œ์ž…๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ์™ธ๋ถ€์—์„œ๋‚˜ ์ƒ์†๋œ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +`#`์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง€์›ํ•˜๋Š” ๋ฌธ๋ฒ•์œผ๋กœ, private ํ•„๋“œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. private ํ•„๋“œ๋Š” ํด๋ž˜์Šค ์™ธ๋ถ€๋‚˜ ์ž์† ํด๋ž˜์Šค์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -private ํ•„๋“œ๋Š” public ํ•„๋“œ์™€ ์ƒ์ถฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ private ํ”„๋กœํผํ‹ฐ์ธ `#waterAmount`์™€ public ํ”„๋กœํผํ‹ฐ์ธ `waterAmount`๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +private ํ•„๋“œ๋Š” public ํ•„๋“œ์™€ ์ƒ์ถฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. private ํ”„๋กœํผํ‹ฐ `#waterAmount`์™€ public ํ”„๋กœํผํ‹ฐ `waterAmount`๋ฅผ ๋™์‹œ์— ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜ˆ์‹œ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด `waterAmount`๊ฐ€ `#waterAmount`์— ์ ‘๊ทผํ•˜๋„๋ก ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. +`#waterAmount`์˜ ์ ‘๊ทผ์ž `waterAmount`๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ```js run class CoffeeMachine { @@ -243,26 +243,26 @@ machine.waterAmount = 100; alert(machine.#waterAmount); // Error ``` -protected์™€ ๋‹ฌ๋ฆฌ private ํ•„๋“œ๋Š” ์–ธ์–ด ์ž์ฒด์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์•„์ฃผ ์ข‹์€ ์ผ์ด์ฃ . +protected ํ•„๋“œ์™€ ๋‹ฌ๋ฆฌ, private ํ•„๋“œ๋Š” ์–ธ์–ด ์ž์ฒด์— ์˜ํ•ด ๊ฐ•์ œ๋œ๋‹ค๋Š” ์ ์ด ์žฅ์ ์ž…๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ `CoffeeMachine` ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„œ `#waterAmount`์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ `waterAmount`์˜ getter์™€ setter์— ์˜์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ `CoffeeMachine`์„ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„  `#waterAmount`์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. `#waterAmount`์— ์ ‘๊ทผํ•˜๋ ค๋ฉด `waterAmount`์˜ getter์™€ setter๋ฅผ ํ†ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js class MegaCoffeeMachine extends CoffeeMachine { method() { *!* - alert( this.#waterAmount ); // Error: can only access from CoffeeMachine + alert( this.#waterAmount ); // Error: CoffeeMachine์„ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. */!* } } ``` -๋งŽ์€ ์ƒํ™ฉ์—์„œ ์ด๋Ÿฐ ์ œํ•œ์€ ๋„ˆ๋ฌด ์—„๊ฒฉํ•ฉ๋‹ˆ๋‹ค. `CoffeeMachine`์„ ์ƒ์†ํ–ˆ๋‹ค๋ฉด `CoffeeMachine`์˜ ๋‚ด๋ถ€์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ์ •๋‹นํ•œ ์ด์œ ๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ protected ํ•„๋“œ๊ฐ€ ์–ธ์–ด์  ๋ฌธ๋ฒ•์˜ ์ง€์›์„ ๋ฐ›์ง€ ๋ชปํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋” ์ž์ฃผ ์“ฐ์ด๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. +๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์ด๋Ÿฐ ์ œ์•ฝ์‚ฌํ•ญ์€ ๋„ˆ๋ฌด ์—„๊ฒฉํ•ฉ๋‹ˆ๋‹ค. `CoffeeMachine`์„ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„  `CoffeeMachine`์˜ ๋‚ด๋ถ€์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ์ •๋‹นํ•œ ์‚ฌ์œ ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ์–ธ์–ด ์ฐจ์›์—์„œ protected ํ•„๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„๋„ ๋” ์ž์ฃผ ์“ฐ์ด๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -````warn header="Private ํ•„๋“œ๋Š” this[name]๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." +````warn header="private ํ•„๋“œ๋Š” this[name]๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." private ํ•„๋“œ๋Š” ํŠน๋ณ„ํ•ฉ๋‹ˆ๋‹ค. -์•Œ๋‹ค์‹œํ”ผ, ๋ณดํ†ต์€ ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ `this[name]`์„ ์ด์šฉํ•ด์„œ ํ•„๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•Œ๋‹ค์‹œํ”ผ, ๋ณดํ†ต์€ `this[name]`์„ ์‚ฌ์šฉํ•ด ํ•„๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js class User { @@ -274,43 +274,43 @@ class User { } ``` -ํ•˜์ง€๋งŒ private ํ•„๋“œ์—๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. `this['#name']`๋Š” ์ž‘๋™๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ”„๋ผ์ด๋ฒ„์‹œ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ๋ฒ•์  ์ œํ•œ์ž…๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ private ํ•„๋“œ๋Š” `this[name]`์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฌธ๋ฒ•์  ์ œ์•ฝ์€ ํ•„๋“œ์˜ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ```` ## ์š”์•ฝ -OOP(Object Oriented Programming, ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)์˜ ๊ด€์ ์—์„œ, ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์„ [์บก์Аํ™”(encapsulation)]๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„  ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์„ [์บก์Аํ™”(encapsulation)]๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. -์บก์Аํ™”๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +์บก์Аํ™”๋Š” ์ด์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -์‚ฌ์šฉ์ž๋“ค์ด ์Šค์Šค๋กœ ์ž์‹ ์˜ ๋ฐœ๋“ฑ์„ ์ฐ์ง€ ์•Š๋„๋ก ๋ณดํ˜ธ -: ์ปคํ”ผ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž ํŒ€์ด ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ด…์‹œ๋‹ค. "Best CoffeeMachine"์ด๋ผ๋Š” ํšŒ์‚ฌ์—์„œ ๋งŒ๋“ค์—ˆ๊ณ  ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ ๋ณดํ˜ธ ์ปค๋ฒ„๊ฐ€ ์—†์–ด์ ธ์„œ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋…ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ๋ฐœ๋“ฑ์„ ์ฐ์ง€ ์•Š๋„๋ก ๋ณดํ˜ธ +: ์ปคํ”ผ ๋จธ์‹ ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœํŒ€์ด ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ด…์‹œ๋‹ค. "Best CoffeeMachine"์ด๋ผ๋Š” ํšŒ์‚ฌ์—์„œ ๋งŒ๋“  ์ด ์ปคํ”ผ ๋จธ์‹ ์€ ํ˜„์žฌ ์ž˜ ์ž‘๋™ํ•˜๊ณ  ์žˆ์ง€๋งŒ, ๋ณดํ˜ธ ์ปค๋ฒ„๊ฐ€ ์—†์–ด์„œ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋…ธ์ถœ๋˜์–ด์žˆ๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. - ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋“ค์€ ๋ฌธ๋ช…์ธ์ด๋ผ์„œ ์˜๋„๋Œ€๋กœ ์ปคํ”ผ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋А ๋‚ , ํ•œ ๊ฐœ๋ฐœ์ž John์ด ์ž์‹ ์ด ๊ฐ€์žฅ ๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด์„œ ์ปคํ”ผ ๋จธ์‹  ๋‚ด๋ถ€๋ฅผ ์‚ด์ง ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ดํ‹€ ํ›„ ์ปคํ”ผ ๋จธ์‹ ์ด ๊ณ ์žฅ ๋‚ฌ์Šต๋‹ˆ๋‹ค. + ๊ต์–‘์žˆ๋Š” ํŒ€์›๋“ค์€ ๋ชจ๋‘ ์„ค๊ณ„ ์˜๋„์— ๋งž๊ฒŒ ์ปคํ”ผ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋А ๋‚  John์ด๋ผ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž์‹ ์˜ ๋Šฅ๋ ฅ์„ ๊ณผ์‹ ํ•˜๋ฉฐ ์ปคํ”ผ ๋จธ์‹  ๋‚ด๋ถ€๋ฅผ ์‚ด์ง ๋งŒ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ดํ‹€ ํ›„, ์ปคํ”ผ ๋จธ์‹ ์€ ๊ณ ์žฅ์ด ๋‚˜๋ฒ„๋ ธ์ฃ . - ๊ทธ๊ฑด ๋ถ„๋ช…ํžˆ John์˜ ์ž˜๋ชป์ด๋ผ๊ธฐ๋ณด๋‹ค๋Š” ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ์—†์• ๊ณ , John์ด ๋ง˜๋Œ€๋กœ ์กฐ์ž‘ํ•˜๋„๋ก ๋‚ด๋ฒ„๋ ค ๋‘” ์‚ฌ๋žŒ์˜ ์ž˜๋ชป์ž…๋‹ˆ๋‹ค. + ์ปคํ”ผ ๋จธ์‹ ์ด ๊ณ ์žฅ ๋‚œ ๊ฑด John์˜ ์ž˜๋ชป์ด๋ผ๊ธฐ๋ณด๋‹ค๋Š”, ๋ณดํ˜ธ ์ปค๋ฒ„๋ฅผ ์—†์• ๊ณ  John์ด ๋งˆ์Œ๋Œ€๋กœ ์กฐ์ž‘ํ•˜๋„๋ก ๋‚ด๋ฒ„๋ ค ๋‘” ์‚ฌ๋žŒ์˜ ์ž˜๋ชป์ž…๋‹ˆ๋‹ค. - ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์™ธ๋ถ€์—์„œ ๋ฐ”๊พธ๋ ค๊ณ  ํ•˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ฐ”๊พผ๋‹ค๋ฉด ๊ฒฐ๊ณผ๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€์—์„œ ์˜๋„์น˜ ์•Š๊ฒŒ ํด๋ž˜์Šค๋ฅผ ์กฐ์ž‘ํ•˜๊ฒŒ ๋˜๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์ง€์› ๊ฐ€๋Šฅํ•œ ๊ฒƒ -: ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ๋“ค์ด ์‹ค์ƒํ™œ์—์„œ์˜ ์ปคํ”ผ ๋จธ์‹ ๋ณด๋‹ค ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์ € ํ•œ ๋ฒˆ ๊ตฌ๋งคํ•˜๊ณ  ๋งˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฝ”๋“œ๋Š” ๊ฑฐ๋“ญํ•ด์„œ ๊ฐœ๋ฐœ๋˜๊ณ  ๊ฐœ์„ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์ง€์› ๊ฐ€๋Šฅ +: ์‹ค์ œ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์€ ์ปคํ”ผ ๋จธ์‹  ์‚ฌ๋ก€๋ณด๋‹ค ํ›จ์”ฌ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์ปคํ”ผ ๋จธ์‹ ์€ ํ•œ๋ฒˆ ๊ตฌ๋งคํ•˜๋ฉด ๋์ด์ง€๋งŒ ์‹ค์ œ ์ฝ”๋“œ๋Š” ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๋Š์ž„์—†์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. - **์—„๊ฒฉํžˆ ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค๋ฉด ํด๋ž˜์Šค ๊ฐœ๋ฐœ์ž๋“ค์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ์ž์œ ๋กญ๊ฒŒ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** + **๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๋ฉด, ํด๋ž˜์Šค ๊ฐœ๋ฐœ์ž๋“ค์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ์ž์œ ๋กญ๊ฒŒ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** - ๋งŒ์•ฝ ์—ฌ๋Ÿฌ๋ถ„์ด ๊ทธ๋Ÿฌํ•œ ํด๋ž˜์Šค์˜ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด, ์–ด๋–ค ์™ธ๋ถ€ ์ฝ”๋“œ๋„ private ๋ฉ”์„œ๋“œ์— ์˜์กดํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— private ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์—†์•จ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„ ๋‘๋ฉด ๋ฉ๋‹ˆ๋‹ค. + ๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์—„๊ฒฉํžˆ ๊ตฌ๋ถ„๋œ ํด๋ž˜์Šค๋ฅผ ๋งŒ์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ๊ทธ ์–ด๋–ค ์™ธ๋ถ€ ์ฝ”๋“œ๋„ ๋‚ด๋ถ€ private ๋ฉ”์„œ๋“œ์— ์˜์กดํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— private ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ณ , ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์—†์•จ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„ ๋‘๋ฉด ๋ฉ๋‹ˆ๋‹ค. - ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ๋Š”, ์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ „๋ฉด์ ์ธ ์ •๋น„๊ฐ€ ์ด๋ฃจ์–ด์ง€๋”๋ผ๋„ ์™ธ๋ถ€์˜ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๋˜‘๊ฐ™๋‹ค๋ฉด ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. + ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„  ์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๋ฉด์„œ ๋‚ด๋ถ€ ์ •๋น„๊ฐ€ ์ „๋ฉด์ ์œผ๋กœ ์ด๋ค„์กŒ๋”๋ผ๋„ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๋˜‘๊ฐ™๋‹ค๋ฉด ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ์šฉ์ดํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -๋ณต์žกํ•จ์„ ์ˆจ๊ธฐ๋Š” ๊ฒƒ -: ์‚ฌ๋žŒ๋“ค์€ ์‹ฌํ”Œํ•œ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€๋Š” ์‹ฌํ”Œํ•˜์ง€ ์•Š์„์ง€๋ผ๋„ ์ตœ์†Œํ•œ ์™ธํ˜•์€ ๋ง์ž…๋‹ˆ๋‹ค. +๋ณต์žก์„ฑ ์€๋‹‰ +: ์‚ฌ๋žŒ๋“ค์€ ๊ฐ„๋‹จํ•œ ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€๋Š” ๊ฐ„๋‹จ์น˜ ์•Š๋”๋ผ๋„ ์ตœ์†Œํ•œ ์™ธํ˜•์€ ๊ฐ„๋‹จํ•ด์•ผ ํ•˜์ฃ . ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. - **๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ์ˆจ๊ฒจ์ ธ ์žˆ๋Š” ๊ฒƒ์€ ์–ธ์ œ๋‚˜ ํŽธ๋ฆฌํ•˜๊ณ , ๊ฐ„๋‹จํ•˜๊ณ  ์ž˜ ๋ฌธ์„œํ™”๋œ ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.** + **๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ์ˆจ๊ฒจ์ ธ ์žˆ์œผ๋ฉด ๊ฐ„๋‹จํ•˜๊ณ  ํŽธ๋ฆฌํ•ด์ง‘๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ ์„ค๋ช…๋„ ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์‰ฌ์›Œ์ง€์ฃ .** -๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ˆจ๊ธฐ๊ธฐ ์œ„ํ•ด์„œ๋Š” protected๋‚˜ private ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”: +๋‚ด๋ถ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ˆจ๊ธฐ๋ ค๋ฉด protected๋‚˜ private ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -- protected ํ•„๋“œ๋Š” `_`๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์–ธ์–ด ์ˆ˜์ค€์—์„œ ๊ฐ•์ œ์ ์ธ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋„๋ฆฌ ์•Œ๋ ค์ง„ ๊ด€์Šต์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ํด๋ž˜์Šค์™€ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ `_`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•„๋“œ์—๋งŒ ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- private ํ•„๋“œ๋Š” `#`๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž์ฒด์ ์œผ๋กœ `#`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•„๋“œ์—๋Š” ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค. +- protected ํ•„๋“œ๋Š” `_`๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `_`์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง€์›ํ•˜๋Š” ๋ฌธ๋ฒ•์€ ์•„๋‹ˆ์ง€๋งŒ, protected ํ•„๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋•Œ ๊ด€์Šต์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” protected ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ •์˜๋œ ํด๋ž˜์Šค์™€ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„œ๋งŒ `_`๊ฐ€ ๋ถ™์€ ํ•„๋“œ์— ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- private ํ•„๋“œ๋Š” `#`๋กœ ์‹œ์ž‘ํ•˜๋ฉฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง€์›ํ•˜๋Š” ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค. `#`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•„๋“œ๋Š” ํ•ด๋‹น ํ•„๋“œ๊ฐ€ ์ •์˜๋œ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -ํ˜„์žฌ private ํ•„๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ € ๊ฐ„์— ์ž˜ ์ง€์›๋˜์ง€๋Š” ์•Š์ง€๋งŒ ํด๋ฆฌํ•„(polyfill)๋ฉ๋‹ˆ๋‹ค. +๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ private ํ•„๋“œ๋ฅผ ์ง€์›ํ•˜์ง„ ์•Š์ง€๋งŒ ํด๋ฆฌํ•„์„ ๊ตฌํ˜„ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/05-extend-natives/article.md b/1-js/09-classes/05-extend-natives/article.md index 9a56867342..d37bca820e 100644 --- a/1-js/09-classes/05-extend-natives/article.md +++ b/1-js/09-classes/05-extend-natives/article.md @@ -1,12 +1,12 @@ -# Extending built-in classes +# ๋‚ด์žฅ ํด๋ž˜์Šค ํ™•์žฅํ•˜๊ธฐ -Built-in classes like Array, Map and others are extendable also. +๋ฐฐ์—ด, ๋งต ๊ฐ™์€ ๋‚ด์žฅ ํด๋ž˜์Šค๋„ ํ™•์žฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -For instance, here `PowerArray` inherits from the native `Array`: +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `PowerArray`๋Š” ๊ธฐ๋ณธ `Array`๋ฅผ ์ƒ์†๋ฐ›์•„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ```js run -// add one more method to it (can do more) +// ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(๋” ๋งŽ์ด ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ). class PowerArray extends Array { isEmpty() { return this.length === 0; @@ -21,20 +21,20 @@ alert(filteredArr); // 10, 50 alert(filteredArr.isEmpty()); // false ``` -Please note a very interesting thing. Built-in methods like `filter`, `map` and others -- return new objects of exactly the inherited type `PowerArray`. Their internal implementation uses the object's `constructor` property for that. +๋ญ”๊ฐ€ ํฅ๋ฏธ๋กœ์šด ์ ์ด ํ•˜๋‚˜ ๋ณด์ด๋„ค์š”. `filter`, `map` ๋“ฑ์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๊ฐ€ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค์ธ `PowerArray`์˜ ์ธ์Šคํ„ด์Šค(๊ฐ์ฒด)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•  ๋• ๋‚ด๋ถ€์—์„œ ๊ฐ์ฒด์˜ `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -In the example above, +๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ด€๊ณ„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ```js arr.constructor === PowerArray ``` -When `arr.filter()` is called, it internally creates the new array of results using exactly `arr.constructor`, not basic `Array`. That's actually very cool, because we can keep using `PowerArray` methods further on the result. +`arr.filter()`๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ๋‚ด๋ถ€์—์„  ๊ธฐ๋ณธ `Array`๊ฐ€ ์•„๋‹Œ `arr.constructor`๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ณ  ์—ฌ๊ธฐ์— ํ•„ํ„ฐ ํ›„ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ด๊น๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด `PowerArray`์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์ƒ๊น๋‹ˆ๋‹ค. -Even more, we can customize that behavior. +๋ฌผ๋ก  ๋™์ž‘ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We can add a special static getter `Symbol.species` to the class. If exists, it should return the constructor that JavaScript will use internally to create new entities in `map`, `filter` and so on. +ํŠน์ˆ˜ ์ •์  getter์ธ `Symbol.species`๋ฅผ ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, `Symbol.species`๊ฐ€ ์žˆ์œผ๋ฉด `map`, `filter` ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฐœ์ฒด์˜ ์ƒ์„ฑ์ž๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜์ฃ . -If we'd like built-in methods like `map` or `filter` to return regular arrays, we can return `Array` in `Symbol.species`, like here: +`map`์ด๋‚˜ `filter`๊ฐ™์€ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๊ฐ€ ์ผ๋ฐ˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ `Symbol.species`๊ฐ€ `Array`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```js run class PowerArray extends Array { @@ -43,7 +43,7 @@ class PowerArray extends Array { } *!* - // built-in methods will use this as the constructor + // ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜ํ™˜ ๊ฐ’์— ๋ช…์‹œ๋œ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ์ž๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. static get [Symbol.species]() { return Array; } @@ -53,37 +53,37 @@ class PowerArray extends Array { let arr = new PowerArray(1, 2, 5, 10, 50); alert(arr.isEmpty()); // false -// filter creates new array using arr.constructor[Symbol.species] as constructor +// filter๋Š” arr.constructor[Symbol.species]๋ฅผ ์ƒ์„ฑ์ž๋กœ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. let filteredArr = arr.filter(item => item >= 10); *!* -// filteredArr is not PowerArray, but Array +// filteredArr๋Š” PowerArray๊ฐ€ ์•„๋‹Œ Array์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. */!* alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function ``` -As you can see, now `.filter` returns `Array`. So the extended functionality is not passed any further. +๋ณด์‹œ๋‹ค์‹œํ”ผ ์ด์ œ `.filter`๊ฐ€ `Array`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋”๋Š” ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -```smart header="Other collections work similarly" -Other collections, such as `Map` and `Set`, work alike. They also use `Symbol.species`. +```smart header="๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜๋„ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." +`Map`, `Set` ๊ฐ™์€ ์ปฌ๋ ‰์…˜๋„ ์œ„์™€ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ปฌ๋ ‰์…˜๋“ค๋„ `Symbol.species`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ``` -## No static inheritance in built-ins +## ๋‚ด์žฅ ๊ฐ์ฒด์™€ ์ •์  ๋ฉ”์„œ๋“œ ์ƒ์† -Built-in objects have their own static methods, for instance `Object.keys`, `Array.isArray` etc. +๋‚ด์žฅ ๊ฐ์ฒด๋Š” `Object.keys`, `Array.isArray` ๋“ฑ์˜ ์ž์ฒด ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. -As we already know, native classes extend each other. For instance, `Array` extends `Object`. +์•ž์„œ ํ•™์Šตํ•œ ๋ฐ”์™€ ๊ฐ™์ด ๋„ค์ดํ‹ฐ๋ธŒ ํด๋ž˜์Šค๋“ค์€ ์„œ๋กœ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๋งบ์Šต๋‹ˆ๋‹ค. `Array`๋Š” `Object`๋ฅผ ์ƒ์†๋ฐ›์ฃ . -Normally, when one class extends another, both static and non-static methods are inherited. That was thoroughly explained in the article [](info:static-properties-methods#statics-and-inheritance). +์ผ๋ฐ˜์ ์œผ๋ก  ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉด ์ •์  ๋ฉ”์„œ๋“œ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ ๋ชจ๋‘๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ [](info:static-properties-methods#statics-and-inheritance)์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ๋“œ๋ฆฐ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -But built-in classes are an exception. They don't inherit statics from each other. +๊ทธ๋Ÿฐ๋ฐ ๋‚ด์žฅ ํด๋ž˜์Šค๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‚ด์žฅํด๋ž˜์Šค๋Š” ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. -For example, both `Array` and `Date` inherit from `Object`, so their instances have methods from `Object.prototype`. But `Array.[[Prototype]]` does not reference `Object`, so there's no, for instance, `Array.keys()` (or `Date.keys()`) static method. +์˜ˆ๋ฅผ ๋“ค์–ด๋ด…์‹œ๋‹ค. `Array`์™€ `Date`๋Š” ๋ชจ๋‘ `Object`๋ฅผ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์—์„  `Object.prototype`์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `Array.[[Prototype]]`์™€ `Date.[[Prototype]]`์€ `Object`๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— `Array.keys()`๋‚˜ `Date.keys()`๊ฐ™์€ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์ธ์Šคํ„ด์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -Here's the picture structure for `Date` and `Object`: +์•„๋ž˜๋Š” `Date`์™€ `Object`์˜ ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ธ ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ![](object-date-inheritance.svg) -As you can see, there's no link between `Date` and `Object`. They are independent, only `Date.prototype` inherits from `Object.prototype`. +๋ณด์‹œ๋‹ค์‹œํ”ผ `Date`์™€ `Object`๋ฅผ ์ง์ ‘ ์ด์–ด์ฃผ๋Š” ๋งํฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. `Date`์™€ `Object`๋Š” ๋…๋ฆฝ์ ์ด์ฃ . `Date.prototype`๋งŒ `Object.prototype`๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -That's an important difference of inheritance between built-in objects compared to what we get with `extends`. +๋‚ด์žฅ ๊ฐ์ฒด ๊ฐ„์˜ ์ƒ์†๊ณผ `extends`๋ฅผ ์‚ฌ์šฉํ•œ ์ƒ์†์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์ด ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg index 470aabf7f8..be47d7fd96 100644 --- a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg +++ b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg @@ -1 +1 @@ -constructor: Object toString: function hasOwnProperty: function ...Object.prototypeconstructor: Date toString: function getDate: function ...Date.prototypeObjectDatenew Date()[[Prototype]][[Prototype]]prototypeprototypedefineProperty keys ...now parse ...1 Jan 2019 \ No newline at end of file +constructor: Object toString: function hasOwnProperty: function ...Object.prototypeconstructor: Date toString: function getDate: function ...Date.prototypeObjectDatenew Date()[[Prototype]][[Prototype]]prototypeprototypedefineProperty keys ...now parse ...1 Jan 2019 \ No newline at end of file diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md index d41d90edf4..aa5be5a165 100644 --- a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md +++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md @@ -1,7 +1,7 @@ -Yeah, looks strange indeed. +๋„ค, ์‹ค์ œ๋กœ ์ด์ƒํ•ด ๋ณด์ด๊ธด ํ•ฉ๋‹ˆ๋‹ค. -But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain. +๊ทธ๋Ÿฐ๋ฐ `instanceof`๋Š” ํ‰๊ฐ€ ์‹œ, ํ•จ์ˆ˜๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ํ‰๊ฐ€ ๋Œ€์ƒ์˜ `prototype`์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ํ‰๊ฐ€ ๋Œ€์ƒ์˜ `prototype`์ด ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์žˆ๋Š” ํ”„๋กœํ† ํƒ€์ž…๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ณ ๋ คํ•˜์ฃ . -And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`. +๋ฌธ์ œ์—์„œ `a.__proto__ == B.prototype`์ด๋ฏ€๋กœ, `instanceof`๋Š” `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function. +`instanceof`์˜ ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•ด `prototype`์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ํƒ€์ž…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md index e9481912ae..596b666f67 100644 --- a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md +++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Strange instanceof +# ์ด์ƒํ•œ instanceof -Why `instanceof` below returns `true`? We can easily see that `a` is not created by `B()`. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `a`๋Š” `B()`๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ๋„ `instanceof`๋Š” ์™œ `true`๋ฅผ ๋ฐ˜ํ™˜ํ• ๊นŒ์š”? ```js run function A() {} diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index 544e07eb7b..e6fa8dc46d 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -1,42 +1,42 @@ -# Class checking: "instanceof" +# 'instanceof'๋กœ ํด๋ž˜์Šค ํ™•์ธํ•˜๊ธฐ -The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account. +`instanceof` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๊ฐ€ ํŠน์ • ํด๋ž˜์Šค์— ์†ํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `instanceof`๋Š” ์ƒ์† ๊ด€๊ณ„๋„ ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค. -Such a check may be necessary in many cases, here we'll use it for building a *polymorphic* function, the one that treats arguments differently depending on their type. +ํ™•์ธ ๊ธฐ๋Šฅ์€ ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ์“ฐ์ด๋Š”๋ฐ, ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  `instanceof`๋ฅผ ์‚ฌ์šฉํ•ด ์ธ์ˆ˜์˜ ํƒ€์ž…์— ๋”ฐ๋ผ ์ด๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” *๋‹คํ˜•์ ์ธ(polymorphic)* ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -## The instanceof operator [#ref-instanceof] +## instanceof ์—ฐ์‚ฐ์ž [#ref-instanceof] -The syntax is: +๋ฌธ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js obj instanceof Class ``` -It returns `true` if `obj` belongs to the `Class` or a class inheriting from it. +`obj`๊ฐ€ `Class`์— ์†ํ•˜๊ฑฐ๋‚˜ `Class`๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์— ์†ํ•˜๋ฉด `true`๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js run class Rabbit {} let rabbit = new Rabbit(); -// is it an object of Rabbit class? +// rabbit์ด ํด๋ž˜์Šค Rabbit์˜ ๊ฐ์ฒด์ธ๊ฐ€์š”? *!* alert( rabbit instanceof Rabbit ); // true */!* ``` -It also works with constructor functions: +`instanceof`๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run *!* -// instead of class +// ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ function Rabbit() {} */!* alert( new Rabbit() instanceof Rabbit ); // true ``` -...And with built-in classes like `Array`: +`Array` ๊ฐ™์€ ๋‚ด์žฅ ํด๋ž˜์Šค์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let arr = [1, 2, 3]; @@ -44,19 +44,19 @@ alert( arr instanceof Array ); // true alert( arr instanceof Object ); // true ``` -Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`. +์œ„ ์˜ˆ์‹œ์—์„œ `arr`์€ ํด๋ž˜์Šค `Object`์—๋„ ์†ํ•œ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. `Array`๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜์œผ๋กœ `Object`๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -Normally, `instanceof` operator examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`. +`instanceof` ์—ฐ์‚ฐ์ž๋Š” ๋ณดํ†ต, ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ์ธ์Šคํ„ด์Šค ์—ฌ๋ถ€๋‚˜ ์ƒ์† ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ •์  ๋ฉ”์„œ๋“œ `Symbol.hasInstance`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง์ ‘ ํ™•์ธ ๋กœ์ง์„ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -The algorithm of `obj instanceof Class` works roughly as follows: +`obj instanceof Class`์€ ๋Œ€๋žต ์•„๋ž˜์™€ ๊ฐ™์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -1. If there's a static method `Symbol.hasInstance`, then just call it: `Class[Symbol.hasInstance](obj)`. It should return either `true` or `false`, and we're done. That's how we can customize the behavior of `instanceof`. +1. ํด๋ž˜์Šค์— ์ •์  ๋ฉ”์„œ๋“œ `Symbol.hasInstance`๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์œผ๋ฉด, `obj instanceof Class`๋ฌธ์ด ์‹คํ–‰๋  ๋•Œ, `Class[Symbol.hasInstance](obj)`๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋Š” `true`๋‚˜ `false`์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ทœ์น™์„ ๊ธฐ๋ฐ˜์œผ๋กœ `instanceof`์˜ ๋™์ž‘์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - For example: + ์˜ˆ์‹œ: ```js run - // setup instanceOf check that assumes that - // anything with canEat property is an animal + // canEat ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์œผ๋ฉด animal์ด๋ผ๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก + // instanceOf์˜ ๋กœ์ง์„ ์ง์ ‘ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. class Animal { static [Symbol.hasInstance](obj) { if (obj.canEat) return true; @@ -65,24 +65,24 @@ The algorithm of `obj instanceof Class` works roughly as follows: let obj = { canEat: true }; - alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called + alert(obj instanceof Animal); // true, Animal[Symbol.hasInstance](obj)๊ฐ€ ํ˜ธ์ถœ๋จ ``` -2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceOf Class` checks whether `Class.prototype` equals to one of prototypes in the `obj` prototype chain. +2. ๊ทธ๋Ÿฐ๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ํด๋ž˜์Šค์—” `Symbol.hasInstance`๊ฐ€ ๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋• ์ผ๋ฐ˜์ ์ธ ๋กœ์ง์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. `obj instanceOf Class`๋Š” `Class.prototype`์ด `obj` ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์˜ ํ”„๋กœํ† ํƒ€์ž… ์ค‘ ํ•˜๋‚˜์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. - In other words, compare one after another: + ๋น„๊ต๋Š” ์ฐจ๋ก€ ์ฐจ๋ก€ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ```js obj.__proto__ === Class.prototype? obj.__proto__.__proto__ === Class.prototype? obj.__proto__.__proto__.__proto__ === Class.prototype? ... - // if any answer is true, return true - // otherwise, if we reached the end of the chain, return false + // ์ด ์ค‘ ํ•˜๋‚˜๋ผ๋„ true๋ผ๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + // ๊ทธ๋ ‡์ง€ ์•Š๊ณ  ์ฒด์ธ์˜ ๋์— ๋„๋‹ฌํ•˜๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ``` - In the example above `rabbit.__proto__ === Rabbit.prototype`, so that gives the answer immediately. + ์œ„ ์˜ˆ์‹œ์—์„œ `rabbit.__proto__ === Rabbit.prototype`๊ฐ€ `true`์ด๊ธฐ ๋•Œ๋ฌธ์— `instanceof`๋Š” `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - In the case of an inheritance, the match will be at the second step: + ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—” ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ์ผ์น˜ ์—ฌ๋ถ€๊ฐ€ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ```js run class Animal {} @@ -95,74 +95,74 @@ The algorithm of `obj instanceof Class` works roughly as follows: // rabbit.__proto__ === Rabbit.prototype *!* - // rabbit.__proto__.__proto__ === Animal.prototype (match!) + // rabbit.__proto__.__proto__ === Animal.prototype (์ผ์น˜!) */!* ``` -Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`: +์•„๋ž˜ ๊ทธ๋ฆผ์€ `rabbit instanceof Animal`์„ ์‹คํ–‰ํ–ˆ์„ ๋•Œ `Animal.prototype`๊ณผ ๋น„๊ต๋˜๋Š” ๋Œ€์ƒ๋“ค์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ![](instanceof.svg) -By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`. +ํ•œํŽธ, `objA`๊ฐ€ `objB`์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ ์–ด๋”˜๊ฐ€์— ์žˆ์œผ๋ฉด `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ, [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf)๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `obj instanceof Class`๋Š” `Class.prototype.isPrototypeOf(obj)`์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters. +`isPrototypeOf`๋Š” `Class` ์ƒ์„ฑ์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ํฌํ•จ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ์ ์ด ์กฐ๊ธˆ ํŠน์ดํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์‚ฌ ์‹œ, ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ๊ณผ `Class.prototype`๋งŒ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. -That can lead to interesting consequences when `prototype` property is changed after the object is created. +`isPrototypeOf`์˜ ์ด๋Ÿฐ ํŠน์ง•์€ ๊ฐ์ฒด ์ƒ์„ฑ ํ›„ `prototype` ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ ํŠน์ดํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . -Like here: +์˜ˆ์‹œ: ```js run function Rabbit() {} let rabbit = new Rabbit(); -// changed the prototype +// ํ”„๋กœํ† ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋จ Rabbit.prototype = {}; -// ...not a rabbit any more! +// ๋” ์ด์ƒ Rabbit์ด ์•„๋‹™๋‹ˆ๋‹ค! *!* alert( rabbit instanceof Rabbit ); // false */!* ``` -## Bonus: Object.prototype.toString for the type +## ๋ณด๋„ˆ์Šค: ํƒ€์ž… ํ™•์ธ์„ ์œ„ํ•œ Object.prototype.toString -We already know that plain objects are converted to string as `[object Object]`: +์ผ๋ฐ˜ ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™”ํ•˜๋ฉด `[object Object]`๊ฐ€ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒ๋‹ˆ๋‹ค. ```js run let obj = {}; alert(obj); // [object Object] -alert(obj.toString()); // the same +alert(obj.toString()); // ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋จ ``` -That's their implementation of `toString`. But there's a hidden feature that makes `toString` actually much more powerful than that. We can use it as an extended `typeof` and an alternative for `instanceof`. +์ด๋ ‡๊ฒŒ `[object Object]`๊ฐ€ ๋˜๋Š” ์ด์œ ๋Š” `toString`์˜ ๊ตฌํ˜„๋ฐฉ์‹ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `toString`์—” `toString`์„ ๋” ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์ˆจ๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. `toString`์˜ ์ˆจ๊ฒจ์ง„ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ™•์žฅ `typeof`, `instanceof`์˜ ๋Œ€์•ˆ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Sounds strange? Indeed. Let's demystify. +์•„์ง ๊ฐ์ด ์•ˆ ์žกํžˆ์‹œ๊ฒ ์ง€๋งŒ, ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), the built-in `toString` can be extracted from the object and executed in the context of any other value. And its result depends on that value. +[๋ช…์„ธ์„œ](https://tc39.github.io/ecma262/#sec-object.prototype.tostring)์— ๋”ฐ๋ฅด๋ฉด, ๊ฐ์ฒด์—์„œ ๋‚ด์žฅ `toString`์„ ์ถ”์ถœํ•˜๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ถ”์ถœํ•œ ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ๊ฐ’์„ ๋Œ€์ƒ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋Š” ๊ฐ’์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -- For a number, it will be `[object Number]` -- For a boolean, it will be `[object Boolean]` -- For `null`: `[object Null]` -- For `undefined`: `[object Undefined]` -- For arrays: `[object Array]` -- ...etc (customizable). +- ์ˆซ์žํ˜• -- `[object Number]` +- ๋ถˆ๋ฆฐํ˜• -- `[object Boolean]` +- `null` -- `[object Null]` +- `undefined` -- `[object Undefined]` +- ๋ฐฐ์—ด -- `[object Array]` +- ๊ทธ์™ธ -- ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅ -Let's demonstrate: +์˜ˆ์‹œ: ```js run -// copy toString method into a variable for convenience +// ํŽธ์˜๋ฅผ ์œ„ํ•ด toString ๋ฉ”์„œ๋“œ๋ฅผ ๋ณ€์ˆ˜์— ๋ณต์‚ฌํ•จ let objectToString = Object.prototype.toString; -// what type is this? +// ์•„๋ž˜ ๋ณ€์ˆ˜์˜ ํƒ€์ž…์€ ๋ฌด์—‡์ผ๊นŒ์š”? let arr = []; alert( objectToString.call(arr) ); // [object *!*Array*/!*] ``` -Here we used [call](mdn:js/function/call) as described in the chapter [](info:call-apply-decorators) to execute the function `objectToString` in the context `this=arr`. +[](info:call-apply-decorators) ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•œ [call](mdn:js/function/call)์„ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ๋ฅผ `this=arr`๋กœ ์„ค์ •ํ•˜๊ณ  ํ•จ์ˆ˜ `objectToString`๋ฅผ ์‹คํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. -Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples: +`toString` ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‚ด๋ถ€์ ์œผ๋กœ `this`๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  ์ƒ์‘ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋ฅผ ๋” ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run let s = Object.prototype.toString; @@ -174,9 +174,9 @@ alert( s.call(alert) ); // [object Function] ### Symbol.toStringTag -The behavior of Object `toString` can be customized using a special object property `Symbol.toStringTag`. +ํŠน์ˆ˜ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ `Symbol.toStringTag`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `toString`์˜ ๋™์ž‘์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js run let user = { @@ -186,33 +186,33 @@ let user = { alert( {}.toString.call(user) ); // [object User] ``` -For most environment-specific objects, there is such a property. Here are few browser specific examples: +๋Œ€๋ถ€๋ถ„์˜ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์€ ์ž์ฒด ๊ฐ์ฒด์— ์ด์™€ ์œ ์‚ฌํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•ด ๋†“๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ๊ด€๋ จ ์˜ˆ์‹œ ๋ช‡ ๊ฐ€์ง€๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run -// toStringTag for the environment-specific object and class: -alert( window[Symbol.toStringTag]); // window +// ํŠน์ • ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์˜ ๊ฐ์ฒด์™€ ํด๋ž˜์Šค์— ๊ตฌํ˜„๋œ toStringTag +alert( window[Symbol.toStringTag]); // Window alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest alert( {}.toString.call(window) ); // [object Window] alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest] ``` -As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`. +์‹คํ–‰ ๊ฒฐ๊ณผ์—์„œ ๋ณด๋“ฏ์ด ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ ๊ณ ์œ  ๊ฐ์ฒด์˜ `Symbol.toStringTag` ๊ฐ’์€ `[object ...]`๋กœ ์Œ“์—ฌ์ง„ ๊ฐ’๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -At the end we have "typeof on steroids" that not only works for primitive data types, but also for built-in objects and even can be customized. +์ด์ฒ˜๋Ÿผ 'typeof' ์—ฐ์‚ฐ์ž์˜ ๊ฐ•๋ ฅํ•œ ๋ณ€ํ˜•๋“ค(`toString`๊ณผ `toStringTag` - ์˜ฎ๊ธด์ด)์€ ์›์‹œ ์ž๋ฃŒํ˜•๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚ด์žฅ ๊ฐ์ฒด์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•๊นŒ์ง€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -We can use `{}.toString.call` instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check. +๋‚ด์žฅ ๊ฐ์ฒด์˜ ํƒ€์ž… ํ™•์ธ์„ ๋„˜์–ด์„œ ํƒ€์ž…์„ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด `instanceof` ๋Œ€์‹ , `{}.toString.call`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -Let's summarize the type-checking methods that we know: +์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ํƒ€์ž… ํ™•์ธ ๋ฉ”์„œ๋“œ๋ฅผ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -| | works for | returns | +| | ๋™์ž‘ ๋Œ€์ƒ | ๋ฐ˜ํ™˜๊ฐ’ | |---------------|-------------|---------------| -| `typeof` | primitives | string | -| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string | -| `instanceof` | objects | true/false | +| `typeof` | ์›์‹œํ˜• | ๋ฌธ์ž์—ด | +| `{}.toString` | ์›์‹œํ˜•, ๋‚ด์žฅ ๊ฐ์ฒด, `Symbol.toStringTag`๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด | ๋ฌธ์ž์—ด | +| `instanceof` | ๊ฐ์ฒด | true๋‚˜ false | -As we can see, `{}.toString` is technically a "more advanced" `typeof`. +์˜ˆ์‹œ์—์„œ ๋ณด์•˜๋“ฏ์ด `{}.toString`์€ `typeof`๋ณด๋‹ค '๊ธฐ๋Šฅ์ด ๋”' ๋งŽ์Šต๋‹ˆ๋‹ค. -And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance. +`instanceof` ์—ฐ์‚ฐ์ž๋Š” ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋‚˜ ํด๋ž˜์Šค์˜ ์ƒ์† ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ณ ์ž ํ•  ๋•Œ ๊ทธ ์ง„๊ฐ€๋ฅผ ๋ฐœํœ˜ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/06-instanceof/instanceof.svg b/1-js/09-classes/06-instanceof/instanceof.svg index 8b63f20709..d63b03a8a2 100644 --- a/1-js/09-classes/06-instanceof/instanceof.svg +++ b/1-js/09-classes/06-instanceof/instanceof.svg @@ -1 +1 @@ -Animal.prototypeObject.prototypeRabbit.prototype[[Prototype]]rabbit[[Prototype]][[Prototype]]null[[Prototype]]= Animal.prototype? \ No newline at end of file +Animal.prototypeObject.prototypeRabbit.prototype[[Prototype]]rabbit[[Prototype]][[Prototype]]null[[Prototype]]= Animal.prototype? \ No newline at end of file diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 3be78c6272..5f86b2beb8 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -1,26 +1,26 @@ -# Mixins +# ๋ฏน์Šค์ธ -In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹จ์ผ์ƒ์†๋งŒ์„ ํ—ˆ์šฉํ•˜๋Š” ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด์—” ๋‹จ ํ•˜๋‚˜์˜ `[[Prototype]]`๋งŒ ์žˆ์„ ์ˆ˜ ์žˆ๊ณ , ํด๋ž˜์Šค๋Š” ํด๋ž˜์Šค ํ•˜๋‚˜๋งŒ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`. +๊ทธ๋Ÿฐ๋ฐ ๊ฐ€๋” ์ด๋Ÿฐ ์ œ์•ฝ์ด ํ•œ๊ณ„์ฒ˜๋Ÿผ ๋А๊ปด์งˆ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ด…์‹œ๋‹ค. ํด๋ž˜์Šค `StreetSweeper`(๋„์‹œ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ์ฒญ์†Œํ•˜๋Š” ์ฐจ๋Ÿ‰ - ์˜ฎ๊ธด์ด)์™€ ํด๋ž˜์Šค `Bicycle`์ด ์žˆ๋Š”๋ฐ, ์ด ๋‘˜์„ ์„ž์–ด `StreetSweepingBicycle`๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. -Or we have a class `User` and a class `EventEmitter` that implements event generation, and we'd like to add the functionality of `EventEmitter` to `User`, so that our users can emit events. +๋˜๋Š” ํด๋ž˜์Šค `User`์™€ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์ฝ”๋“œ๊ฐ€ ๋‹ด๊ธด ํด๋ž˜์Šค `EventEmitter`๊ฐ€ ์žˆ๋Š”๋ฐ, `EventEmitter`์˜ ๊ธฐ๋Šฅ์„ `User`์— ์ถ”๊ฐ€ํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋‚ด๋ฟœ์„ ์ˆ˜ ์žˆ๊ฒŒ(emit) ํ•ด์ฃผ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. -There's a concept that can help here, called "mixins". +์ด๋Ÿด ๋•Œ ๋ฏน์Šค์ธ์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. -As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class containing methods that can be used by other classes without a need to inherit from it. +Wikipedia์—์„  [๋ฏน์Šค์ธ(mixin)](https://en.wikipedia.org/wiki/Mixin)์„ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์„ ํ•„์š” ์—†์ด ์ด๋“ค ํด๋ž˜์Šค์— ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ํด๋ž˜์Šค๋ผ๊ณ  ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. -In other words, a *mixin* provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes. +๋‹ค์‹œ ๋งํ•ด์„œ *๋ฏน์Šค์ธ*์€ ํŠน์ • ํ–‰๋™์„ ์‹คํ–‰ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ ๋‹จ๋…์œผ๋กœ ์“ฐ์ด์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ํ–‰๋™์„ ๋”ํ•ด์ฃผ๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -## A mixin example +## ๋ฏน์Šค์ธ ์˜ˆ์‹œ -The simplest way to implement a mixin in JavaScript is to make an object with useful methods, so that we can easily merge them into a prototype of any class. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฏน์Šค์ธ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์œ ์šฉํ•œ ๋ฉ”์„œ๋“œ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ๋‹ด๊ธด ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค์ˆ˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์›ํ•˜๋Š” ํด๋ž˜์Šค์˜ ํ”„๋กœํ† ํƒ€์ž…์— ์‰ฝ๊ฒŒ ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`: +์•„๋ž˜ ์˜ˆ์‹œ์˜ ๋ฏน์Šค์ธ `sayHiMixin`์€ `User`์—๊ฒŒ '์–ธ์–ด ๋Šฅ๋ ฅ'์„ ๋ถ€์—ฌํ•ด์ค๋‹ˆ๋‹ค. ```js run *!* -// mixin +// ๋ฏน์Šค์ธ */!* let sayHiMixin = { sayHi() { @@ -32,7 +32,7 @@ let sayHiMixin = { }; *!* -// usage: +// ์‚ฌ์šฉ๋ฒ•: */!* class User { constructor(name) { @@ -40,14 +40,14 @@ class User { } } -// copy the methods +// ๋ฉ”์„œ๋“œ ๋ณต์‚ฌ Object.assign(User.prototype, sayHiMixin); -// now User can say hi +// ์ด์ œ User๊ฐ€ ์ธ์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. new User("Dude").sayHi(); // Hello Dude! ``` -There's no inheritance, but a simple method copying. So `User` may inherit from another class and also include the mixin to "mix-in" the additional methods, like this: +์ƒ์† ์—†์ด ๋ฉ”์„œ๋“œ๋งŒ ๊ฐ„๋‹จํžˆ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฏน์Šค์ธ์„ ํ™œ์šฉํ•˜๋ฉด `User`๊ฐ€ ์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋™์‹œ์—, ๋ฏน์Šค์ธ์— ๊ตฌํ˜„๋œ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js class User extends Person { @@ -57,9 +57,9 @@ class User extends Person { Object.assign(User.prototype, sayHiMixin); ``` -Mixins can make use of inheritance inside themselves. +๋ฏน์Šค์ธ ์•ˆ์—์„œ ๋ฏน์Šค์ธ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -For instance, here `sayHiMixin` inherits from `sayMixin`: +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `sayHiMixin`์€ `sayMixin`์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. ```js run let sayMixin = { @@ -69,11 +69,11 @@ let sayMixin = { }; let sayHiMixin = { - __proto__: sayMixin, // (or we could use Object.create to set the prototype here) + __proto__: sayMixin, // (Object.create๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํ† ํƒ€์ž…์„ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.) sayHi() { *!* - // call parent method + // ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ */!* super.say(`Hello ${this.name}`); // (*) }, @@ -88,44 +88,44 @@ class User { } } -// copy the methods +// ๋ฉ”์„œ๋“œ ๋ณต์‚ฌ Object.assign(User.prototype, sayHiMixin); -// now User can say hi +// ์ด์ œ User๊ฐ€ ์ธ์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. new User("Dude").sayHi(); // Hello Dude! ``` -Please note that the call to the parent method `super.say()` from `sayHiMixin` (at lines labelled with `(*)`) looks for the method in the prototype of that mixin, not the class. +`sayHiMixin`์—์„œ ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ `super.say()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด(`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„) ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ `sayHiMixin`์˜ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๋Š”๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -Here's the diagram (see the right part): +๊ทธ๋ฆผ์˜ ์šฐ์ธก์„ ๋ด…์‹œ๋‹ค. ![](mixin-inheritance.svg) -That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown on the picture above. +์ด๋Š” `sayHi`์™€ `sayBye`๊ฐ€ ์ƒ์„ฑ๋œ ๊ณณ์ด `sayHiMixin`์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ–ˆ๋”๋ผ๋„, ์ด ๋ฉ”์„œ๋“œ๋“ค์˜ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ธ `[[HomeObject]]`๋Š” ์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ `sayHiMixin`์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. -As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`. +๋ฉ”์„œ๋“œ์˜ `super`๊ฐ€ `[[HomeObject]].[[Prototype]]`๋‚ด์—์„œ ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”์„œ๋“œ๋Š” `User.[[Prototype]]`์ด ์•„๋‹Œ `sayHiMixin.[[Prototype]]`์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. -## EventMixin +## ์ด๋ฒคํŠธ ๋ฏน์Šค์ธ -Now let's make a mixin for real life. +์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฏน์Šค์ธ์„ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. -An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object. +์ƒ๋‹น์ˆ˜ ๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑ์ด๋ผ๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๋Š” ์ •๋ณด๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ๊ณณ์— '์ •๋ณด๋ฅผ ๋„๋ฆฌ ์•Œ๋ฆฌ๋Š”(broadcast)' ํ›Œ๋ฅญํ•œ ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„  ํด๋ž˜์Šค๋‚˜ ๊ฐ์ฒด์— ์ด๋ฒคํŠธ ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋ฏน์Šค์ธ์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data. -- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from `.trigger` call. -- ...And the method `.off(name, handler)` that removes the `handler` listener. +- ๋ฏน์Šค์ธ์€ ๋ญ”๊ฐ€ ์ค‘์š”ํ•œ ์ผ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ '์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š”' ๋ฉ”์„œ๋“œ, `.trigger(name, [...data])`๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜ `name`์€ ์ด๋ฒคํŠธ ์ด๋ฆ„์ด๊ณ , ๋’ค๋”ฐ๋ฅด๋Š” ์„ ํƒ ์ธ์ˆ˜๋Š” ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ์ •๋ณด๋ฅผ ๋‹ด์Šต๋‹ˆ๋‹ค. +- ๋ฉ”์„œ๋“œ `.on(name, handler)`์€ `name`์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฒคํŠธ์— ๋ฆฌ์Šค๋„ˆ๋กœ `handler` ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. `.on()`์€ ์ด๋ฒคํŠธ(`name`)๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ ๋  ๋•Œ ํ˜ธ์ถœ๋˜๊ณ , `.trigger` ํ˜ธ์ถœ์—์„œ ์ธ์ˆ˜๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. +- ๋ฉ”์„œ๋“œ `.off(name, handler)`๋Š” `handler` ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. -After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person. +๋ฏน์Šค์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•  ๋•Œ ๊ฐ์ฒด `user`๊ฐ€ `"login"`์ด๋ผ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด `calendar`๋Š” `user`๊ฐ€ ์ƒ์„ฑํ•œ ์ด๋ฒคํŠธ์ธ `"login"`์„ ๋“ฃ๊ณ  ์‚ฌ์šฉ์ž์— ๋งž๋Š” ๋‹ฌ๋ ฅ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๊ฒ ์ฃ . -Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may assign handlers to react on that event. And so on. +๋ฉ”๋‰ด์˜ ํ•ญ๋ชฉ์„ ์„ ํƒํ–ˆ์„ ๋•Œ ๊ฐ์ฒด `menu`๊ฐ€ `"select"`๋ผ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๋‹ค๋ฅธ ๊ฐ์ฒด๋Š” `"select"`์— ๋ฐ˜์‘ํ•˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜๋„ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋ฏน์Šค์ธ์€ ์ด๋Ÿฐ ์šฉ๋„๋กœ ํ™œ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -Here's the code: +์ด๋ฒคํŠธ ๋ฏน์Šค์ธ์„ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค. ```js run let eventMixin = { /** - * Subscribe to event, usage: - * menu.on('select', function(item) { ... } + * ์ด๋ฒคํŠธ ๊ตฌ๋… + * ์‚ฌ์šฉํŒจํ„ด: menu.on('select', function(item) { ... } */ on(eventName, handler) { if (!this._eventHandlers) this._eventHandlers = {}; @@ -136,11 +136,11 @@ let eventMixin = { }, /** - * Cancel the subscription, usage: - * menu.off('select', handler) + * ๊ตฌ๋… ์ทจ์†Œ + * ์‚ฌ์šฉํŒจํ„ด: menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for (let i = 0; i < handlers.length; i++) { if (handlers[i] === handler) { @@ -150,59 +150,59 @@ let eventMixin = { }, /** - * Generate an event with the given name and data - * this.trigger('select', data1, data2); + * ์ฃผ์–ด์ง„ ์ด๋ฆ„๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฒคํŠธ ์ƒ์„ฑ + * ์‚ฌ์šฉํŒจํ„ด: this.trigger('select', data1, data2); */ trigger(eventName, ...args) { - if (!this._eventHandlers || !this._eventHandlers[eventName]) { + if (!this._eventHandlers?.[eventName]) { return; // no handlers for that event name } - // call the handlers + // ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœ this._eventHandlers[eventName].forEach(handler => handler.apply(this, args)); } }; ``` -- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list. -- `.off(eventName, handler)` -- removes the function from the handlers list. -- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`. +- `.on(eventName, handler)` -- `eventName`์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์‹คํ–‰์‹œํ‚ฌ ํ•จ์ˆ˜ `handler`๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ํ•œ ์ด๋ฒคํŠธ์— ๋Œ€์‘ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์„ ๋•Œ, ํ”„๋กœํผํ‹ฐ `_eventHandlers`๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ฐฐ์—ด์— ์ถ”๊ฐ€๋งŒ ๋ฉ๋‹ˆ๋‹ค. +- `.off(eventName, handler)` -- ํ•ธ๋“ค๋Ÿฌ ๋ฆฌ์ŠคํŠธ์—์„œ `handler`๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. +- `.trigger(eventName, ...args)` -- ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. `_eventHandlers[eventName]`์— ์žˆ๋Š” ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ `...args`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -Usage: +์‚ฌ์šฉ๋ฒ•: ```js run -// Make a class +// ํด๋ž˜์Šค ์ƒ์„ฑ class Menu { choose(value) { this.trigger("select", value); } } -// Add the mixin with event-related methods +// ์ด๋ฒคํŠธ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ตฌํ˜„๋œ ๋ฏน์Šค์ธ ์ถ”๊ฐ€ Object.assign(Menu.prototype, eventMixin); let menu = new Menu(); -// add a handler, to be called on selection: +// ๋ฉ”๋‰ด ํ•ญ๋ชฉ์„ ์„ ํƒํ•  ๋•Œ ํ˜ธ์ถœ๋  ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ *!* -menu.on("select", value => alert(`Value selected: ${value}`)); +menu.on("select", value => alert(`์„ ํƒ๋œ ๊ฐ’: ${value}`)); */!* -// triggers the event => the handler above runs and shows: -// Value selected: 123 +// ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ ๋˜๋ฉด ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜์–ด ์–ผ๋Ÿฟ์ฐฝ์ด ๋œธ +// ์–ผ๋Ÿฟ์ฐฝ ๋ฉ”์‹œ์ง€: Value selected: 123 menu.choose("123"); ``` -Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`. +์ด์ œ `menu.on(...)`์„ ์‚ฌ์šฉํ•ด ๋ฉ”๋‰ด ์„ ํƒ์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๋“ค์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ , ์ด์— ๋ฐ˜์‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain. +๊ทธ๋ฆฌ๊ณ  ๋ฏน์Šค์ธ `eventMixin`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ๋™์ž‘์„ ์ƒ์† ์ฒด์ด๋‹์— ๋ผ์–ด๋“ค์ง€ ์•Š๊ณ ๋„ ์›ํ•˜๋Š” ํด๋ž˜์Šค์— ๋ชจ๋‘์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes. +*๋ฏน์Šค์ธ* ์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์—์„œ ๋ฒ”์šฉ์ ์œผ๋กœ ์“ฐ์ด๋Š” ์šฉ์–ด๋กœ, ๋‹ค๋ฅธ ํด๋ž˜์Šค๋“ค์˜ ๋ฉ”์„œ๋“œ ์กฐํ•ฉ์„ ํฌํ•จํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype. +๋ช‡๋ช‡ ์–ธ์–ด๋Š” ๋‹ค์ค‘์ƒ์†์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์ค‘์ƒ์†์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋ฐ, ๋ฏน์Šค์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ๋ณต์‚ฌํ•ด ํ”„๋กœํ† ํƒ€์ž…์— ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above. +์ด๋ฒคํŠธ ๋ฏน์Šค์ธ ์˜ˆ์‹œ์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ, ๋ฏน์Šค์ธ์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ๋“ฑ์˜ ํ–‰๋™์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening. +mixin์ด ์‹ค์ˆ˜๋กœ ๊ธฐ์กด ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ๋ฎ์–ด์“ฐ๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ mixin์„ ๋งŒ๋“ค ๋• ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์ •ํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html index 77ea38b204..20e3a63547 100644 --- a/1-js/09-classes/07-mixins/head.html +++ b/1-js/09-classes/07-mixins/head.html @@ -18,7 +18,7 @@ * menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for(let i = 0; i < handlers.length; i++) { if (handlers[i] == handler) { diff --git a/1-js/09-classes/07-mixins/mixin-inheritance.svg b/1-js/09-classes/07-mixins/mixin-inheritance.svg index aaa8cb7d0d..1fdc223936 100644 --- a/1-js/09-classes/07-mixins/mixin-inheritance.svg +++ b/1-js/09-classes/07-mixins/mixin-inheritance.svg @@ -1 +1 @@ -sayHi: function sayBye: functionsayHiMixinsay: functionsayMixin[[Prototype]]constructor: User sayHi: function sayBye: functionUser.prototype[[Prototype]]name: ...user[[HomeObject] \ No newline at end of file +sayHi: function sayBye: functionsayHiMixinsay: functionsayMixin[[Prototype]]constructor: User sayHi: function sayBye: functionUser.prototype[[Prototype]]name: ...user[[HomeObject] \ No newline at end of file diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md index 303431d6d0..ad3197d848 100644 --- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md +++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md @@ -1,47 +1,47 @@ -The difference becomes obvious when we look at the code inside a function. +์ฐจ์ด์ ์€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ถ„๋ช…ํ•ด์ง‘๋‹ˆ๋‹ค. -The behavior is different if there's a "jump out" of `try..catch`. +`try..catch`์— '๋น ์ ธ๋‚˜์˜ค๊ฒŒ ํ•˜๋Š”' ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•จ์ˆ˜์˜ ํ–‰๋™์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -For instance, when there's a `return` inside `try..catch`. The `finally` clause works in case of *any* exit from `try..catch`, even via the `return` statement: right after `try..catch` is done, but before the calling code gets the control. +์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `try..catch` ๋‚ด๋ถ€์— `return`์ด ์žˆ์„ ๋•Œ๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. `finally` ์ ˆ์€ `return`๋ฌธ์„ ํ†ตํ•ด `try..catch`๋ฅผ ๋น ์ ธ๋‚˜๊ฐ€๋Š” ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•˜์—ฌ `try..catch`๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” *๋ชจ๋“ * ์ƒํ™ฉ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `try..catch`๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์ง€๋งŒ, ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ฝ”๋“œ๊ฐ€ ์ œ์–ด๊ถŒ์„ ๊ฐ–๊ธฐ ์ง์ „์— ์‹คํ–‰๋˜์ฃ . ```js run function f() { try { - alert('start'); + alert('์‹œ์ž‘'); *!* - return "result"; + return "๊ฒฐ๊ณผ"; */!* } catch (e) { /// ... } finally { - alert('cleanup!'); + alert('์ดˆ๊ธฐํ™”!'); } } f(); // cleanup! ``` -...Or when there's a `throw`, like here: +๋˜๋Š”, ์•„๋ž˜์™€ ๊ฐ™์ด `throw`๊ฐ€ ์žˆ์–ด๋„ ํ•จ์ˆ˜์˜ ํ–‰๋™์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ```js run function f() { try { - alert('start'); - throw new Error("an error"); + alert('์‹œ์ž‘'); + throw new Error("์—๋Ÿฌ ๋ฐœ์ƒ!"); } catch (e) { // ... - if("can't handle the error") { + if("์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋ง ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด") { *!* throw e; */!* } } finally { - alert('cleanup!') + alert('์ดˆ๊ธฐํ™”!') } } f(); // cleanup! ``` -It's `finally` that guarantees the cleanup here. If we just put the code at the end of `f`, it wouldn't run in these situations. +์ด๋ ‡๊ฒŒ `finally` ์ ˆ์„ ๋ถ™์—ฌ์ค˜์•ผ ์ดˆ๊ธฐํ™”๊ฐ€ ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค. ์ž‘์—… ๋‚ด์—ญ์„ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํžˆ `f`์˜ ๋์— ๋ถ™์˜€๋‹ค๋ฉด, ์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์ผ ๋•Œ ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md index c573cc2327..b9e5324615 100644 --- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md +++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md @@ -2,37 +2,37 @@ importance: 5 --- -# Finally or just the code? +# finally ์•„๋‹ˆ๋ฉด ์ฝ”๋“œ๋งŒ? -Compare the two code fragments. +๋‘ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๋น„๊ตํ•ด๋ณด์„ธ์š”. -1. The first one uses `finally` to execute the code after `try..catch`: +1. ์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ ์กฐ๊ฐ์€ `try..catch` ์ดํ›„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด `finally`๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. ```js try { - work work + ์ž‘์—… } catch (e) { - handle errors + ์—๋Ÿฌ ํ•ธ๋“ค๋ง } finally { *!* - cleanup the working space + ์ž‘์—… ๋‚ด์—ญ ์‚ญ์ œ */!* } ``` -2. The second fragment puts the cleaning right after `try..catch`: +2. ๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ ์กฐ๊ฐ์—์„  `try..catch` ๋ฐ”๋กœ ์•„๋ž˜์— ์ž‘์—… ๋‚ด์—ญ์„ ์‚ญ์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋†“์•˜์Šต๋‹ˆ๋‹ค. ```js try { - work work + ์ž‘์—… } catch (e) { - handle errors + ์—๋Ÿฌ ํ•ธ๋“ค๋ง } *!* - cleanup the working space + ์ž‘์—… ๋‚ด์—ญ ์‚ญ์ œ */!* ``` -We definitely need the cleanup after the work, doesn't matter if there was an error or not. +ํ˜„์žฌ ์ƒํ™ฉ์€ ์—๋Ÿฌ์˜ ์œ ๋ฌด์™€ ์ƒ๊ด€์—†์ด, ์ž‘์—… ํ›„ ์ดˆ๊ธฐํ™”๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. -Is there an advantage here in using `finally` or both code fragments are equal? If there is such an advantage, then give an example when it matters. +`finally`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ ์ด ์žˆ์„๊นŒ์š”? ์•„๋‹ˆ๋ฉด ๋‘ ์ฝ”๋“œ ์กฐ๊ฐ์€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”? ๋งŒ์•ฝ ์ด์ ์ด ์žˆ๋‹ค๋ฉด, ์ด์ ์ด ๋“œ๋Ÿฌ๋‚˜๋Š” ์˜ˆ์‹œ๋ฅผ ์ œ์‹œํ•ด ์ฃผ์„ธ์š”. diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md index ddafd06fba..2a43345582 100644 --- a/1-js/10-error-handling/1-try-catch/article.md +++ b/1-js/10-error-handling/1-try-catch/article.md @@ -1,14 +1,14 @@ -# "try..catch"๋กœ ์—๋Ÿฌ ํ•ธ๋“ค๋งํ•˜๊ธฐ +# 'try..catch'์™€ ์—๋Ÿฌ ํ•ธ๋“ค๋ง ์•„๋ฌด๋ฆฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Šฅํ•œ ์‚ฌ๋žŒ์ด๋”๋ผ๋„ ์—๋Ÿฌ๊ฐ€ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›์ธ์€ ์•„๋งˆ๋„ ์‹ค์ˆ˜, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ, ์ž˜๋ชป๋œ ์„œ๋ฒ„ ์‘๋‹ต ๋“ฑ์˜ ์ˆ˜์ฒœ๋งŒ ๊ฐ€์ง€ ์ด์œ  ๋•Œ๋ฌธ์ผ ๊ฒ๋‹ˆ๋‹ค. -์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” "์ฃฝ๊ณ " (์ฆ‰์‹œ ์ค‘๋‹จ๋˜๊ณ ), ์ฝ˜์†”์— ์—๋Ÿฌ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. +์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” '์ฃฝ๊ณ '(์ฆ‰์‹œ ์ค‘๋‹จ๋˜๊ณ ), ์ฝ˜์†”์— ์—๋Ÿฌ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. -๊ทธ๋Ÿฌ๋‚˜ `try..catch` ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ณ , ์—๋Ÿฌ๋ฅผ "์žก์•„์„œ(catch)" ๋” ํ•ฉ๋‹นํ•œ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +๊ทธ๋Ÿฌ๋‚˜ `try..catch` ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ณ , ์—๋Ÿฌ๋ฅผ '์žก์•„์„œ(catch)' ๋” ํ•ฉ๋‹นํ•œ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -## "try..catch" ๋ฌธ๋ฒ• +## 'try..catch' ๋ฌธ๋ฒ• -'try..catch' ๊ตฌ๋ฌธ์€ 'try'์™€ 'catch'๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ฃผ์š” ๋ธ”๋ก์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. +'try..catch' ๋ฌธ๋ฒ•์€ 'try'์™€ 'catch'๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ฃผ์š” ๋ธ”๋ก์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ```js try { @@ -22,19 +22,19 @@ try { } ``` -์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜์ฃ . +try..catch ๋™์ž‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. 1. ๋จผ์ €, `try {...}` ์•ˆ์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. 2. ์—๋Ÿฌ๊ฐ€ ์—†๋‹ค๋ฉด, `try` ์•ˆ์˜ ๋งˆ์ง€๋ง‰ ์ค„๊นŒ์ง€ ์‹คํ–‰๋˜๊ณ , `catch` ๋ธ”๋ก์€ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. -3. ์—๋Ÿฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, `try` ์•ˆ ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์ค‘๋‹จ๋˜๊ณ , `catch(err)` ๋ธ”๋ก์œผ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. `err` ๋ณ€์ˆ˜(์•„๋ฌด ์ด๋ฆ„์ด๋‚˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)๋Š” ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€๋ฅผ ์ƒ์„ธํžˆ ์„ค๋ช…ํ•˜๋Š” ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. +3. ์—๋Ÿฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, `try` ์•ˆ ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์ค‘๋‹จ๋˜๊ณ , `catch(err)` ๋ธ”๋ก์œผ๋กœ ์ œ์–ด ํ๋ฆ„์ด ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ๋ณ€์ˆ˜ `err`(์•„๋ฌด ์ด๋ฆ„์ด๋‚˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)๋Š” ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋‹ด๊ธด ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ![](try-catch-flow.svg) -`try {โ€ฆ}` ๋ธ”๋ก ์•ˆ์˜ ์ฝ”๋“œ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด๋„ `catch`์—์„œ ์—๋Ÿฌ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ `try {โ€ฆ}` ๋ธ”๋ก ์•ˆ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ `catch`์—์„œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธ๋Š” ์ฃฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. -- ์•„๋ž˜๋Š” ์—๋Ÿฌ๊ฐ€ ์—†๋Š” ์˜ˆ์ œ๋กœ, `(1)`๊ณผ `(2)`๋ฅผ `alert` ์ฐฝ์— ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +- ์—๋Ÿฌ๊ฐ€ ์—†๋Š” ์˜ˆ์‹œ: `(1)`๊ณผ `(2)`๋ฅผ `alert` ์ฐฝ์— ๋ณด์—ฌ์คŒ ```js run try { @@ -47,11 +47,11 @@ try { } catch(err) { - alert('์—๋Ÿฌ๊ฐ€ ์—†์œผ๋ฏ€๋กœ, catch๋Š” ๋ฌด์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'); // (3) + alert('์—๋Ÿฌ๊ฐ€ ์—†์œผ๋ฏ€๋กœ, catch๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.'); // (3) } ``` -- ์•„๋ž˜๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ๋Š” ์˜ˆ์ œ๋กœ, `(1)`๊ณผ `(3)`์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +- ์—๋Ÿฌ๊ฐ€ ์žˆ๋Š” ์˜ˆ์‹œ: `(1)`๊ณผ `(3)`์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ```js run try { @@ -72,10 +72,10 @@ try { ``` -````warn header="`try..catch`๋Š” ์˜ค์ง ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ์—๋งŒ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค." -`try..catch`๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋ ค๋ฉด, ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰ ๊ฐ€๋Šฅ(runnable)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ ํšจํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ์ด์—ฌ์•ผ ํ•˜์ฃ . +````warn header="`try..catch`๋Š” ์˜ค์ง ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ์—๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." +`try..catch`๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ(runnable) ์ฝ”๋“œ์—๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋Š” ์œ ํšจํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -์ค‘๊ด„ํ˜ธ ์ง์ด ์•ˆ ๋งž๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฝ”๋“œ๊ฐ€ ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ์—” try..catch๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์ค‘๊ด„ํ˜ธ ์ง์ด ์•ˆ ๋งž๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฝ”๋“œ๊ฐ€ ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ์—” `try..catch`๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js run try { @@ -85,14 +85,14 @@ try { } ``` -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ฝ๊ณ  ๋‚œ ํ›„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋Š” "parse-time" ์—๋Ÿฌ๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด ์—๋Ÿฌ๋Š” (ํ•ด๋‹น ์ฝ”๋“œ ์•ˆ์—์„œ) ๋ณต๊ตฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์—”์ง„์ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ๋‚œ ํ›„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋Š” 'parse-time ์—๋Ÿฌ'๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์—”์ง„์€ ์ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— parse-time ์—๋Ÿฌ๋Š” ์ฝ”๋“œ ์•ˆ์—์„œ ๋ณต๊ตฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -๋”ฐ๋ผ์„œ `try..catch`๋Š” ์œ ํšจํ•œ ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์—๋Ÿฌ๋ฅผ "๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ(runtime error)"๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ, "์˜ˆ์™ธ(exception)"๋ผ๊ณ  ๋ถ€๋ฅผ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +`try..catch`๋Š” ์œ ํšจํ•œ ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์—๋Ÿฌ๋ฅผ '๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ(runtime error)' ํ˜น์€ '์˜ˆ์™ธ(exception)'๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ```` ````warn header="`try..catch`๋Š” ๋™๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." -setTimeout์ฒ˜๋Ÿผ "์Šค์ผ€์ค„ ๋œ(scheduled)" ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” `try..catch`์—์„œ ์žก์•„๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +setTimeout์ฒ˜๋Ÿผ '์Šค์ผ€์ค„ ๋œ(scheduled)' ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” `try..catch`์—์„œ ์žก์•„๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ```js run try { @@ -104,15 +104,15 @@ try { } ``` -์™œ๋ƒํ•˜๋ฉด ํ•จ์ˆ˜๋Š” ์—”์ง„์ด ์ด๋ฏธ `try..catch` ๊ตฌ๋ฌธ์„ ๋– ๋‚œ ๋‹ค์Œ์—์•ผ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +`setTimeout`์— ๋„˜๊ฒจ์ง„ ์ต๋ช… ํ•จ์ˆ˜๋Š” ์—”์ง„์ด `try..catch`๋ฅผ ๋– ๋‚œ ๋‹ค์Œ์—์„œ์•ผ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์Šค์ผ€์ค„ ๋œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์˜ˆ์™ธ๋ฅผ ์žก๊ณ  ์‹ถ๋‹ค๋ฉด, `try..catch`๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์Šค์ผ€์ค„ ๋œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์˜ˆ์™ธ๋ฅผ ์žก์œผ๋ ค๋ฉด, `try..catch`๋ฅผ ๋ฐ˜๋“œ์‹œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run setTimeout(function() { try { noSuchVariable; // ์ด์ œ try..catch์—์„œ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! } catch { - alert( "error is caught here!" ); + alert( "์—๋Ÿฌ๋ฅผ ์žก์•˜์Šต๋‹ˆ๋‹ค!" ); } }, 1000); ``` @@ -120,28 +120,28 @@ setTimeout(function() { ## ์—๋Ÿฌ ๊ฐ์ฒด -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์—๋Ÿฌ์˜ ์ƒ์„ธ๋‚ด์šฉ์„ ํฌํ•จํ•œ ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” `catch` ๋ธ”๋ก์— ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. +์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์—๋Ÿฌ ์ƒ์„ธ๋‚ด์šฉ์ด ๋‹ด๊ธด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„, `catch` ๋ธ”๋ก์— ์ด ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ```js try { // ... -} catch(err) { // <-- "์—๋Ÿฌ ๊ฐ์ฒด", err ๋Œ€์‹  ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ๋„ ์“ธ ์ˆ˜ ์žˆ์Œ +} catch(err) { // <-- '์—๋Ÿฌ ๊ฐ์ฒด', err ๋Œ€์‹  ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ๋„ ์“ธ ์ˆ˜ ์žˆ์Œ // ... } ``` -๋ชจ๋“  ๋‚ด์žฅ ์—๋Ÿฌ์— ๋Œ€ํ•ด์„œ, `catch` ๋ธ”๋ก์— ์ „๋‹ฌ๋œ ์—๋Ÿฌ ๊ฐ์ฒด๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. +๋‚ด์žฅ ์—๋Ÿฌ ์ „์ฒด์™€ ์—๋Ÿฌ ๊ฐ์ฒด๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. `name` -: ์—๋Ÿฌ์˜ ์ด๋ฆ„. ์ •์˜๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ผ๋ฉด `"ReferenceError"`๊ฐ€ ์ด๋ฆ„์ด ๋ฉ๋‹ˆ๋‹ค. +: ์—๋Ÿฌ ์ด๋ฆ„. ์ •์˜๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ผ๋ฉด `"ReferenceError"`๊ฐ€ ์ด๋ฆ„์ด ๋ฉ๋‹ˆ๋‹ค. `message` -: ์—๋Ÿฌ์˜ ์ƒ์„ธ ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฌธ์ž ํ˜•ํƒœ์˜ ๋ฉ”์‹œ์ง€. +: ์—๋Ÿฌ ์ƒ์„ธ ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฌธ์ž ๋ฉ”์‹œ์ง€ -๊ทธ ๋ฐ–์— ํ‘œ์ค€์€ ์•„๋‹ˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์—์„œ ์ง€์›ํ•˜๋Š” ๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `stack`์€ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. +ํ‘œ์ค€์€ ์•„๋‹ˆ์ง€๋งŒ, `name`๊ณผ `message` ์ด์™ธ์— ๋Œ€๋ถ€๋ถ„์˜ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `stack`์€ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. `stack` -: ํ˜„์žฌ ํ˜ธ์ถœ ์Šคํƒ. ์—๋Ÿฌ๋ฅผ ์œ ๋ฐœํ•œ ์ค‘์ฒฉ ํ˜ธ์ถœ๋“ค์˜ ์ˆœ์„œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ ๋ฌธ์ž์—ด๋กœ, ๋””๋ฒ„๊น… ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +: ํ˜„์žฌ ํ˜ธ์ถœ ์Šคํƒ. ์—๋Ÿฌ๋ฅผ ์œ ๋ฐœํ•œ ์ค‘์ฒฉ ํ˜ธ์ถœ๋“ค์˜ ์ˆœ์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ ๋ฌธ์ž์—ด๋กœ ๋””๋ฒ„๊น… ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -153,7 +153,7 @@ try { } catch(err) { alert(err.name); // ReferenceError alert(err.message); // lalala is not defined - alert(err.stack); // ReferenceError: lalala is not defined at (...call stack) + alert(err.stack); // ReferenceError: lalala is not defined at ... (ํ˜ธ์ถœ ์Šคํƒ) // ์—๋Ÿฌ ์ „์ฒด๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. // ์ด๋•Œ, ์—๋Ÿฌ ๊ฐ์ฒด๋Š” "name: message" ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. @@ -161,7 +161,7 @@ try { } ``` -## "catch"์—์„œ ์—๋Ÿฌ๊ฐ์ฒด ์ƒ๋žตํ•˜๊ธฐ +## ์„ ํƒ์  'catch' ๋ฐ”์ธ๋”ฉ [recent browser=new] @@ -170,18 +170,18 @@ try { ```js try { // ... -} catch { // <-- (err) ์—†์ด ์“ฐ์ž„ +} catch { // <-- (err) ์—†์ด ์“ธ ์ˆ˜ ์žˆ์Œ // ... } ``` -## "try..catch" ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ +## 'try..catch' ์‚ฌ์šฉํ•˜๊ธฐ -`try..catch`๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. +`try..catch`๊ฐ€ ์‹ค๋ฌด์—์„œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. ์•ž์„œ JSON์œผ๋กœ ์ธ์ฝ”๋”ฉ๋œ ๊ฐ’์„ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” [JSON.parse(str)](mdn:js/JSON/parse) ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ๋ฐฐ์šด ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ๋กœ ์„œ๋ฒ„ ๋“ฑ์˜ ์ถœ์ฒ˜์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ๋กœ ์„œ๋ฒ„ ๋“ฑ์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ์— `JSON.parse`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹์œผ๋กœ ์‚ฌ์šฉ๋˜์ฃ . @@ -192,20 +192,20 @@ let json = '{"name":"John", "age": 30}'; // ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ด let user = JSON.parse(json); // ์ „๋‹ฌ๋ฐ›์€ ๋ฌธ์ž์—ด์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ */!* -// ๋ฌธ์ž์—ด๋กœ ์ „๋‹ฌ๋ฐ›์€ user๊ฐ€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ user ๊ฐ์ฒด๊ฐ€ ๋จ +// ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ „๋‹ฌ๋ฐ›์€ user๊ฐ€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๊ฐ€ ๋จ alert( user.name ); // John alert( user.age ); // 30 ``` -JSON์— ๊ด€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +JSON์— ๊ด€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” ์ฑ•ํ„ฐ์—์„œ ์ฝ์–ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -**`json`์ด ์ž˜๋ชป ๋งŒ๋“ค์–ด์ง„ ๊ฒฝ์šฐ `JSON.parse`์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ "์ฃฝ์Šต๋‹ˆ๋‹ค".** +**์ž˜๋ชป๋œ ํ˜•์‹์˜ `json`์ด ๋“ค์–ด์˜จ ๊ฒฝ์šฐ, `JSON.parse`๋Š” ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธ๊ฐ€ '์ฃฝ์Šต๋‹ˆ๋‹ค'.** ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š” ๊ฒƒ์— ๋งŒ์กฑํ•ด์•ผ ํ• ๊นŒ์š”? ๋‹น์—ฐํžˆ ์•„๋‹ˆ์ฃ ! -์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์—์„œ ์ „๋‹ฌ๋ฐ›์•„ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š”๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๋Š” (๊ฐœ๋ฐœ์ž ์ฝ˜์†”์„ ์—ด์ง€ ์•Š๋Š” ์ด์ƒ) ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š” ์›์ธ์ด ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ ๋•Œ๋ฌธ์ด๋ž€ ๊ฑธ ์ ˆ๋Œ€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ ์—๋Ÿฌ์˜ ์›์ธ์„ ์•Œ๋ ค์ฃผ๋Š” ๋ฉ”์‹œ์ง€ ์—†์ด ๋ฌด์–ธ๊ฐ€๊ฐ€ "๊ทธ๋ƒฅ ์ฃฝ๋Š”" ๊ฒƒ์„ ์ •๋ง ์‹ซ์–ดํ•˜์ฃ . +์„œ๋ฒ„์—์„œ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜๋ชป๋˜์–ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋Š” ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๋Š” ๊ฐœ๋ฐœ์ž ์ฝ˜์†”์„ ์—ด์ง€ ์•Š๋Š” ์ด์ƒ ์ ˆ๋Œ€ ์›์ธ์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ๋žŒ๋“ค์€ ๋ฉ”์‹œ์ง€ ๋“ฑ์„ ํ†ตํ•ด ์—๋Ÿฌ์˜ ์›์ธ์„ ์•Œ์ง€ ๋ชปํ•œ ์ฑ„ ๋ฌด์–ธ๊ฐ€๊ฐ€ '๊ทธ๋ƒฅ ์ฃฝ๋Š” ๊ฒƒ'์„ ์ •๋ง ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. -`try..catch`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด ๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. +`try..catch`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฅผ ์ฒ˜๋ฆฌํ•ด ๋ด…์‹œ๋‹ค. ```js run let json = "{ bad json }"; @@ -213,25 +213,25 @@ let json = "{ bad json }"; try { *!* - let user = JSON.parse(json); // <-- ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + let user = JSON.parse(json); // <-- ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ */!* - alert( user.name ); // ๋”ฐ๋ผ์„œ ์ด ์ฝ”๋“œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ , + alert( user.name ); // ์ด ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. } catch (e) { *!* - // ๋ฐ”๋กœ catch ๋ฌธ์œผ๋กœ ๋„˜์–ด์˜ต๋‹ˆ๋‹ค. - alert( "๋ฐ์ดํ„ฐ์— ์—๋Ÿฌ๊ฐ€ ์žˆ์–ด ์žฌ์š”์ฒญ์„ ์‹œ๋„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค." ); + // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ œ์–ด ํ๋ฆ„์ด catch ๋ฌธ์œผ๋กœ ๋„˜์–ด์˜ต๋‹ˆ๋‹ค. + alert( "๋ฐ์ดํ„ฐ์— ์—๋Ÿฌ๊ฐ€ ์žˆ์–ด ์žฌ์š”์ฒญ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค." ); alert( e.name ); alert( e.message ); */!* } ``` -์œ„ ์˜ˆ์‹œ์—์„  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฑธ ๋‹จ์ˆœํžˆ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด `catch` ๋ธ”๋ก์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, catch ๋ธ”๋ก ์•ˆ์—์„œ ๋” ๋งŽ์€ ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋ณด๋‚ด๊ธฐ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋Œ€์•ˆ ์ œ์•ˆํ•˜๊ธฐ, ์—๋Ÿฌ ์ •๋ณด๋ฅผ ๋กœ๊น… ์žฅ์น˜์— ๋ณด๋‚ด๊ธฐ ๋“ฑ ๋ง์ด์ฃ . ์ด ๋ชจ๋“  ๊ฒƒ๋“ค์ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ทธ๋ƒฅ ์ฃฝ๋„๋ก ๋†”๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋‚˜์€ ๋Œ€์‘์ž…๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฑธ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๊ฐ„๋‹จํžˆ ์˜ˆ์™ธ์ฒ˜๋ฆฌํ–ˆ์ง€๋งŒ, `catch` ๋ธ”๋ก ์•ˆ์—์„œ ์ƒˆ๋กœ์šด ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋ณด๋‚ด๊ธฐ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋Œ€์•ˆ ์ œ์•ˆํ•˜๊ธฐ, ๋กœ๊น… ์žฅ์น˜์— ์—๋Ÿฌ ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋“ฑ๊ณผ ๊ฐ™์€ ๊ตฌ์ฒด์ ์ธ ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ๋„๋ก ๋†”๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋‚˜์€ ๋Œ€์‘์ด์ฃ . -## ์ž์ฒด ์—๋Ÿฌ ๋˜์ง€๊ธฐ +## ์ง์ ‘ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋˜์ง€๊ธฐ -`json`์ด ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ž˜๋ชป๋˜์ง„ ์•Š์•˜์ง€๋งŒ, ์ฝ”๋“œ ๋‚ด์—์„œ ์“ฐ์ด๊ณ  ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ์ธ `name`์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? +`json`์ด ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ž˜๋ชป๋˜์ง„ ์•Š์•˜์ง€๋งŒ, ์Šคํฌ๋ฆฝํŠธ ๋‚ด์—์„œ ์‚ฌ์šฉ ์ค‘์ธ ํ•„์ˆ˜ ํ”„๋กœํผํ‹ฐ `name`์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด ๋ฌด์Šจ ์ผ์ด ์ƒ๊ธธ๊นŒ์š”? ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . @@ -250,11 +250,11 @@ try { } ``` -`JSON.parse` ๋Š” ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ์— `name`์ด ์—†๋Š” ๊ฑด, ์œ„ ์ฝ”๋“œ์—์„  ์—๋Ÿฌ๋ฅผ ์œ ๋ฐœํ•˜๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„œ `JSON.parse`๋Š” ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ์ง€๋งŒ `name`์ด ์—†๋Š” ๊ฑด ์—๋Ÿฌ๋ฅผ ์œ ๋ฐœํ•˜๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. ์ด์ œ `throw` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ฉํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -### "Throw" ์—ฐ์‚ฐ์ž +### 'throw' ์—ฐ์‚ฐ์ž `throw` ์—ฐ์‚ฐ์ž๋Š” ์—๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. @@ -264,9 +264,9 @@ try { throw ``` -์ด๋ก ์ ์œผ๋กœ๋Š” ์–ด๋–ค ๊ฒƒ์ด๋“  ์—๋Ÿฌ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆซ์ž, ๋ฌธ์ž์—ด ๊ฐ™์€ ์›์‹œ ํƒ€์ž…๋„ ํ—ˆ์šฉ๋˜์ฃ . ํ•˜์ง€๋งŒ ๋˜๋„๋ก (๋‚ด์žฅ ์—๋Ÿฌ์™€์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด) `name`๊ณผ `message` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. +์ด๋ก ์ ์œผ๋กœ๋Š” ์ˆซ์ž, ๋ฌธ์ž์—ด ๊ฐ™์€ ์›์‹œํ˜• ์ž๋ฃŒ๋ฅผ ํฌํ•จํ•œ ์–ด๋–ค ๊ฒƒ์ด๋“  ์—๋Ÿฌ ๊ฐ์ฒด(error object)๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด์žฅ ์—๋Ÿฌ์™€์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด ๋˜๋„๋ก ์—๋Ÿฌ ๊ฐ์ฒด์— `name`๊ณผ `message` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ‘œ์ค€ ์—๋Ÿฌ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” `Error`, `SyntaxError`, `ReferenceError`, `TypeError`๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋‚ด์žฅ ์ƒ์„ฑ์ž๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ƒ์„ฑ์ž๋“ค์„ ์ด์šฉํ•ด ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” `Error`, `SyntaxError`, `ReferenceError`, `TypeError`๋“ฑ์˜ ํ‘œ์ค€ ์—๋Ÿฌ ๊ฐ์ฒด ๊ด€๋ จ ์ƒ์„ฑ์ž๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ƒ์„ฑ์ž๋“ค์„ ์ด์šฉํ•ด ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . @@ -278,35 +278,35 @@ let error = new ReferenceError(message); // ... ``` -์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋‚ด์žฅ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๋‚ด์žฅ ์—๋Ÿฌ ๊ฐ์ฒด์˜ `name` ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž์˜ ์ด๋ฆ„๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. `message`๋Š” ์ธ์ˆ˜์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. +์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋‚ด์žฅ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๋‚ด์žฅ ์—๋Ÿฌ ๊ฐ์ฒด์˜ `name` ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ์ด๋ฆ„๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ `message`์˜ ๊ฐ’์€ ์ธ์ˆ˜์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: ```js run -let error = new Error("Things happen o_O"); +let error = new Error("์ด์ƒํ•œ ์ผ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. o_O"); alert(error.name); // Error -alert(error.message); // Things happen o_O +alert(error.message); // ์ด์ƒํ•œ ์ผ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. o_O ``` ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜์„ ๋•Œ, `JSON.parse`๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š”์ง€ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run try { - JSON.parse("{ bad json o_O }"); + JSON.parse("{ ์ž˜๋ชป๋œ ํ˜•์‹์˜ json o_O }"); } catch(e) { *!* alert(e.name); // SyntaxError */!* - alert(e.message); // Unexpected token o in JSON at position 2 + alert(e.message); // Unexpected token b in JSON at position 2 } ``` `SyntaxError`๊ฐ€ ๋ฐœ์ƒํ•˜๋„ค์š”. -์‚ฌ์šฉ์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด์— `name` ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ, `name`์ด ์—†์œผ๋ฉด error๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์‚ฌ์šฉ์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด์— `name` ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์ด์ œ `name`์ด ์—†์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•ด๋ด…์‹œ๋‹ค. -Throw ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์—๋Ÿฌ๋ฅผ ๋˜์ ธ๋ด…์‹œ๋‹ค: +`throw` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์—๋Ÿฌ๋ฅผ ๋˜์ ธ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let json = '{ "age": 30 }'; // ๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ @@ -328,56 +328,60 @@ try { } ``` -`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `throw` ์—ฐ์‚ฐ์ž๋Š” ์ „๋‹ฌ๋ฐ›์€ `message`๋ฅผ ์ด์šฉํ•ด `SyntaxError`๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋™์ผํ•˜๊ฒŒ ๋ง์ด์ฃ . ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์œผ๋ฏ€๋กœ `try`์˜ ์‹คํ–‰์€ ์ฆ‰์‹œ ์ค‘๋‹จ๋˜๊ณ  ์ด์ œ ์ œ์–ด ํ๋ฆ„์€ `catch`๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `throw` ์—ฐ์‚ฐ์ž๋Š” `message`๋ฅผ ์ด์šฉํ•ด `SyntaxError`๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ ์ƒ์„ฑ ๋ฐฉ์‹์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์œผ๋ฏ€๋กœ `try`์˜ ์‹คํ–‰์€ ์ฆ‰์‹œ ์ค‘๋‹จ๋˜๊ณ  ์ œ์–ด ํ๋ฆ„์ด `catch`๋กœ ๋„˜์–ด๊ฐ„ ๊ฒƒ์„ ์–ผ๋Ÿฟ ์ฐฝ์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„ค์š”. -์ด์ œ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ `catch` ๋ธ”๋ก ์•ˆ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `JSON.parse`์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•ด์„œ ๋ง์ด์ฃ . +์ด์ œ `JSON.parse`์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•ด์„œ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ `catch` ๋ธ”๋ก ์•ˆ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ## ์—๋Ÿฌ ๋‹ค์‹œ ๋˜์ง€๊ธฐ -์œ„ ์˜ˆ์ œ์—์„  `try..catch`๋ฅผ ์‚ฌ์šฉํ•ด ๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ *๋˜ ๋‹ค๋ฅธ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์—๋Ÿฌ*๊ฐ€ `try {...}` ๋ธ”๋ก ์•ˆ์—์„œ ๋ฐœ์ƒํ•˜๋ฉด ํ•  ์ˆ˜๋„ ์žˆ์ง€ ์•Š์„๊นŒ์š”? ์ •์˜ํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋“ฑ์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์€ ํ•ญ์ƒ ์žˆ์Šต๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„  ๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ `try..catch`๋กœ ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ *๋˜ ๋‹ค๋ฅธ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์—๋Ÿฌ*๊ฐ€ `try {...}` ๋ธ”๋ก ์•ˆ์—์„œ ๋ฐœ์ƒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์˜๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ๋“ฑ์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์€ ํ•ญ์ƒ ์žˆ์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ์ฒ˜๋Ÿผ์š”. +์˜ˆ์‹œ: ```js run let json = '{ "age": 30 }'; // ๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ try { - user = JSON.parse(json); // <-- user ์•ž์— let์„ ์“ฐ์ง€ ์•Š์Œ + user = JSON.parse(json); // <-- user ์•ž์— let์„ ๋ถ™์ด๋Š” ๊ฑธ ์žŠ์—ˆ๋„ค์š”. // ... } catch(err) { alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined - // (์‹ค์ œ๋ก  JSON Error๊ฐ€ ์•„๋‹˜์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , JSON Error๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.) + // (์‹ค์ œ๋ก  JSON Error๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.) } ``` -ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์‹ค์ˆ˜๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์–ด๋–ค ์—๋Ÿฌ๋“  ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๋”์ฐํ•œ ํ•ดํ‚น์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ์—„์ฒญ๋‚œ ๋ฒ„๊ทธ๊ฐ€ ๋ช‡์‹ญ ๋…„๊ฐ„ ๋ช‡๋ฐฑ๋งŒ ๋ช…์ด ์‚ฌ์šฉํ•œ ์˜คํ”ˆ์†Œ์Šค ์œ ํ‹ธ๋ฆฌํ‹ฐ์—์„œ๋„ ์กฐ์ฐจ ๋ฐœ๊ฒฌ๋ฉ๋‹ˆ๋‹ค. +์—๋Ÿฌ๋Š” ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๋ช‡์‹ญ ๋…„๊ฐ„ ๋ช‡๋ฐฑ๋งŒ ๋ช…์ด ์‚ฌ์šฉํ•œ ์˜คํ”ˆ์†Œ์Šค ์œ ํ‹ธ๋ฆฌํ‹ฐ์—์„œ๋„ ๋”์ฐํ•œ ํ•ดํ‚น์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ์—„์ฒญ๋‚œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ฃ . + +์œ„์—์„  '๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ'๋ฅผ ๋‹ค๋ฃจ๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ `try..catch`๋ฅผ ์ผ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `catch`๋Š” ์›๋ž˜ `try` ๋ธ”๋ก์—์„œ ๋ฐœ์ƒํ•œ *๋ชจ๋“ * ์—๋Ÿฌ๋ฅผ ์žก์œผ๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์œ„ ์˜ˆ์‹œ์—์„œ `catch`๋Š” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ์žก์•„๋‚ด ์ฃผ๊ธด ํ–ˆ์ง€๋งŒ, ์—๋Ÿฌ ์ข…๋ฅ˜์™€ ๊ด€๊ณ„์—†์ด `"JSON Error"` ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์—๋Ÿฌ ์ข…๋ฅ˜์™€ ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋””๋ฒ„๊น…์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ณ ์ž '๋‹ค์‹œ ๋˜์ง€๊ธฐ(rethrowing)' ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. -์œ„์—์„  "๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ"๋ฅผ ๋‹ค๋ฃจ๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ `try..catch`๋ฅผ ์ผ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `catch`๋Š” ๊ทผ๋ณธ์ ์œผ๋กœ `try` ๋ธ”๋ก์—์„œ ๋ฐœ์ƒํ•œ *๋ชจ๋“ * ์—๋Ÿฌ๋“ค์„ ์žก์Šต๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ catch๋Š” ์—๋Ÿฌ๋ฅผ ์žก์•„๋ƒˆ์ง€๋งŒ, ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์˜ ์ข…๋ฅ˜์— ๊ด€๊ณ„์—†์ด "JSON Error" ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์—๋Ÿฌ ์ข…๋ฅ˜์™€ ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์˜ ๋””๋ฒ„๊น…์€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋””๋ฒ„๊น…์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค์ฃ . +**catch๋Š” ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” '๋‹ค์‹œ ๋˜์ ธ์•ผ' ํ•ฉ๋‹ˆ๋‹ค.** -๋‹คํ–‰ํžˆ๋„, `name` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +'๋‹ค์‹œ ๋˜์ง€๊ธฐ' ๊ธฐ์ˆ ์„ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. + +1. catch๊ฐ€ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. +2. `catch(err) {...}` ๋ธ”๋ก ์•ˆ์—์„œ ์—๋Ÿฌ ๊ฐ์ฒด `err`๋ฅผ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. +3. ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์•Œ์ง€ ๋ชปํ•˜๋ฉด `throw err`๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. + +๋ณดํ†ต ์—๋Ÿฌ ํƒ€์ž…์„ `instanceof` ๋ช…๋ น์–ด๋กœ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค. ```js run try { user = { /*...*/ }; -} catch(e) { +} catch(err) { *!* - alert(e.name); // ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋ ค ํ–ˆ์œผ๋ฏ€๋กœ "ReferenceError"๊ฐ€ ๋ฐœ์ƒ + if (err instanceof ReferenceError) { */!* + alert('ReferenceError'); // ์ •์˜๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜์—ฌ 'ReferenceError' ๋ฐœ์ƒ + } } ``` -๊ทœ์น™์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. - -**catch์—์„  ํƒ€์ž…์„ ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋‚˜๋จธ์ง€ ์—๋Ÿฌ๋Š” ๋ชจ๋‘ "๋‹ค์‹œ ๋˜์ง‘๋‹ˆ๋‹ค."** - -"๋‹ค์‹œ ๋˜์ง€๊ธฐ" ๊ธฐ์ˆ ์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. - -1. catch์—์„œ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. -2. `catch(err) {...}` ๋ธ”๋ก์—์„œ ์—๋Ÿฌ ๊ฐ์ฒด, `err`์„ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. -2. ์—๋Ÿฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ๋ชจ๋ฅด๋Š” ๊ฒฝ์šฐ๋Š” `throw err`๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. +`err.name` ํ”„๋กœํผํ‹ฐ๋กœ ์—๋Ÿฌ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์•Œ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธํ˜• ์—๋Ÿฌ๋Š” ๋ชจ๋‘ `err.name` ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋˜๋Š” `err.constructor.name`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ๋‹ค์‹œ ๋˜์ง€๊ธฐ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ `catch`๋ธ”๋ก์—์„  `SyntaxError`๋งŒ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. +์—๋Ÿฌ๋ฅผ ๋‹ค์‹œ ๋˜์ ธ์„œ `catch` ๋ธ”๋ก์—์„  `SyntaxError`๋งŒ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let json = '{ "age": 30 }'; // ๋ถˆ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ @@ -398,21 +402,21 @@ try { } catch(e) { *!* - if (e.name == "SyntaxError") { + if (e instanceof SyntaxError) { alert( "JSON Error: " + e.message ); } else { - throw e; // rethrow (*) + throw e; // ์—๋Ÿฌ ๋‹ค์‹œ ๋˜์ง€๊ธฐ (*) } */!* } ``` -`catch` ๋ธ”๋ก ์•ˆ์˜ `(*)`๋กœ ํ‘œ์‹œ๋œ ์ค„์—์„œ ๋‹ค์‹œ ๋˜์ ธ์ง„(rethrow) ์—๋Ÿฌ๋Š” `try..catch` "๋ฐ–์œผ๋กœ ๋˜์ ธ์ ธ" ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฃฝ์ž…๋‹ˆ๋‹ค. ๋ฐ”๊นฅ์— `try..catch`๊ฐ€ ์žˆ๋‹ค๋ฉด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฃฝ์ด์ง€ ์•Š๊ณ  ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`catch` ๋ธ”๋ก ์•ˆ์˜ `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ๋‹ค์‹œ ๋˜์ ธ์ง„(rethrow) ์—๋Ÿฌ๋Š” `try..catch` '๋ฐ–์œผ๋กœ ๋˜์ ธ์ง‘๋‹ˆ๋‹ค'. ์ด๋•Œ ๋ฐ”๊นฅ์— `try..catch`๊ฐ€ ์žˆ๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๋ฅผ ์žก์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ผ๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” ์ฃฝ์„ ๊ฒ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ์ง€ ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋“ค๋งŒ `catch` ๋ธ”๋ก์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๋ฅผ "๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค". +์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `catch` ๋ธ”๋ก์—์„  ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ์ง€ ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๋Š” '๊ฑด๋„ˆ๋›ธ ์ˆ˜' ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์ œ๋Š” `try..catch`๋ฅผ ํ•œ ๋ ˆ๋ฒจ ๋” ๋งŒ๋“ค์–ด, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +์ด์ œ `try..catch`๋ฅผ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด, ๋‹ค์‹œ ๋˜์ ธ์ง„ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run function readData() { @@ -425,7 +429,7 @@ function readData() { */!* } catch (e) { // ... - if (e.name != 'SyntaxError') { + if (!(e instanceof SyntaxError)) { *!* throw e; // ์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ ๋‹ค์‹œ ๋˜์ง€๊ธฐ */!* @@ -437,25 +441,25 @@ try { readData(); } catch (e) { *!* - alert( "External catch got: " + e ); // caught it! + alert( "External catch got: " + e ); // ์—๋Ÿฌ๋ฅผ ์žก์Œ */!* } ``` -`readData`์•ˆ์—์„  `SyntaxError`๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋Š” ํ•จ์ˆ˜ ๋ฐ”๊นฅ์˜ `try..catch`์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. +`readData`๋Š” `SyntaxError`๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•จ์ˆ˜ ๋ฐ”๊นฅ์˜ `try..catch`์—์„œ๋Š” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ## try..catch..finally -์ž ๊น๋งŒ์š”, ์ด๊ฒŒ ๋‹ค๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. +์ž ๊น! ์—๋Ÿฌ ํ•ธ๋“ค๋ง์€ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹™๋‹ˆ๋‹ค. `try..catch`๋Š” `finally`๋ผ๋Š” ์ฝ”๋“œ ์ ˆ์„ ํ•˜๋‚˜ ๋” ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -finally ์ ˆ์€ ์•„๋ž˜์˜ ๊ฒฝ์šฐ์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +`finally`์•ˆ์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -- ์—๋Ÿฌ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, `try` ์‹คํ–‰์ด ๋๋‚œ ํ›„ -- ์—๋Ÿฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, `catch` ์‹คํ–‰์ด ๋๋‚œ ํ›„ +- ์—๋Ÿฌ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ: `try` ์‹คํ–‰์ด ๋๋‚œ ํ›„ +- ์—๋Ÿฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ: `catch` ์‹คํ–‰์ด ๋๋‚œ ํ›„ -finally๋ฅผ ์‚ฌ์šฉํ•ด try..catch ๋ฅผ ํ™•์žฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +`finally`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `try..catch`๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js *!*try*/!* { @@ -471,8 +475,8 @@ finally๋ฅผ ์‚ฌ์šฉํ•ด try..catch ๋ฅผ ํ™•์žฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js run try { - alert( 'try' ); - if (confirm('Make an error?')) BAD_CODE(); + alert( 'try ๋ธ”๋ก ์‹œ์ž‘' ); + if (confirm('์—๋Ÿฌ๋ฅผ ๋งŒ๋“œ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) ์ด์ƒํ•œ_์ฝ”๋“œ(); } catch (e) { alert( 'catch' ); } finally { @@ -482,16 +486,16 @@ try { ์œ„ ์ฝ”๋“œ๋Š” ๋‘ ๊ฐ€์ง€ ๊ฒฝ๋กœ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -1. "Make an error?"์— "Yes"๋กœ ๋‹ตํ•˜๋ฉด, `try -> catch -> finally`. -2. "No"๋กœ ํ•˜๋ฉด, `try -> finally`. +1. "์—๋Ÿฌ๋ฅผ ๋งŒ๋“œ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?"์— 'OK'๋กœ ๋‹ตํ•œ ๊ฒฝ์šฐ: `try -> catch -> finally` +2. 'No'๋กœ ๋‹ตํ•œ ๊ฒฝ์šฐ: `try -> finally` -`finally` ์ ˆ์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ๊ฒฐ๊ณผ์— ์ƒ๊ด€์—†์ด ์‹คํ–‰์„ ์™„๋ฃŒํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +`finally` ์ ˆ์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์‹คํ–‰ ๊ฒฐ๊ณผ์— ์ƒ๊ด€์—†์ด ์‹คํ–‰์„ ์™„๋ฃŒํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด, ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜ `fib(n)`์˜ ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด ๋ด…์‹œ๋‹ค. ํ•จ์ˆ˜ ์‹คํ–‰ ์ „์— ์ธก์ •์„ ์‹œ์ž‘ํ•ด์„œ ์‹คํ–‰์ด ๋๋‚œ ํ›„ ์ธก์ •์„ ์ข…๋ฃŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ž์—ฐ์Šค๋ ˆ ๋– ์˜ฌ๋ž์„ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ํ•จ์ˆ˜ ์‹คํ–‰ ๋„์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์•„๋ž˜ ์ฝ”๋“œ์˜ ํ•จ์ˆ˜ `fib(n)`๋Š” ์Œ์ˆ˜๋‚˜ ์ •์ˆ˜๊ฐ€ ์•„๋‹Œ ์ˆ˜๊ฐ€ ์ž…๋ ฅ๋  ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋ฆฌํ„ด๋ฉ๋‹ˆ๋‹ค. +ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜ `fib(n)`์˜ ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด ๋ด…์‹œ๋‹ค. ํ•จ์ˆ˜ ์‹คํ–‰ ์ „์— ์ธก์ •์„ ์‹œ์ž‘ํ•ด์„œ ์‹คํ–‰์ด ๋๋‚œ ํ›„ ์ธก์ •์„ ์ข…๋ฃŒํ•˜๋ฉด ๋˜๊ฒ ์ฃ . ๊ทธ๋Ÿฐ๋ฐ ํ•จ์ˆ˜ ์‹คํ–‰ ๋„์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์•„๋ž˜ `fib(n)`์—๋Š” ์Œ์ˆ˜๋‚˜ ์ •์ˆ˜๊ฐ€ ์•„๋‹Œ ์ˆ˜๋ฅผ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -`finally` ์ ˆ์€ ์—ฐ์‚ฐ ์‹œ๊ฐ„ ์ธก์ •์„ ์ข…๋ฃŒํ•˜๊ธฐ ์ ์ ˆํ•œ ๊ณณ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ๊ฒฝ์šฐ์— `finally`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `finally` ์ ˆ์€ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋“  ๊ด€๊ณ„์—†์ด ์—ฐ์‚ฐ ์‹œ๊ฐ„ ์ธก์ •์„ ๋๋งˆ์น˜๊ธฐ ์ ์ ˆํ•œ ๊ณณ์ด์ฃ . -`fib` ํ•จ์ˆ˜๊ฐ€ ์—๋Ÿฌ ์—†์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋“  ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒํ•˜๋“  ์ƒ๊ด€์—†์ด, `finally`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ์ œ๋Œ€๋กœ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`fib` ํ•จ์ˆ˜๊ฐ€ ์—๋Ÿฌ ์—†์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋“  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋“  ์ƒ๊ด€์—†์ด, `finally`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ์ œ๋Œ€๋กœ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let num = +prompt("์–‘์˜ ์ •์ˆ˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", 35) @@ -500,7 +504,7 @@ let diff, result; function fib(n) { if (n < 0 || Math.trunc(n) != n) { - throw new Error("Must not be negative, and also an integer."); + throw new Error("์Œ์ˆ˜๋‚˜ ์ •์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ’์€ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); } return n <= 1 ? n : fib(n - 1) + fib(n - 2); } @@ -522,21 +526,21 @@ alert(result || "์—๋Ÿฌ ๋ฐœ์ƒ"); alert( `์—ฐ์‚ฐ ์‹œ๊ฐ„: ${diff}ms` ); ``` -์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  `35`๋ฅผ `ํ”„๋กฌํ”„ํŠธ ๋Œ€ํ™”์ƒ์ž`์— ์ž…๋ ฅํ•˜๋ฉด `try` ๋‹ค์Œ์— `finally`๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉด์„œ ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `-1`์„ ์ž…๋ ฅํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์—ฐ์‚ฐ ์‹œ๊ฐ„์€ `0ms`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์—ฐ์‚ฐ ์‹œ๊ฐ„์ด ์ •์ƒ์ ์œผ๋กœ ์ธก์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํ”„๋กฌํ”„ํŠธ ๋Œ€ํ™”์ƒ์ž์— `35`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด `try` ๋‹ค์Œ์— `finally`๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉด์„œ ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `-1`์„ ์ž…๋ ฅํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์—ฐ์‚ฐ ์‹œ๊ฐ„์€ `0ms`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์—ฐ์‚ฐ ์‹œ๊ฐ„์ด ์ •์ƒ์ ์œผ๋กœ ์ธก์ •๋˜์—ˆ๋„ค์š”. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํ•จ์ˆ˜๋ฅผ ๋น ์ ธ๋‚˜๊ฐ€๋ ค๋ฉด `return` ์ด๋‚˜ `throw`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ, `finally` ์ ˆ์„ ์ด์šฉํ•˜๋ฉด ๋‘ ๊ฒฝ์šฐ๋ฅผ ๋ชจ๋‘ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•จ์ˆ˜๋Š” `return` ์ด๋‚˜ `throw`๋ฅผ ๋งŒ๋‚˜๋ฉด ์ข…๋ฃŒ๋˜๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ `finally` ์ ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```smart header="`try..catch..finally` ์•ˆ์˜ ๋ณ€์ˆ˜๋Š” ์ง€์—ญ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค." -์œ„ ์ฝ”๋“œ์—์„œ `diff`์™€ `result`๋Š” `try..catch`๋ธ”๋ก *๋ฐ–*์˜ ์ „์—ญ ๊ณต๊ฐ„์—์„œ ์„ ์–ธ๋˜์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค์— ์ฃผ์˜ํ•˜์„ธ์š”. +์œ„ ์˜ˆ์‹œ์—์„œ ๋ณ€์ˆ˜ `diff`์™€ `result`๋Š” `try..catch` *์ „* ์— ์„ ์–ธ๋˜์—ˆ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”. -`{...}` ๋ธ”๋ก ์•ˆ์—์„œ `let`์„ ์‚ฌ์šฉํ•ด ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ–ˆ๋‹ค๋ฉด, ๋ธ”๋ก ์•ˆ์—์„œ๋งŒ ์œ ํšจํ•œ ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +`try` ๋ธ”๋ก ์•ˆ์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋Š” ๋ธ”๋ก ์•ˆ์—์„œ๋งŒ ์œ ํšจํ•œ ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ``` ````smart header="`finally` ์™€ `return`" -`finally` ์ ˆ์€ `try..catch`์ ˆ์„ ๋น ์ ธ๋‚˜๊ฐ€๋Š” *์–ด๋–ค* ๊ฒฝ์šฐ์—๋„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `return`์„ ์‚ฌ์šฉํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋น ์ ธ๋‚˜๊ฐ€๋ ค๋Š” ๊ฒฝ์šฐ์—๋„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +`finally` ์ ˆ์€ `try..catch` ์ ˆ์„ ๋น ์ ธ๋‚˜๊ฐ€๋Š” *์–ด๋–ค* ๊ฒฝ์šฐ์—๋„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `return`์„ ์‚ฌ์šฉํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋น ์ ธ๋‚˜๊ฐ€๋ ค๋Š” ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. -์•„๋ž˜ ์ฝ”๋“œ์˜ `try`๋ธ”๋ก ์•ˆ์—” `return`๋ฌธ์ด ์žˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ์—๋„ `finally`๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `try..catch`์ ˆ ๋ฐ”๊นฅ์˜ ์ฝ”๋“œ๋Š” ๊ทธ ์ดํ›„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์˜ `try` ๋ธ”๋ก ์•ˆ์—” `return`์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—” ๊ฐ’์ด ๋ฐ”๊นฅ ์ฝ”๋“œ๋กœ ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „์— `finally`๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ```js run function func() { @@ -561,7 +565,7 @@ alert( func() ); // finally ์•ˆ์˜ alert๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๋‚œ ํ›„, ์‹คํ–‰๋จ ````smart header="`try..finally`" -`catch` ์ ˆ์ด ์—†๋Š” `try..finally` ๊ตฌ๋ฌธ๋„ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์žฅ์€ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์ง€ ์•Š์ง€๋งŒ, ์‹œ์ž‘ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํžˆ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +`catch` ์ ˆ์ด ์—†๋Š” `try..finally` ๊ตฌ๋ฌธ๋„ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `try..finally` ์•ˆ์—์„  ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์ง€ ์•Š์ง€๋งŒ, ์‹œ์ž‘ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํžˆ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ```js function func() { @@ -573,22 +577,22 @@ function func() { } } ``` -์œ„์˜ ์ฝ”๋“œ์—์„œ `try` ์•ˆ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋Š” `catch`๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ํ•ญ์ƒ ๋ฐ–์œผ๋กœ ๋–จ์–ด์ ธ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹คํ–‰ ํ๋ฆ„์ด ํ•จ์ˆ˜๋ฅผ ๋– ๋‚˜๊ธฐ ์ „์— `finally`๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +์œ„ ์ฝ”๋“œ์—” `catch`๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— `try` ์•ˆ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋Š” ํ•ญ์ƒ ๋ฐ–์œผ๋กœ ๋–จ์–ด์ ธ ๋‚˜์˜ต๋‹ˆ๋‹ค. `finally`๋Š” ์‹คํ–‰ ํ๋ฆ„์ด ํ•จ์ˆ˜๋ฅผ ๋– ๋‚˜๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ```` ## ์ „์—ญ catch -```warn header="ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์„ ํ™•์ธํ•˜์„ธ์š”" -์ด ์ ˆ์˜ ๋‚ด์šฉ์€ ์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์šฉ์ด ์•„๋‹™๋‹ˆ๋‹ค. +```warn header="ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์„ ํ™•์ธํ•˜์„ธ์š”." +์ด ์ ˆ์€ ์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ``` `try..catch` ๋ฐ”๊นฅ์—์„œ ์น˜๋ช…์ ์ธ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฃฝ์—ˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ด…์‹œ๋‹ค. -์–ด๋–ป๊ฒŒ ๋Œ€์ฒ˜ํ•ด์•ผ ํ• ๊นŒ์š”? ์—๋Ÿฌ๋ฅผ ๊ธฐ๋กํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ ๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . +๋Œ€์ฒ˜ ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ์š”? ์–ด๋”˜๊ฐ€์— ์—๋Ÿฌ ๋‚ด์—ญ์„ ๊ธฐ๋กํ•ด ๋†“๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ์•Œ๋ ค์ฃผ๋Š” ํ–‰์œ„๋ฅผ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์—๋Š” ์ด๋Ÿฐ ์น˜๋ช…์ ์ธ ์—๋Ÿฌ์— ๋Œ€์‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ ํ˜€์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ try..catch ๋ฐ–์˜ ์—๋Ÿฌ๋ฅผ ์žก๋Š” ๊ฒƒ์€ ์•„์ฃผ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๋Ÿฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ํ™˜๊ฒฝ์—์„  ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Node.js์˜ [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception)์ด ๊ทธ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„  [window.onerror](mdn:api/GlobalEventHandlers/onerror)๋ฅผ ์ด์šฉํ•ด ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. window.onerrorํ”„๋กœํผํ‹ฐ์— ํŠน๋ณ„ํ•œ ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋ฉด, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์—๋Š” ์ด๋Ÿฐ ์น˜๋ช…์ ์ธ ์—๋Ÿฌ์— ๋Œ€์‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ ํ˜€์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `try..catch`์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ์žก๋Š” ๊ฒƒ์€ ์•„์ฃผ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ ๋Œ€๋‹ค์ˆ˜๋Š” ์ž์ฒด์ ์œผ๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Node.js์˜ [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception)์ด ๊ทธ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„  [window.onerror](mdn:api/GlobalEventHandlers/onerror)๋ฅผ ์ด์šฉํ•ด ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. window.onerror ํ”„๋กœํผํ‹ฐ์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋ฉด, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -๋ฌธ๋ฒ•์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค. +๋ฌธ๋ฒ•: ```js window.onerror = function(message, url, line, col, error) { @@ -626,20 +630,20 @@ window.onerror = function(message, url, line, col, error) { ``` -์ „์—ญ ํ•ธ๋“ค๋Ÿฌ `window.onerror`๋ฅผ ์ฃฝ์–ด๋ฒ„๋ฆฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋ก  ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ `window.onerror`๋งŒ์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณต๊ตฌํ•˜๋Š” ๊ฑด ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅ ํ•˜์ฃ . `window.onerror`๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ „์—ญ ํ•ธ๋“ค๋Ÿฌ `window.onerror`๋Š” ์ฃฝ์–ด๋ฒ„๋ฆฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ๋Š” ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ `window.onerror`๋งŒ์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณต๊ตฌํ•˜๋Š” ๊ฑด ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•˜์ฃ . `window.onerror`๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -์ „์—ญ ํ•ธ๋“ค๋Ÿฌ ์ด์™ธ์—๋„ ์—๋Ÿฌ๋ฅผ ๋กœ๊น… ํ•ด์ฃผ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์›น ์„œ๋น„์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜ ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . +`window.onerror`๋ง๊ณ  ๋‚˜ ๊ฐ™์€ ์—๋Ÿฌ ๋กœ๊น… ๊ด€๋ จ ์ƒ์šฉ ์„œ๋น„์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์›น ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์„œ๋น„์Šค๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -1. ์„œ๋น„์Šค ๊ฐ€์ž…ํ•˜๋ฉด JS ํŒŒ์ผ(ํ˜น์€ ์Šคํฌ๋ฆฝํŠธ์˜ url)์„ ์ œ๊ณต๋ฐ›๋Š”๋ฐ, ์ด ํŒŒ์ผ์„ ํŽ˜์ด์ง€์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. -2. JS ํŒŒ์ผ์—๋Š” ์ปค์Šคํ…€ `window.onerror` ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -3. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์—๋Ÿฌ์— ๊ด€ํ•œ ๋‚ด์šฉ์„ ์„œ๋น„์Šค๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. -4. ์›น ์„œ๋น„์Šค ์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•˜๊ณ  ๋กœ๊น…๋œ ์—๋Ÿฌ๋ฅผ ๋ด…๋‹ˆ๋‹ค. +1. ์„œ๋น„์Šค๋ฅผ ๊ฐ€์ž…ํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ(ํ˜น์€ ์Šคํฌ๋ฆฝํŠธ url)์„ ๋ฐ›๋Š”๋ฐ, ๊ฐœ๋ฐœ์ž๋Š” ์ด ํŒŒ์ผ์„ ํŽ˜์ด์ง€์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +2. ๋ฐ›์€ ํŒŒ์ผ์€ ์ปค์Šคํ…€ `window.onerror` ํ•จ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +3. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์ด ์ปค์Šคํ…€ ํ•จ์ˆ˜๊ฐ€ ์—๋Ÿฌ์— ๊ด€ํ•œ ๋‚ด์šฉ์„ ๋‹ด์•„ ์„œ๋น„์Šค์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. +4. ๊ฐœ๋ฐœ์ž๋Š” ์„œ๋น„์Šค ์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•ด ๊ธฐ๋ก๋œ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ## ์š”์•ฝ -`try..catch`๋ฅผ ์ด์šฉํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "try"์—์„  ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด "catch"์—์„œ ์žก์•„๋ƒ…๋‹ˆ๋‹ค. +`try..catch`๋ฅผ ์ด์šฉํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `try`์—์„  ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด `catch`์—์„œ ์žก์•„๋ƒ…๋‹ˆ๋‹ค. ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. @@ -650,22 +654,22 @@ try { // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์—ฌ๊ธฐ๋ถ€ํ„ฐ ์‹คํ–‰๋จ // err๋Š” ์—๋Ÿฌ ๊ฐ์ฒด } finally { - // ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ์ƒ๊ด€ ์—†์ด try/catch ์ดํ›„์— ์‹คํ–‰ ๋จ + // ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด try/catch ์ดํ›„์— ์‹คํ–‰๋จ } ``` -`catch` ๋‚˜ `finally`๋ฅผ ๋”ฐ๋กœ ๋‹ค๋ฃจ๋Š” ์ ˆ์ด ์—†๋Š” ๊ฑธ ๋ด์„œ, `try..catch`์™€ `try..finally`๋„ ์œ ํšจํ•œ ๋ฌธ๋ฒ•์ด๋ž€ ๊ฑธ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`try..catch`, `try..catch..finally`์ด์™ธ์—๋„ `try..finally`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์—๋Ÿฌ ๊ฐ์ฒด์—” ๋‹ค์Œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์—๋Ÿฌ ๊ฐ์ฒด์—” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- `message` -- ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ์˜ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€. -- `name` -- ์—๋Ÿฌ ์ด๋ฆ„์„ ๋‹ด์€ ๋ฌธ์ž์—ด (์—๋Ÿฌ ์ƒ์„ฑ์ž ์ด๋ฆ„). -- `stack` (ํ‘œ์ค€์ด ์•„๋‹ˆ์ง€๋งŒ ์ž˜ ์ง€์›๋จ) -- ์—๋Ÿฌ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์ˆœ๊ฐ„์˜ ์Šคํƒ. +- `message` -- ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ์˜ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ +- `name` -- ์—๋Ÿฌ ์ด๋ฆ„์„ ๋‹ด์€ ๋ฌธ์ž์—ด (์—๋Ÿฌ ์ƒ์„ฑ์ž ์ด๋ฆ„) +- `stack` -- ํ‘œ์ค€์ด ์•„๋‹ˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์ด ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ˆœ๊ฐ„์˜ ์Šคํƒ์„ ๋‚˜ํƒ€๋ƒ„ ์—๋Ÿฌ ๊ฐ์ฒด๊ฐ€ ํ•„์š” ์—†์œผ๋ฉด `catch(err) {` ๋Œ€์‹  `catch {`๋ฅผ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`throw` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปค์Šคํ…€ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ก ์ƒ์œผ๋ก , `throw`์˜ ์ธ์ˆ˜๋กœ ์•„๋ฌด๊ฒƒ์ด๋‚˜ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋Œ€๊ฒŒ ๋‚ด์žฅ `Error` ํด๋ž˜์Šค์—์„œ ์ƒ์†๋ฐ›์€ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜์— ๋„ฃ์Šต๋‹ˆ๋‹ค. ํ™•์žฅ ์—๋Ÿฌ์— ๋Œ€ํ•ด์„  ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +`throw` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ก ์ƒ์œผ๋ก , `throw` ์ธ์ˆ˜์— ๋ชจ๋“  ๊ฒƒ์„ ๋„˜๊ธธ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋Œ€๊ฐœ ๋‚ด์žฅ `Error` ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜์— ๋„˜๊น๋‹ˆ๋‹ค. ์—๋Ÿฌ ์ƒ์†์— ๋Œ€ํ•ด์„  ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -*๋‹ค์‹œ ๋˜์ง€๊ธฐ*๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์‹œ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. `catch` ๋ธ”๋ก์—์„  ๋Œ€๊ฒŒ, ์˜ˆ์ƒํ•˜์˜€๊ฑฐ๋‚˜ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ์ง€ ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ๋‹ค๋ฃจ๊ณ , ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋Š” ๋‹ค์‹œ ๋˜์ง€๊ธฐ๋ฅผ ํ†ตํ•ด ๋‹ค๋ฃน๋‹ˆ๋‹ค. +*๋‹ค์‹œ ๋˜์ง€๊ธฐ*๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์‹œ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. `catch` ๋ธ”๋ก์—์„  ๋Œ€๊ฐœ ์˜ˆ์ƒํ•˜์˜€๊ฑฐ๋‚˜ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ์ง€ ์•Œ๊ณ  ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ๋‹ค๋ฃจ๊ณ , ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋Š” ๋‹ค์‹œ ๋˜์ง€๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. -๋Œ€๋‹ค์ˆ˜์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์—์„œ๋Š” `try..catch` ์—†์ด๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” "์ „์—ญ" ์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•ธ๋“ค๋Ÿฌ์—์„  "๋–จ์–ด์ ธ ๋‚˜์˜จ" ์—๋Ÿฌ๋ฅผ ๋‹ค๋ฃจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์˜ ์ „์—ญ ์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ๋Š” `window.onerror`์ž…๋‹ˆ๋‹ค. +`try..catch`๊ฐ€ ์—†์–ด๋„ ๋Œ€๋ถ€๋ถ„์˜ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์ด '์ „์—ญ' ์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— '๋–จ์–ด์ ธ ๋‚˜์˜จ' ์—๋Ÿฌ๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `window.onerror`๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์˜ ์ „์—ญ ์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. diff --git a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg index ab17dcda04..2c0d71348c 100644 --- a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg +++ b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg @@ -1 +1 @@ -BeginNo ErrorsAn error occured in the codeIgnore catch blockIgnore the rest of tryExecute catch blocktry { }// code... \ No newline at end of file +BeginNo ErrorsAn error occured in the codeIgnore catch blockIgnore the rest of tryExecute catch blocktry { }// code... \ No newline at end of file diff --git a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md index bb6b74cfaf..754e68f9a4 100644 --- a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md +++ b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md @@ -2,7 +2,7 @@ class FormatError extends SyntaxError { constructor(message) { super(message); - this.name = "FormatError"; + this.name = this.constructor.name; } } diff --git a/1-js/10-error-handling/2-custom-errors/1-format-error/task.md b/1-js/10-error-handling/2-custom-errors/1-format-error/task.md index 2c8e910fc0..f593245837 100644 --- a/1-js/10-error-handling/2-custom-errors/1-format-error/task.md +++ b/1-js/10-error-handling/2-custom-errors/1-format-error/task.md @@ -2,13 +2,13 @@ importance: 5 --- -# Inherit from SyntaxError +# SyntaxError ์ƒ์† -Create a class `FormatError` that inherits from the built-in `SyntaxError` class. +๋‚ด์žฅ๋œ `SyntaxError` ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” `FormatError` ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. -It should support `message`, `name` and `stack` properties. +๋งŒ๋“ค์–ด์ง„ ํด๋ž˜์Šค์—์„œ `message`, `name`, `stack`๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Usage example: +์ฐธ๊ณ  ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ```js let err = new FormatError("formatting error"); @@ -18,5 +18,5 @@ alert( err.name ); // FormatError alert( err.stack ); // stack alert( err instanceof FormatError ); // true -alert( err instanceof SyntaxError ); // true (because inherits from SyntaxError) +alert( err instanceof SyntaxError ); // true (SyntaxError ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.) ``` diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md index 062f31e68a..6962138d14 100644 --- a/1-js/10-error-handling/2-custom-errors/article.md +++ b/1-js/10-error-handling/2-custom-errors/article.md @@ -1,42 +1,42 @@ -# ์ปค์Šคํ…€ ์—๋Ÿฌ, ์—๋Ÿฌ ํ™•์žฅํ•˜๊ธฐ +# ์ปค์Šคํ…€ ์—๋Ÿฌ์™€ ์—๋Ÿฌ ํ™•์žฅ -๋ฌด์–ธ๊ฐ€ ๊ฐœ๋ฐœํ•  ๋•Œ, ์ข…์ข… ์ž‘์—…์—์„œ ์ž˜๋ชป๋  ์ˆ˜ ์žˆ๋Š” ํŠน์ •ํ•œ ๊ฒƒ๋“ค์„ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฒด์ ์ธ ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๋™์ž‘์‹œ ์—๋Ÿฌ๋“ค์— ๋Œ€ํ•ด `HttpError`, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋™์ž‘์‹œ์— `DbError`, ๊ฒ€์ƒ‰ ๋™์ž‘์‹œ์— `NotFoundError` ๋“ฑ๋“ฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์ž์ฒด ์—๋Ÿฌ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์ƒ๊น๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์ž‘์—… ์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด `HttpError`, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ์ž‘์—… ์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด `DbError`, ๊ฒ€์ƒ‰ ๊ด€๋ จ ์ž‘์—… ์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด `NotFoundError`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ง๊ด€์ ์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . -์šฐ๋ฆฌ์˜ ์—๋Ÿฌ๋Š” `message`, `name` ๊ฐ™์€ ๊ธฐ๋ณธ์ ์ธ ์—๋Ÿฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๊ณ , `stack`์„ ์ง€์›ํ•˜๋Š” ๊ฒƒ๋„ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ทธ๋ฐ–์— ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ๋„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `HttpError` ๊ฐ์ฒด๋“ค์€ `statusCode` ํ”„๋กœํผํ‹ฐ๋กœ `404` ๋˜๋Š” `403` ๋˜๋Š” `500` ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ง์ ‘ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ, ์ด ์—๋Ÿฌ๋“ค์€ `message`์ด๋‚˜ `name`, ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `stack` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด๋Ÿฐ ํ”„๋กœํผํ‹ฐ ์ด์™ธ์—๋„ ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `HttpError` ํด๋ž˜์Šค์˜ ๊ฐ์ฒด์— `statusCode` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๊ณ  `404`๋‚˜ `403`, `500`๊ฐ™์€ ์ˆซ์ž๋ฅผ ๊ฐ’์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” `throw` ๋ฅผ ์•„๋ฌด ์ธ์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค์€ `Error`๋ฅผ ์ƒ์†ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ƒ์†์„ ํ•˜๋ฉด `obj instanceof Error`๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—๋Ÿฌ ๊ฐ์ฒด๋“ค์„ ์‹๋ณ„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์†๋ฐ›๋Š” ๊ฒŒ ๋‚ซ์Šต๋‹ˆ๋‹ค. +์•ž์„œ ๋ฐฐ์šด ๋ฐ”์™€ ๊ฐ™์ด `throw`์˜ ์ธ์ˆ˜์—” ์•„๋ฌด๋Ÿฐ ์ œ์•ฝ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ `Error`๋ฅผ ์ƒ์†ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ `Error`๋ฅผ ์ƒ์†๋ฐ›์•„ ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด `obj instanceof Error`๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์ƒ๊น๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์žฅ์  ๋•Œ๋ฌธ์— ๋งจ๋•…์—์„œ ์ปค์Šคํ…€ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค `Error`๋ฅผ ์ƒ์†๋ฐ›์•„ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋‚ซ์Šต๋‹ˆ๋‹ค. -์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํฌ๊ธฐ๊ฐ€ ์ ์  ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ, ์ž์ฒด ์—๋Ÿฌ๋“ค์€ ์ž์—ฐ์Šค๋ ˆ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `HttpTimeoutError`๋Š” `HttpError`๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋“ฑ์ž…๋‹ˆ๋‹ค. +์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํฌ๊ธฐ๊ฐ€ ์ ์  ์ปค์ง€๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค๊ฒŒ ๋  ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค์€ ์ž์—ฐ์Šค๋ ˆ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. `HttpTimeoutError`๋Š” `HttpError`๋ฅผ ์ƒ์†๋ฐ›๋Š” ์‹์œผ๋กœ ๋ง์ด์ฃ . ## ์—๋Ÿฌ ํ™•์žฅํ•˜๊ธฐ -์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ JSON์„ ์ฝ์–ด์•ผ ํ•˜๋Š” `readUser(json)`๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค. +์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ JSON์„ ์ฝ๋Š” ํ•จ์ˆ˜ `readUser(json)`๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. -๋‹ค์Œ์€ ์œ ํšจํ•œ `json`์˜ ๋ชจ์Šต์— ๋Œ€ํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค. +์œ ํšจํ•œ `json`์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js let json = `{ "name": "John", "age": 30 }`; ``` -๋‚ด๋ถ€์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” `JSON.parse`๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ‹€๋ฆฐ `json`์„ ๋ฐ›์œผ๋ฉด, `SyntaxError`๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ `json`์ด ๋ฌธ๋ฒ•์ ์œผ๋กœ ๋งž๋‹ค๊ณ  ํ•˜๋”๋ผ๋„, ์œ ํšจํ•œ ์‚ฌ์šฉ์ž๋ผ๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค, ๊ทธ๋ ‡์ฃ ? ํ•„์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋œจ๋ ธ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ํ•„์ˆ˜์ธ `name`๊ณผ `age` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +`readUser` ๋‚ด๋ถ€์—์„  `JSON.parse`๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž˜๋ชป๋œ ํ˜•์‹์˜ `json`์ด ๋“ค์–ด์˜ค๋ฉด `SyntaxError`๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒ ์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์ธ์ˆ˜๋กœ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๊ฐ€ JSON ํ˜•์‹์ด๊ธด ํ•˜์ง€๋งŒ, ์œ ํšจํ•œ ์‚ฌ์šฉ์ž์ผ ๊ฒƒ์ด๋ผ๋Š” ๋ณด์žฅ์€ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ผ๋ฉด ํ•„์ˆ˜์ ์œผ๋กœ ์žˆ์–ด์•ผ ํ•  `name`์ด๋‚˜ `age`๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์ฃ . -์šฐ๋ฆฌ์˜ ํ•จ์ˆ˜ `readUser(json)`๋Š” JSON์„ ์ฝ์„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธ("๊ฒ€์ฆ")ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์ž…๋ ฅ๋ž€์ด ์—†๊ฑฐ๋‚˜, ํ˜•์‹์ด ํ‹€๋ ธ๋‹ค๋ฉด, ๊ทธ๊ฒƒ์€ ์—๋Ÿฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌธ๋ฒ•์ ์œผ๋กœ ๋งž๊ธฐ ๋•Œ๋ฌธ์— `SyntaxError`๋Š” ์•„๋‹ˆ๊ณ , ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ `ValidationError`๋ผ๊ณ  ๋ถ€๋ฅผ ๊ฒƒ์ด๊ณ  ์ด๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋Š” ๋˜ํ•œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ํ•„๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ `readUser(json)`์€ JSON ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฐ์ดํ„ฐ๋ฅผ '๊ฒ€์ฆ'ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•„์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜, ์œ„ ํ˜•์‹์— ๋งž์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์ด๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋Š” `SyntaxError`๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. JSON ํ˜•์‹์€ ๋งž์ง€๋งŒ, ์ž์ฒด ๊ธฐ์ค€์— ๋งž์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ด๋ฏ€๋กœ ์ „ํ˜€ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ์ด์ฃ . ์ง€๊ธˆ๋ถ€ํ„ด ์ด ์—๋Ÿฌ๋ฅผ `ValidationError`๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ž ์ด์ œ `ValidationError`๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. -์šฐ๋ฆฌ์˜ `ValidationError` ํด๋ž˜์Šค๋Š” ๋‚ด์žฅ๋œ `Error` ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`ValidationError` ํด๋ž˜์Šค์—” ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ํ•„๋“œ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ ํด๋ž˜์Šค `Error`๋ฅผ ์ƒ์†๋ฐ›์•„ `ValidationError` ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. -๊ทธ ํด๋ž˜์Šค๋Š” ๋‚ด์žฅ ํด๋ž˜์Šค์ง€๋งŒ, ์šฐ๋ฆฌ ๋ˆˆ ์•ž์— ๋Œ€๋žต์ ์ธ ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์•ผ๋งŒ ์šฐ๋ฆฌ๊ฐ€ ํ™•์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . ์•„๋ž˜ ์ˆ˜๋„ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. +๊ทธ ์ „์— ๋จผ์ € ์ž ์‹œ ์Šˆ๋„ ์ฝ”๋“œ๋กœ `Error` ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js -// ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž์ฒด์—์„œ ์ •์˜ํ•œ ๋‚ด์žฅ ์—๋Ÿฌ ํด๋ž˜์Šค์˜ "์ˆ˜๋„์ฝ”๋“œ" +// ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž์ฒด ๋‚ด์žฅ ์—๋Ÿฌ ํด๋ž˜์Šค Error์˜ '์Šˆ๋„ ์ฝ”๋“œ' class Error { constructor(message) { this.message = message; - this.name = "Error"; // (์„œ๋กœ ๋‹ค๋ฅธ ๋‚ด์žฅ ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์ด๋ฆ„๋“ค) - this.stack = ; // ํ‘œ์ค€์€ ์•„๋‹ˆ์ง€๋งŒ, ๋Œ€๋‹ค์ˆ˜์˜ ํ™˜๊ฒฝ์ด ์ง€์›ํ•ฉ๋‹ˆ๋‹ค + this.name = "Error"; // (name์€ ๋‚ด์žฅ ์—๋Ÿฌ ํด๋ž˜์Šค๋งˆ๋‹ค ๋‹ค๋ฆ…๋‹ˆ๋‹ค.) + this.stack = ; // stack์€ ํ‘œ์ค€์€ ์•„๋‹ˆ์ง€๋งŒ, ๋Œ€๋‹ค์ˆ˜ ํ™˜๊ฒฝ์ด ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. } } ``` -์ด์ œ ๊ณ„์†ํ•ด์„œ `ValidationError`์ด ๊ทธ๊ฑธ ์ƒ์† ๋ฐ›๋„๋ก ํ•ด ๋ด…์‹œ๋‹ค. +์ด์ œ `ValidationError`์—์„œ `Error`๋ฅผ ์ƒ์†๋ฐ›์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run untrusted *!* @@ -49,23 +49,23 @@ class ValidationError extends Error { } function test() { - throw new ValidationError("Whoops!"); + throw new ValidationError("์—๋Ÿฌ ๋ฐœ์ƒ!"); } try { test(); } catch(err) { - alert(err.message); // Whoops! + alert(err.message); // ์—๋Ÿฌ ๋ฐœ์ƒ! alert(err.name); // ValidationError alert(err.stack); // ๊ฐ ํ–‰ ๋ฒˆํ˜ธ๊ฐ€ ์žˆ๋Š” ์ค‘์ฒฉ๋œ ํ˜ธ์ถœ๋“ค์˜ ๋ชฉ๋ก } ``` -`(1)` ์ค„์—์„œ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์ž์‹ ์ƒ์„ฑ์ž ์•ˆ์—์„œ `super`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ด๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋Š” `message` ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +`(1)`์—์„œ ๋ถ€๋ชจ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์ž์‹ ์ƒ์„ฑ์ž ์•ˆ์—์„œ `super`๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `message` ํ”„๋กœํผํ‹ฐ๋Š” ๋ถ€๋ชจ ์ƒ์„ฑ์ž์—์„œ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. -๋ถ€๋ชจ ์ƒ์„ฑ์ž๋Š” ๋˜ํ•œ `name` ํ”„๋กœํผํ‹ฐ๋ฅผ `"Error"`๋กœ ์„ค์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, `(2)` ์ฅด์—์„œ ์˜ฌ๋ฐ”๋ฅธ ๊ฐ’์œผ๋กœ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +๋ถ€๋ชจ ์ƒ์„ฑ์ž์—์„  `message`๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `name` ํ”„๋กœํผํ‹ฐ๋„ ์„ค์ •(`"Error"`)ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, `(2)`์—์„œ ์›ํ•˜๋Š” ๊ฐ’์œผ๋กœ ์žฌ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. -`readUser(json)` ์•ˆ์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•ด ๋ด…์‹œ๋‹ค. +์ด์ œ `readUser(json)` ์•ˆ์—์„œ `ValidationError`๋ฅผ ์‚ฌ์šฉํ•ด ๋ด…์‹œ๋‹ค. ```js run class ValidationError extends Error { @@ -75,7 +75,7 @@ class ValidationError extends Error { } } -// ์‚ฌ์šฉ +// ์‚ฌ์šฉ๋ฒ• function readUser(json) { let user = JSON.parse(json); @@ -89,7 +89,7 @@ function readUser(json) { return user; } -// try..catch์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ ๋™์ž‘ ์˜ˆ์ œ +// try..catch์™€ readUser๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ try { let user = readUser('{ "age": 25 }'); @@ -101,31 +101,31 @@ try { } else if (err instanceof SyntaxError) { // (*) alert("JSON Syntax Error: " + err.message); } else { - throw err; // ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์—๋Ÿฌ, ์žฌ๋˜์ง€๊ธฐ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค (**) + throw err; // ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์—๋Ÿฌ๋Š” ์žฌ๋˜์ง€๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. (**) } } ``` -์œ„์˜ ์ฝ”๋“œ์—์„œ `try..catch` ๋ธ”๋ก์€ `JSON.parse`์—์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  `ValidationError`์™€ ๋‚ด์žฅ๋œ `SyntaxError` ๋‘˜ ๋‹ค ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. +์ด์ œ `try..catch` ๋ธ”๋ก์—์„œ ์ปค์Šคํ…€ ์—๋Ÿฌ `ValidationError`์™€ `JSON.parse`์—์„œ ๋ฐœ์ƒํ•˜๋Š” `SyntaxError` ๋‘˜ ๋‹ค๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -`instanceof`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `(*)` ์ค„์—์„œ ์—๋Ÿฌ ์œ ํ˜•์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด์„ธ์š”. +์ด ๊ณผ์ •์—์„œ `instanceof`๋กœ ์—๋Ÿฌ ์œ ํ˜•์„ ํ™•์ธ(`(*)`)ํ•˜์˜€์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ๊ณผ ๊ฐ™์ด `err.name`๋ฅผ ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์—๋Ÿฌ ์œ ํ˜• ํ™•์ธ์€ `instanceof` ๋ง๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด `err.name`์„ ์‚ฌ์šฉํ•ด๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ```js // ... -// instead of (err instanceof SyntaxError) +// (err instanceof SyntaxError) ๋Œ€์‹  ์‚ฌ์šฉ ๊ฐ€๋Šฅ } else if (err.name == "SyntaxError") { // (*) // ... ``` -`instanceof`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋‚˜์ค‘์— `ValidationError`๋ฅผ ํ™•์žฅํ•˜์—ฌ `PropertyRequiredError` ๊ฐ™์€ ์„œ๋ธŒ ํƒ€์ž…์„ ๋งŒ๋“ค ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  `instanceof` ๊ฒ€์‚ฌ๋Š” ์ƒ์†๋ฐ›์€ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋“ค์—์„œ๋„ ๋™์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚˜์ค‘์— ๋Œ€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์—๋Ÿฌ ์œ ํ˜• ํ™•์ธ์€ `err.name`๋ณด๋‹ค๋Š” `instanceof`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— `ValidationError`๋ฅผ ํ™•์žฅํ•˜์—ฌ `PropertyRequiredError` ๊ฐ™์€ ์ƒˆ๋กœ์šด ํ™•์žฅ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋  ํ…๋ฐ, `instanceof`๋Š” ์ƒˆ๋กœ์šด ์ƒ์† ํด๋ž˜์Šค์—์„œ๋„ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -๋˜ํ•œ `catch`๊ฐ€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚˜๋ฉด `(**)` ์ค„์—์„œ ์žฌ๋˜์ง€๊ธฐ๋ฅผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. `catch` ๋ธ”๋ก์€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์™€ ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋งŒ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ์ข…๋ฅ˜(์ฝ”๋“œ ์˜คํƒ€ ๋“ฑ)๋Š” ๋น ์ ธ๋‚˜๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`catch`์— ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์—๋Ÿฌ๊ฐ€ ์žˆ์„ ๋•Œ ์ด ์—๋Ÿฌ๋Š” ์žฌ ๋˜์ง€๊ธฐ ๋œ๋‹ค๋Š” ์ (`(**)`) ๋˜ํ•œ ์ฃผ๋ชฉํ•ด์„œ ๋ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. `catch` ๋ธ”๋ก์—์„  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์™€ ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋Š” ๋ฐ–์œผ๋กœ ๋˜์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ## ๋” ๊นŠ๊ฒŒ ์ƒ์†ํ•˜๊ธฐ -`ValidationError` ํด๋ž˜์Šค๋Š” ๋„ˆ๋ฌด ์ถ”์ƒ์ ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฒƒ๋“ค์ด ์ž˜๋ชป๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ํ˜•์‹(๊ฐ€๋ น `age`์— ๋ฌธ์ž์—ด ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ)์œผ๋กœ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋Š” ๋ฐ”๋กœ ๊ทธ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด์„œ ๋” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์ธ `PropertyRequiredError`๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. ๋ˆ„๋ฝ๋œ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋‹ด์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์•ž์„œ ๋งŒ๋“  `ValidationError` ํด๋ž˜์Šค๋Š” ๋„ˆ๋ฌด ํฌ๊ด„์ ์ด์–ด์„œ ๋ญ”๊ฐ€ ์ž˜๋ชป๋  ํ™•๋ฅ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ผญ ํ•„์š”ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ `age`์— ๋ฌธ์ž์—ด ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ˜•์‹์ด ์ž˜๋ชป๋œ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์ฃ . ํ•„์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์— ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค `PropertyRequiredError`๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. `PropertyRequiredError`์—” ๋ˆ„๋ฝ๋œ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run class ValidationError extends Error { @@ -145,7 +145,7 @@ class PropertyRequiredError extends ValidationError { } */!* -// Usage +// ์‚ฌ์šฉ๋ฒ• function readUser(json) { let user = JSON.parse(json); @@ -159,7 +159,7 @@ function readUser(json) { return user; } -// try..catch์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ ๋™์ž‘ ์˜ˆ์ œ +// try..catch์™€ readUser๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. try { let user = readUser('{ "age": 25 }'); @@ -173,18 +173,18 @@ try { } else if (err instanceof SyntaxError) { alert("JSON Syntax Error: " + err.message); } else { - throw err; // unknown error, rethrow it + throw err; // ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์—๋Ÿฌ๋Š” ์žฌ๋˜์ง€๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. } } ``` -์ƒˆ๋กœ์šด ํด๋ž˜์Šค `PropertyRequiredError`๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹จ์ง€ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ์ „๋‹ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. `new PropertyRequiredError(property)`. ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด `message`๋Š” ์ƒ์„ฑ์ž์— ์˜ํ•ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“  ํด๋ž˜์Šค `PropertyRequiredError`๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. `new PropertyRequiredError(property)`์ฒ˜๋Ÿผ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ์ „๋‹ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜์ฃ . ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” `message`๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์•Œ์•„์„œ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. -Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = ` in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name = this.constructor.name`. And then inherit all ours custom errors from it. +์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•  ์ ์€ `PropertyRequiredError` ์ƒ์„ฑ์ž ์•ˆ์—์„œ `this.name`์„ ์ˆ˜๋™์œผ๋กœ ํ• ๋‹นํ•ด ์ฃผ์—ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ๋งค๋ฒˆ ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ์•ˆ์—์„œ `this.name`๋ฅผ ํ• ๋‹นํ•ด ์ฃผ๋Š” ๊ฒƒ์€ ๊ท€์ฐฎ์€ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์€ '๊ธฐ๋ณธ ์—๋Ÿฌ' ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์ปค์Šคํ…€ ์—๋Ÿฌ๋“ค์ด ์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•˜๋ฉด ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์—๋Ÿฌ์˜ ์ƒ์„ฑ์ž์— `this.name = this.constructor.name`๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜์ฃ . -์ด ํด๋ž˜์Šค๋ฅผ `MyError`๋ผ๊ณ  ๋ถ€๋ฆ…์‹œ๋‹ค. +๊ธฐ๋ณธ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ `MyError`๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. -์—ฌ๊ธฐ `MyError`์™€ ๋‹ค๋ฅธ ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค์˜ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +`MyError`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run class MyError extends Error { @@ -205,23 +205,51 @@ class PropertyRequiredError extends ValidationError { } } -// name is correct +// ์ œ๋Œ€๋กœ ๋œ ์ด๋ฆ„์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. alert( new PropertyRequiredError("field").name ); // PropertyRequiredError ``` -์ด์ œ ์ปค์Šคํ…€ ์—๋Ÿฌ๋“ค, ํŠนํžˆ `ValidationError`๋Š”, ์ƒ์„ฑ์ž์—์„œ `"this.name = ..."` ์ค„์„ ์ œ๊ฑฐํ•˜์—ฌ ํ›จ์”ฌ ์งง์•„์กŒ์Šต๋‹ˆ๋‹ค. +`"this.name = ..."` ์ด ์‚ฌ๋ผ์กŒ๊ธฐ ๋•Œ๋ฌธ์— `ValidationError`๊ฐ™์€ ์ปค์Šคํ…€ ์—๋Ÿฌ์˜ ์ƒ์„ฑ์ž๊ฐ€ ๋” ๊น”๋”ํ•ด์ง„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ -์œ„์˜ ์ฝ”๋“œ์—์„œ ํ•จ์ˆ˜ `readUser`์˜ ๋ชฉ์ ์€ "์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ฒƒ"์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๋“ค์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ์€ `SyntaxError`์™€ `ValidationError`๋งŒ ์žˆ์ง€๋งŒ, ์•ž์œผ๋กœ `readUser` ํ•จ์ˆ˜๊ฐ€ ๋” ์ปค์ง€๋ฉด ๋‹ค๋ฅธ ์˜ค๋ฅ˜๋“ค์„ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•จ์ˆ˜ `readUser`๋Š” '์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ' ์œ„ํ•œ ์šฉ๋„๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ์€ `SyntaxError`์™€ `ValidationError`๋ฅผ ์‚ฌ์šฉํ•ด ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์•ž์œผ๋กœ `readUser`๊ฐ€ ๋” ์ปค์ง€๋ฉด ๋‹ค๋ฅธ ์ปค์Šคํ…€ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•  ๊ฒ๋‹ˆ๋‹ค. -The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. But if the `readUser` function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`? +`readUser`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณณ์—์„  ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์งˆ ์ปค์Šคํ…€ ์—๋Ÿฌ๋“ค์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ง€๊ธˆ์€ `catch` ๋ธ”๋ก ์•ˆ์— `if`๋ฌธ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋„ฃ์–ด ์ข…๋ฅ˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ์—๋Ÿฌ๋Š” ๋‹ค์‹œ ๋˜์ง€๊ธฐ๋ฅผ ํ•ด ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์‹ค์ •์ž…๋‹ˆ๋‹ค. -๋ณดํ†ต ๋Œ€๋‹ต์€ "์•„๋‹ˆ์š”"์ž…๋‹ˆ๋‹ค. ๋ฐ”๊นฅ์ชฝ ์ฝ”๋“œ๋Š” "๋ชจ๋“  ๊ฒƒ๋“ค์˜ ํ•œ ์ˆ˜์ค€ ์œ„"๊ฐ€ ๋˜๊ณ  ์‹ถ์–ดํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๊นฅ์ชฝ ์ฝ”๋“œ๋Š” ์ผ์ข…์˜ "data reading error"๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ์™œ ๊ทธ๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€๋Š” ๋ณดํ†ต ๋ฌด์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. (์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ทธ๊ฒƒ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค). ๋˜๋Š”, ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์˜ค๋ฅ˜ ์ƒ์„ธ๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. +ํ˜„์žฌ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์Šคํ‚ค๋งˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์˜ค๋ฅ˜๋“ค์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒˆ๋กœ์šด `ReadError` ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. If an error occurs inside `readUser` ์•ˆ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์˜ค๋ฅ˜๋ฅผ ๊ฑฐ๊ธฐ์—์„œ ์žก์•„์„œ `ReadError`๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ `cause` ํ”„๋กœํผํ‹ฐ์— ์‹ค์ œ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋„ ๋ณด๊ด€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฐ”๊นฅ์ชฝ ์ฝ”๋“œ์—์„œ๋Š” `ReadError`๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.. +```js +try { + ... + readUser() // ์ž ์žฌ์  ์—๋Ÿฌ ๋ฐœ์ƒ์ฒ˜ + ... +} catch (err) { + if (err instanceof ValidationError) { + // validation ์—๋Ÿฌ ์ฒ˜๋ฆฌ + } else if (err instanceof SyntaxError) { + // ๋ฌธ๋ฒ• ์—๋Ÿฌ ์ฒ˜๋ฆฌ + } else { + throw err; // ์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๋Š” ๋‹ค์‹œ ๋˜์ง€๊ธฐ ํ•จ + } +} +``` + +์œ„ ์Šคํ‚ค๋งˆ์—” ๋‘ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋งŒ ๋‚˜์™€ ์žˆ๋„ค์š”. ๊ทธ๋Ÿฐ๋ฐ ์—๋Ÿฌ์˜ ์ข…๋ฅ˜๋Š” ๋” ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด์ฏค ๋˜๋ฉด "๋ฏธ๋ž˜์— `readUser` ๊ธฐ๋Šฅ์ด ์ปค์ง€๋ฉด์„œ ์—๋Ÿฌ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„์งˆ ํ…๋ฐ ๊ทธ๋•Œ๋งˆ๋‹ค ์—๋Ÿฌ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ„๊ธฐ๋ฌธ์„ ๋งค๋ฒˆ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋‚˜?"๋ผ๋Š” ์˜๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋ณดํ†ต์€ ๊ทธ๋ ‡์ง€ '์•Š์Šต๋‹ˆ๋‹ค'. ์‹ค์ œ ์šฐ๋ฆฌ๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ์ •๋ณด๋Š” '๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ' ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. ์™œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€์™€ ์ž์„ธํ•œ ์„ค๋ช…์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•  ๋•Œ ์—๋Ÿฌ ์„ธ๋ถ€์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ๋” ์ข‹๊ฒ ์ง€๋งŒ ๋ง์ด์ฃ . + +์ด๋Ÿฐ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ธฐ์ˆ ์€ '์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ(wrapping exception)'๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. + +1. '๋ฐ์ดํ„ฐ ์ฝ๊ธฐ'์™€ ๊ฐ™์€ ํฌ๊ด„์ ์ธ ์—๋Ÿฌ๋ฅผ ๋Œ€๋ณ€ํ•˜๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค `ReadError`๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +2. ํ•จ์ˆ˜ `readUser` ๋ฐœ์ƒํ•œ `ValidationError`, `SyntaxError` ๋“ฑ์˜ ์—๋Ÿฌ๋Š” `readUser` ๋‚ด๋ถ€์—์„œ ์žก๊ณ  ์ด๋•Œ `ReadError`๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +3. `ReadError` ๊ฐ์ฒด์˜ `cause` ํ”„๋กœํผํ‹ฐ์—” ์‹ค์ œ ์—๋Ÿฌ์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. + +์ด๋ ‡๊ฒŒ ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ ๊ธฐ์ˆ ์„ ์จ ์Šคํ‚ค๋งˆ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด `readUser`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์—์„  `ReadError`๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ ์ข…๋ฅ˜ ์ „์ฒด๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์•„๋„ ๋˜์ฃ . ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—” `cause` ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -์—ฌ๊ธฐ์— `ReadError`๋ฅผ ์ •์˜ํ•˜๊ณ  `readUser`์™€ `try..catch` ์•ˆ์—์„œ ์“ฐ์ž„์„ ์‹œ์—ฐํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด์ œ ์‹ค์ œ๋กœ `ReadError`๋ฅผ ์ •์˜ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. `ReadError`๋Š”`readUser`์™€ `try..catch` ์•ˆ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run class ReadError extends Error { @@ -275,7 +303,7 @@ function readUser(json) { } try { - readUser('{bad json}'); + readUser('{์ž˜๋ชป๋œ ํ˜•์‹์˜ json}'); } catch (e) { if (e instanceof ReadError) { *!* @@ -289,14 +317,14 @@ try { } ``` -์œ„์˜ ์ฝ”๋“œ์—์„œ `readUser`๋Š” ์ •ํ™•ํžˆ ์„ค๋ช…ํ•œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ๋ฒ• ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์˜ค๋ฅ˜๋“ค์„ ์žก์•„์„œ `ReadError` ์˜ค๋ฅ˜๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค (์•Œ๋ ค์ง€์ง€ ์•Š์€ ์˜ค๋ฅ˜๋“ค์€ ๋ณดํ†ต์ฒ˜๋Ÿผ ๋‹ค์‹œ ๋˜์ ธ์ง‘๋‹ˆ๋‹ค). +์ด์ œ `readUser`๋Š” ์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. Syntax ์—๋Ÿฌ๋‚˜ Validation ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ์—๋Ÿฌ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ๋˜์ง€๊ธฐ ํ•˜์ง€ ์•Š๊ณ  `ReadError`๋ฅผ ๋˜์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -๋”ฐ๋ผ์„œ ๋ฐ”๊นฅ์ชฝ ์ฝ”๋“œ๋Š” `instanceof ReadError`๋งŒ ์ฒดํฌํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค. ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์˜ค๋ฅ˜ ์œ ํ˜•๋“ค์„ ๋‚˜์—ดํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ๋˜๋ฉด, `readUser`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ”๊นฅ ์ฝ”๋“œ์—์„  `instanceof ReadError` ๋”ฑ ํ•˜๋‚˜๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ถ„๊ธฐ๋ฌธ์„ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์–ด์ง‘๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์ ‘๊ทผ๋ฒ•์„ "์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ"๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. "๋กœ์šฐ๋ ˆ๋ฒจ ์˜ˆ์™ธ"๋“ค์„ ๊ฐ€์ ธ๋‹ค๊ฐ€ `ReadError` ์•ˆ์œผ๋กœ "๊ฐ์‹ธ์„œ", ๋” ์ถ”์ƒ์ ์ด๊ณ  ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋ณดํŽธ์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +'์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ'๋ž€ ์ด๋ฆ„์€ ์ข…๋ฅ˜๋ณ„ ์—๋Ÿฌ๋ฅผ ์ข€ ๋” ์ถ”์ƒ์ ์ธ ์—๋Ÿฌ, `ReadError`์— ํ•˜๋‚˜๋กœ ๋ชจ์•„(wrap) ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ™์—ฌ์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ธฐ๋ฒ•์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„๋ฆฌ ์“ฐ์ด๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ## ์š”์•ฝ -- `Error`๋‚˜ ๋‹ค๋ฅธ ๋‚ด์žฅ ์˜ค๋ฅ˜ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ `name` ํ”„๋กœํผํ‹ฐ์™€ `super`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋งŒ ์žŠ์ง€ ์•Š์œผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -- ํŠน์ • ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜๋Š”๋ฐ `instanceof`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์†๋œ ํด๋ž˜์Šค์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ฃ . ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋ถ€ํ„ฐ ์˜จ ์˜ค๋ฅ˜ ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ์—” ํด๋ž˜์Šค๋ฅผ ์•Œ์•„๋‚ด๋Š” ๊ฒƒ์ด ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋•Œ๋Š” `name` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ๋Š” ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋กœ์šฐ-๋ ˆ๋ฒจ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ด๋•Œ ๋กœ์šฐ-๋ ˆ๋ฒจ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹ ์— ํ•˜์ด-๋ ˆ๋ฒจ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋กœ์šฐ-๋ ˆ๋ฒจ ์˜ˆ์™ธ๋Š” ์œ„์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๊ฐ€๋” ํ•ด๋‹น ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. `err.cause`์ฒ˜๋Ÿผ ๋ง์ด์ฃ . ๋‹ค๋งŒ ํ•„์ˆ˜์‚ฌํ•ญ์€ ์•„๋‹™๋‹ˆ๋‹ค. +- ์ปค์Šคํ…€ ํด๋ž˜์Šค๋Š” `Error`๋‚˜ ๋‹ค๋ฅธ ๋‚ด์žฅ ์—๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ `super`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ๊ณผ `name` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. +- `instanceof`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—๋Ÿฌ ์ข…๋ฅ˜๋ฅผ ํŒ๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์†๋œ ํด๋ž˜์Šค์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜จ ์—๋Ÿฌ ๊ฐ์ฒด๋Š” ํด๋ž˜์Šค๋ฅผ ์•Œ์•„๋‚ด๋Š” ๊ฒƒ์ด ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋• `name` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋ฅ˜ ์ข…๋ฅ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ๋Š” ๋„๋ฆฌ ์•Œ๋ ค์ง„ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ๋ฅผ ์ ์šฉํ•œ ํ•จ์ˆ˜์—์„  ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ์ข…๋ฅ˜๋ณ„๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์ถ”์ƒ ์—๋Ÿฌ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ , ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด ์ถ”์ƒ ์—๋Ÿฌ๋ฅผ ๋˜์ง€๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ถ”์ƒ ์—๋Ÿฌ๋ฅผ ๋˜์งˆ ๋•Œ ์‹ค์ œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์ถ”์ƒ ์—๋Ÿฌ์˜ ํ”„๋กœํผํ‹ฐ(`err.cause`)๋กœ ๋„˜๊ธฐ๋ฉด ๊ตฌ์ฒด์ ์ธ ์—๋Ÿฌ ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ฐ˜๋“œ์‹œ ์ด ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. diff --git a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html b/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html index b2192681c9..7fbb4efcab 100644 --- a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html +++ b/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html @@ -22,14 +22,14 @@ - + ``` -์ฐธ๊ณ ๋กœ, ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ถ€๋“์ดํ•˜๊ฒŒ window ๋ ˆ๋ฒจ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด `window` ๊ฐ์ฒด์— ๋ณ€์ˆ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ• ๋‹นํ•˜๊ณ  `window.user`์™€ ๊ฐ™์ด ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์„ ์ทจํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฐฉ๋ฒ•์€ ์ •๋ง ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๊ธธ ๊ถŒ์œ ํ•ฉ๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ถ€๋“์ดํ•˜๊ฒŒ window ๋ ˆ๋ฒจ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด `window` ๊ฐ์ฒด์— ๋ณ€์ˆ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ• ๋‹นํ•˜๊ณ  `window.user`์™€ ๊ฐ™์ด ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์„ ์ทจํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฐฉ๋ฒ•์€ ์ •๋ง ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๊ธธ ๊ถŒ์œ ํ•ฉ๋‹ˆ๋‹ค. ### ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ‰๊ฐ€๋จ -๋™์ผํ•œ ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๋”๋ผ๋„ ๋ชจ๋“ˆ์€ ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ํ›„ ๊ฒฐ๊ณผ๋Š” ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ๊ฐ€๋ ค๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์— ๋‚ด๋ณด๋‚ด ์ง‘๋‹ˆ๋‹ค. +๋™์ผํ•œ ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๋”๋ผ๋„ ๋ชจ๋“ˆ์€ ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ํ›„ ๊ฒฐ๊ณผ๋Š” ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ๊ฐ€๋ ค๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์— ๋‚ด๋ณด๋‚ด ์ง‘๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์ž‘๋™๋ฐฉ์‹์€ ์ค‘์š”ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ด์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. +์ด๋Ÿฐ ์ž‘๋™ ๋ฐฉ์‹์€ ์ค‘์š”ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ด์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. -alert ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๋ชจ๋“ˆ(`alert.js`)์„ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ๋กœ ํ•ด๋ด…์‹œ๋‹ค. alert ์ฐฝ์€ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. +alert ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๋ชจ๋“ˆ(`alert.js`)์„ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ๋กœ ํ•ด๋ด…์‹œ๋‹ค. ์–ผ๋Ÿฟ ์ฐฝ์€ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ```js // ๐Ÿ“ alert.js @@ -129,7 +133,7 @@ import `./alert.js`; // ์–ผ๋Ÿฟ์ฐฝ์— '๋ชจ๋“ˆ์ด ํ‰๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค!'๊ฐ€ ์ถœ import `./alert.js`; // ์•„๋ฌด ์ผ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` -์‹ค๋ฌด์—์„  ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ ๋ชจ๋“ˆ์„ ๋Œ€๊ฒŒ ์ดˆ๊ธฐํ™”๋‚˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์„ ๋‚ด๋ณด๋‚ด ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์ฃ . +์‹ค๋ฌด์—์„  ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ ๋ชจ๋“ˆ์„ ๋Œ€๊ฐœ ์ดˆ๊ธฐํ™”๋‚˜ ๋‚ด๋ถ€์—์„œ ์“ฐ์ด๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ๋‚ด๋ณด๋‚ด ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ข€ ๋” ์–ด๋ ค์šด ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -142,7 +146,7 @@ export let admin = { }; ``` -์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ ๊ฐœ์ด๋”๋ผ๋„ ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ชจ๋“ˆ์€ ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ `admin` ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์— `admin` ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. +์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ ๊ฐœ์ด๋”๋ผ๋„ ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“ˆ์€ ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ `admin` ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์— `admin` ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ชจ๋“ˆ์— ๋™์ผํ•œ `admin` ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์ด์ฃ . @@ -163,7 +167,7 @@ alert(admin.name); // Pete ์ž, ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์€ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๊ณ  ์‹คํ–‰๋œ ๋ชจ๋“ˆ์€ ํ•„์š”ํ•œ ๊ณณ์— ๊ณต์œ ๋˜๋ฏ€๋กœ ์–ด๋А ํ•œ ๋ชจ๋“ˆ์—์„œ `admin` ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ๋„ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•˜๋ฉด ๋ชจ๋“ˆ *์„ค์ •*์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ดˆ๋กœ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“ˆ์˜ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋ฅผ ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ค์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ด ์„ค์ •์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . +์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•˜๋ฉด ๋ชจ๋“ˆ *์„ค์ •(configuration)*์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ดˆ๋กœ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“ˆ์˜ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋ฅผ ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ค์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ด ์„ค์ •์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ด์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค. ์•„๋ž˜ `admin.js` ๋ชจ๋“ˆ์€ ์–ด๋–ค ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ฃผ๋Š”๋ฐ, ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์™ธ๋ถ€์—์„œ `admin` ๊ฐ์ฒด์™€ ๊ด€๋ จ๋œ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. @@ -181,7 +185,7 @@ export function sayHi() { ```js // ๐Ÿ“ init.js import {admin} from './admin.js'; -admin.name = "Pete"; +admin.name = "๋ณด๋ผ"; ``` ๋˜ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ๋„ `admin.name`์— ์ €์žฅ๋œ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. @@ -190,16 +194,16 @@ admin.name = "Pete"; // ๐Ÿ“ other.js import {admin, sayHi} from './admin.js'; -alert(admin.name); // *!*Pete*/!* +alert(admin.name); // *!*๋ณด๋ผ*/!* -sayHi(); // *!*Pete*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! +sayHi(); // *!*๋ณด๋ผ*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! ``` ### import.meta `import.meta` ๊ฐ์ฒด๋Š” ํ˜„์žฌ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค. -ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ œ๊ณตํ•˜๋Š” ์ •๋ณด์˜ ๋‚ด์šฉ์€ ๋‹ค๋ฅธ๋ฐ, ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„  ์Šคํฌ๋ฆฝํŠธ์˜ url ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. HTML ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“ˆ์ด๋ผ๋ฉด, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์›นํŽ˜์ด์ง€์˜ url ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ œ๊ณตํ•˜๋Š” ์ •๋ณด์˜ ๋‚ด์šฉ์€ ๋‹ค๋ฅธ๋ฐ, ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„  ์Šคํฌ๋ฆฝํŠธ์˜ URL ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. HTML ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“ˆ์ด๋ผ๋ฉด, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์›นํŽ˜์ด์ง€์˜ URL ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run height=0 ``` -### "this"๋Š” undefined +### this๋Š” undefined ์‚ฌ์†Œํ•œ ๋‚ด์šฉ์ด์ง€๋งŒ ํŠœํ† ๋ฆฌ์–ผ์˜ ์™„์ „์„ฑ์„ ์œ„ํ•ด ์ด ๋‚ด์šฉ์„ ์–ธ๊ธ‰ํ•˜๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. @@ -240,14 +244,14 @@ sayHi(); // *!*Pete*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! - ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋Š” HTML ๋ฌธ์„œ๊ฐ€ ์™„์ „ํžˆ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์ƒํƒœ์— ์žˆ๋‹ค๊ฐ€ HTML ๋ฌธ์„œ๊ฐ€ ์™„์ „ํžˆ ๋งŒ๋“ค์–ด์ง„ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์˜ ํฌ๊ธฐ๊ฐ€ ์•„์ฃผ ์ž‘์•„์„œ HTML๋ณด๋‹ค ๋นจ๋ฆฌ ๋ถˆ๋Ÿฌ์˜จ ๊ฒฝ์šฐ์—๋„ ๋ง์ด์ฃ . - ์Šคํฌ๋ฆฝํŠธ์˜ ์ƒ๋Œ€์  ์ˆœ์„œ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ์ƒ ์œ„์ชฝ์˜ ์Šคํฌ๋ฆฝํŠธ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•ญ์ƒ ์™„์ „ํ•œ HTML ํŽ˜์ด์ง€๋ฅผ "๋ณผ ์ˆ˜" ์žˆ๊ณ  ๋ฌธ์„œ ๋‚ด ์š”์†Œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•ญ์ƒ ์™„์ „ํ•œ HTML ํŽ˜์ด์ง€๋ฅผ '๋ณผ ์ˆ˜' ์žˆ๊ณ  ๋ฌธ์„œ ๋‚ด ์š”์†Œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: ```html run @@ -268,15 +272,15 @@ sayHi(); // *!*Pete*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋Š” ์ง€์—ฐ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์„œ ์ „์ฒด๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ธฐ ์ „๊นŒ์ง€ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฐ”๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ์œ„์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. -๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋• HTML ํŽ˜์ด์ง€๊ฐ€ ์™„์ „ํžˆ ๋‚˜ํƒ€๋‚œ ์ดํ›„์— ๋ชจ๋“ˆ์ด ์‹คํ–‰๋œ๋‹ค๋Š” ์ ์— ํ•ญ์ƒ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ๋‚ด ํŠน์ • ๊ธฐ๋Šฅ์ด ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ์— ์˜์กด์ ์ธ ๊ฒฝ์šฐ, ๋ชจ๋“ˆ์ด ์™„์ „ํžˆ ๋กœ๋”ฉ๋˜๊ธฐ ์ „์— ํŽ˜์ด์ง€๋งŒ ๋จผ์ € ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœ๋˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ผ๋ž€์„ ๋А๋‚„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ์—” ํˆฌ๋ช… ์˜ค๋ฒ„๋ ˆ์ด๋‚˜ "๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ(loading indicator)"๋ฅผ ๋ณด์—ฌ์ฃผ์–ด ์‚ฌ์šฉ์ž์˜ ํ˜ผ๋ž€์„ ์˜ˆ๋ฐฉํ•ด ์ฃผ๋„๋ก ํ•ฉ์‹œ๋‹ค. +๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋• HTML ํŽ˜์ด์ง€๊ฐ€ ์™„์ „ํžˆ ๋‚˜ํƒ€๋‚œ ์ดํ›„์— ๋ชจ๋“ˆ์ด ์‹คํ–‰๋œ๋‹ค๋Š” ์ ์— ํ•ญ์ƒ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ๋‚ด ํŠน์ • ๊ธฐ๋Šฅ์ด ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ์— ์˜์กด์ ์ธ ๊ฒฝ์šฐ, ๋ชจ๋“ˆ์ด ์™„์ „ํžˆ ๋กœ๋”ฉ๋˜๊ธฐ ์ „์— ํŽ˜์ด์ง€๊ฐ€ ๋จผ์ € ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœ๋˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ผ๋ž€์„ ๋А๋‚„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ์—” ํˆฌ๋ช… ์˜ค๋ฒ„๋ ˆ์ด๋‚˜ '๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ(loading indicator)'๋ฅผ ๋ณด์—ฌ์ฃผ์–ด ์‚ฌ์šฉ์ž์˜ ํ˜ผ๋ž€์„ ์˜ˆ๋ฐฉํ•ด ์ฃผ๋„๋ก ํ•ฉ์‹œ๋‹ค. ### ์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ชจ๋“ˆ์ด ์•„๋‹Œ ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ `async` ์†์„ฑ์€ ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋งŒ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. `async` ์†์„ฑ์ด ๋ถ™์€ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋กœ๋”ฉ์ด ๋๋‚˜๋ฉด ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋‚˜ HTML ๋ฌธ์„œ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -๋ฐ˜๋ฉด, ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ์—์„  ์™ธ๋ถ€/๋‚ด๋ถ€ ์Šคํฌ๋ฆฝํŠธ ์ƒ๊ด€์—†์ด `async` ์†์„ฑ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ฐ˜๋ฉด, ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ์—์„  `async` ์†์„ฑ์„ ์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜ ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ์—” `async` ์†์„ฑ์ด ๋ถ™์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋‚˜ HTML์ด ์ฒ˜๋ฆฌ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ์—” `async` ์†์„ฑ์ด ๋ถ™์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋‚˜ HTML์ด ์ฒ˜๋ฆฌ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ฐ€์ ธ์˜ค๊ธฐ(`./analytics.js`) ์ž‘์—…์ด ๋๋‚˜๋ฉด HTML ํŒŒ์‹ฑ์ด ๋๋‚˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋Œ€๊ธฐ ์ƒํƒœ์— ์žˆ๋”๋ผ๋„ ๋ชจ๋“ˆ์ด ๋ฐ”๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @@ -298,7 +302,7 @@ sayHi(); // *!*Pete*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! 1. `src` ์†์„ฑ๊ฐ’์ด ๋™์ผํ•œ ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ```html - + ``` @@ -312,9 +316,9 @@ sayHi(); // *!*Pete*/!*๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! ์ด ํŠน์ง•์€ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•ด ์ค๋‹ˆ๋‹ค. -### "๊ฒฝ๋กœ๊ฐ€ ์—†๋Š”" ๋ชจ๋“ˆ์€ ๊ธˆ์ง€ +### ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ๋ชจ๋“ˆ์€ ๊ธˆ์ง€ -๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ `import`๋Š” ๋ฐ˜๋“œ์‹œ ์ƒ๋Œ€ ํ˜น์€ ์ ˆ๋Œ€ URL ์•ž์— ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ๋ชจ๋“ˆ์€ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ `import`๋Š” ๋ฐ˜๋“œ์‹œ ์ƒ๋Œ€ ํ˜น์€ ์ ˆ๋Œ€ URL ์•ž์— ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. '๊ฒฝ๋กœ๊ฐ€ ์—†๋Š”' ๋ชจ๋“ˆ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ `import`๋Š” ๋ฌดํšจํ•ฉ๋‹ˆ๋‹ค. ```js @@ -322,9 +326,9 @@ import {sayHi} from 'sayHi'; // Error! // './sayHi.js'์™€ ๊ฐ™์ด ๊ฒฝ๋กœ ์ •๋ณด๋ฅผ ์ง€์ •ํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ``` -Node.js๋‚˜ ๋ฒˆ๋“ค๋ง ํˆด์€ ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด๋„ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ์ฐพ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฒฝ๋กœ ์—†๋Š” ๋ชจ๋“ˆ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +Node.js๋‚˜ ๋ฒˆ๋“ค๋ง ํˆด์€ ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด๋„ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฒฝ๋กœ ์—†๋Š” ๋ชจ๋“ˆ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -### ํ˜ธํ™˜์„ ์œ„ํ•œ "nomodule" +### ํ˜ธํ™˜์„ ์œ„ํ•œ nomodule ๊ตฌ์‹ ๋ธŒ๋ผ์šฐ์ €๋Š” `type="module"`์„ ํ•ด์„ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ ํƒ€์ž…์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋‚˜๋ฉด ์ด๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. `nomodule` ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋Œ€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -335,29 +339,29 @@ Node.js๋‚˜ ๋ฒˆ๋“ค๋ง ํˆด์€ ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด๋„ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ์ฐพ์ˆ˜ ์žˆ๋Š” ``` ## ๋นŒ๋“œ ํˆด -๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ชจ๋“ˆ์„ "๋‹จ๋…"์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€๊ฒŒ [์›นํŒฉ(Webpack)](https://webpack.js.org/)๊ณผ ๊ฐ™์€ ํŠน๋ณ„ํ•œ ํˆด์„ ์‚ฌ์šฉํ•ด ๋ชจ๋“ˆ์„ ํ•œ ๋ฐ ๋ฌถ์–ด(๋ฒˆ๋“ค๋ง) ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„์— ์˜ฌ๋ฆฌ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ชจ๋“ˆ์„ '๋‹จ๋…'์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€๊ฐœ [์›นํŒฉ(Webpack)](https://webpack.js.org/)๊ณผ ๊ฐ™์€ ํŠน๋ณ„ํ•œ ํˆด์„ ์‚ฌ์šฉํ•ด ๋ชจ๋“ˆ์„ ํ•œ ๋ฐ ๋ฌถ์–ด(๋ฒˆ๋“ค๋ง) ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„์— ์˜ฌ๋ฆฌ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“ˆ ๋ถ„ํ•ด๋ฅผ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ๋ชจ๋“ˆ์ด๋‚˜ CSS, HTML ํฌ๋งท์˜ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ ํˆด์˜ ์—ญํ• ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. HTML์˜ ` - + diff --git a/1-js/13-modules/03-modules-dynamic-imports/say.view/say.js b/1-js/13-modules/03-modules-dynamic-imports/say.view/say.js index cff234b7c5..7c39106b44 100644 --- a/1-js/13-modules/03-modules-dynamic-imports/say.view/say.js +++ b/1-js/13-modules/03-modules-dynamic-imports/say.view/say.js @@ -1,11 +1,11 @@ export function hi() { - alert(`Hello`); + alert(`์•ˆ๋…•ํ•˜์„ธ์š”.`); } export function bye() { - alert(`Bye`); + alert(`์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”.`); } export default function() { - alert("Module loaded (export default)!"); + alert("export defaultํ•œ ๋ชจ๋“ˆ์„ ๋ถˆ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค!"); } diff --git a/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md b/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md index 6489585301..357a573134 100644 --- a/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md +++ b/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md @@ -19,5 +19,5 @@ function wrap(target) { user = wrap(user); alert(user.name); // John -alert(user.age); // ReferenceError: Property doesn't exist +alert(user.age); // ReferenceError: Property doesn't exist "age" ``` diff --git a/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md b/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md index cb35c527f1..67e853f537 100644 --- a/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md +++ b/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md @@ -27,6 +27,6 @@ user = wrap(user); alert(user.name); // John *!* -alert(user.age); // Error: Property doesn't exist +alert(user.age); // ReferenceError: Property doesn't exist "age" */!* ``` diff --git a/1-js/99-js-misc/01-proxy/03-observable/task.md b/1-js/99-js-misc/01-proxy/03-observable/task.md index 013d38dd89..52f2280fd4 100644 --- a/1-js/99-js-misc/01-proxy/03-observable/task.md +++ b/1-js/99-js-misc/01-proxy/03-observable/task.md @@ -20,7 +20,7 @@ user.observe((key, value) => { user.name = "John"; // alerts: SET name=John ``` -`makeObservable`๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด๋Š” ๊ธฐ์กด ๊ฐ์ฒด์™€ ๋™์ผ์ง€๋งŒ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ธ `handler`๋ฅผ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ `observe(handler)`๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`makeObservable`๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด๋Š” ๊ธฐ์กด ๊ฐ์ฒด์™€ ๋™์ผํ•˜์ง€๋งŒ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ธ `handler`๋ฅผ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ `observe(handler)`๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ”„๋กœํผํ‹ฐ ํ‚ค์™€ ๊ฐ’์„ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ `handler(key, value)`๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜์ฃ . diff --git a/1-js/99-js-misc/01-proxy/article.md b/1-js/99-js-misc/01-proxy/article.md index b33eba0997..4c8d328819 100644 --- a/1-js/99-js-misc/01-proxy/article.md +++ b/1-js/99-js-misc/01-proxy/article.md @@ -2,7 +2,9 @@ `Proxy`๋Š” ํŠน์ • ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ ํ”„๋กœํผํ‹ฐ ์ฝ๊ธฐ, ์“ฐ๊ธฐ์™€ ๊ฐ™์€ ๊ฐ์ฒด์— ๊ฐ€ํ•ด์ง€๋Š” ์ž‘์—…์„ ์ค‘๊ฐ„์—์„œ ๊ฐ€๋กœ์ฑ„๋Š” ๊ฐ์ฒด๋กœ, ๊ฐ€๋กœ์ฑ„์ง„ ์ž‘์—…์€ `Proxy` ์ž์ฒด์—์„œ ์ฒ˜๋ฆฌ๋˜๊ธฐ๋„ ํ•˜๊ณ , ์›๋ž˜ ๊ฐ์ฒด๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. -ํ”„๋ฝ์‹œ๋Š” ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ € ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ํ”„๋ฝ์‹œ๋ฅผ ์–ด๋–ป๊ฒŒ ์‹ค๋ฌด์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์„์ง€ ๋‹ค์–‘ํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +ํ”„๋ฝ์‹œ๋Š” ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ € ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ํ”„๋ฝ์‹œ๋ฅผ ์–ด๋–ป๊ฒŒ ์‹ค๋ฌด์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์„์ง€ ๋‹ค์–‘ํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. + +## Proxy ๋ฌธ๋ฒ•: @@ -13,7 +15,7 @@ let proxy = new Proxy(target, handler) - `target` -- ๊ฐ์‹ธ๊ฒŒ ๋  ๊ฐ์ฒด๋กœ, ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - `handler` -- ๋™์ž‘์„ ๊ฐ€๋กœ์ฑ„๋Š” ๋ฉ”์„œ๋“œ์ธ 'ํŠธ๋žฉ(trap)'์ด ๋‹ด๊ธด ๊ฐ์ฒด๋กœ, ์—ฌ๊ธฐ์„œ ํ”„๋ฝ์‹œ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ์‹œ: `get` ํŠธ๋žฉ์€ `target`์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋•Œ, `set` ํŠธ๋žฉ์€ `target`์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์“ธ ๋•Œ ํ™œ์„ฑํ™”๋จ). -`proxy`์— ์ž‘์—…์ด ๊ฐ€ํ•ด์ง€๊ณ , `handler`์— ์ƒ์‘ํ•˜๋Š” ํŠธ๋žฉ์ด ์žˆ์œผ๋ฉด ํŠธ๋žฉ์ด ์‹คํ–‰๋˜์–ด ํ”„๋ฝ์‹œ๊ฐ€ ์ด ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๊ธฐํšŒ๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํŠธ๋žฉ์ด ์—†์œผ๋ฉด ์ž‘์—…์€ `target`์— ์ง์ ‘ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. +`proxy`์— ์ž‘์—…์ด ๊ฐ€ํ•ด์ง€๊ณ , `handler`์— ์ž‘์—…๊ณผ ์ƒ์‘ํ•˜๋Š” ํŠธ๋žฉ์ด ์žˆ์œผ๋ฉด ํŠธ๋žฉ์ด ์‹คํ–‰๋˜์–ด ํ”„๋ฝ์‹œ๊ฐ€ ์ด ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๊ธฐํšŒ๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํŠธ๋žฉ์ด ์—†์œผ๋ฉด `target`์— ์ž‘์—…์ด ์ง์ ‘ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋จผ์ €, ํŠธ๋žฉ์ด ์—†๋Š” ํ”„๋ฝ์‹œ๋ฅผ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. @@ -45,7 +47,7 @@ for(let key in proxy) alert(key); // test, ๋ฐ˜๋ณต๋„ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- (3) ๊ทธ ์ „์— ๋จผ์ €, ํŠธ๋žฉ์„ ์‚ฌ์šฉํ•ด ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์€ ๋ฌด์—‡์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. -๊ฐ์ฒด์— ์–ด๋–ค ์ž‘์—…์„ ํ•  ๋•, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์— ์ •์˜๋œ '๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ(internal method)'๊ฐ€ ๊นŠ์ˆ™ํ•œ ๊ณณ์—์„œ ๊ด€์—ฌํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋• `[[Get]]`์ด๋ผ๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๊ฐ€, ํ”„๋กœํผํ‹ฐ์— ์“ธ ๋• `[[Set]]`์ด๋ผ๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ด€์—ฌํ•˜๊ฒŒ ๋˜์ฃ . ์ด๋Ÿฐ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋“ค์€ ๋ช…์„ธ์„œ์—๋งŒ ์ •์˜๋œ ๋ฉ”์„œ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํ˜ธ์ถœํ•  ์ˆœ ์—†์Šต๋‹ˆ๋‹ค. +๊ฐ์ฒด์— ์–ด๋–ค ์ž‘์—…์„ ํ•  ๋• ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์— ์ •์˜๋œ '๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ(internal method)'๊ฐ€ ๊นŠ์ˆ™ํ•œ ๊ณณ์—์„œ ๊ด€์—ฌํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋• `[[Get]]`์ด๋ผ๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๊ฐ€, ํ”„๋กœํผํ‹ฐ์— ์“ธ ๋• `[[Set]]`์ด๋ผ๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ด€์—ฌํ•˜๊ฒŒ ๋˜์ฃ . ์ด๋Ÿฐ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋“ค์€ ๋ช…์„ธ์„œ์—๋งŒ ์ •์˜๋œ ๋ฉ”์„œ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํ˜ธ์ถœํ•  ์ˆœ ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋ฝ์‹œ์˜ ํŠธ๋žฉ์€ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์˜ ํ˜ธ์ถœ์„ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค. ํ”„๋ฝ์‹œ๊ฐ€ ๊ฐ€๋กœ์ฑ„๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ ๋ฆฌ์ŠคํŠธ๋Š” [๋ช…์„ธ์„œ](https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์•„๋ž˜ ํ‘œ์—๋„ ์ด๋ฅผ ์ •๋ฆฌํ•ด ๋†“์•˜์Šต๋‹ˆ๋‹ค. @@ -70,7 +72,7 @@ for(let key in proxy) alert(key); // test, ๋ฐ˜๋ณต๋„ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- (3) ```warn header="๊ทœ์น™" ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋‚˜ ํŠธ๋žฉ์„ ์“ธ ๋• ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ •ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ทœ์น™(invariant)์„ ๋ฐ˜๋“œ์‹œ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -๋Œ€๋ถ€๋ถ„์˜ ์กฐ๊ฑด์€ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ๊ด€๋ จ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. +๋Œ€๋ถ€๋ถ„์˜ ๊ทœ์น™์€ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ๊ด€๋ จ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. - ๊ฐ’์„ ์“ฐ๋Š” ๊ฒŒ ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ์œผ๋ฉด `[[Set]]`์€ ๋ฐ˜๋“œ์‹œ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” `false`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - ๊ฐ’์„ ์ง€์šฐ๋Š” ๊ฒŒ ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ์œผ๋ฉด `[[Delete]]`๋Š” ๋ฐ˜๋“œ์‹œ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” `false`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - ๊ธฐํƒ€ ๋“ฑ๋“ฑ(์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ๋” ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.) @@ -78,14 +80,14 @@ for(let key in proxy) alert(key); // test, ๋ฐ˜๋ณต๋„ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- (3) ์ด ์™ธ์— ๋‹ค๋ฅธ ์กฐ๊ฑด๋„ ์žˆ์Šต๋‹ˆ๋‹ค. - ํ”„๋ฝ์‹œ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ `[[GetPrototypeOf]]`๊ฐ€ ์ ์šฉ๋˜๋ฉด ํ”„๋ฝ์‹œ ๊ฐ์ฒด์˜ ํƒ€๊นƒ ๊ฐ์ฒด์— `[[GetPrototypeOf]]`๋ฅผ ์ ์šฉํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ฝ์‹œ์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์ฝ๋Š” ๊ฒƒ์€ ํƒ€๊นƒ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์ฝ๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ด์•ผ ํ•˜์ฃ . -ํŠธ๋žฉ์ด ์—ฐ์‚ฐ์„ ๊ฐ€๋กœ์ฑŒ ๋• ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ทœ์น™์„ ๋”ฐ๋ผ์•ผ ํ•˜์ฃ . +ํŠธ๋žฉ์ด ์—ฐ์‚ฐ์„ ๊ฐ€๋กœ์ฑŒ ๋• ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ทœ์น™์„ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -๊ทœ์น™์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ผ๊ด€๋œ ๋™์ž‘์„ ํ•˜๊ณ  ์ž˜๋ชป๋œ ๋™์ž‘์ด ์žˆ์œผ๋ฉด ์ด๋ฅผ ๊ณ ์ณ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™ ๋ชฉ๋ก์€ [๋ช…์„ธ์„œ](https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ƒํ•œ ์ง“์„ ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ์ด ๊ทœ์น™์„ ์–ด๊ธธ ์ผ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. +์ด์™€ ๊ฐ™์€ ๊ทœ์น™์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ผ๊ด€๋œ ๋™์ž‘์„ ํ•˜๊ณ  ์ž˜๋ชป๋œ ๋™์ž‘์ด ์žˆ์œผ๋ฉด ์ด๋ฅผ ๊ณ ์ณ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™ ๋ชฉ๋ก์€ [๋ช…์„ธ์„œ](https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„์ฃผ ์ด์ƒํ•œ ์ง“์„ ํ•˜์ง€ ์•Š๋Š”ํ•œ ์ด ๊ทœ์น™์„ ์–ด๊ธธ ์ผ์€ ๊ฑฐ์˜ ์—†์„๊ฒ๋‹ˆ๋‹ค. ``` ์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹ค์šฉ์ ์ธ ์˜ˆ์‹œ๋“ค์„ ์‚ดํŽด๋ณด๋ฉด์„œ ํ”„๋ฝ์‹œ ๊ฐ์ฒด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. -## 'get' ํŠธ๋žฉ์œผ๋กœ ํ”„๋กœํผํ‹ฐ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ +## get ํŠธ๋žฉ์œผ๋กœ ํ”„๋กœํผํ‹ฐ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ ๊ฐ€์žฅ ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํŠธ๋žฉ์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํŠธ๋žฉ์ž…๋‹ˆ๋‹ค. @@ -95,7 +97,7 @@ for(let key in proxy) alert(key); // test, ๋ฐ˜๋ณต๋„ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- (3) - `target` -- ๋™์ž‘์„ ์ „๋‹ฌํ•  ๊ฐ์ฒด๋กœ `new Proxy`์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž์ž…๋‹ˆ๋‹ค. - `property` -- ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„ -- `receiver` -- ํƒ€๊นƒ ํ”„๋กœํผํ‹ฐ๊ฐ€ getter๋ผ๋ฉด `receiver`๋Š” getter๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ `this` ์ž…๋‹ˆ๋‹ค. ๋Œ€๊ฒŒ๋Š” `proxy` ๊ฐ์ฒด ์ž์‹ ์ด `this`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ฝ์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ `this`๊ฐ€ ๋˜๊ธฐ๋„ ํ•˜์ฃ . ์ง€๊ธˆ ๋‹น์žฅ์€ ์ด ์ธ์ˆ˜๊ฐ€ ํ•„์š” ์—†์œผ๋ฏ€๋กœ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‚˜์ค‘์— ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +- `receiver` -- ํƒ€๊นƒ ํ”„๋กœํผํ‹ฐ๊ฐ€ getter๋ผ๋ฉด `receiver`๋Š” getter๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ `this` ์ž…๋‹ˆ๋‹ค. ๋Œ€๊ฐœ๋Š” `proxy` ๊ฐ์ฒด ์ž์‹ ์ด `this`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ฝ์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ `this`๊ฐ€ ๋˜๊ธฐ๋„ ํ•˜์ฃ . ์ง€๊ธˆ ๋‹น์žฅ์€ ์ด ์ธ์ˆ˜๊ฐ€ ํ•„์š” ์—†์œผ๋ฏ€๋กœ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‚˜์ค‘์— ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. `get`์„ ํ™œ์šฉํ•ด ๊ฐ์ฒด์— ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -179,7 +181,7 @@ dictionary = new Proxy(dictionary, ...); ํƒ€๊นƒ ๊ฐ์ฒด์˜ ์œ„์น˜์™€ ์ƒ๊ด€์—†์ด ํ”„๋ฝ์‹œ ๊ฐ์ฒด๋Š” ํƒ€๊นƒ ๊ฐ์ฒด๋ฅผ ๋ฎ์–ด์จ์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ํ”„๋ฝ์‹œ๋กœ ๊ฐ์‹ผ ์ดํ›„์—” ์ ˆ๋Œ€๋กœ ํƒ€๊นƒ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์—‰๋ง์ด ๋  ํ™•๋ฅ ์ด ์•„์ฃผ ๋†’์•„์ง‘๋‹ˆ๋‹ค. ```` -## 'set' ํŠธ๋žฉ์œผ๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’ ๊ฒ€์ฆํ•˜๊ธฐ +## set ํŠธ๋žฉ์œผ๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’ ๊ฒ€์ฆํ•˜๊ธฐ ์ˆซ์ž๋งŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ์ˆซ์žํ˜•์ด ์•„๋‹Œ ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋„๋ก ํ•ด์•ผ๊ฒ ์ฃ . @@ -237,7 +239,7 @@ alert("์œ—์ค„์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ค„์€ ์ ˆ๋Œ€ ์‹คํ–‰๋˜ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ falsyํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋ฉด `TypeError`๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ``` -## 'ownKeys'์™€ 'getOwnPropertyDescriptor'๋กœ ๋ฐ˜๋ณต ์ž‘์—…ํ•˜๊ธฐ +## ownKeys์™€ getOwnPropertyDescriptor๋กœ ๋ฐ˜๋ณต ์ž‘์—…ํ•˜๊ธฐ `Object.keys`, `for..in` ๋ฐ˜๋ณต๋ฌธ์„ ๋น„๋กฏํ•œ ํ”„๋กœํผํ‹ฐ ์ˆœํ™˜ ๊ด€๋ จ ๋ฉ”์„œ๋“œ ๋Œ€๋‹ค์ˆ˜๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ `[[OwnPropertyKeys]]`(ํŠธ๋žฉ ๋ฉ”์„œ๋“œ๋Š” `ownKeys`์ž„)๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์„ ์–ป์Šต๋‹ˆ๋‹ค. @@ -310,7 +312,7 @@ user = new Proxy(user, { return { enumerable: true, configurable: true - /* ์ด ์™ธ์˜ ํ”Œ๋ž˜๊ทธ๋„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "value:..."๋„ ๊ฐ€๋Šฅํ•˜์ฃ . */ + /* ์ด ์™ธ์˜ ํ”Œ๋ž˜๊ทธ๋„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "value:..."๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. */ }; } @@ -321,7 +323,7 @@ alert( Object.keys(user) ); // a, b, c ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์„ ๋•Œ `[[GetOwnProperty]]`๋งŒ ๊ฐ€๋กœ์ฑ„๋ฉด ๋œ๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ƒ๊ธฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -## 'deleteProperty'์™€ ์—ฌ๋Ÿฌ ํŠธ๋žฉ์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ ๋ณดํ˜ธํ•˜๊ธฐ +## deleteProperty์™€ ์—ฌ๋Ÿฌ ํŠธ๋žฉ์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ ๋ณดํ˜ธํ•˜๊ธฐ `_`(๋ฐ‘์ค„)์ด ์•ž์— ๋ถ™์€ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€์šฉ์œผ๋กœ๋งŒ ์“ฐ๋„๋ก ํ•˜๋Š” ์ปจ๋ฒค์…˜์€ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ์ปจ๋ฒค์…˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. `_`์ด ์•ž์— ๋ถ™์œผ๋ฉด ๊ฐ์ฒด ๋ฐ”๊นฅ์—์„  ์ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•ด์„  ์•ˆ ๋ฉ๋‹ˆ๋‹ค. @@ -451,7 +453,7 @@ user = { ๊ทธ๋Ÿฐ๋ฐ private ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ``` -## 'has' ํŠธ๋žฉ์œผ๋กœ '๋ฒ”์œ„` ๋‚ด ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ +## has ํŠธ๋žฉ์œผ๋กœ '๋ฒ”์œ„' ๋‚ด ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ ์ข€ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. @@ -485,7 +487,7 @@ range = new Proxy(range, { *!* has(target, prop) { */!* - return prop >= target.start && prop <= target.end + return prop >= target.start && prop <= target.end; } }); @@ -497,7 +499,7 @@ alert(50 in range); // false ์ •๋ง ๋ฉ‹์ง„ ํŽธ์˜ ๋ฌธ๋ฒ•์ด์ง€ ์•Š๋‚˜์š”? ๊ตฌํ˜„๋„ ์•„์ฃผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. -## 'apply' ํŠธ๋žฉ์œผ๋กœ ํ•จ์ˆ˜ ๊ฐ์‹ธ๊ธฐ [#proxy-apply] +## apply ํŠธ๋žฉ์œผ๋กœ ํ•จ์ˆ˜ ๊ฐ์‹ธ๊ธฐ [#proxy-apply] ํ•จ์ˆ˜ ์—ญ์‹œ ํ”„๋ฝ์‹œ๋กœ ๊ฐ์Œ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -507,7 +509,7 @@ alert(50 in range); // false - `thisArg` -- `this`์˜ ๊ฐ’ - `args` -- ์ธ์ˆ˜ ๋ชฉ๋ก - ์ฑ•ํ„ฐ์—์„œ ์‚ดํŽด๋ณด์•˜๋˜ `delay(f, ms)` ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(decorator)๋ฅผ ๋– ์˜ฌ๋ ค๋ด…์‹œ๋‹ค. +์—์„œ ์‚ดํŽด๋ณด์•˜๋˜ `delay(f, ms)` ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(decorator)๋ฅผ ๋– ์˜ฌ๋ ค๋ด…์‹œ๋‹ค. ํ•ด๋‹น ์ฑ•ํ„ฐ ์—์„  ํ”„๋ฝ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. `delay(f, ms)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜ `f`๊ฐ€ `ms`๋ฐ€๋ฆฌ์ดˆ ํ›„์— ํ˜ธ์ถœ๋˜๋„๋ก ํ•ด์ฃผ์—ˆ์ฃ . @@ -587,13 +589,13 @@ sayHi("John"); // Hello, John! (3์ดˆ ํ›„) ์ข€ ๋” ์„ฑ๋Šฅ์ด ์ข‹์€ ๋ž˜ํผ๋ฅผ ๊ฐ–๊ฒŒ ๋˜์—ˆ๋„ค์š”. -์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ํŠธ๋žฉ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋žฉ ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋Š” ์ƒ๋‹จ๋ถ€ ํ‘œ์— ์ •๋ฆฌ๋˜์–ด์žˆ์œผ๋‹ˆ ํ™•์ธํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ์˜ˆ์‹œ๋ฅผ ์‘์šฉํ•˜๋ฉด ์ถฉ๋ถ„ํžˆ ํ”„๋ฝ์‹œ๋ฅผ ํ™œ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. +์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ํŠธ๋žฉ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋žฉ ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋Š” ์œ„์ชฝ ํ‘œ์— ์ •๋ฆฌ๋˜์–ด์žˆ์œผ๋‹ˆ ํ™•์ธํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ์˜ˆ์‹œ๋ฅผ ์‘์šฉํ•˜๋ฉด ์ถฉ๋ถ„ํžˆ ํ”„๋ฝ์‹œ๋ฅผ ํ™œ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ## Reflect `Reflect` is a built-in object that simplifies creation of `Proxy`. -It was said previously that internal methods, such as `[[Get]]`, `[[Set]]` and others are specifiction only, they can't be called directly. +It was said previously that internal methods, such as `[[Get]]`, `[[Set]]` and others are specification-only, they can't be called directly. The `Reflect` object makes that somewhat possible. Its methods are minimal wrappers around the internal methods. @@ -603,7 +605,7 @@ Here are examples of operations and `Reflect` calls that do the same: |-----------------|----------------|-------------| | `obj[prop]` | `Reflect.get(obj, prop)` | `[[Get]]` | | `obj[prop] = value` | `Reflect.set(obj, prop, value)` | `[[Set]]` | -| `delete obj[prop]` | `Reflect.deleteProperty(obj, prop)` | `[[HasProperty]]` | +| `delete obj[prop]` | `Reflect.deleteProperty(obj, prop)` | `[[Delete]]` | | `new F(value)` | `Reflect.construct(F, value)` | `[[Construct]]` | | ... | ... | ... | @@ -619,7 +621,7 @@ alert(user.name); // John In particular, `Reflect` allows us to call operators (`new`, `delete`...) as functions (`Reflect.construct`, `Reflect.deleteProperty`, ...). That's an interesting capability, but here another thing is important. -**For every internal method, trappable by `Proxy`, there's a corresponding method in `Reflect`, with the same name and arguments as `Proxy` trap.** +**For every internal method, trappable by `Proxy`, there's a corresponding method in `Reflect`, with the same name and arguments as the `Proxy` trap.** So we can use `Reflect` to forward an operation to the original object. @@ -660,7 +662,7 @@ In most cases we can do the same without `Reflect`, for instance, reading a prop ### Proxying a getter -Let's see an example that demonstrates why `Reflect.get` is better. And we'll also see why `get/set` have the fourth argument `receiver`, that we didn't use before. +Let's see an example that demonstrates why `Reflect.get` is better. And we'll also see why `get/set` have the third argument `receiver`, that we didn't use before. We have an object `user` with `_name` property and a getter for it. @@ -685,7 +687,7 @@ let userProxy = new Proxy(user, { alert(userProxy.name); // Guest ``` -The `get` trap is 'transparent' here, it returns the original property, and doesn't do anything else. That's enough for our example. +The `get` trap is "transparent" here, it returns the original property, and doesn't do anything else. That's enough for our example. Everything seems to be all right. But let's make the example a little bit more complex. @@ -838,7 +840,7 @@ So there's no such problem when proxying an array. ### Private fields -The similar thing happens with private class fields. +A similar thing happens with private class fields. For example, `getName()` method accesses the private `#name` property and breaks after proxying: @@ -961,7 +963,7 @@ revoke(); alert(proxy.data); // Error ``` -A call to `revoke()` removes all internal references to the target object from the proxy, so they are no more connected. The target object can be garbage-collected after that. +A call to `revoke()` removes all internal references to the target object from the proxy, so they are no longer connected. The target object can be garbage-collected after that. We can also store `revoke` in a `WeakMap`, to be able to easily find it by a proxy object: diff --git a/1-js/99-js-misc/01-proxy/proxy-inherit-admin.svg b/1-js/99-js-misc/01-proxy/proxy-inherit-admin.svg index a5e158400c..bc6c4ce2f5 100644 --- a/1-js/99-js-misc/01-proxy/proxy-inherit-admin.svg +++ b/1-js/99-js-misc/01-proxy/proxy-inherit-admin.svg @@ -1 +1 @@ -_name: "Guest" name: getter_name: "Admin"user (proxied)original useradmin[[Prototype]] \ No newline at end of file +_name: "Guest" name: getter_name: "Admin"user (proxied)original useradmin[[Prototype]] \ No newline at end of file diff --git a/1-js/99-js-misc/01-proxy/proxy-inherit.svg b/1-js/99-js-misc/01-proxy/proxy-inherit.svg index 510dcef1bd..6c34c0f4ed 100644 --- a/1-js/99-js-misc/01-proxy/proxy-inherit.svg +++ b/1-js/99-js-misc/01-proxy/proxy-inherit.svg @@ -1 +1 @@ -_name: "Guest" name: getteruser (proxied)original user \ No newline at end of file +_name: "Guest" name: getteruser (proxied)original user \ No newline at end of file diff --git a/1-js/99-js-misc/01-proxy/proxy.svg b/1-js/99-js-misc/01-proxy/proxy.svg index 76a41670c0..157e350f44 100644 --- a/1-js/99-js-misc/01-proxy/proxy.svg +++ b/1-js/99-js-misc/01-proxy/proxy.svg @@ -1 +1 @@ -test: 5proxytargetget proxy.test5 \ No newline at end of file +test: 5proxytargetget proxy.test5 \ No newline at end of file diff --git a/1-js/99-js-misc/03-currying-partials/article.md b/1-js/99-js-misc/03-currying-partials/article.md index e11aebeb66..e9601348e2 100644 --- a/1-js/99-js-misc/03-currying-partials/article.md +++ b/1-js/99-js-misc/03-currying-partials/article.md @@ -39,7 +39,7 @@ alert( curriedSum(1)(2) ); // 3 ์œ„์˜ ์˜ˆ์‹œ์—์„œ ๋ณด๋“ฏ์ด, ์‹ค์ œ ๊ตฌํ˜„์€ ๊ทธ์ € ๋‘ ๊ฐœ์˜ ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. - `curry(func)`์˜ ๋ฐ˜ํ™˜๊ฐ’์€ `function(a)`ํ˜•ํƒœ์˜ ๋ž˜ํผ์ž…๋‹ˆ๋‹ค. -- `carriedSum`์ด `sum(1)`๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ์ฒ˜๋Ÿผ, ๊ทธ ์ธ์ˆ˜๋Š” ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์— ์ €์žฅ์ด ๋˜๊ณ  ์ƒˆ๋กœ์šด ๋ž˜ํผ `function(b)`์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. +- `curriedSum(1)`๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, ๊ทธ ์ธ์ˆ˜๋Š” ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์— ์ €์žฅ์ด ๋˜๊ณ  ์ƒˆ๋กœ์šด ๋ž˜ํผ `function(b)`์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. - ๊ทธ๋ฆฌ๊ณ  ๋ฐ˜ํ™˜๋œ `function(b)`๋ž˜ํผ ํ•จ์ˆ˜๊ฐ€ `2`๋ฅผ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐ˜ํ™˜๊ฐ’์ด ์›๋ž˜์˜ `sum`์œผ๋กœ ๋„˜๊ฒจ์ ธ์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ [_.curry](https://lodash.com/docs#curry) ๊ฐ™์ด ๋ž˜ํผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ํ•จ์ˆ˜๊ฐ€ ๋ณดํ†ต ๋•Œ์ฒ˜๋Ÿผ ๋˜๋Š” partial ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ๋” ์ง„๋ณด์ ์œผ๋กœ ๊ตฌํ˜„๋œ ์ปค๋ง๋„ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -111,7 +111,7 @@ debugNow("message"); // [HH:mm] DEBUG ๋ฉ”์„ธ์ง€ ## ๊ณ ๊ธ‰ ์ปค๋ฆฌ ๊ตฌํ˜„ -๋งŒ์•ฝ ์ข€ ๋” ๊นŠ์ด ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด (ํ•„์ˆ˜๋Š” ์•„๋‹™๋‹ˆ๋‹ค!), ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ๋‹ค์ค‘-์ธ์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” "๊ณ ๊ธ‰"์ปค๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +์ข€ ๋” ๊นŠ์ด ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ์€ ๋ถ„๋“ค์„ ์œ„ํ•ด ๋‹ค์ค‘-์ธ์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” "๊ณ ๊ธ‰" ์ปค๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๊ฝค ์งง์Šต๋‹ˆ๋‹ค. @@ -175,7 +175,7 @@ function curried(...args) { 2. `pass`๋ž˜ํผ๊ฐ€ `(2)`์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด์ „์˜ ์ธ์ˆ˜์ธ (`1`)์„ ๊ฐ€์ ธ์„œ `(2)`์™€ ์—ฐ๊ฒฐํ•˜๊ณ `curried (1, 2)`๋ฅผ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋Š” ์•„์ง 3๋ณด๋‹ค ์ž‘๊ธฐ๋•Œ๋ฌธ์— `curry`๋Š” `pass`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 3. `pass` ๋ž˜ํผ๊ฐ€ ๋‹ค์‹œ `(3)`๊ณผ ํ•จ๊ป˜ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ํ˜ธ์ถœ์ธ `pass(3)`๊ฐ€ ์ด์ „์˜ ์ธ์ˆ˜๋“ค์ธ (`1`, `2`)๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  `3`์„ ์ถ”๊ฐ€ํ•˜๊ณ  `curried(1, 2, 3)` ํ˜ธ์ถœ์„ ํ•ฉ๋‹ˆ๋‹ค -- ์—ฌ๊ธฐ์— `3`์ธ์ˆ˜๋Š” ๋งˆ์ง€๋ง‰์œผ๋กœ, ์›๋ž˜์˜ ํ•จ์ˆ˜์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. -์•„์ง ํ™•์‹คํ•˜๊ฒŒ ์ดํ•ด๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ๋ฅผ ๋งˆ์Œ์†์ด๋‚˜ ์ข…์ด์— ๊ทธ๋ ค๋ณด์„ธ์š”. +์•„์ง ํ™•์‹คํ•˜๊ฒŒ ์ดํ•ด๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ํ˜ธ์ถœ ์ˆœ์„œ๋ฅผ ๋งˆ์Œ์†์ด๋‚˜ ์ข…์ด์— ๊ทธ๋ ค๋ณด์„ธ์š”. ```smart header="์˜ค์ง ๊ณ ์ •๋œ ๊ธธ์ด์˜ ํ•จ์ˆ˜๋“ค๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค" ์ปค๋ง์€ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ๊ณ ์ •๋œ ๊ฐœ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง€๋„๋ก ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. @@ -191,6 +191,6 @@ function curried(...args) { ## ์š”์•ฝ -*์ปค๋ง*์€ `f(a,b,c)`๋ฅผ `f(a)(b)(c)` ์™€ ๊ฐ™์ด ๋‹ค์ค‘ callable ํ”„๋กœ์„ธ์Šค ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ ์ปค๋ง๋˜์–ด์ง„ ํ•จ์ˆ˜๋Š” ํ‰์†Œ์ฒ˜๋Ÿผ ํ˜ธ์ถœ๋„ ํ•˜๊ณ  ๋งŒ์•ฝ์— ์ธ์ˆ˜๋“ค์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์„ ๋•Œ์—๋Š” partial์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +*์ปค๋ง*์€ `f(a,b,c)`๋ฅผ `f(a)(b)(c)` ์™€ ๊ฐ™์ด ๋‹ค์ค‘ callable ํ”„๋กœ์„ธ์Šค ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ ์ปค๋ง๋˜์–ด์ง„ ํ•จ์ˆ˜๋Š” ํ‰์†Œ์ฒ˜๋Ÿผ ํ˜ธ์ถœ๋„ ํ•˜๊ณ  ๋งŒ์•ฝ์— ์ธ์ˆ˜๋“ค์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์„ ๋•Œ์—๋Š” partial์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -์ปค๋ง์€ partials๋ฅผ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ ์˜ˆ์‹œ์—์„œ ๋ณด์•˜๋“ฏ์ด ๋‹ค๋ชฉ์ ์œผ๋กœ ์“ฐ์˜€๋˜ `log(date, importance, message)` ํ•จ์ˆ˜๋Š” ์ปค๋งํ›„์— `log(date)`๊ฐ™์ด ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง„ ํ˜•ํƒœ๋‚˜ `log(date, importance)`์ฒ˜๋Ÿผ ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง„ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +์ปค๋ง์€ partial์„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ๋กœ๊ทธ ์˜ˆ์‹œ์—์„œ ๋ณด์•˜๋“ฏ์ด ์ปค๋ง์„ ์ ์šฉํ•˜๋ฉด ์ธ์ˆ˜ ์„ธ ๊ฐœ์˜ ๋ฒ”์šฉ ํ•จ์ˆ˜ `log(date, importance, message)`๋ฅผ `log(date)`๊ฐ™์ด ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ˜•ํƒœ๋‚˜ `log(date, importance)`์ฒ˜๋Ÿผ ์ธ์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ธ ํ˜•ํƒœ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md b/1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md new file mode 100644 index 0000000000..e08e77a834 --- /dev/null +++ b/1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md @@ -0,0 +1,37 @@ +**์—๋Ÿฌ**๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค! + +์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•ด๋ด…์‹œ๋‹ค. + +```js run +let user = { + name: "John", + go: function() { alert(this.name) } +} + +(user.go)() // error! +``` + +๋ธŒ๋ผ์šฐ์ €์—์„œ ์ถœ๋ ฅ๋˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋งŒ ๋ด์„œ๋Š” ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒ๋‹ˆ๋‹ค. + +**์—๋Ÿฌ๋Š” `user = {...}`๋’ค์— ์„ธ๋ฏธ์ฝœ๋ก ์ด ์—†์–ด์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.** + +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ด„ํ˜ธ(`(us...` ) ์•ž์— ์„ธ๋ฏธ์ฝœ๋ก ์„ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. + +```js no-beautify +let user = { go:... }(user.go)() +``` + +์ด๋ ‡๊ฒŒ ๋‘ ํ‘œํ˜„์‹์ด ํ•ฉ์ณ์ง€๋ฉด์„œ ์ธ์ˆ˜๊ฐ€ `(user.go)`์ธ ๊ฐ์ฒด ํ˜•ํƒœ์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ ๊ฐ์ฒด `user`๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๊ฐ™์€ ์ค„์— `let user`๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + +`user = {...}`๋’ค์— ์„ธ๋ฏธ์ฝœ๋ก ์„ ๋ถ™์—ฌ์„œ ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•ด๋ด…์‹œ๋‹ค. + +```js run +let user = { + name: "John", + go: function() { alert(this.name) } +}*!*;*/!* + +(user.go)() // John +``` + +์ฐธ๊ณ ๋กœ, `(user.go)`๋ฅผ ๊ฐ์‹ธ๋Š” ๊ด„ํ˜ธ๋Š” ์•„๋ฌด๋Ÿฐ ์—ญํ• ์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ด„ํ˜ธ๋Š” ๋Œ€๊ฐœ ์—ฐ์‚ฐ์ž ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ฐ”๊พธ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š”๋ฐ, `(user.go)`์—์„  ์  `.` ์—ฐ์‚ฐ์ž๊ฐ€ ๋จผ์ € ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ ์ถœ์ œ ์˜๋„๋Š” ์„ธ๋ฏธ์ฝœ๋ก  ์—ฌ๋ถ€์˜€์Šต๋‹ˆ๋‹ค. diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/99-js-misc/04-reference-type/2-check-syntax/task.md similarity index 100% rename from 1-js/04-object-basics/04-object-methods/2-check-syntax/task.md rename to 1-js/99-js-misc/04-reference-type/2-check-syntax/task.md diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/99-js-misc/04-reference-type/3-why-this/solution.md similarity index 67% rename from 1-js/04-object-basics/04-object-methods/3-why-this/solution.md rename to 1-js/99-js-misc/04-reference-type/3-why-this/solution.md index 19bc9ceada..9748f9c2ae 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md +++ b/1-js/99-js-misc/04-reference-type/3-why-this/solution.md @@ -5,7 +5,7 @@ 2. ์—ญ์‹œ ์ผ๋ฐ˜์ ์ธ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•์— ์†ํ•ฉ๋‹ˆ๋‹ค. ๊ด„ํ˜ธ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๊ธด ํ•˜์ง€๋งŒ ์—ฐ์‚ฐ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ฐ”๊พธ์ง„ ์•Š์œผ๋ฏ€๋กœ ์  ์—ฐ์‚ฐ์ž๊ฐ€ ๋จผ์ € ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -3. ์ข€ ๋” ๋ณต์žกํ•œ ํŒจํ„ด์˜ ํ˜ธ์ถœ(`(expression).method()`)์ด ๋“ฑ์žฅํ–ˆ๋„ค์š”. ์„ธ ๋ฒˆ์งธ ํ˜ธ์ถœ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ ๋‘ ์ค„๋กœ ์ชผ๊ฐค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +3. ์ข€ ๋” ๋ณต์žกํ•œ ํŒจํ„ด์˜ ํ˜ธ์ถœ(`(expression).method()`)์ด ๋“ฑ์žฅํ–ˆ๋„ค์š”. ์„ธ ๋ฒˆ์งธ ํ˜ธ์ถœ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋กœ ์ชผ๊ฐค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js no-beautify f = obj.go; // ํ‘œํ˜„์‹ ๊ณ„์‚ฐํ•˜๊ธฐ @@ -16,8 +16,7 @@ 4. `(3)`๊ณผ ๋™์ผํ•œ ํŒจํ„ด์˜ ํ˜ธ์ถœ์ž…๋‹ˆ๋‹ค. `expression`์ด `obj.go || obj.stop`๋ผ๋Š” ์ฐจ์ด์ ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. -`(3)`๊ณผ `(4)`์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ๋ ค๋ฉด ์ฐธ์กฐ ํƒ€์ž…์„ ๋‹ค์‹œ ์ƒ๊ธฐ์‹œํ‚ค์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. - ์ ์ด๋‚˜ ๋Œ€๊ด„ํ˜ธ๋ฅผ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’(`(base, name, strict)`)์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. +`(3)`๊ณผ `(4)`์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ๋ ค๋ฉด ์ฐธ์กฐ ํƒ€์ž…์„ ๋‹ค์‹œ ์ƒ๊ธฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ ์ด๋‚˜ ๋Œ€๊ด„ํ˜ธ๋ฅผ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’(`(base, name, strict)`)์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. -๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์ œ์™ธํ•˜๊ณ , ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’์— ํ–‰ํ•ด์ง€๋Š” ๋ชจ๋“  ์—ฐ์‚ฐ์€ ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’์„ ์ผ๋ฐ˜์ ์ธ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜์‹œํ‚ต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ `this`์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ๋ˆ„๋ฝ๋ฉ๋‹ˆ๋‹ค. +๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์ œ์™ธํ•˜๊ณ , ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’์— ํ–‰ํ•ด์ง€๋Š” ๋ชจ๋“  ์—ฐ์‚ฐ์€ ์ฐธ์กฐ ํƒ€์ž… ๊ฐ’์„ ์ผ๋ฐ˜ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜์‹œํ‚ต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ `this`์— ์ •๋ณด๊ฐ€ ๋ˆ„๋ฝ๋ฉ๋‹ˆ๋‹ค. diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/99-js-misc/04-reference-type/3-why-this/task.md similarity index 75% rename from 1-js/04-object-basics/04-object-methods/3-why-this/task.md rename to 1-js/99-js-misc/04-reference-type/3-why-this/task.md index 9fb0f1378b..f55b86947c 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/task.md +++ b/1-js/99-js-misc/04-reference-type/3-why-this/task.md @@ -2,9 +2,9 @@ importance: 3 --- -# "this" ๊ฐ’ ์•Œ์•„๋‚ด๊ธฐ +# 'this' ๊ฐ’ ์•Œ์•„๋‚ด๊ธฐ -์•„๋ž˜ ์˜ˆ์‹œ์—์„  ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด `user.go()`๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด 4๋ฒˆ ํ˜ธ์ถœํ•˜์˜€๋„ค์š”. +์•„๋ž˜ ์ฝ”๋“œ์—์„  ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ `user.go()`๋ฅผ 4๋ฒˆ ์—ฐ์† ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ฒซ ๋ฒˆ์งธ(`(1)`)์™€ ๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ(`(2)`) ๊ฒฐ๊ณผ๋Š” ์„ธ ๋ฒˆ์งธ(`(3)`)์™€ ๋„ค ๋ฒˆ์งธ(`(4)`) ํ˜ธ์ถœ ๊ฒฐ๊ณผ์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด์œ ๊ฐ€ ๋ญ˜๊นŒ์š”? diff --git a/1-js/99-js-misc/04-reference-type/article.md b/1-js/99-js-misc/04-reference-type/article.md new file mode 100644 index 0000000000..2228ea9399 --- /dev/null +++ b/1-js/99-js-misc/04-reference-type/article.md @@ -0,0 +1,108 @@ + +# ์ฐธ์กฐ ํƒ€์ž… + +```warn header="์‹ฌํ™” ํ•™์Šต" +์ด๋ฒˆ ์ ˆ์—์„  ํŠน์ • ์—์ง€ ์ผ€์ด์Šค(edge case)๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ์‹ฌํ™” ๋‚ด์šฉ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. + +์ˆ™๋ จ๋œ ์ƒ๋‹น์ˆ˜์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด ์ ˆ์—์„œ ๋‹ค๋ฃฐ ๋‚ด์šฉ์„ ๋ชจ๋ฅธ ์ฑ„๋กœ ์ผํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ์—†๊ณ , ์ค‘์š”ํ•œ ๋‚ด์šฉ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด ์ด๋ฒˆ ๊ธ€์€ ๋„˜์–ด๊ฐ€๊ฑฐ๋‚˜ ๋ฏธ๋ค„๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. +``` + +๋ณต์žกํ•œ ์ƒํ™ฉ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `this` ๊ฐ’์„ ์žƒ์–ด๋ฒ„๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. + +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. + +```js run +let user = { + name: "John", + hi() { alert(this.name); }, + bye() { alert("Bye"); } +}; + +user.hi(); // John (๊ฐ„๋‹จํ•œ ํ˜ธ์ถœ์€ ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.) + +// name์— ๋”ฐ๋ผ user.hi๋‚˜ user.bye๊ฐ€ ํ˜ธ์ถœ๋˜๊ฒŒ ํ•ด๋ด…์‹œ๋‹ค. +*!* +(user.name == "John" ? user.hi : user.bye)(); // TypeError: Cannot read property 'name' of undefined +*/!* +``` + +๋งˆ์ง€๋ง‰ ์ค„์—์„œ ์กฐ๊ฑด๋ถ€ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด `user.hi`๋‚˜ `user.bye` ์ค‘ ํ•˜๋‚˜๊ฐ€ ํ˜ธ์ถœ๋˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. user์˜ name์ด "John"์ด๋ฏ€๋กœ `user.hi`๊ฐ€ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋ผ ์˜ˆ์ƒํ•˜๋ฉฐ ๋ง์ด์ฃ . + +๊ทธ๋Ÿฐ๋ฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋’ค์— `()`๊ฐ€ ์žˆ์–ด์„œ ๋ฉ”์„œ๋“œ hi๊ฐ€ ์ฆ‰์‹œ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋ผ ์˜ˆ์ƒํ–ˆ๋Š”๋ฐ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋˜์ง€ ์•Š์•˜๋„ค์š”. + +์—๋Ÿฌ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ `"this"`์— `undefined`๊ฐ€ ํ• ๋‹น๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. + +๋งˆ์ง€๋ง‰ ์ค„์ด ์•„๋ž˜์™€ ๊ฐ™์•˜๋‹ค๋ฉด ์—๋Ÿฌ ์—†์ด ์ž˜ ์ž‘๋™ํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค. +```js +user.hi(); +``` + +๊ทธ๋Ÿฐ๋ฐ ์•„๋ž˜ ์ฝ”๋“œ์—์„  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ฃ . +```js +(user.name == "John" ? user.hi : user.bye)(); +``` + +์›์ธ์ด ๋ญ˜๊นŒ์š”? ์›์ธ์„ ์•Œ๋ ค๋ฉด `obj.method()`๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +## ์ฐธ์กฐ ํƒ€์ž… ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ + +์ฝ”๋“œ๋ฅผ ์œ ์‹ฌํžˆ ์‚ดํŽด๋ณด๋ฉด `obj.method()`์—” ์—ฐ์‚ฐ์ด ๋‘ ๊ฐœ ์žˆ๋‹ค๋Š” ๊ฑธ ๋ˆˆ์น˜์ฑŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +1. ์  `'.'`์€ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ `obj.method`์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. +2. ๊ด„ํ˜ธ `()`๋Š” ์ ‘๊ทผํ•œ ํ”„๋กœํผํ‹ฐ(๋ฉ”์„œ๋“œ)๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋ ‡๋‹ค๋ฉด ์ฒซ ๋ฒˆ์งธ ์—ฐ์‚ฐ์—์„œ ์–ป์€ `this` ์ •๋ณด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‘ ๋ฒˆ์งธ ์—ฐ์‚ฐ์œผ๋กœ ์ „๋‹ฌ๋ ๊นŒ์š”? + +๋‘ ์—ฐ์‚ฐ์„ ๊ฐ๊ฐ ๋ณ„๋„์˜ ์ค„์—์„œ ๋‘์—ˆ๋‹ค๋ฉด `this` ์ •๋ณด๋ฅผ ์žƒ๋Š” ๊ฑด ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค. + +```js run +let user = { + name: "John", + hi() { alert(this.name); } +} + +*!* +// ๋ฉ”์„œ๋“œ ์ ‘๊ทผ๊ณผ ํ˜ธ์ถœ์„ ๋ณ„๋„์˜ ์ค„์—์„œ ์‹คํ–‰ํ•จ +let hi = user.hi; +hi(); // this๊ฐ€ undefined์ด๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +*/!* +``` + +`hi = user.hi`์—์„  ํ•จ์ˆ˜๊ฐ€ ๋ณ€์ˆ˜์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งˆ์ง€๋ง‰ ์ค„๊ณผ๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ `this`์—” ์•„๋ฌด๋Ÿฐ ๊ฐ’๋„ ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +**`user.hi()`๋ฅผ ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์†์ž„์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. `'.'`์ด ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ, [์ฐธ์กฐ ํƒ€์ž…(Reference Type)](https://tc39.github.io/ecma262/#sec-reference-specification-type) ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•˜์ฃ .** + +์ฐธ์กฐ ํƒ€์ž…์€ '๋ช…์„ธ์„œ ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…(specification type)'์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ œ๋ก  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + +์ฐธ์กฐ ํƒ€์ž…์— ์†ํ•˜๋Š” ๊ฐ’์€ `(base, name, strict)`์ด ์กฐํ•ฉ๋œ ํ˜•ํƒœ๋ฅผ ๋ฑ๋‹ˆ๋‹ค. + +- `base`: ๊ฐ์ฒด +- `name`: ํ”„๋กœํผํ‹ฐ์˜ ์ด๋ฆ„ +- `strict`: ์—„๊ฒฉ ๋ชจ๋“œ์—์„œ true + +`user.hi`๋กœ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ, ์ฐธ์กฐํ˜•(์ฐธ์กฐ ํƒ€์ž…) ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์—„๊ฒฉ ๋ชจ๋“œ์—์„  ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜์ฃ . + +```js +// ์ฐธ์กฐํ˜• ๊ฐ’ +(user, "hi", true) +``` + +์ฐธ์กฐํ˜• ๊ฐ’์— ๊ด„ํ˜ธ `()`๋ฅผ ๋ถ™์—ฌ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด, ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ์™€ ์—ฐ๊ด€๋œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ `this`(`=user`)๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. + +์ด๋ ‡๊ฒŒ ์ฐธ์กฐ ํƒ€์ž…์€ ๋‚ด๋ถ€์—์„œ ์  `.`์—ฐ์‚ฐ์—์„œ ์•Œ์•„๋‚ธ ์ •๋ณด๋ฅผ ๊ด„ํ˜ธ `()`๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” '์ค‘๊ฐœ์ธ' ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ๋ฐ ์  ์—ฐ์‚ฐ ์ด์™ธ์˜ ์—ฐ์‚ฐ(ํ• ๋‹น ์—ฐ์‚ฐ ๋“ฑ)์€ ์ฐธ์กฐ ํƒ€์ž…์„ ํ†ต์งธ๋กœ ๋ฒ„๋ฆฌ๊ณ  `user.hi` ๊ฐ’(ํ•จ์ˆ˜)๋งŒ ๋ฐ›์•„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ์  ์ด์™ธ์˜ ์—ฐ์‚ฐ์—์„  `this` ์ •๋ณด๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. + +`obj.method()` ๊ฐ™์ด ์ ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, `obj[method]()` ๊ฐ™์ด ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ๋งŒ `this` ๊ฐ’์ด ์˜๋„ํ•œ ๋Œ€๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋Š” [func.bind()](/bind#solution-2-bind) ๋“ฑ์„ ์ด์šฉํ•˜๋ฉด ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด์— ๋Œ€ํ•ด์„  ์ถ”ํ›„์— ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. + +## ์š”์•ฝ + +์ฐธ์กฐ ํƒ€์ž…์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค. + +`.`์ด๋‚˜ ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ์ธ ๋ฉ”์„œ๋“œ(`obj.method()`)์— ์ ‘๊ทผํ•˜๋ ค ํ•˜๋ฉด ์ •ํ™•ํ•œ ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํŠน๋ณ„ํ•œ ํ˜•ํƒœ์˜ ๊ฐ’์ธ '์ฐธ์กฐ ํƒ€์ž…' ๊ฐ’์ด ๋ฐ˜ํ•œ๋ฉ๋‹ˆ๋‹ค. ์ด ์ฐธ์กฐํƒ€์ž… ๊ฐ’์—” ํ”„๋กœํผํ‹ฐ ๊ฐ’๊ณผ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ •์˜๋œ ๊ฐ์ฒด ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค. + +`()`๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” `this`์— ์ œ๋Œ€๋กœ ๋œ ๊ฐ์ฒด ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ด ์ค„ ์ˆ˜ ์žˆ๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ '์ฐธ์กฐ ํƒ€์ž…' ๋•๋ถ„์ž…๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ๋ฐ `.`์ด๋‚˜ ๋Œ€๊ด„ํ˜ธ ์ด์™ธ์˜ ์—ฐ์‚ฐ์—์„  ์ฐธ์กฐ ํƒ€์ž…์ด ๊ทธ๋ƒฅ ํ”„๋กœํผํ‹ฐ ๊ฐ’์œผ๋กœ ๋ณ€ํ•ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ผ๋ฉด ํ•จ์ˆซ๊ฐ’์œผ๋กœ ๋ณ€ํ•ด๋ฒ„๋ฆฌ์ฃ . + +์ด๋Ÿฐ ๋‚ด๋ถ€ ๋™์ž‘์€ ๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์—์„œ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ ํƒ€์ž…์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋Š” ํ‘œํ˜„์‹์„ ์ด์šฉํ•ด ๋™์ ์œผ๋กœ ๊ฐ์ฒด์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ์™€ ๊ฐ™์ด ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. diff --git a/1-js/99-js-misc/05-bigint/article.md b/1-js/99-js-misc/05-bigint/article.md new file mode 100644 index 0000000000..7f59ecb55e --- /dev/null +++ b/1-js/99-js-misc/05-bigint/article.md @@ -0,0 +1,130 @@ +# BigInt + +[recent caniuse="bigint"] + +`BigInt`๋Š” ๊ธธ์ด์˜ ์ œ์•ฝ ์—†์ด ์ •์ˆ˜๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ˆซ์žํ˜•์ž…๋‹ˆ๋‹ค. + +์ •์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด ๋์— `n`์„ ๋ถ™์ด๊ฑฐ๋‚˜ ํ•จ์ˆ˜ `BigInt`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž๋ฅผ ๊ฐ€์ง€๊ณ  `BigInt` ํƒ€์ž…์˜ ๊ฐ’์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js +const bigint = 1234567890123456789012345678901234567890n; + +const sameBigint = BigInt("1234567890123456789012345678901234567890"); + +const bigintFromNumber = BigInt(10); // 10n๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. +``` + +## ์ˆ˜ํ•™ ์—ฐ์‚ฐ์ž + +`BigInt`๋Š” ๋Œ€๊ฐœ ์ผ๋ฐ˜ ์ˆซ์ž์™€ ํฐ ์ฐจ์ด ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js run +alert(1n + 2n); // 3 + +alert(5n / 2n); // 2 +``` + +์œ„ ์˜ˆ์‹œ์—์„œ ๋‚˜๋ˆ—์…ˆ ์—ฐ์‚ฐ `5/2`์˜ ๊ฒฐ๊ณผ์—” ์†Œ์ˆ˜๋ถ€๊ฐ€ ์—†๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. `BigInt`ํ˜• ๊ฐ’์„ ๋Œ€์ƒ์œผ๋กœ ํ•œ ์—ฐ์‚ฐ์€ `BigInt`ํ˜• ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + +`BigInt`ํ˜• ๊ฐ’๊ณผ ์ผ๋ฐ˜ ์ˆซ์ž๋ฅผ ์„ž์–ด์„œ ์‚ฌ์šฉํ•  ์ˆœ ์—†์Šต๋‹ˆ๋‹ค. + +```js run +alert(1n + 2); // Error: Cannot mix BigInt and other types +``` + +์ผ๋ฐ˜ ์ˆซ์ž์™€ ์„ž์–ด์„œ ์จ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด `BigInt()`๋‚˜ `Number()`๋ฅผ ์‚ฌ์šฉํ•ด ๋ช…์‹œ์ ์œผ๋กœ ํ˜• ๋ณ€ํ™˜์„ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. + +```js run +let bigint = 1n; +let number = 2; + +// ์ˆซ์ž๋ฅผ bigint๋กœ +alert(bigint + BigInt(number)); // 3 + +// bigint๋ฅผ ์ˆซ์ž๋กœ +alert(Number(bigint) + number); // 3 +``` + +ํ˜• ๋ณ€ํ™˜๊ณผ ๊ด€๋ จ๋œ ์—ฐ์‚ฐ์€ ํ•ญ์ƒ ์กฐ์šฉํžˆ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์ฃ . ๊ทธ๋Ÿฐ๋ฐ bigint๊ฐ€ ๋„ˆ๋ฌด ์ปค์„œ ์ˆซ์žํ˜•์—์„œ ํ—ˆ์šฉํ•˜๋Š” ์ž๋ฆฟ์ˆ˜๋ฅผ ๋„˜์œผ๋ฉด ๋‚˜๋จธ์ง€ ๋น„ํŠธ๋Š” ์ž๋™์œผ๋กœ ์ž˜๋ ค ๋‚˜๊ฐ‘๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ ์„ ์—ผ๋‘ํ•˜๊ณ  ํ˜• ๋ณ€ํ™˜์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +````smart header="๋‹จํ•ญ ๋ง์…ˆ ์—ฐ์‚ฐ์ž๋Š” bigint์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." +๋‹จํ•ญ ๋ง์…ˆ ์—ฐ์‚ฐ์ž `+value`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `value`๋ฅผ ์†์‰ฝ๊ฒŒ ์ˆซ์žํ˜•์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ๋ฐ ํ˜ผ๋ž€์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด bigint๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ์—ฐ์‚ฐ์—์„  ๋‹จํ•ญ ๋ง์…ˆ ์—ฐ์‚ฐ์ž๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +```js run +let bigint = 1n; + +alert( +bigint ); // ์—๋Ÿฌ +``` +bigint๋ฅผ ์ˆซ์žํ˜•์œผ๋กœ ๋ฐ”๊ฟ€ ๋•Œ๋Š” `Number()`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +```` + +## ๋น„๊ต ์—ฐ์‚ฐ์ž + +๋น„๊ต ์—ฐ์‚ฐ์ž `<`, `>`๋Š” bigint์™€ ์ผ๋ฐ˜ ์ˆซ์ž ๋ชจ๋‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```js run +alert( 2n > 1n ); // true + +alert( 2n > 1 ); // true +``` + +๊ทธ๋Ÿฐ๋ฐ ๋น„๊ตํ•˜๋ ค๋Š” ๋Œ€์ƒ์ด ๋‹ค๋ฅธ ํƒ€์ž…์— ์†ํ•˜๋ฉด `==`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ฐ™์„์ง€ ๋ชจ๋ฅด์ง€๋งŒ `===`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‹ค๋ฅด๋‹ค๊ณ  ํŒ๋‹จ๋ฉ๋‹ˆ๋‹ค. + +```js run +alert( 1 == 1n ); // true + +alert( 1 === 1n ); // false +``` + +## ๋…ผ๋ฆฌ ์—ฐ์‚ฐ + +bigint๋Š” `if` ์•ˆ์ด๋‚˜ ๋‹ค๋ฅธ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ผ๋ฐ˜ ์ˆซ์ž์™€ ๋™์ผํ•˜๊ฒŒ ํ–‰๋™ํ•ฉ๋‹ˆ๋‹ค. + +`if`์•ˆ์—์„œ `0n`์€ falsy์ด๊ณ  ๋‹ค๋ฅธ ๊ฐ’๋“ค์€ truthy๋กœ ํ‰๊ฐ€๋˜์ฃ . + +```js run +if (0n) { + // ์ ˆ๋Œ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +} +``` + +`||`, `&&` ๋“ฑ์˜ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž๋ฅผ bigint์— ์ ์šฉํ•  ๋•Œ๋„ ์ผ๋ฐ˜ ์ˆซ์ž์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. + +```js run +alert( 1n || 2 ); // 1 (1n์€ truthy๋กœ ํŒ๋‹จ๋ฉ๋‹ˆ๋‹ค.) + +alert( 0n || 2 ); // 2 (0n์€ falsy๋กœ ํŒ๋‹จ๋ฉ๋‹ˆ๋‹ค.) +``` + +## ํด๋ฆฌํ•„ + +bigint ํด๋ฆฌํ•„์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๊ฝค ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. `+`, `-`๋ฅผ ๋น„๋กฏํ•œ ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ์ž๋“ค์ด bigint์™€ ์ผ๋ฐ˜ ์ˆซ์ž์—์„œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +bigint๋ผ๋ฆฌ ๋‚˜๋ˆ„๋ฉด ํ•ญ์ƒ bigint๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•ž์„œ ๋ง์”€๋“œ๋ฆฐ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. + +๋™์ผํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ํ•˜๋ ค๋ฉด ํด๋ฆฌํ•„์—์„œ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ๋‚ด์žฅ ์—ฐ์‚ฐ์ž ๋ชจ๋‘๋ฅผ ๊ด€๋ จ ํ•จ์ˆ˜๋กœ ๋Œ€์ฒดํ•ด ์ค„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ํ’ˆ์ด ๋งŽ์ด ๋“ค๊ณ  ์„ฑ๋Šฅ ์ด์Šˆ๋„ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ ์•„์ง๊นŒ์ง„ ์ œ๋Œ€๋กœ ๋œ bigint ํด๋ฆฌํ•„์ด ๋‚˜์˜ค์ง€ ์•Š์€ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. + +์ž˜ ์•Œ๋ ค์ง„ ํด๋ฆฌํ•„์€ ์—†์ง€๋งŒ [JSBI](https://github.com/GoogleChromeLabs/jsbi) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋Œ€์•ˆ์„ ์ œ์‹œํ•˜๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค. + +์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ž์ฒด์ ์œผ๋กœ ๋งŒ๋“  ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ํฐ ์ˆซ์ž๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ bigint๋Œ€์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋งŒ๋“  ์ˆซ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋Œ€์•ˆ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +| ์—ฐ์‚ฐ | ๋„ค์ดํ‹ฐ๋ธŒ `BigInt` | JSBI | +|-----------|-----------------|------| +| ์ผ๋ฐ˜ ์ˆซ์ž๋ฅผ ์‚ฌ์šฉํ•ด bigint๋งŒ๋“ค๊ธฐ | `a = BigInt(789)` | `a = JSBI.BigInt(789)` | +| ๋ง์…ˆ | `c = a + b` | `c = JSBI.add(a, b)` | +| ๋บ„์…ˆ | `c = a - b` | `c = JSBI.subtract(a, b)` | +| ... | ... | ... | + +์ด๋ ‡๊ฒŒ JSBI๋ฅผ ์‚ฌ์šฉํ•ด ์ˆซ์ž๋ฅผ ๋งŒ๋“  ๋‹ค์Œ ๋ฐ”๋ฒจ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์žˆ๋Š” ํด๋ฆฌํ•„์„ ์‚ฌ์šฉํ•ด JSBI ํ˜ธ์ถœ์„ ๋„ค์ดํ‹ฐ๋ธŒ bigint๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ์›ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +In other words, this approach suggests that we write code in JSBI instead of native bigints. But JSBI works with numbers as with bigints internally, emulates them closely following the specification, so the code will be "bigint-ready". + +We can use such JSBI code "as is" for engines that don't support bigints and for those that do support - the polyfill will convert the calls to native bigints. + +## ์ฐธ๊ณ  ์ž๋ฃŒ + +- [MDN docs on BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). +- [Specification](https://tc39.es/ecma262/#sec-bigint-objects). diff --git a/1-js/99-js-misc/index.md b/1-js/99-js-misc/index.md index 79cd72fe7c..5c8602892b 100644 --- a/1-js/99-js-misc/index.md +++ b/1-js/99-js-misc/index.md @@ -1,2 +1,2 @@ -# Miscellaneous +# ๊ธฐํƒ€ diff --git a/1-js/index.md b/1-js/index.md index f4ca5d1199..c41d31a3cf 100644 --- a/1-js/index.md +++ b/1-js/index.md @@ -1,4 +1,6 @@ -# ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ -๊ธฐ์ดˆ ๋ฌธ๋ฒ•๋ถ€ํ„ฐ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ฐœ๋…๊นŒ์ง€ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. +# ์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ + +ํŒŒํŠธ1์—์„  ๊ธฐ๋ณธ ๋ฌธ๋ฒ•๋ถ€ํ„ฐ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ฐœ๋…๊นŒ์ง€ ๋‹ค์–‘ํ•œ ๋‚ด์šฉ์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. + +ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์— ์ข…์†๋˜์ง€ ์•Š๋Š” ์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ง‘์ค‘ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์— ์ข…์†๋˜์ง€ ์•Š๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md index afc21c42de..f9fcd3e89e 100644 --- a/2-ui/1-document/01-browser-environment/article.md +++ b/2-ui/1-document/01-browser-environment/article.md @@ -1,25 +1,25 @@ -# ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ๊ณผ ๋‹ค์–‘ํ•œ ๋ช…์„ธ +# ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ๊ณผ ๋‹ค์–‘ํ•œ ๋ช…์„ธ์„œ -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ณธ๋ž˜ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ๋งŒ๋“ค์–ด์ง„ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์ดํ›„ ์ง„ํ™”๋ฅผ ๊ฑฐ์ณ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ฒ˜์™€ ํ”Œ๋žซํผ์„ ์ง€์›ํ•˜๋Š” ์–ธ์–ด๋กœ ๋ณ€๋ชจํ•˜์˜€์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ณธ๋ž˜ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ๋งŒ๋“  ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์ดํ›„ ์ง„ํ™”๋ฅผ ๊ฑฐ์ณ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ฒ˜์™€ ํ”Œ๋žซํผ์„ ์ง€์›ํ•˜๋Š” ์–ธ์–ด๋กœ ๋ณ€๋ชจํ•˜์˜€์Šต๋‹ˆ๋‹ค. -์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ํ”Œ๋žซํผ์€ *ํ˜ธ์ŠคํŠธ(host)* ๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €, ์›น์„œ๋ฒ„, ์‹ฌ์ง€์–ด๋Š” ์ปคํ”ผ ๋จธ์‹ ์ด ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”Œ๋žซํผ์€ ํ•ด๋‹น ํ”Œ๋žซํผ์— ํŠน์ •๋˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์—์„  ์ด๋ฅผ *ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ(host environment)* ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ํ”Œ๋žซํผ์€ *ํ˜ธ์ŠคํŠธ(host)* ๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €, ์›น์„œ๋ฒ„, ์‹ฌ์ง€์–ด๋Š” ์ปคํ”ผ ๋จธ์‹ ์ด ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”Œ๋žซํผ์€ ํ•ด๋‹น ํ”Œ๋žซํผ์— ํŠน์ •๋˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…์„ธ์„œ์—์„  ์ด๋ฅผ *ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ(host environment)* ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์€ ๋žญ๊ท€์ง€ ์ฝ”์–ด(ECMAScript)์— ๋”ํ•˜์—ฌ ํ”Œ๋žซํผ์— ํŠน์ •๋˜๋Š” ๊ฐ์ฒด์™€ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์›น๋ธŒ๋ผ์šฐ์ €๋Š” ์›นํŽ˜์ด์ง€๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•˜๊ณ , Node.js๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ฃผ์ฃ . +ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์€ ๋žญ๊ท€์ง€ ์ฝ”์–ด(ECMAScript - ์˜ฎ๊ธด์ด)์— ๋”ํ•˜์—ฌ ํ”Œ๋žซํผ์— ํŠน์ •๋˜๋Š” ๊ฐ์ฒด์™€ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์›น๋ธŒ๋ผ์šฐ์ €๋Š” ์›นํŽ˜์ด์ง€๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•˜๊ณ , Node.js๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ฃผ์ฃ . -์•„๋ž˜๋Š” ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์ด ์›น ๋ธŒ๋ผ์šฐ์ €์ผ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐœ๊ด„์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. +์•„๋ž˜ ๊ทธ๋ฆผ์€ ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ์ด ์›น ๋ธŒ๋ผ์šฐ์ €์ผ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐœ๊ด„์ ์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ![](windowObjects.svg) -์ตœ์ƒ๋‹จ์—” `window` ๊ฐ์ฒด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” 2๊ฐ€์ง€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +์ตœ์ƒ๋‹จ์—” `window`๋ผ ๋ถˆ๋ฆฌ๋Š” '๋ฃจํŠธ' ๊ฐ์ฒด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. `window` ๊ฐ์ฒด๋Š” 2๊ฐ€์ง€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. -1. ์—์„œ ์„ค๋ช…ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์˜ ์ „์—ญ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. -2. "๋ธŒ๋ผ์šฐ์ € ์ฐฝ(browser window)"์„ ๋Œ€๋ณ€ํ•˜๊ณ , ์ด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +1. ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์˜ ์ „์—ญ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. +2. '๋ธŒ๋ผ์šฐ์ € ์ฐฝ(browser window)'์„ ๋Œ€๋ณ€ํ•˜๊ณ , ์ด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ๋Š” `window` ๊ฐ์ฒด๋ฅผ ์ „์—ญ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„  `window` ๊ฐ์ฒด๋ฅผ ์ „์—ญ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -```js run +```js run global function sayHi() { - alert("์•ˆ๋…•ํ•˜์„ธ์š”"); + alert("์•ˆ๋…•ํ•˜์„ธ์š”."); } // ์ „์—ญ ํ•จ์ˆ˜๋Š” ์ „์—ญ ๊ฐ์ฒด(window)์˜ ๋ฉ”์„œ๋“œ์ž„ @@ -29,16 +29,16 @@ window.sayHi(); ์•„๋ž˜ ์˜ˆ์‹œ์—์„  `window` ๊ฐ์ฒด๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ๋Œ€๋ณ€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์ด์šฉํ•ด ์ฐฝ์˜ ๋†’์ด๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ```js run -alert(window.innerHeight); // ์ฐฝ ๋‚ด๋ถ€ ๋†’์ด +alert(window.innerHeight); // ์ฐฝ ๋‚ด๋ถ€(inner window) ๋†’์ด ``` -`window` ๊ฐ์ฒด์— ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋Š” ์ถ”ํ›„ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +`window` ๊ฐ์ฒด์—” ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ถ”ํ›„ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -## DOM(๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ) +## ๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ(DOM) -Document Object Model, or DOM for short, represents all page content as objects that can be modified. +๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ(Document Object Model, DOM)์€ ์›น ํŽ˜์ด์ง€ ๋‚ด์˜ ๋ชจ๋“  ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ์ฒด๋กœ ๋‚˜ํƒ€๋‚ด์ค๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์ˆ˜์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -The `document` object is the main "entry point" to the page. We can change or create anything on the page using it. +`document` ๊ฐ์ฒด๋Š” ํŽ˜์ด์ง€์˜ ๊ธฐ๋ณธ '์ง„์ž…์ ' ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. `document` ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ํŽ˜์ด์ง€ ๋‚ด ๊ทธ ๋ฌด์—‡์ด๋“  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ณ , ์›ํ•˜๋Š” ๊ฒƒ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: ```js run @@ -49,32 +49,30 @@ document.body.style.background = "red"; setTimeout(() => document.body.style.background = "", 1000); ``` -๋ฌธ์„œ ๊ฐ์ฒด๋Š” ์˜ˆ์‹œ์—์„œ ์†Œ๊ฐœํ•œ `document.body.style` ์™ธ์—๋„ ์ˆ˜๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋ช…์„ธ(specification)์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -- **DOM์— ๊ด€ํ•œ ํ‘œ์ค€** ์€ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ์€ ์˜ˆ์‹œ์—์„œ ์†Œ๊ฐœํ•œ `document.body.style` ์™ธ์—๋„ ์ˆ˜๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” WHATWG์˜ [DOM Living Standard](https://dom.spec.whatwg.org)์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```smart header="DOM is not only for browsers" -The DOM specification explains the structure of a document and provides objects to manipulate it. There are non-browser instruments that use DOM too. +```smart header="DOM์€ ๋ธŒ๋ผ์šฐ์ €๋งŒ์„ ์œ„ํ•œ ๋ชจ๋ธ์ด ์•„๋‹™๋‹ˆ๋‹ค." +DOM ๋ช…์„ธ์„œ์—” ๋ฌธ์„œ์˜ ๊ตฌ์กฐ์™€ ์ด๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ๊ณณ์—์„œ๋„ DOM์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, server-side scripts that download HTML pages and process them can also use DOM. They may support only a part of the specification though. +HTML ํŽ˜์ด์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์ด๋ฅผ ๊ฐ€๊ณตํ•ด์ฃผ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ DOM์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์Šคํฌ๋ฆฝํŠธ์—์„  ๋ช…์„ธ์„œ ์ผ๋ถ€๋งŒ์„ ์ง€์›ํ•˜๊ฒ ์ง€๋งŒ์š”. ``` -```smart header="CSSOM for styling" -CSS rules and stylesheets are structured in a different way than HTML. There's a separate specification, [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/), that explains how they are represented as objects, and how to read and write them. +```smart header="์Šคํƒ€์ผ๋ง์„ ์œ„ํ•œ CSSOM" +CSS ๊ทœ์น™๊ณผ ์Šคํƒ€์ผ์‹œํŠธ(stylesheet)๋Š” HTML๊ณผ๋Š” ๋‹ค๋ฅธ ๊ตฌ์กฐ๋ฅผ ๋ฑ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ CSS ๊ทœ์น™๊ณผ ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ ๊ฐ์ฒด๋กœ ๋‚˜ํƒ€๋‚ด๊ณ  ์ด ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์„์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์„ ๋‹ด์€ ๋ณ„๋„์˜ ๋ช…์„ธ์„œ, [CSS ๊ฐ์ฒด ๋ชจ๋ธ(CSS Object Model, CSSOM)](https://www.w3.org/TR/cssom-1/)์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -CSSOM is used together with DOM when we modify style rules for the document. In practice though, CSSOM is rarely required, because usually CSS rules are static. We rarely need to add/remove CSS rules from JavaScript, but that's also possible. +CSSOM์€ ๋ฌธ์„œ์— ์“ฐ์ด๋Š” ์Šคํƒ€์ผ ๊ทœ์น™์„ ์ˆ˜์ •ํ•  ๋•Œ DOM๊ณผ ํ•จ๊ป˜ ์“ฐ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ CSS ๊ทœ์น™์€ ๋Œ€๋ถ€๋ถ„ ์ •์ ์ด๊ธฐ ๋•Œ๋ฌธ์— CSSOM์„ ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์ ‘ํ•˜์ง€๋Š” ์•Š์„ ๊ฒ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด CSS ๊ทœ์น™์„ ์ถ”๊ฐ€ ํ˜น์€ ์ œ๊ฑฐํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ทนํžˆ ๋“œ๋ฌผ๊ธด ํ•˜์ง€๋งŒ, ์ด๋•Œ CSSOM์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ``` -## BOM(๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด ๋ชจ๋ธ) +## ๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด ๋ชจ๋ธ(BOM) -๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด ๋ชจ๋ธ(Browser Object Model, BOM)์€ HTML ๋ช…์„ธ์˜ ์ผ๋ถ€๋กœ, ๋ฌธ์„œ ์ด์™ธ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €(ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ)๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ถ”๊ฐ€์ ์ธ ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด ๋ชจ๋ธ(Browser Object Model, BOM)์€ ๋ฌธ์„œ ์ด์™ธ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €(ํ˜ธ์ŠคํŠธ ํ™˜๊ฒฝ)๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ถ”๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์˜ˆ์‹œ: -- [navigator](mdn:api/Window/navigator) ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์™€ ์šด์˜์ฒด์ œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด์—” ๋งŽ์€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์ง€๋งŒ, ๊ฐ€์žฅ ๋งŽ์ด ์•Œ๋ ค์ง„ ํ”„๋กœํผํ‹ฐ๋Š” ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋ฐ ์“ฐ์ด๋Š” `navigator.userAgent`์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ์šด์˜์ฒด์ œ(Windows, Linux, Mac ๋“ฑ)๋ฅผ ์•Œ์•„๋‚ด๋Š” ๋ฐ ์“ฐ์ด๋Š” `navigator.platform`์ž…๋‹ˆ๋‹ค. -- [location](mdn:api/Window/location) ๊ฐ์ฒด๋Š” ํ˜„์žฌ ์ฐฝ์˜ URL ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒˆ๋กœ์šด URL๋กœ ๋ณ€๊ฒฝ(redirect)ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +- [navigator](mdn:api/Window/navigator) ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €์™€ ์šด์˜์ฒด์ œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด์—” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ฐ€์žฅ ์ž˜ ์•Œ๋ ค์ง„ ํ”„๋กœํผํ‹ฐ๋Š” ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋ฅผ ์•Œ๋ ค์ฃผ๋Š” `navigator.userAgent`์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ์šด์˜์ฒด์ œ(Windows, Linux, Mac ๋“ฑ) ์ •๋ณด๋ฅผ ์•Œ๋ ค์ฃผ๋Š” `navigator.platform`์ž…๋‹ˆ๋‹ค. +- [location](mdn:api/Window/location) ๊ฐ์ฒด๋Š” ํ˜„์žฌ URL์„ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ณ  ์ƒˆ๋กœ์šด URL๋กœ ๋ณ€๊ฒฝ(redirect)ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -์˜ˆ์ œ๋ฅผ ํ†ตํ•ด `location` ๊ฐ์ฒด์˜ ์šฉ๋ก€๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ๋Š” `location` ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์„์ง€ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ```js run alert(location.href); // ํ˜„์žฌ URL์„ ๋ณด์—ฌ์คŒ @@ -83,33 +81,33 @@ if (confirm("์œ„ํ‚คํ”ผ๋””์•„ ํŽ˜์ด์ง€๋กœ ๊ฐ€์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?")) { } ``` -๋ฉ”์„œ๋“œ `alert/confirm/prompt` ์—ญ์‹œ BOM์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ์™€ ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ, ์‚ฌ์šฉ์ž์™€ ๋ธŒ๋ผ์šฐ์ € ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ๋„์™€์ฃผ๋Š” ์ˆœ์ˆ˜ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”์„œ๋“œ์ด์ฃ . +`alert/confirm/prompt` ์—ญ์‹œ BOM์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ์™€ ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ, ์‚ฌ์šฉ์ž์™€ ๋ธŒ๋ผ์šฐ์ € ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ๋„์™€์ฃผ๋Š” ์ˆœ์ˆ˜ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”์„œ๋“œ์ด์ฃ . ```smart header="๋‹ค์–‘ํ•œ ๋ช…์„ธ" -[HTML ๋ช…์„ธ](https://html.spec.whatwg.org)๋Š” BOM์— ๋Œ€ํ•œ ๋‚ด์šฉ๋„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. BOM์— ๊ด€๋ จ๋œ ๋ช…์„ธ๊ฐ€ ๋”ฐ๋กœ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ๋„ ๋ง์ด์ฃ . +BOM์€ [HTML ๋ช…์„ธ์„œ](https://html.spec.whatwg.org)์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. -์—์„  ํƒœ๊ทธ, HTML ์†์„ฑ(attribute) ๊ฐ™์€ "HTML"์— ๊ด€๋ จ๋œ ๋‚ด์šฉ๋งŒ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ์ „๋ฐ˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด, ๋ฉ”์„œ๋“œ ๋ถ€ํ„ฐ ํŠน์ • ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” DOM ํ™•์žฅ๊นŒ์ง€๋„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๊ฒƒ์ด HTML ๊ธฐ์ˆ ์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. HTML ๋ช…์„ธ์—์„œ ๋‹ค๋ฃจ์ง€ ์•Š๋Š” ๊ฒƒ๋“ค์— ๋Œ€ํ•œ ๋ช…์„ธ๋Š” ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +BOM์— ๊ด€๋ จ๋œ ๋ช…์„ธ๊ฐ€ ๋”ฐ๋กœ ์žˆ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” HTML ๋ช…์„ธ์„œ๋Š” ํƒœ๊ทธ, HTML ์†์„ฑ(attribute) ๊ฐ™์€ 'HTML' ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์–‘ํ•œ ๊ฐ์ฒด์™€ ๋ฉ”์„œ๋“œ, ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” DOM ํ™•์žฅ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๊ฒƒ์ด HTML ๊ธฐ์ˆ ์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. HTML ๋ช…์„ธ์„œ์—” ์ด ์™ธ์—๋„ ์— ์žˆ๋Š” ๋‚ด์šฉ๋„ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ``` ## ์š”์•ฝ -ํ‘œ์ค€์— ๋Œ€ํ•˜์—ฌ ์ด์•ผ๊ธฐํ•˜๋ฉด์„œ ๋‹ค์Œ ๋ช…์„ธ๋“ค์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. +ํ‘œ์ค€์— ๋Œ€ํ•˜์—ฌ ์ด์•ผ๊ธฐํ•˜๋ฉด์„œ ๋‹ค์Œ ๋ช…์„ธ์„œ๋“ค์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. -DOM ๋ช…์„ธ -: ๋ฌธ์„œ ๊ตฌ์กฐ, ์กฐ์ž‘, ์ด๋ฒคํŠธ๋ฅผ ์„ค๋ช…ํ•˜๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +DOM ๋ช…์„ธ์„œ +: ๋ฌธ์„œ ๊ตฌ์กฐ, ์กฐ์ž‘, ์ด๋ฒคํŠธ์— ๊ด€ํ•œ ์„ค๋ช…์ด ๋‹ด๊ฒจ์žˆ๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -CSSOM ๋ช…์„ธ -: CSS์™€ ์Šคํƒ€์ผ์‹œํŠธ์— ๋Œ€ํ•œ ๊ทœ์น™, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ฌธ์„œ ์Šคํƒ€์ผ์„ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +CSSOM ๋ช…์„ธ์„œ +: ์Šคํƒ€์ผ์‹œํŠธ์™€ ์Šคํƒ€์ผ ๊ทœ์น™, ์ด ๋‘˜์„ ์–ด๋–ป๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ์ด ๋‘˜๊ณผ ๋ฌธ์„œ ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ์–ด๋–ป๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋‹ด๊ฒจ์žˆ๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -HTML ๋ช…์„ธ -: ํƒœ๊ทธ์™€ ๊ฐ™์€ HTML ์–ธ์–ด, `setTimeout`, `alert`, `location` ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ์„ ์ •์˜ํ•œ BOM(browser object model)์— ๊ด€ํ•ด ์„ค๋ช…ํ•˜๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DOM ๋ช…์„ธ์— ์ถ”๊ฐ€์ ์ธ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๋”ํ•ด ํ™•์žฅํ•œ ๋ช…์„ธ์ž…๋‹ˆ๋‹ค. +HTML ๋ช…์„ธ์„œ +: ํƒœ๊ทธ ๋“ฑ์˜ HTML ์–ธ์–ด, `setTimeout`, `alert`, `location` ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ์„ ์ •์˜ํ•œ BOM์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋‹ด๊ฒจ์žˆ๊ณ , ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DOM ๋ช…์„ธ์„œ์— ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ํ™•์žฅํ•œ ๋ช…์„ธ์„œ์ž…๋‹ˆ๋‹ค. -Additionally, some classes are described separately at . +๋ช‡๋ช‡ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Please note these links, as there's so much stuff to learn it's impossible to cover and remember everything. +๋ฐฐ์šธ ๊ฒŒ ๋งŽ์ง€๋งŒ, ๋ชจ๋“  ๊ฑธ ํ•œ๊บผ๋ฒˆ์— ๋‹ค๋ฃจ๊ณ  ๊ธฐ์–ตํ•˜๊ธฐ์—” ๊ทธ ์–‘์ด ๋„ˆ๋ฌด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ๋งํฌ๋ฅผ ์ž˜ ๊ธฐ๋กํ•ด ๋†“์œผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -When you'd like to read about a property or a method, the Mozilla manual at is also a nice resource, but the corresponding spec may be better: it's more complex and longer to read, but will make your fundamental knowledge sound and complete. +ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ฝ๊ณ  ์‹ถ์„ ๋•Œ Mozilla ์žฌ๋‹จ์˜ ๋งค๋‰ด์–ผ ์„ ์ฐพ์•„๋ณด๋Š” ๊ฒƒ๋„ ์ข‹๊ธด ํ•˜์ง€๋งŒ, ๋ช…์„ธ์„œ์—์„œ ๊ด€๋ จ ์„ค๋ช…์„ ์ฐพ๋Š” ๊ฒŒ ๋” ๋‚˜์„ ๋•Œ๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ช…์„ธ์„œ์— ์žˆ๋Š” ์„ค๋ช…์€ ๋ณต์žกํ•˜๊ณ  ๋‚ด์šฉ๋„ ๋” ๋งŽ๊ธด ํ•˜์ง€๋งŒ ๋ช…์„ธ์„œ๋ฅผ ์ฝ๋Š” ์Šต๊ด€์„ ๋“ค์ด๋‹ค ๋ณด๋ฉด ๊ธฐ๋ณธ ์ง€์‹์„ ํƒ„ํƒ„ํ•˜๊ฒŒ ์Œ“์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -To find something, it's often convenient to use an internet search "WHATWG [term]" or "MDN [term]", e.g , . +๊ฒ€์ƒ‰์ฐฝ์— 'WHATWG [์šฉ์–ด]' ํ˜น์€ 'MDN [์šฉ์–ด]'๋กœ ๊ฒ€์ƒ‰ํ•˜๋ฉด ๋ช…์„ธ์„œ๋‚˜ MDN๋ฌธ์„œ์—์„œ ์›ํ•˜๋Š” ๋‚ด์šฉ์„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. , ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . -Now we'll get down to learning DOM, because the document plays the central role in the UI. +์ž ์ด์ œ UI์—์„œ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•˜๋Š” DOM์— ๋Œ€ํ•ด ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. diff --git a/2-ui/1-document/01-browser-environment/windowObjects.svg b/2-ui/1-document/01-browser-environment/windowObjects.svg index 59a10a4413..b7e18bb347 100644 --- a/2-ui/1-document/01-browser-environment/windowObjects.svg +++ b/2-ui/1-document/01-browser-environment/windowObjects.svg @@ -1 +1 @@ -windowdocumentObjectnavigatorscreenlocationframeshistoryArrayFunctionXMLHttpRequestBOMJavaScriptDOMโ€ฆโ€ฆ \ No newline at end of file +windowdocumentObjectnavigatorscreenlocationframeshistoryArrayFunctionXMLHttpRequestBOMJavaScriptDOMโ€ฆโ€ฆ \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md index 9e8b630877..7128c0d135 100644 --- a/2-ui/1-document/02-dom-nodes/article.md +++ b/2-ui/1-document/02-dom-nodes/article.md @@ -6,33 +6,33 @@ libs: # DOM ํŠธ๋ฆฌ -HTML์˜ ๊ทผ๊ฐ„์€ ํƒœ๊ทธ(tag)์ž…๋‹ˆ๋‹ค. +HTML์„ ์ง€ํƒฑํ•˜๋Š” ๊ฒƒ์€ ํƒœ๊ทธ(tag)์ž…๋‹ˆ๋‹ค. -According to the Document Object Model (DOM), every HTML tag is an object. Nested tags are "children" of the enclosing one. The text inside a tag is an object as well. +๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ(DOM)์— ๋”ฐ๋ฅด๋ฉด, ๋ชจ๋“  HTML ํƒœ๊ทธ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ํƒœ๊ทธ ํ•˜๋‚˜๊ฐ€ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” '์ž์‹' ํƒœ๊ทธ๋Š” ์ค‘์ฒฉ ํƒœ๊ทธ(nested tag)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ํƒœ๊ทธ ๋‚ด์˜ ๋ฌธ์ž(text) ์—ญ์‹œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. -All these objects are accessible using JavaScript, and we can use them to modify the page. +์ด๋Ÿฐ ๋ชจ๋“  ๊ฐ์ฒด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , ํŽ˜์ด์ง€๋ฅผ ์กฐ์ž‘ํ•  ๋•Œ ์ด ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -For example, `document.body` is the object representing the `` tag. +`document.body`๋Š” `` ํƒœ๊ทธ๋ฅผ ๊ฐ์ฒด๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด์ฃ . -Running this code will make the `` red for 3 seconds: +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ``๊ฐ€ 3์ดˆ๊ฐ„ ๋ถ‰์€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ```js run -document.body.style.background = 'red'; // make the background red +document.body.style.background = 'red'; // ๋ฐฐ๊ฒฝ์„ ๋ถ‰์€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ -setTimeout(() => document.body.style.background = '', 3000); // return back +setTimeout(() => document.body.style.background = '', 3000); // ์›์ƒํƒœ๋กœ ๋ณต๊ตฌํ•˜๊ธฐ ``` -Here we used `style.background` to change the background color of `document.body`, but there are many other properties, such as: +์œ„ ์˜ˆ์‹œ์—์„  `document.body`์˜ ๋ฐฐ๊ฒฝ์ƒ‰์„ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด `style.background`์„ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -- `innerHTML` -- HTML contents of the node. -- `offsetWidth` -- the node width (in pixels) -- ...and so on. +- `innerHTML` -- ํ•ด๋‹น ๋…ธ๋“œ์˜ HTML ์ฝ˜ํ…์ธ  +- `offsetWidth` -- ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋„ˆ๋น„(ํ”ฝ์…€) +- ๊ธฐํƒ€ ๋“ฑ๋“ฑ -Soon we'll learn more ways to manipulate the DOM, but first we need to know about its structure. +์ด์–ด์ง€๋Š” ์ฑ•ํ„ฐ์—์„œ DOM์„ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ฐฐ์šธ ์˜ˆ์ •์ธ๋ฐ, ๊ทธ ์ „์— ๋จผ์ € DOM์˜ ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ## DOM ์˜ˆ์ œ -Let's start with the following simple document: +๊ฐ„๋‹จํ•œ ๋ฌธ์„œ๋ฅผ ์ด์šฉํ•ด DOM ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. ```html run no-beautify @@ -46,7 +46,7 @@ Let's start with the following simple document: ``` -DOM์€ ํƒœ๊ทธ์˜ ํŠธ๋ฆฌ๊ตฌ์กฐ๋กœ HTML์„ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ†ตํ•ด ์ด๋ฅผ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. +DOM์€ HTML์„ ์•„๋ž˜์™€ ๊ฐ™์ด ํƒœ๊ทธ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

@@ -57,31 +57,31 @@ drawHtmlTree(node1, 'div.domtree', 690, 320); ```online -์œ„์—์„œ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ทธ ์ž์‹๋“ค์„ ๋ณด๊ฑฐ๋‚˜ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์œ„ ๊ทธ๋ฆผ์—์„œ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ทธ ์ž์‹๋“ค์„ ๋ณด๊ฑฐ๋‚˜ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -Every tree node is an object. +ํŠธ๋ฆฌ์— ์žˆ๋Š” ๋…ธ๋“œ๋Š” ๋ชจ๋‘ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. -Tags are *element nodes* (or just elements) and form the tree structure: `` is at the root, then `` and `` are its children, etc. +ํƒœ๊ทธ๋Š” *์š”์†Œ ๋…ธ๋“œ(element node)* (ํ˜น์€ ๊ทธ๋ƒฅ ์š”์†Œ)์ด๊ณ , ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ``์€ ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ๋˜๊ณ , ``์™€ ``๋Š” `๋ฃจํŠธ ๋…ธ๋“œ์˜ ์ž์‹์ด ๋ฉ๋‹ˆ๋‹ค. -์š”์†Œ ์•ˆ์ชฝ์˜ ๋ฌธ์ž๋Š” *ํ…์ŠคํŠธ(text) ๋…ธ๋“œ*๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ `#text`๋กœ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์ฃ . ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ์˜ค๋กœ์ง€ ๋ฌธ์ž์—ด๋งŒ ๋‹ด์Šต๋‹ˆ๋‹ค. ์ž์‹์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๊ณ  ํŠธ๋ฆฌ์˜ ๋์—์„œ ์žŽ ๋…ธ๋“œ(leaf node)๋กœ๋งŒ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. +์š”์†Œ ๋‚ด์˜ ๋ฌธ์ž๋Š” *ํ…์ŠคํŠธ(text) ๋…ธ๋“œ*๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„œ `#text`๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”. ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ๋ฌธ์ž์—ด๋งŒ ๋‹ด์Šต๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๊ณ , ํŠธ๋ฆฌ์˜ ๋์—์„œ ์žŽ ๋…ธ๋“œ(leaf node)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ `` ํƒœ๊ทธ๋Š” `"์‚ฌ์Šด์— ๊ด€ํ•˜์—ฌ"`๋ผ๋Š” ๋ฌธ์ž ๋…ธ๋“œ๋ฅผ ์ž์‹์œผ๋กœ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์œ„ ๊ทธ๋ฆผ์—์„œ `<title>` ํƒœ๊ทธ๋Š” `"์‚ฌ์Šด์— ๊ด€ํ•˜์—ฌ"`๋ผ๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์ž์‹์œผ๋กœ ๊ฐ–์Šต๋‹ˆ๋‹ค. -ํ…์ŠคํŠธ ๋…ธ๋“œ์— ์žˆ๋Š” ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ๋ˆˆ์—ฌ๊ฒจ๋ณด์„ธ์š”. +ํ…์ŠคํŠธ ๋…ธ๋“œ์— ์žˆ๋Š” ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ๋ˆˆ์—ฌ๊ฒจ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. - ์ƒˆ ์ค„(newline): `โ†ต` (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  `\n`๋กœ ํ‘œ์‹œ) - ๊ณต๋ฐฑ(space): `โฃ` -Spaces and newlines are totally valid characters, like letters and digits. They form text nodes and become a part of the DOM. So, for instance, in the example above the `<head>` tag contains some spaces before `<title>`, and that text becomes a `#text` node (it contains a newline and some spaces only). +์ƒˆ ์ค„๊ณผ ๊ณต๋ฐฑ์€ ๊ธ€์ž๋‚˜ ์ˆซ์ž์ฒ˜๋Ÿผ ํ•ญ์ƒ ์œ ํšจํ•œ ๋ฌธ์ž๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋‘ ํŠน์ˆ˜๋ฌธ์ž๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋˜๊ณ , DOM์˜ ์ผ๋ถ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์œ„ HTML ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด `<head>`์™€ `<title>`์‚ฌ์ด์— ์ƒˆ ์ค„๊ณผ ์•ฝ๊ฐ„์˜ ๊ณต๋ฐฑ์ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Ÿฐ ํŠน์ˆ˜๋ฌธ์ž ์—ญ์‹œ `#text` ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -There are only two top-level exclusions: -1. Spaces and newlines before `<head>` are ignored for historical reasons. -2. If we put something after `</body>`, then that is automatically moved inside the `body`, at the end, as the HTML spec requires that all content must be inside `<body>`. So there can't be any spaces after `</body>`. +ํ…์ŠคํŠธ ๋…ธ๋“œ ์ƒ์„ฑ์—” ๋‘ ๊ฐ€์ง€ ์˜ˆ์™ธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +1. ์—ญ์‚ฌ์ ์ธ ์ด์œ ๋กœ, `<head>` ์ด์ „์˜ ๊ณต๋ฐฑ๊ณผ ์ƒˆ ์ค„์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. +2. HTML ๋ช…์„ธ์„œ์—์„œ ๋ชจ๋“  ์ฝ˜ํ…์ธ ๋Š” `body` ์•ˆ์ชฝ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ, `</body>` ๋’ค์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋„ฃ๋”๋ผ๋„ ๊ทธ ์ฝ˜ํ…์ธ ๋Š” ์ž๋™์œผ๋กœ `body` ์•ˆ์ชฝ์œผ๋กœ ์˜ฎ๊ฒจ์ง‘๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `</body>` ๋’ค์—” ๊ณต๋ฐฑ์ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -๋‘ ์˜ˆ์™ธ๋ฅผ ์ œ์™ธํ•˜๊ณค ์•„์ฃผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋‚ด์— ๊ณต๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ฌธ์ž์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณต๋ฐฑ์„ ์ง€์šฐ๋ฉด ๊ทธ ๋…ธ๋“œ๋Š” ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. +๋‘ ์˜ˆ์™ธ๋ฅผ ์ œ์™ธํ•˜๊ณค ์•„์ฃผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋‚ด์— ๊ณต๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ฌธ์ž์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณต๋ฐฑ์„ ์ง€์šฐ๋ฉด ํ…์ŠคํŠธ ๋…ธ๋“œ๋„ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -๊ณต๋ฐฑ์ด ์—†๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๋งŒ์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ HTML์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ณต๋ฐฑ์ด ์—†๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๋งŒ์œผ๋กœ HTML ๋ฌธ์„œ๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด HTML์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```html no-beautify <!DOCTYPE HTML> @@ -96,19 +96,19 @@ let node2 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1, drawHtmlTree(node2, 'div.domtree', 690, 210); </script> -```smart header="Spaces at string start/end and space-only text nodes are usually hidden in tools" -Browser tools (to be covered soon) that work with DOM usually do not show spaces at the start/end of the text and empty text nodes (line-breaks) between tags. +```smart header="๋ฌธ์ž์—ด ์–‘ ๋ ๊ณต๋ฐฑ๊ณผ ๊ณต๋ฐฑ๋งŒ ์žˆ๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค." +DOM์„ ๋‹ค๋ฃฐ ๋•Œ ํ‚ค๊ฒŒ ๋˜๋Š” ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ(๊ณง ๋‹ค๋ฃฐ ์˜ˆ์ •์ž„)์—์„  ๋ฌธ์ž ๋งจ ์•ž์ด๋‚˜ ๋์ชฝ์˜ ๊ณต๋ฐฑ๊ณผ ํƒœ๊ทธ ์‚ฌ์ด์˜ ์ƒˆ ์ค„ ๋•Œ๋ฌธ์— ๋งŒ๋“ค์–ด์ง€๋Š” ๋น„์–ด์žˆ๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -Developer tools save screen space this way. +๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋Š” ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ํ™”๋ฉด์„ ๋œ ์ฐจ์ง€ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. -On further DOM pictures we'll sometimes omit them when they are irrelevant. Such spaces usually do not affect how the document is displayed. +๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋„ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ๊ทธ๋ฆผ์—์„œ ์ƒ๋žตํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ณต๋ฐฑ์ด๋‚˜ ์ƒˆ ์ค„์ด ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ณต๊ฐ„์€ HTML ๋ฌธ์„œ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์ƒ์— ์–ด๋–ป๊ฒŒ ํ‘œํ˜„๋˜๋Š”์ง€ ๋Œ€๊ฐœ๋Š” ์˜ํ–ฅ์„ ๋ผ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` ## ์ž๋™ ๊ต์ • -๋ธŒ๋ผ์šฐ์ €๋Š” ๊ทœ์น™์— ์–ด๊ธ‹๋‚˜๋Š” HTML์„ DOM ์ƒ์„ฑ๊ณผ์ •์—์„œ ์ž๋™ ๊ต์ •ํ•ฉ๋‹ˆ๋‹ค. +๊ธฐํ˜•์ ์ธ HTML์„ ๋งŒ๋‚˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” DOM ์ƒ์„ฑ๊ณผ์ •์—์„œ HTML์„ ์ž๋™์œผ๋กœ ๊ต์ •ํ•ฉ๋‹ˆ๋‹ค. -๊ฐ€์žฅ ์ตœ์ƒ์œ„ ํƒœ๊ทธ๋Š” ํ•ญ์ƒ `<html>`์ด์–ด์•ผ ํ•˜๋Š”๋ฐ, ๋ฌธ์„œ์— `<html>` ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ๋ฌธ์„œ ์ตœ์ƒ์œ„์— ์ด๋ฅผ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ์‹์œผ๋กœ ๋ง์ด์ฃ . `<body>`๋„ ๊ฐ™์€ ๋ฐฉ์‹์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. +์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ€์žฅ ์ตœ์ƒ์œ„ ํƒœ๊ทธ๋Š” ํ•ญ์ƒ `<html>`์ด์–ด์•ผ ํ•˜๋Š”๋ฐ ๋ฌธ์„œ์— `<html>` ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, ๋ฌธ์„œ ์ตœ์ƒ์œ„์— ์ด๋ฅผ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ์ฃ . ๋”ฐ๋ผ์„œ DOM์—๋Š” `<html>`์— ๋Œ€์‘ํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ํ•ญ์ƒ ์žˆ์Šต๋‹ˆ๋‹ค. `<body>`๋„ ๊ฐ™์€ ๋ฐฉ์‹์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ HTML ํŒŒ์ผ์— `"์•ˆ๋…•ํ•˜์„ธ์š”."`๋ผ๋Š” ๋ฌธ์žฅ ํ•˜๋‚˜๋งŒ ์ €์žฅ๋œ ์ƒํ™ฉ์ด๋ผ๋ฉด, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ ์ด ๋ฌธ์žฅ์„ `<html>` ๊ณผ `<body>`๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  `<head>`๋„ ๋”ํ•ด์ค˜์„œ ์•„๋ž˜์™€ ๊ฐ™์€ DOM์ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. @@ -116,14 +116,14 @@ On further DOM pictures we'll sometimes omit them when they are irrelevant. Such <div class="domtree"></div> <script> -let node3 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•ˆ๋…•ํ•˜์„ธ์š”"}]}]} +let node3 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•ˆ๋…•ํ•˜์„ธ์š”."}]}]} drawHtmlTree(node3, 'div.domtree', 690, 150); </script> -DOM ์ƒ์„ฑ๊ณผ์ •์—์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์€ ๋ฌธ์„œ ์—๋Ÿฌ๋„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค. +DOM ์ƒ์„ฑ๊ณผ์ •์—์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ฌธ์„œ์— ์žˆ๋Š” ์—๋Ÿฌ ๋“ฑ, ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ์—๋Ÿฌ ๋“ฑ์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. +๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ: ```html no-beautify <p>์•ˆ๋…•ํ•˜์„ธ์š” @@ -132,26 +132,26 @@ DOM ์ƒ์„ฑ๊ณผ์ •์—์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์€ <li>์•„๋น  ``` -๋ธŒ๋ผ์šฐ์ €๋Š” ํƒœ๊ทธ๋ฅผ ์ฝ๊ณ , ์ž๋™์œผ๋กœ ๋น ์ง„ ๋ถ€๋ถ„์„ ์ฑ„์›Œ ๋„ฃ์–ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ์ •์ƒ์ ์ธ DOM์ด ๋ฉ๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ํƒœ๊ทธ ์ง์ด ์•ˆ ๋งž์•„๋„ ๋ธŒ๋ผ์šฐ์ €๋Š” ํƒœ๊ทธ๋ฅผ ์ฝ๊ณ , ์ž๋™์œผ๋กœ ๋น ์ง„ ๋ถ€๋ถ„์„ ์ฑ„์›Œ ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ์ •์ƒ์ ์ธ DOM์ด ๋ฉ๋‹ˆ๋‹ค. <div class="domtree"></div> <script> -let node4 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"P","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•ˆ๋…•ํ•˜์„ธ์š”"}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์—„๋งˆ"}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"๊ทธ๋ฆฌ๊ณ "}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•„๋น "}]}]}]} +let node4 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"P","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•ˆ๋…•ํ•˜์„ธ์š”."}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์—„๋งˆ"}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"๊ทธ๋ฆฌ๊ณ "}]},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"์•„๋น "}]}]}]} drawHtmlTree(node4, 'div.domtree', 690, 360); </script> ````warn header="ํ…Œ์ด๋ธ”์—” ์–ธ์ œ๋‚˜ `<tbody>`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค." -ํ…Œ์ด๋ธ”์€ ์กฐ๊ธˆ ํฅ๋ฏธ๋กœ์šด ์ผ€์ด์Šค์ž…๋‹ˆ๋‹ค. DOM ๋ช…์„ธ์—” ํ…Œ์ด๋ธ”์— ๋ฐ˜๋“œ์‹œ `<tbody>`๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์–ธ๊ธ‰๋˜์–ด ์žˆ์ง€๋งŒ, HTML์—์„  `<tbody>`๋ฅผ ์ƒ๋žตํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž๋™์œผ๋กœ DOM์— `<tbody>`๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. +ํ…Œ์ด๋ธ”์€ ์กฐ๊ธˆ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. DOM ๋ช…์„ธ์„œ์—์„  ํ…Œ์ด๋ธ”์— ๋ฐ˜๋“œ์‹œ `<tbody>`๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋ชป ๋ฐ•์•„ ๋†“์•˜์ง€๋งŒ, HTML์—์„  `<tbody>`๋ฅผ ์ƒ๋žตํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž๋™์œผ๋กœ DOM์— `<tbody>`๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์€ HTML์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. +HTML: ```html no-beautify <table id="table"><tr><td>1</td></tr></table> ``` -๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋งŒ๋“ค์–ด ๋‚ธ DOM ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋งŒ๋“ค์–ด ๋‚ธ DOM ๊ตฌ์กฐ: <div class="domtree"></div> <script> @@ -165,9 +165,9 @@ drawHtmlTree(node5, 'div.domtree', 600, 200); ## ๊ธฐํƒ€ ๋…ธ๋“œ ํƒ€์ž… -There are some other node types besides elements and text nodes. +์š”์†Œ์™€ ํ…์ŠคํŠธ ๋…ธ๋“œ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋…ธ๋“œ ํƒ€์ž…์ด ์žˆ์Šต๋‹ˆ๋‹ค. -For example, comments: +์ฃผ์„๋„ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ```html <!DOCTYPE HTML> @@ -193,32 +193,32 @@ let node6 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1, drawHtmlTree(node6, 'div.domtree', 690, 500); </script> -We can see here a new tree node type -- *comment node*, labeled as `#comment`, between two text nodes. +ํŠธ๋ฆฌ์— *์ฃผ์„ ๋…ธ๋“œ(comment node)* ๋ผ๋Š” ์ƒˆ๋กœ์šด ๋…ธ๋“œ ํƒ€์ž…์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ `#comment`๋กœ ํ‘œํ˜„๋˜๋Š” ์ฃผ์„ ๋…ธ๋“œ๋Š” ๋‘ ํ…์ŠคํŠธ ๋…ธ๋“œ ์‚ฌ์ด์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -์ฃผ์„์€ ์–ด๋–ป๊ฒŒ ํ™”๋ฉด์ด ์ถœ๋ ฅ๋ ์ง€์— ๋Œ€ํ•ด ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋ฐ, ์™œ DOM์— ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ์˜์•„ํ•ดํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์„ ๋…ธ๋“œ๋Š” HTML์— ๋ญ”๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ DOM ํŠธ๋ฆฌ์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™ ๋•Œ๋ฌธ์— DOM์— ์ถ”๊ฐ€๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ฃผ์„์€ ํ™”๋ฉด ์ถœ๋ ฅ๋ฌผ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋ฐ, ์™œ DOM์—๋Š” ์ถ”๊ฐ€๋˜๋Š”์ง€ ์˜์•„ํ•ดํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์„ ๋…ธ๋“œ๋Š” HTML์— ๋ญ”๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ DOM ํŠธ๋ฆฌ์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™ ๋•Œ๋ฌธ์— DOM์— ์ถ”๊ฐ€๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -**์ฃผ์„์„ ํฌํ•จํ•œ HTML ์•ˆ์˜ ๋ชจ๋“  ๊ฒƒ๋“ค์€ DOM์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.** +**HTML ์•ˆ์˜ ๋ชจ๋“  ๊ฒƒ์€ (์‹ฌ์ง€์–ด ๊ทธ๊ฒƒ์ด ์ฃผ์„์ด๋”๋ผ๋„) DOM์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.** -HTML ๋ฌธ์„œ ์ œ์ผ ์ฒ˜์Œ์— ๋“ฑ์žฅํ•˜๋Š” `<!DOCTYPE...>` ์ง€์‹œ์ž ์—ญ์‹œ DOM ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ๋…ธ๋“œ๋Š” DOM ํŠธ๋ฆฌ์˜ `<html>` ๋ฐ”๋กœ ์•ž์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„  ์ด ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š์„ ์˜ˆ์ •์ด๋ผ ๋‹ค์ด์–ด๊ทธ๋žจ์—๋„ ํ‘œ์‹œ๋Š” ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์กด์žฌํ•˜๋Š” ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +HTML ๋ฌธ์„œ ์ตœ์ƒ๋‹จ์— ์œ„์น˜ํ•˜๋Š” `<!DOCTYPE...>` ์ง€์‹œ์ž ๋˜ํ•œ DOM ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋…ธ๋“œ๋Š” DOM ํŠธ๋ฆฌ์˜ `<html>` ๋ฐ”๋กœ ์œ„์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„  ์ด ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š์„ ์˜ˆ์ •์ด๋ผ ๋‹ค์ด์–ด๊ทธ๋žจ์—๋„ ํ‘œ์‹œ๋Š” ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์กด์žฌํ•˜๋Š” ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ ์ „์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” `document` ๊ฐ์ฒด ๋˜ํ•œ DOM ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. -๋…ธ๋“œ๋Š” ์ด [์—ด๋‘ ๊ฐ€์ง€](https://dom.spec.whatwg.org/#node) ์ข…๋ฅ˜๋กœ ๊ตฌ์„ฑ๋˜๊ณ , ์‹ค๋ฌด์—์„  ์ฃผ๋กœ ๋‹ค์Œ 4๊ฐ€์ง€ ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. +๋…ธ๋“œ ํƒ€์ž…์€ ์ด [์—ด๋‘ ๊ฐ€์ง€](https://dom.spec.whatwg.org/#node) ์ธ๋ฐ, ์‹ค๋ฌด์—์„  ์ฃผ๋กœ ๋‹ค์Œ ๋„ค ๊ฐ€์ง€ ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. -1. DOM์˜ "์ง„์ž…์ (entry point)"์ด ๋˜๋Š” `๋ฌธ์„œ(document)` ๋…ธ๋“œ. -2. HTML ํƒœ๊ทธ์—์„œ ๋งŒ๋“ค์–ด์ง€๋ฉฐ, DOM ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ธ”๋ก์ธ ์š”์†Œ ๋…ธ๋“œ(element node). -3. ํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ(text node). -4. ํ™”๋ฉด์— ๋ณด์ด์ง€๋Š” ์•Š์ง€๋งŒ, ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์ด ์ •๋ณด๋ฅผ DOM์œผ๋กœ๋ถ€ํ„ฐ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ฃผ์„(comment) ๋…ธ๋“œ. +1. DOM์˜ '์ง„์ž…์ "์ด ๋˜๋Š” `๋ฌธ์„œ(document)` ๋…ธ๋“œ +2. HTML ํƒœ๊ทธ์—์„œ ๋งŒ๋“ค์–ด์ง€๋ฉฐ, DOM ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ธ”๋ก์ธ ์š”์†Œ ๋…ธ๋“œ(element node) +3. ํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ(text node) +4. ํ™”๋ฉด์— ๋ณด์ด์ง€๋Š” ์•Š์ง€๋งŒ, ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์ด ์ •๋ณด๋ฅผ DOM์œผ๋กœ๋ถ€ํ„ฐ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ฃผ์„(comment) ๋…ธ๋“œ -## ๋ˆˆ์œผ๋กœ ์ง์ ‘ ๋ณด๊ธฐ +## DOM ๊ตฌ์กฐ ์ง์ ‘ ๋ณด๊ธฐ -์‹ค์‹œ๊ฐ„์œผ๋กœ DOM ๊ตฌ์กฐ๋ฅผ ๋ณด๋ ค๋ฉด [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/)๋ฅผ ์ด์šฉํ•ด ๋ณด์„ธ์š”. ๋ฌธ์„œ๊ฐ€ ๋ฐ”๋กœ DOM์œผ๋กœ ๋ฐ”๋€Œ์–ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. +[Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/)์— ๋“ค์–ด๊ฐ€๋ฉด ์‹ค์‹œ๊ฐ„์œผ๋กœ DOM ๊ตฌ์กฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ดํŠธ์— ๋“ค์–ด๊ฐ€ DOM ๊ตฌ์กฐ๋ฅผ ๋ณด๊ณ  ์‹ถ์€ HTML ๋ฌธ์„œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด HTML์ด ๋ฐ”๋กœ DOM์œผ๋กœ ๋ฐ”๋€Œ์–ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. -Another way to explore the DOM is to use the browser developer tools. Actually, that's what we use when developing. +Live DOM Viewer๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ ๋ง๊ณ ๋„ ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด DOM์„ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋ก  ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -[elk.html](elk.html) ํŽ˜์ด์ง€๋ฅผ ์—ด๊ณ , ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ผ  ๋‹ค์Œ Elements ํƒญ์œผ๋กœ ์ด๋™ํ•ด๋ด…์‹œ๋‹ค. +[elk.html](elk.html) ํŽ˜์ด์ง€๋ฅผ ์—ด๊ณ , ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์—ฐ ๋‹ค์Œ Elements ํŒจ๋„์œผ๋กœ ์ด๋™ํ•ด๋ด…์‹œ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋ณด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋ณด์ผ ๊ฒ๋‹ˆ๋‹ค. ![](elk.svg) @@ -226,57 +226,57 @@ Another way to explore the DOM is to use the browser developer tools. Actually, ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด DOM ๊ตฌ์กฐ๋ฅผ ๋ณผ ๋•, ์ƒ๋žต๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ๊ทธ๋ƒฅ ํ…์ŠคํŠธ๋กœ๋งŒ ํ‘œ์‹œ๋˜๊ณ , ๋„์–ด์“ฐ๊ธฐ๋งŒ ์žˆ๋Š” ๋นˆ ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์ค‘์—” ๋Œ€๋ถ€๋ถ„ ์š”์†Œ ๋…ธ๋“œ๋งŒ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€๋Š” ์•Š์ง€๋งŒ ๋ง์ด์ฃ . -์ขŒ์ธก ์ƒ๋‹จ์˜ <span class="devtools" style="background-position:-328px -124px"></span> ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ํ›„, ๋งˆ์šฐ์Šค ๋“ฑ์˜ ์žฅ๋น„๋กœ ์›นํŽ˜์ด์ง€ ์ƒ์˜ ๋…ธ๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด, Elements ํƒญ์˜ ํ•ด๋‹น ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜์–ด ๋…ธ๋“œ๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฉ๋Œ€ํ•œ ํฌ๊ธฐ์˜ HTML์„ ๋‹ค๋ฃฐ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํŠน์ • ์š”์†Œ๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์ขŒ์ธก ์ƒ๋‹จ์˜ <span class="devtools" style="background-position:-328px -124px"></span> ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ํ›„, ๋งˆ์šฐ์Šค ๋“ฑ์˜ ํฌ์ธํ„ฐ ์žฅ๋น„๋กœ ์›นํŽ˜์ด์ง€ ์ƒ์˜ ๋…ธ๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด, Elements ํŒจ๋„์˜ ํ•ด๋‹น ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜์–ด ๋…ธ๋“œ๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์š”์†Œ๊ฐ€ DOM ํŠธ๋ฆฌ ๋‚ด ์–ด๋””์— ์žˆ๋Š”์ง€ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฉ๋Œ€ํ•œ HTML์„ ๋‹ค๋ฃฐ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -์›นํŽ˜์ด์ง€์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋‚˜ํƒ€๋‚˜๋Š” ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์—์„œ "๊ฒ€์‚ฌ(Inspect)"๋ฅผ ํด๋ฆญํ•ด๋„ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฒ€์‚ฌ ํ•˜๊ณ  ์‹ถ์€ ์š”์†Œ์— ํฌ์ธํ„ฐ๋ฅผ ๋Œ„ ํ›„์— ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋‚˜ํƒ€๋‚˜๋Š” ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์—์„œ 'Inspect'๋ฅผ ํด๋ฆญํ•ด๋„ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ![](inspect.svg) -Elements ํƒญ์—” ์•„๋ž˜์™€ ๊ฐ™์€ ํ•˜์œ„ ํƒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค: -- **Styles** -- ๋‚ด์žฅ ๊ทœ์น™(ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ)์„ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ์„ ํƒํ•œ ์š”์†Œ์— ์ ์šฉ๋œ CSS ๊ทœ์น™ ์ „์ฒด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ•˜๋‹จ๋ถ€ ๋ฐ•์Šค์— ์žˆ๋Š” ํฌ๊ธฐ(dimension), ๋งˆ์ง„(margin), ํŒจ๋”ฉ(padding)์— ๋”ํ•˜์—ฌ ๋Œ€๋ถ€๋ถ„์˜ ์Šคํƒ€์ผ์„ ์ด ํƒญ์—์„œ ๋ฐ”๋กœ ์ˆ˜์ •ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **Computed** -- ํ˜„์žฌ ์„ ํƒํ•œ ์š”์†Œ์— ์ ์šฉ๋œ CSS๊ทœ์น™์„ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. CSS ์ƒ์† ๋“ฑ ํ•ด๋‹น ๊ทœ์น™์˜ ์›์ฒœ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **Event Listeners** -- DOM ์š”์†Œ์— ์ ์šฉ๋œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํŒŒํŠธ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +Elements ํŒจ๋„ ์šฐ์ธก์—” ์—ฌ๋Ÿฌ ํ•˜์œ„ ํŒจ๋„์ด ์žˆ์Šต๋‹ˆ๋‹ค. +- **Styles** -- ๋‚ด์žฅ ๊ทœ์น™(ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ)์„ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ์„ ํƒํ•œ ์š”์†Œ์— ์ ์šฉ๋œ CSS ๊ทœ์น™์„ ์ผ๋ฅ ์ ์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ•˜๋‹จ๋ถ€ ๋ฐ•์Šค์— ์žˆ๋Š” ํฌ๊ธฐ(dimension), ๋งˆ์ง„(margin), ํŒจ๋”ฉ(padding)์„ ๋น„๋กฏํ•œ ์Šคํƒ€์ผ ๋Œ€๋ถ€๋ถ„์„ Styles ํŒจ๋„์—์„œ ๋ฐ”๋กœ ์ˆ˜์ •ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **Computed** -- ํ˜„์žฌ ์„ ํƒํ•œ ์š”์†Œ์— ์ ์šฉ๋œ CSS ๊ทœ์น™์„ ํ”„๋กœํผํ‹ฐ ๊ธฐ์ค€์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. CSS ์ƒ์† ๋“ฑ์„ ํ†ตํ•ด ์ ์šฉ๋œ ๊ทœ์น™๋„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **Event Listeners** -- DOM ์š”์†Œ์— ๋ถ™์€ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํŒŒํŠธ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - ๊ธฐํƒ€ ๋“ฑ๋“ฑ -๊ฐ ํƒญ์ด ๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ง์ ‘ ํด๋ฆญํ•ด ๋ณด๊ณ  ์ด๋ฆฌ์ €๋ฆฌ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ’์€ ๋ฐ”๋กœ ์ˆ˜์ • ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ, ์‹ค์Šต์„ ํ†ตํ•ด ํ•™์Šตํ•ด ๋ณด์‹œ๊ธธ ๊ถŒ์œ  ๋“œ๋ฆฝ๋‹ˆ๋‹ค. +๊ฐ ํŒจ๋„์ด ๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๋ ค๋ฉด ์ง์ ‘ ํด๋ฆญํ•ด ๋ณด๊ณ  ์ด๋ฆฌ์ €๋ฆฌ ์‚ดํŽด๋ณด๋Š” ๊ฒŒ ์ œ์ผ ์ข‹์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ’์€ ๋ฐ”๋กœ ์ˆ˜์ •ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## ์ฝ˜์†” ๋‹ค๋ฃจ๊ธฐ +## ์ฝ˜์†”์„ ์‚ฌ์šฉํ•ด DOM ๋‹ค๋ฃจ๊ธฐ -As we work the DOM, we also may want to apply JavaScript to it. Like: get a node and run some code to modify it, to see the result. Here are few tips to travel between the Elements tab and the console. +๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด DOM์„ ํƒ์ƒ‰ํ•˜๋‹ค ๋ณด๋ฉด, DOM์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ ์šฉํ•ด ๋ณด๊ณ  ์‹ถ์–ด์งˆ ๋•Œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ฝ”๋“œ๋กœ ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €์ƒ์—์„œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ”๋กœ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋ง์ด์ฃ . ์ด๋Ÿด ๋•Œ ์“ธ ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. -For the start: +๋จผ์ € ์•„๋ž˜ ์ž‘์—…์„ ํ•ด์ฃผ์„ธ์š”. -1. Select the first `<li>` in the Elements tab. -2. Press `key:Esc` -- it will open console right below the Elements tab. +- Elements ํŒจ๋„์—์„œ ์ฒซ ๋ฒˆ์งธ `<li>`๋ฅผ ์„ ํƒํ•˜์„ธ์š”. +- `key:Esc`๋ฅผ ๋ˆŒ๋Ÿฌ Elements ํŒจ๋„ ์•„๋ž˜์— ์ฝ˜์†”์„ ๋„์šฐ์„ธ์š”. -๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์„ ํƒํ–ˆ๋˜ ์š”์†Œ๋Š” `$0`์œผ๋กœ, ๊ทธ ์ด์ „์— ์„ ํƒํ–ˆ๋˜ ์š”์†Œ๋Š” `$1`์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด์ œ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์„ ํƒํ–ˆ๋˜ ์š”์†Œ๋Š” `$0`์œผ๋กœ, ๊ทธ ์ด์ „์— ์„ ํƒํ–ˆ๋˜ ์š”์†Œ๋Š” `$1`๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด `$0.style.background = 'red'`์„ ์ฝ˜์†” ์ฐฝ์— ์ž…๋ ฅํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ฒซ ๋ฒˆ์งธ list ์•„์ดํ…œ์ด ๋ถ‰์€์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜ˆ๋ฅผ ๋“ค์–ด ์ฝ˜์†” ์ฐฝ์— `$0.style.background = 'red'`์„ ์ž…๋ ฅํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ฒซ ๋ฒˆ์งธ list ์•„์ดํ…œ์ด ๋ถ‰์€์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ![](domconsole0.svg) -That's how to get a node from Elements in Console. +์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด Elements ํŒจ๋„์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์ฝ˜์†”์ฐฝ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -There's also a road back. If there's a variable referencing a DOM node, then we can use the command `inspect(node)` in Console to see it in the Elements pane. +๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. DOM ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ฝ˜์†”์— `inspect(node)` ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด Elements ํŒจ๋„์—์„œ ํ•ด๋‹น ์š”์†Œ๊ฐ€ ๊ฐ•์กฐ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Or we can just output the DOM node in the console and explore "in-place", like `document.body` below: +์•„๋‹ˆ๋ฉด ์•„๋ž˜์—์„œ `document.body`๋ฅผ ์ž…๋ ฅํ•ด์„œ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ, DOM ๋…ธ๋“œ๋ฅผ ์ฝ˜์†” ์ฐฝ์— ์ถœ๋ ฅํ•ด์„œ ํƒ์ƒ‰ํ•ด๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ![](domconsole1.svg) -์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ์ด ํŒ๋“ค์€ ๋””๋ฒ„๊น… ์šฉ๋„์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ๋ถ€ํ„ด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ DOM์— ์ ‘๊ทผํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ํŒ๋“ค์€ ๋””๋ฒ„๊น… ์šฉ๋„์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด DOM์— ์ ‘๊ทผํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ ์ฑ•ํ„ฐ๋ถ€ํ„ฐ ๋ฐฐ์šฐ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -๋ธŒ๋ผ์šฐ์ €์˜ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋Š” ๊ฐœ๋ฐœ์„ ๋„์™€์ฃผ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. DOM์„ ํƒ์ƒ‰ํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ฑธ ์ ์šฉํ•œ ๋‹ค์Œ ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š”์ง€ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ฃ . +๋ธŒ๋ผ์šฐ์ €์˜ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋Š” ๊ฐœ๋ฐœ์„ ๋„์™€์ฃผ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DOM์„ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ณ , ์ƒˆ๋กœ์šด ๊ฒƒ์„ ์ ์šฉํ•ด ๋ณธ ํ›„ ์–ด๋–ค ๋ณ€ํ™”๋‚˜ ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธฐ๋Š”์ง€ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์š”์•ฝ HTML/XML ๋ฌธ์„œ๋Š” ๋ธŒ๋ผ์šฐ์ € ์•ˆ์—์„œ DOM ํŠธ๋ฆฌ๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. - ํƒœ๊ทธ๋Š” ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ๋˜๊ณ  ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. -- ํ…์ŠคํŠธ๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -- ์ด ์™ธ์— HTML ๋‚ด์˜ ๋ชจ๋“  ๊ฒƒ์€ DOM์˜ ์ผ๋ถ€๋ถ„์ด ๋ฉ๋‹ˆ๋‹ค. ์ฃผ์„๊นŒ์ง€๋„ ๋ง์ด์ฃ . +- ๋ฌธ์ž๋Š” ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +- ์ด ์™ธ์— HTML ๋‚ด์˜ ๋ชจ๋“  ๊ฒƒ์€ DOM์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์„๊นŒ์ง€๋„ ๋ง์ด์ฃ . ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DOM์„ ๊ฒ€์‚ฌํ•˜๊ณ , ๋ฐ”๋กœ ์ˆ˜์ •ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ง€๊ธˆ๊นŒ์ง„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ, ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ์œ„์ฃผ๋กœ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•ด ๋“œ๋ ธ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์— ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋“ค์€ Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ• ๋ฌธ์„œ ์‚ฌ์ดํŠธ, <https://developers.google.com/web/tools/chrome-devtools> ์—์„œ ๋” ์ƒ์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ•์„ ๊ธˆ๋ฐฉ ์ตํžˆ๋ ค๋ฉด ์ด๋ฆฌ์ €๋ฆฌ ํด๋ฆญํ•ด๋ณด๊ณ  ๋ฉ”๋‰ด๋ฅผ ์ง์ ‘ ์—ด์–ด๋ณด์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ณผ์ •์„ ํ†ตํ•ด ๋„๊ตฌ๊ฐ€ ์–ด๋А ์ •๋„ ์†์— ์ต์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ •๋…ํ•ด ๋ถ€์กฑํ•œ ๋‚˜๋จธ์ง€๋ฅผ ์ฑ„์šฐ๋„๋ก ํ•ฉ์‹œ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•ด ๋“œ๋ฆฐ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ•์€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ , ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ ์œ„์ฃผ์˜€์Šต๋‹ˆ๋‹ค. Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๋ฌธ์„œ ์‚ฌ์ดํŠธ <https://developers.google.com/web/tools/chrome-devtools>๋กœ ๊ฐ€์‹œ๋ฉด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํˆด์„ ๋ฐฐ์šธ ๋•Œ ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ด๋ฆฌ์ €๋ฆฌ ํด๋ฆญํ•ด๋ณด๊ณ  ๋ฉ”๋‰ด๋ฅผ ์ง์ ‘ ์—ด์–ด๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์˜ต์…˜์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ ๋˜ํ•œ ์žŠ์œผ๋ฉด ์•ˆ ๋˜์ฃ . ์ด๋Ÿฐ ๊ณผ์ •์„ ํ†ตํ•ด ๋„๊ตฌ๊ฐ€ ์–ด๋А ์ •๋„ ์†์— ์ต์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ •๋…ํ•ด ๋ถ€์กฑํ•œ ๋‚˜๋จธ์ง€๋ฅผ ์ฑ„์šฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -DOM ๋…ธ๋“œ๋Š” ๋…ธ๋“œ ๊ฐ„ ์ด๋™, ์ˆ˜์ • ๋“ฑ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ด์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. \ No newline at end of file +DOM ๋…ธ๋“œ๋Š” ๋…ธ๋“œ ๊ฐ„ ์ด๋™, ์ˆ˜์ • ๋“ฑ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ด์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/02-dom-nodes/domconsole0.svg b/2-ui/1-document/02-dom-nodes/domconsole0.svg index c0096060aa..ea0d9141c9 100644 --- a/2-ui/1-document/02-dom-nodes/domconsole0.svg +++ b/2-ui/1-document/02-dom-nodes/domconsole0.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="699" height="450" viewBox="0 0 699 450"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h699v450H0z"/><path id="path-2" d="M72 305v21.429l5.25-5.358L81.625 330h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H86L72 305z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="domconsole0.svg"><g id="Bitmap"><image width="699" height="450" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXYAAAOECAYAAAAFQmncAAAMSWlDQ1BJQ0MgUHJvZmlsZQAASImVVwdUU8kanltSSWiBCEgJvYlSpEsJoUUQkCrYCEkgocSYEETsyqKCaxcRsKGrIoquBRA79rIodtfyUBaVlXWxYEPlTQro6nnvnfefM3e+/PPP95fMnTsDgE41TyrNRXUByJPky+IjQljjUtNYpA5AACZAG7gCLx5fLmXHxUUDKAP9P+XtLYAo++suSq4fx/+r6AmEcj4ASBzEGQI5Pw/iAwDgxXypLB8Aog/UW0/LlyrxBIgNZDBAiKVKnKXGxUqcocYVKpvEeA7EuwAg03g8WRYA2k1QzyrgZ0Ee7TsQu0oEYgkAOmSIA/kingDiSIiH5eVNUWJoBxwyvuHJ+gdnxiAnj5c1iNW5qIQcKpZLc3nT/89y/G/Jy1UM+LCDjSaSRcYrc4Z1u5MzJUqJaRB3SzJiYiHWh/i9WKCyhxilihSRSWp71JQv58CaASbErgJeaBTEphCHS3JjojX6jExxOBdiuELQQnE+N1Ezd5FQHpag4ayWTYmPHcCZMg5bM7eeJ1P5VdqfVuQksTX8d0RC7gD/myJRYoo6ZoxaIE6OgVgbYqY8JyFKbYPZFIk4MQM2MkW8Mn4biP2EkogQNT82KVMWHq+xl+XJB/LFFonE3BgNrswXJUZqeHbxear4jSBuEkrYSQM8Qvm46IFcBMLQMHXu2FWhJEmTL9YuzQ+J18x9Jc2N09jjVGFuhFJvBbGpvCBBMxcPzIcLUs2Px0jz4xLVceIZ2bzRcep48EIQDTggFLCAArYMMAVkA3Frd2M3/KUeCQc8IANZQAhcNJqBGSmqEQl8JoAi8BdEQiAfnBeiGhWCAqj/PKhVP11Apmq0QDUjBzyBOA9EgVz4W6GaJRn0lgz+gBrxD975MNZc2JRjP+rYUBOt0SgGeFk6A5bEMGIoMZIYTnTETfBA3B+Phs9g2NxxH9x3INqv9oQnhDbCY8JNQjvh7mTxfNl3+bDAGNAOPYRrcs74NmfcDrJ64iF4AOSH3DgTNwEu+EjoiY0HQd+eUMvRRK7M/nvuf+TwTdU1dhRXCkoZQgmmOHw/U9tJ23OQRVnTbyukjjVjsK6cwZHv/XO+qbQA9lHfW2KLsP3YOewkdgE7gjUCFnYca8IuY0eVeHAV/aFaRQPe4lXx5EAe8Q/+eBqfykrKXetcu1w/qcfyhYXK/RFwpkiny8RZonwWG+78QhZXwh8+jOXu6uYLgPI7ot6mXjNV3weEefGrbsEGAAIO9Pf3H/6qi2oGYH8ZANTbX3X2s+B2cBKA81V8haxArcOVDwKgAh34RhkDc2ANHGA+7sAL+INgEAZGg1iQCFLBJFhlEVzPMjANzATzQAkoA8vBGlAJNoItYAfYDfaBRnAEnARnwSVwFdwE9+Dq6QTPQQ94C/oQBCEhdISBGCMWiC3ijLgjPkggEoZEI/FIKpKOZCESRIHMRBYgZchKpBLZjNQivyKHkJPIBaQNuYs8QrqQV8hHFENpqAFqhtqhI1AflI1GoYnoRDQLnYoWocXoUrQCrUF3oQ3oSfQSehNtR5+jvRjAtDAmZom5YD4YB4vF0rBMTIbNxkqxcqwGq8ea4f98HWvHurEPOBFn4CzcBa7gSDwJ5+NT8dn4ErwS34E34Kfx6/gjvAf/QqATTAnOBD8ClzCOkEWYRighlBO2EQ4SzsC3qZPwlkgkMon2RG/4NqYSs4kziEuI64l7iCeIbcQOYi+JRDImOZMCSLEkHimfVEJaR9pFOk66RuokvSdrkS3I7uRwchpZQp5PLifvJB8jXyM/JfdRdCm2FD9KLEVAmU5ZRtlKaaZcoXRS+qh6VHtqADWRmk2dR62g1lPPUO9TX2tpaVlp+WqN1RJrzdWq0NqrdV7rkdYHmj7NicahTaApaEtp22knaHdpr+l0uh09mJ5Gz6cvpdfST9Ef0t9rM7SHa3O1BdpztKu0G7Svab/QoejY6rB1JukU6ZTr7Ne5otOtS9G10+Xo8nRn61bpHtK9rdurx9Bz04vVy9NbordT74LeM32Svp1+mL5Av1h/i/4p/Q4GxrBmcBh8xgLGVsYZRqcB0cDegGuQbVBmsNug1aDHUN9wpGGyYaFhleFRw3YmxrRjcpm5zGXMfcxbzI9DzIawhwiHLB5SP+TakHdGQ42CjYRGpUZ7jG4afTRmGYcZ5xivMG40fmCCmziZjDWZZrLB5IxJ91CDof5D+UNLh+4b+rspaupkGm86w3SL6WXTXjNzswgzqdk6s1Nm3eZM82DzbPPV5sfMuywYFoEWYovVFsct/mQZstisXFYF6zSrx9LUMtJSYbnZstWyz8reKslqvtUeqwfWVGsf60zr1dYt1j02FjZjbGba1Nn8bkux9bEV2a61PWf7zs7eLsVuoV2j3TN7I3uufZF9nf19B7pDkMNUhxqHG45ERx/HHMf1jledUCdPJ5FTldMVZ9TZy1nsvN65bRhhmO8wybCaYbddaC5slwKXOpdHw5nDo4fPH944/MUImxFpI1aMODfii6una67rVtd7bvpuo93muzW7vXJ3cue7V7nf8KB7hHvM8WjyeDnSeaRw5IaRdzwZnmM8F3q2eH728vaSedV7dXnbeKd7V3vf9jHwifNZ4nPel+Ab4jvH94jvBz8vv3y/fX5/+7v45/jv9H82yn6UcNTWUR0BVgG8gM0B7YGswPTATYHtQZZBvKCaoMfB1sGC4G3BT9mO7Gz2LvaLENcQWcjBkHccP84szolQLDQitDS0NUw/LCmsMuxhuFV4VnhdeE+EZ8SMiBORhMioyBWRt7lmXD63ltsz2nv0rNGno2hRCVGVUY+jnaJl0c1j0DGjx6wacz/GNkYS0xgLYrmxq2IfxNnHTY07PJY4Nm5s1dgn8W7xM+PPJTASJifsTHibGJK4LPFekkOSIqklWSd5QnJt8ruU0JSVKe3jRoybNe5SqkmqOLUpjZSWnLYtrXd82Pg14zsneE4omXBrov3EwokXJplMyp10dLLOZN7k/emE9JT0nemfeLG8Gl5vBjejOqOHz+Gv5T8XBAtWC7qEAcKVwqeZAZkrM59lBWStyuoSBYnKRd1ijrhS/DI7Mntj9ruc2JztOf25Kbl78sh56XmHJPqSHMnpKeZTCqe0SZ2lJdL2qX5T10ztkUXJtskR+UR5U74BPLBfVjgoflI8KggsqCp4Py152v5CvUJJ4eXpTtMXT39aFF70ywx8Bn9Gy0zLmfNmPprFnrV5NjI7Y3bLHOs5xXM650bM3TGPOi9n3m/zXeevnP9mQcqC5mKz4rnFHT9F/FRXol0iK7m90H/hxkX4IvGi1sUei9ct/lIqKL1Y5lpWXvZpCX/JxZ/dfq74uX9p5tLWZV7LNiwnLpcsv7UiaMWOlXori1Z2rBqzqmE1a3Xp6jdrJq+5UD6yfONa6lrF2vaK6IqmdTbrlq/7VCmqvFkVUrWn2rR6cfW79YL11zYEb6jfaLaxbOPHTeJNdzZHbG6osasp30LcUrDlydbkred+8fmldpvJtrJtn7dLtrfviN9xuta7tnan6c5ldWidoq5r14RdV3eH7m6qd6nfvIe5p2wv2KvY++ev6b/e2he1r2W/z/76A7YHqg8yDpY2IA3TG3oaRY3tTalNbYdGH2pp9m8+eHj44e1HLI9UHTU8uuwY9Vjxsf7jRcd7T0hPdJ/MOtnRMrnl3qlxp26cHnu69UzUmfNnw8+eOsc+d/x8wPkjF/wuHLroc7Hxktelhsuelw/+5vnbwVav1oYr3learvpebW4b1XbsWtC1k9dDr5+9wb1x6WbMzbZbSbfu3J5wu/2O4M6zu7l3X/5e8Hvfvbn3CfdLH+g+KH9o+rDmX47/2tPu1X70Ueijy48THt/r4Hc8/0P+x6fO4if0J+VPLZ7WPnN/dqQrvOvqn+P/7Hwufd7XXfKX3l/VLxxeHPg7+O/LPeN6Ol/KXva/WvLa+PX2NyPftPTG9T58m/e2713pe+P3Oz74fDj3MeXj075pn0ifKj47fm7+EvXlfn9ef7+UJ+OpjgIYbGhmJgCvtgNATwWAcRWeH8ar73kqQdR3UxUC/wmr74Iq8QKgHnbK4zrnBAB7YbMLhtywVx7VE4MB6uEx2DQiz/RwV3PR4I2H8L6//7UZACR4nvks6+/vW9/f/3krDPYuACemqu+XSiHCu8GmYCW6aTSpGnwn/wZ3TIEEcU5bKwAAQABJREFUeAHs3QncZlP9APDzMvZ93012ERUpS0QqadOmlFJo31WIZCkqSytSVCpCtFgSIoT+lKxF9n3fxhhjm5n3+Z/fzb3u8867L9N75/mez+ed567nnvM9d6b83vP8Tlcrl6QQIECAAAECBAgQIECAAAECBAgQIECAQGME5mhMSzWUAAECBAgQIECAAAECBAgQIECAAAECBAoBgV0vAgECBAgQIECAAAECBAgQIECAAAECBBomILDbsAHTXAIECBAgQIAAAQIECBAgQIAAAQIECAjsegcIECBAgAABAgQIECBAgAABAgQIECDQMAGB3YYNmOYSIECAAAECBAgQIECAAAECBAgQINDZAjNmzEhdrVw6m0HvCRAgQIAAAQIECBAgQIAAAQIECBAg0CwBM3abNV5aS4AAAQIECBAgQIAAAQIECBAgQIAAgSSw6yUgQIAAAQIECBAgQIAAAQIECBAgQIBAwwQEdhs2YJpLgAABAgQIECBAgAABAgQIECBAgAABgV3vAAECBAgQIECAAAECBAgQIECAAAECBBokEMumCew2aMA0lQABAgQIECBAgAABAgQIECBAgAABAhHY7cp/tFAQIECAAAECBAgQIECAAAECBAgQIECAQHMEzNhtzlhpKQECBAgQIECAAAECBAgQIECAAAECBAoBgV0vAgECBAgQIECAAAECBAgQIECAAAECBBomILDbsAHTXAIECBAgQIAAAQIECBAgQIAAAQIEOlugu7vb4mmd/QroPQECBAgQIECAAAECBAgQIECAAAECTRPo6uoS2G3aoGkvAQIECBAgQIAAAQIECBAgQIAAAQKdLSCw29njr/cECBAgQIAAAQIECBAgQIAAAQIECDRUYFzm2J0+fXp64IEHGko6vpr95JNPpsmTJ4+vRuXWPPvss+nhhx8ed+1qSoNuvvnmdMcdd/TbXL798jhJgAABAgQIECBAgAABAgQIEGi0wIThtv7ss89Ol1566XBvr+5beOGF05e+9KX0+OOPpwsuuCCdeeaZ6eSTT0477LBDOvroo6vrbAxe4O67705//vOf0xlnnJFOO+20dPzxx6cdd9xx8BWM0ZWPPvpoOv/881O8O6ecckr6zGc+k775zW+O0dNmr2qnTZuW/v73v6dzzjmn+Ptx0003pYMPPjjtscceVUenTp2aLrroonTWWWelP/zhD2nppZdOV1xxRXXeBgECBAgQIECAAAECBAgQIECAwOwjMOzAbgQOv/e9741YYqGFFkrrrbde2mabbUZclwpS2n///dMBBxww7igOO+ywtPvuu4+7djWhQZMmTUoTJ05MU6ZM6bO5hx56aFuQNy6MwK5CgAABAgQIECBAgAABAgQIECAwewoMOxXD008/XYl8+MMfTqeffnq67LLLUswkvPDCC6tzsbHffvul+Or4lVdemc4999z0rW99qwo6RbBq6623Trfeemvafvvt2+6zM3SBPffcM1199dVpzTXXHPrNY3jHpz/96XTdddelzTbbbAyfMntWvdhii6XHHnss3XLLLWn99dfvtZO77bZbcc14DOr32mAHCRAgQIAAAQIECBAgQIAAAQIERiQw7MBufO07ypFHHpmOPfbY9Na3vjW96lWvSmussUZaffXV2xq1/PLLF8de/vKXp9e97nXpK1/5Svrb3/5WXTPnnHOmVVddNb3zne+sjo3Hjcj7+4Y3vGHcNC2+ih8pDeplvvnmSy996UvTa1/72vrh//l2tGudddZJ22677f+8LaPRgPjlRaQQmVVlwoQJabXVVktbbrllr4+M8xEAfsc73tHreQcJECBAgAABAgQIECBAgAABAgRmL4FhB3afeeaZYtbtJz7xiWGJRPA3cqxGicXSokRahvFaZsyYkXbaaad0zTXXjIsmRj7iCJD39fX8yF08Hst4bddQrCLA/973vvd/svjboosu2m9T55577n7PO0mAAAECBAgQIECAAAECBAgQINB8gVarlYYd2H3qqafSu971rjTHHMOuopjlG4zPPffcuNf8+te/XqSRGA8Nvffee9N22203HprScW2IX0K8733vSw899FDH9V2HCRAgQIAAAQIECBAgQIAAAQIExodAV1dXGvbiabFw2gILLDCinsTXyiMlw/zzzz9gPRFQi5955513wGtH+4If/OAHKQK7gy0xi7Y++ziC4JGKIMBHWu67774iHURfM3UHU3/Mto6v7sfPaJT4DcHDDz+cnnjiifSiF71o2PWOpF0xozpSeoxliV9AfOhDH5oph/RoPDMMR+P9GI22qIMAAQIECBAgQIAAAQIECBAgQGD8Cwx7um3k0o3cuSMp8bXxTTfdtM8quru7029+85v0yle+Ms0111xFcPTVr351kdO3z5vyiVhkKhYRi2vjq//xE7lxTzrppP5u6/Xc/vvvn77whS9U52Km5hZbbFH8bLXVVimCtlEisHj++eenHXfcsXheLC73r3/9q0jfEAHwtddeO33qU59K6667btvP2WefXdUdweOe5+OeskS/Io/x9ddfXx4qFqYr23PMMcdUx3tuPPnkk+mQQw4p8rRGkDk83/a2t7XlOu55z0D7N954Y5GSIGZtL7PMMkV+5ah3k002Seedd95Atxfnw+/AAw9sa1eM1R/+8Id+748g8He/+9307ne/O6200kpFMHmttdYq/H/xi1+keHfq5cwzz5zJ9qCDDqou6e38hhtuWNUT7Xz729/e9g6deuqp1bvwyU9+sqprsBuRTiPui5zIYRj9eM973pP++c9/DraKQV8XvxSJ9r/lLW+Z6eezn/3soOtxIQECBAgQIECAAAECBAgQIECAwP9eIGJfww7sjnXzp02bliJ/7w477JAuv/zy6nExw3eXXXZJv//976tj9Y0IlG6wwQYpgnuRxzfSRUQ599xzi6/QR2Dr2Wefrd/S53a0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xu5YC6ufAAECBAgQIECAAAECBAgQIECAAAECoyjQ3d2dunI+htYo1qkqAgQIECBAgAABAgQIECBAgAABAgQIEBhjATN2xxhY9QQIECBAgAABAgQIECBAgAABAgQIEBhtAYHd0RZVHwECBAgQIECAAAECBAgQIECAAAECBMZQIJIwCOyOIbCqCRAgQIAAAQIECBAgQIAAAQIECBAgMBYCArtjoapOAgQIECBAgAABAgQIECBAgAABAgQIjJFAV1eXGbtjZKtaAgQIECBAgAABAgQIECBAgAABAgQIjJmAGbtjRqtiAgQIECBAgAABAgQIECBAgAABAgQIjI2AwO7YuKqVAAECBAgQIECAAAECBAgQIECAAAECYyYgsDtmtComQIAAAQIECBAgQIAAAQIECBAgQIDA2AgI7I6Nq1oJECBAgAABAgQIECBAgAABAgQIECAwJgIzZsxIXa1cxqR2lRIgQIAAAQIECBAgQIAAAQIECBAgQIDAmAiYsTsmrColQIAAAQIECBAgQIAAAQIECBAgQIDA2AkI7I6drZoJECBAgAABAgQIECBAgAABAgQIECAwJgICu2PCqlICBAgQIECAAAECBAgQIECAAAECBAiMnYDA7tjZqpkAAQIECBAgQIAAAQIECBAgQIAAAQKjLhDLpgnsjjqrCgkQIECAAAECBAgQIECAAAECBAgQIDB2AhHY7cp/tMbuEWomQIAAAQIECBAgQIAAAQIECBAgQIAAgdEWMGN3tEXVR4AAAQIECBAgQIAAAQIECBAgQIAAgTEWENgdY2DVEyBAgAABAgQIECBAgAABAgQIECBAYLQFBHZHW1R9BAgQIECAAAECBAgQIECAAAECBAgQGEOB7u5ui6eNoa+qCRAgQIAAAQIECBAgQIAAAQIECBAgMOoCXV1dArujrqpCAgQIECBAgAABAgQIECBAgAABAgQIjKFABHYnjGH9qu5H4OFXrN7PWacIECBAgAABAgQIECBAgAABAgQIEJidBZb65y0j6p4cuyPiczMBAgQIECBAgAABAgQIECBAgAABAgRmvYDA7qw390QCBAgQIECAAAECBAgQIECAAAECBAiMSEBgd0R8biZAgAABAgQIECBAgAABAgQIECBAgMCsFxDYnfXmnkiAAAECBAgQIECAAAECBAgQIECAAIERCQjsjojPzSMRmNFK6eqn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+OYc/O7ZrwigfiPX89L8TkQ5N9t+/PYHZ7ouzsWifOesvWIx87qvd/NTOb3Dx5dZJG2WZ2P3fFbUEeXidVdKL5p7ruK9OC4He8sSaSH2yrab5V8KxC8RvnDnw8WM7rXmnTvttcLixS8mon19lQvXWalt4cC4LtoQs3PrQfpI1xEzuxUCBAgQIECAAAECBAgQIECAwHgWWOqft4yoeQK7I+J74eZbbrkl3X///WmTTTZJEyZMeOFEH1sPv2L1Ps408/BdeYZnzBKOQGTk4F0i59VtcokZr3OmrjRPTl8QKRvufG5aTrGR0jJzzZmWzYHdFxIrDK2Xkb7gjmenFzOjJ84zYaYUFZF6YJE552xLmzDQE6J9i074b4sezPc/kNNuRFuj/sX/x+MQbbsn2y2XzXouGBcziyMlRyz2NpISv5m6Oc++np431ph3rjRXLQ3ESOp1LwECBAgQIECAAAECBAgQIEBgLAUEdsdSdwzrnt0Cu2NIpWoCBAgQIECAAAECBAgQIECAAAECs53ASAK73XlS4nAnHs52kDpEgAABAgQIECBAgAABAgQIECBAgACBJgh05W8sC+w2YaS0kQABAgQIECBAgAABAgQIECBAgAABAs8LCOx6FQgQIECAAAECBAgQIECAAAECBAgQINBAATN2GzhomkyAAAECBAgQIECAAAECBAgQIECAQGcLCOx29vjrPQECBAgQIECAAAECBAgQIECAAAECDRQQ2G3goGkyAQIECBAgQIAAAQIECBAgQIAAAQKdLdDVyqWzCfSeAAECBAgQIECAAAECBAgQIECAAAECzRIwY7dZ46W1BAgQIECAAAECBAgQIECAAAECBAgQSAK7XgICBAgQIECAAAECBAgQIECAAAECBAg0SCCSMAjsNmjANJUAAQIECBAgQIAAAQIECBAgQIAAAQJdXV0Cu14DAgQIECBAgAABAgQIECBAgAABAgQINE3AjN2mjdhs2N5bbrllNuzV2HbpvvvuS88999zYPmQ2rX12sLv55pvTHXfcMZuOkG4RIECAAAECBAgQIECAAAECAwl0d3ebsVsi3X333WnPPfdMW221VVpmmWXShhtumD7ykY+ks846q7zE5ygJREDykksuSfvtt19aa6210hprrDFKNXdGNV/60pfSCiuskFZaaaUkKD60MW+q3bRp04q/M1/72teKvzNrrrlmOvnkk/vs/NSpU9PWW2+d4msZ++67b5/XOUGAAAECBAgQIECAAAECBAg0U2COOeZIXTnRbquZzR+9Vh9yyCFFULevGj/4wQ+mo446Ki2wwAJ9XeL4IAWuv/76tO666850tddwJpJeD8yYMSNNmDChOnfQQQelvffeu9q30bdAU+0mTZqUJk6cmKZMmdLWuYMPPjjtsccebcfKnfiF1Jve9KZyNz366KNp8cUXr/ZtECBAgAABAgQIECBAgAABAs0X6PhUDMcdd1xbUDdmwvUscc1ee+3V87D9YQiss8466cknn0y//OUvq7sXWmihattG/wJzzjln2myzzaqLNtlkk2rbRv8CTbVbbLHF0mOPPVbMzl5//fX77+TzZ6+++uq26x566KG2fTsECBAgQIAAAQIECBAgQIBAswVikmRHB3bja+w77bRTMYonnHBCevbZZ9ONN96Y4mvPxxxzTNvoHn744enyyy9vO2ZneAIx83nbbbcd3s3uKtKDHH/88emKK64oUocgGbxAzGRtol3M0l5ttdXSlltuOajORhC7XuLfNoUAAQIECBAgQIAAAQIECBCYvQRe+E737NWvQfXmxBNPLK679tpr03rrrVfdE0GUyK+71FJLpbe//e3V8QsvvDBttNFG1b6N4QvMO++81c3zzTdftW1jYIGY4bzjjjsOfKErZhJout2iiy46U596O7D00ku3He6533bSDgECBAgQIECAAAECBAgQINA4gVhXp6Nn7P7iF79IkaO0HtStj+J2222XNt988+pQBIAVAgQIjHeByMlbL7EgpEKAAAECBAgQIECAAAECBAjMXgIdG9i96667ilyvn/jEJ/od0U033bTf8006OX369HT33XcXP0NZrOyZZ55p62YsQvXUU0+1HRvMTuTWffrppwdz6bCuiRQaTzzxxLDuHc5NvfWl5wJX/dU70vuj7oG+Yj9aYzd16tRhjXl//Y9z8R5G/tdIixLv52DLrLAbbFtGct1w+z/QM1deeeXqklVXXTXFSpkKAQIECBAgQIAAAQIECBAgMHsJdOx/7Ufg48EHHxxwpfiFF164GvG+ZvZWF4zTjfPOOy/FIltzzTVXin7HzyKLLJLe8pa3pDvvvHOmVkew6Z///Gf62te+VuT13HPPPYtrIhXFJz/5ybT88sunyJP7pje9KV1yySUz3V8/cPPNNxdpLSI/aHwNfv75509bbLFFOvXUU+uXDXv7gQceSF/+8pfTq1/96jT33HMX/Yoxe8973pOuvPLKqt4zzzwzrbvuum0/MVu7LL2d33DDDVN3d3d5SfF52223pe9///uF58te9rLiWORl/upXv5rWWmutFM+O+4499ti2+8qdkd4f9cQvJb7zne8Uzzv44IPLqovP0Ry7sN15552Ld2DBBRcsxjz69rnPfS7FgoL/+te/UgR8I5geQfWhlDB773vfWwQcYzbpGmusUbyf8Z7G+9pbGWu7eGaM90UXXVS8s+Us18mTJ6dDDjmkeN/jaw4rrbRS+vznP1/0vWznX//61yJtS9wT78Db3va29Nvf/rY8PdPncPo/UyX9HIg2liVsFQIECBAgQIAAAQIECBAgQGA2FMiBIKUfgfe///2tPOzFzznnnNPPlePz1Le+9a2q/b/61a9ajz76aOuGG25obbbZZsXxnHuzlWdLVo3/y1/+0opjZZ/jMwdzW7vvvnvbsfJ8Dta27rjjjur++sa5557bivNxbQ4Ot84///xW1L/NNtu01bXiiivWbxv09gUXXFC19cADD2zF8372s5+11Z0Xyirqy7OMW9dcc01rgw02qM5/9KMfrZ6VZ74WLrvuumt1PtqdZ5EW19x3332t9ddfv+3cmmuu2cp5mtuOlS7xecYZZ1T1j/T+qOgnP/lJNW7lcw444IDqGaM5dpdeemk1dnvttVdhu++++/bZ17y4YNWOgTZi3Mr277bbbq0cqG7de++9rc9+9rPV8T/+8Y9VNbPCLs9Ab+29996teBfLtsVnDthW71j9eGznVC2tHNBua3fPa3r7N2Oo/a8g8kZ9DHJQv35qpu2yLx/72MdmOucAAQIECBAgQIAAAQIECBAg0HyB+Cq00o9A/hpzEeiJoF4Z5Ovn8nF16vrrr6+CVNtuu21b23K+4OpcBNTK8vDDD7ciGFr2ux6o+uIXv9i6+OKLi5/6+XqAtKwnz7qs6o9ga71EkLUe3B1OYPess84q6o/A8eWXX16vvrXffvtVz47256/tV+fzbNvqXG/tjiBjvc/lmD/33HOtP/3pT63Xv/71befj2ne9612t008/vXX11VcXwb7y/nq/Rnp/dCDPAi4C12WwPJ5TD+yO1tjllBnV+OeZz5VdbOyzzz5t/Y+A/Ve+8pVWBIIHUyIQWv/FQQTUyxLWZd8iaF6WWWGXZx63Dj300LbxK8cxxvx3v/tdK/4+xTXl8fhcZ511iv1wCIN4F+vvdr0f0Z/h9L90iM+hBHZf+9rXFm2LX3ooBAgQIECAAAECBAgQIECAwOwlEHEUgd1+xjRmDZZBnJgN2rSSvy5ftT+CTfWSc8FW5yJo3bMcccQR1fkItsXMxXqp173RRhvVTxXBqzLglRefaztX7kR9pW09AFqe7+8zZleWgeXDDjtspktjRnJZd3zGbNCy/PKXv6zO9RbYzWkFqvNxbxnYLe+PWb/1uiNQXC+333572/mor15Gen/UFbNcyzbUA7vlc0YydlHHj370o6r+nkH5SZMmVeeiDTndRfnYQX3mdApt9+fUB233xbtU9u2RRx5pOzcr7B577LHq+dGOsI5gbL1EsLtsY/zduOyyy+qnWz3foZglX5aR9D/qGEpgN+cPL9oZM/UVAgQIECBAgAABAgQIECBAYPYT6Ngcuzkw02/JAb2UZ6gW1+yyyy7pda97Xb/Xj8eTecZeyrMji6ZtueWWbU2cd955q/3IpdqzlPlF43gOthV5cevXxLGy5FmKxSJY5X4OJKU8u7HYjXysvZXVV1+9t8ODOva9730vRb7VKL0tfhe5br/73e+mPFsy5cBnkRN4UBUP4qKlllqq7arPfOYzbfsvetGLKvM4EYuC1ctI74+6llhiiXqVM22PZOyisr///e9VnT3bu+iii6YctK/OR67YoZRVVlklle9ingmbImdtveRAabWbg6zVdmz0bMtQ7aOOgewWW2yxIhd0XBslp2dIEyZM+O/O83++4Q1vqPZ32GGH9KpXvaraj43oQ7x7ZcmB3XIzjaT/VSWD3Cjz7OZfnAzyDpcRIECAAAECBAgQIECAAAECTRJoj1g0qZczn4kAAEAASURBVOVj3NYf//jH6aabbkobb7xxOvLII8f4aWNTfSxyds8996Q88zEtt9xy1UMiEJu/1l/t51QF1Xa50TPgVh4vP2MxtHqJRafmnHPO4tBJJ51UnXrFK15Rbdc36gG8+vHBbJcLr+WZxsWCXr3dk2dapvgZ7TKQSzzvJS95Scr5hItHx+Ji9TLS+6OugeoY6Hx/Yxf1x2JoZcn5bcvN6jN+YVAG7vPM7+r4YDdyjtmUZ1G3vZOxiF8syBbvZll6vpcD9Svu688+zg+mjvnmmy/116/ylyVRX18lfrkQ/35E6VnXcPvf17P6Ol4GdMvPvq5znAABAgQIECBAgAABAgQIEGimgBm7vYzbP/7xj5Tzzqb8df+Uc6em+uzWXi4f14fmmmuuIoCWc5kWgbMNN9wwvfKVr0w5l+yI2t1fgCx/Zb6qux5Qrg6OYCPn562CfxMnThxBTZ17a39jFypvfOMbK5y8AFy1XW7ELwzK8rKXvazcHNLnCiuskOaYY46UF3xLb3vb21LMdD7llFNmCoIOqdJZdHEEfgcq9X8z4p3tWWZF/8sAdDxLIUCAAAECBAgQIECAAAECBGY/AYHdHmMaMwnf+ta3Fl+nzyvaz/T17x6XN2I3ZtBG6oOddtopRWA356BNp5122pi0PedgTQ899FBVd8zkHajMPffcA11SnY+ZnWXpLYVEec7n8AXqqQbOPPPMdNVVV7VVlheJK/YjHcfLX/7ytnOD3YlfnmyxxRZFipPHH388XXjhhSl+IRCzgcd76ZmaYTjtnRX9j9QVMTN+/vnnH04T3UOAAAECBAgQIECAAAECBAiMY4GcMTgJ7NYGKL4y/aY3vSnFV8DzYmlFMLR2unGbEVSNHLfve9/7ipQMkV7i6KOPTvE18bEqEaSrlwiUj2apzzaNr+1HLmRldAVi9uxPfvKTqtKYwXvJJZekGNuf/vSn6eSTTy4Chr/+9a9nyj9b3dTPxoknnljkpb344ovThz/84WLW7mte85p+7pi9Ts2q/kdgd4011pi98PSGAAECBAgQIECAAAECBAgQKAQEdmsvwnPPPZe23377dO2116azzz47Rf7WppdYxOzwww8vuhELwX384x8f8y6VCzaVD6rnTC2PjeRz5ZVXbrs9vr7fX4lF1sp8sP1d51y7wMc+9rEUM9ajxAzszTffPMXCYvEe7brrrun2228fVtAwFlt7//vfX9Qbf8d+/vOfp0gX0illVvZ/2WWXLRYR7BRb/SRAgAABAgQIECBAgAABAp0kECkuzdjNIx45MHfeeecikBUzdTfddNM+34O4LmYvNqF873vfq5oZ6SVmRYmvqa+zzjrVo0Z74blYoK0edN9nn33SU089VT2vvvHYY4+l17/+9enSSy+tH662e84urk7YSLFoWuSZjtQI//rXv4qFwO6///5iYbWYtbvEEksMS+mYY46p7nvXu941qMXMqhtmg41Z2f9IcdJJM6Fng9dDFwgQIECAAAECBAgQIECAwJAEBHYz12677ZZOOOGEFAtFve51r+sVML7yH7Nff/GLX6SeC0bFuchF+oMf/CANJ+/rQPcP93zMqizLgw8+WG4Wn//+97+r/UhBEdO366Xnfv1cbPeXOze+Xl+Wv/3tb+m3v/1tuVt9RrCwLDGrtr/6yuvKz8gVXJa4N3LCPvroo+Wh4jOCkG9/+9uLhePq7Vl44YWr66644opqu9w477zzys3i8+GHH27bH8glLu6vLyO9P+qP96EsvS3MNdAz+mtf1Pvkk0+mrbbaqgjmxti95CUvKWbnxgzQkZY77rijqqLn35Vnnnkm1d/L2K+XgfoV1w7Ut4Hs6s/raztStZRl2rRp5eagPkfS/0E9oHZR/N2ItA+R91ohQIAAAQIECBAgQIAAAQIEZj+BCbNfl4bWo6997WtVuoKvf/3rKX56lmeffbb46nkEQD/1qU+lBRdcsO2SyFv76U9/ujj2ox/9qFicrJ4Ltu3iXnYGun+45+ebb74UbY4SuXYXWGCBNHHixGLG8f77718cL/+44IILiqBY5FeNhdYmT55cniry81Y7z2/0DKTec889Rd1x+jOf+Uz64Q9/WN0XKS6OO+649M53vrNYyOmf//xnMRu0XmcExV/xilekTTbZZMC8rdGX+Ap/mWIhgscxS3ibbbYp2h5B7BiHKBFAjlm+ZVlzzTXLzRSBr3333Td94QtfKMY3cscecsgh1fnYCPsY8yWXXLI4/sQTT7Sdf+SRR9IyyyzTdixmu5YlFnt79atfXe4WM16rnbwx1Pvj3nqgLu7vWUYydlFXBANvuummotoYy5ghHfla55lnnuInguPLL798WmWVVYp3qufz+9tfZJFFqtNHHXVUWnfddYtZwZECJX5xUl94L1KixPXxbm299dazxC4C5fU2RPC5HPuy4XXzWAStt1KfDR6/ZCjLSPofddR/0VAf57L+8jMWvNtggw2K3VhALf5OxL8HCgECBAgQIECAAAECBAgQIDB7CBST2/IsuI4t3/72t2Oa6pB+8izPmbzyV8rb6rj77rtnuqa/AwPdP9zze+21V1u76n3db7/9Wjlv6kznc9qCVl7wrJW/gt92LgdPqy7koFVrjz32aDt/wAEHtHIAvLomrs8BpbZr4vnlsfKz3qaNNtqolYNmVR39bVxzzTWtFVdccab66/XlQO1MVeQZmzP1rX5PTh3RWnXVVdvqjefkgF8rB8lbu+++e9u5Qw89tJVnbRbPic+TTjqp7fyb3/zmVk4JUZwf6f1RSZ7x2dbvaFv9fRuNscsB1rY+1H16bh900EGtnJ+66N9g/jjrrLP6rHu77bZr5dnzM50/7LDDRmw/GLu4Judsbnt+DvS3dSve/Z5/N6688sq2a6677rq2OqJf5Tsw3P7HA6Le+t+b/MuMVg7Ytj273On5b9uFF15YnvJJgAABAgQIECBAgAABAgQIzAYCObDbiq/gd2TJsz3bgi89A1a97ecZcL1a5a+rV3VFsHSoZaD7h3s+f2W89dGPfrRqW/Rps802a+XZuUUT8+JYVZAwgkS///3vWznHcNv1dYecr7aV89n2eX7ppZdu63oEIXsGwSIwlVMjtG655ZaingiiRnDw5ptvbrt3MDt55mpRV72NZR8jCNZXyTNqWznncFs/oh3R/yixHQHTCFZfffXVrfiLEoG5ns8p96NPefZkK88Y7vOayy67rM9zg7k/gof9BbLjvRutsYv35h3veEef7S37XX7usssufVH3evyII45oqzv6lfP2Fs55FnUrAvxRd7xPBx54YBHsL5/V83O07CIg3pdvvA95EcBWnoXe1u56W6LNUTbeeOM+rzn22GOLa4ba//iFSV9tizZsueWWRb31P3JKi6odcW+MqUKAAAECBAgQIECAAAECBAjMXgJd0Z0cHFBGKJADlSm+cj2YVAK9PWqg+0dyPhYRi5QAK6ywQsrBsrbHR47QSB0QKRrGqkRO0vhqfyys9uIXvzjFqn3xlfccrEwbbrhhsT+SZ0fe1BtuuCFFXyLVQqScGEy56667ir4vtthiabXVVqtSQNx4441FTtloZyeWSEWw7bbbFukXvvOd76Qc9CzSE8QidTGW8RMpKSIVxmmnnZZycDXFOxbjO9gSdcU7HWkdVl555ZnegcgPHcfraTQGW3cTrpsV/Y9xzL8wKVKcRBoNhQABAgQIECBAgAABAgQIEJi9BAR2Z6/x1BsCIxKI/LGvec1riqBt5CCOPLr9lZy6IL3nPe9JeXb2mP5yoL82OEeAAAECBAgQIECAAAECBAgQ6ESBzpyS2Ikjrc8EBiHwgQ98oAjq5tQCAwZ1o7qY1Zy/6i+oOwhblxAgQIAAAQIECBAgQIAAAQIERlNAYHc0NdVFoMECeXG3lPMuFz2I1B2PPvpov7255JJL0s4775x22mmnfq9zkgABAgQIECBAgAABAgQIECBAYPQFpGIYfVM1EmiswFprrVXkQ44ORO7cCNxG3uI11lgjLbHEEkWw99Zbb00nnnhiuvjii9Oee+6ZvvnNb86UI7exABpOgAABAgQIECBAgAABAgQIEGiIgMBuQwZKMwnMCoHrrrsuvfa1ry0WS+vveRHs3X///dP73ve+/i5zjgABAgQIECBAgAABAgQIECBAYIwEBHbHCFa1BJoq8PTTT6eTTjopxcJoMTv3pptuSquuumoxazdm9MZiaZtuumnq6upqahe1mwABAgQIECBAgAABAgQIECDQaIFWq5UEdhs9hBpPgAABAgQIECBAgAABAgQIECBAgEAnClg8rRNHXZ8JECBAgAABAgQIECBAgAABAgQIEGi0gMBuo4dP4wkQIECAAAECBAgQIECAAAECBAgQ6DSB7u5uqRg6bdD1lwABAgQIECBAgAABAgQIECBAgACB5guYsdv8MdQDAgQIECBAgAABAgQIECBAgAABAgQ6TEBgt8MGXHcJECBAgAABAgQIECBAgAABAgQIEGi2QKvVSgK7zR5DrSdAgAABAgQIECBAgAABAgQIECBAoAMFBHY7cNB1mQABAgQIECBAgAABAgQIECBAgACB5gp0dXWZsdvc4dNyAgQIECBAgAABAgQIECBAgAABAgQ6VcCM3U4def0mQIAAAQIECBAgQIAAAQIECBAgQKCxAgK7jR06DSdAgAABAgQIECBAgAABAgQIECBAoFMFBHY7deT1mwABAgQIECBAgAABAgQIECBAgACBxgoI7DZ26DScAAECBAgQIECAAAECBAgQIECAAIFOFJgxY0bqauXSiZ3XZwIECBAgQIAAAQIECBAgQIAAAQIECDRVwIzdpo6cdhMgQIAAAQIECBAgQIAAAQIECBAg0LECArsdO/Q6ToAAAQIECBAgQIAAAQIECBAgQIBAUwUEdps6ctpNgAABAgQIECBAgAABAgQIECBAgEDHCgjsduzQ6zgBAgQIECBAgAABAgQIECBAgAABAk0UiGXTBHabOHLaTIAAAQIECBAgQIAAAQIECBAgQIBAxwpEYLcr/9HqWAEdJ0CAAAECBAgQIECAAAECBAgQIECAQAMFzNht4KBpMgECBAgQIECAAAECBAgQIECAAAECnS0gsNvZ46/3BAgQIECAAAECBAgQIECAAAECBAg0UEBgt4GDpskECBAgQIAAAQIECBAgQIAAAQIECHSuQHd3t8XTOnf49ZwAAQIECBAgQIAAAQIECBAgQIAAgSYKdHV1Cew2ceC0mQABAgQIECBAgAABAgQIECBAgACBzhUQ2O3csddzAgQIECBAgAABAgQIECBAgAABAgQaLCDHboMHT9MJECBAgAABAgQIECBAgAABAgQIEOhMAYHdzhx3vSZAgAABAgQIECBAgAABAgQIECBAoMECArsNHjxNJ0CAAAECBAgQIECAAAECBAgQIECgMwUEdjtz3PWaAAECBAgQIECAAAECBAgQIECAAIEGCwjsNnjwNJ0AAQIECBAgQIAAAQIECBAgQIAAgc4UENjtzHHXawIECBAgQIAAAQIECBAgQIAAAQIEGirQarWSwG5DB0+zCRAgQIAAAQIECBAgQIAAAQIECBDoTIGuri6B3c4cer0mQIAAAQIECBAgQIAAAQIECBAgQKDJAmbsNnn0tJ0AAQIECBAgQIAAAQIECBAgQIAAgY4T6O7uTl05H0Or43quwwQIECBAgAABAgQIECBAgAABAgQIEGiwgBm7DR48TSdAgAABAgQIECBAgAABAgQIECBAoDMFBHY7c9z1mgABAgQIECBAgAABAgQIECBAgACBhgpEEgaB3YYOnmYTIECAAAECBAgQIECAAAECBAgQINC5AgK7nTv2ek6AAAECBAgQIECAAAECBAgQIECAQAMFurq6zNht4LhpMgECBAgQIECAAAECBAgQIECAAAECHS5gxm6HvwC6T4AAAQIECBAgQIAAAQIECBAgQIBA8wQEdps3ZlpMgAABAgQIECBAgAABAgQIECBAgECHCwjsdvgLoPsECBAgQIAAAQIECBAgQIAAAQIECDRPQGC3eWOmxQQIECBAgAABAgQIECBAgAABAgQIdLDAjBkzUlcrlw420HUCBAgQIECAAAECBAgQIECAAAECBAg0TsCM3cYNmQYTIECAAAECBAgQIECAAAECBAgQINDpAgK7nf4G6D8BAgQIECBAgAABAgQIECBAgAABAo0TENht3JBpMAECBAgQIECAAAECBAgQIECAAAECnS4gsNvpb4D+EyBAgAABAgQIECBAgAABAgQIECDQKIFYNk1gt1FDprEECBAgQIAAAQIECBAgQIAAAQIECHS6QAR2u/IfrU6H0H8CBAgQIECAAAECBAgQIECAAAECBAg0ScCM3SaNlrYSIECAAAECBAgQIECAAAECBAgQIEAgCwjseg0IECBAgAABAgQIECBAgAABAgQIECDQMAGB3YYNmOYSIECAAAECBAgQIECAAAECBAgQINDZAt3d3WbsdvYroPcECBAgQIAAAQIECBAgQIAAAQIECDRNoKurS2C3aYOmvQQIECBAgAABAgQIECBAgAABAgQIdLaAwG5nj7/eEyBAgAABAgQIECBAgAABAgQIECDQUAE5dhs6cJpNgAABAgQIECBAgAABAgQIECBAgEDnCgjsdu7Y6zkBAgQIECBAgAABAgQIECBAgAABAg0VENht6MBpNgECBAgQIECAAAECBAgQIECAAAECnSsgsNu5Y6/nBAgQIECAAAECBAgQIECAAAECBAg0VEBgt6EDp9kECBAgQIAAAQIECBAgQIAAAQIECHSugMBu5469nhMgQIAAAQIECBAgQIAAAQIECBAg0ECBVquVBHYbOHCaTIAAAQIECBAgQIAAAQIECBAgQIBA5wp0dXUJ7Hbu8Os5AQIECBAgQIAAAQIECBAgQIAAAQJNFTBjt6kjp90ECBAgQIAAAQIECBAgQIAAAQIECHSkQHd3d+rK+RhaHdl7nSZAgAABAgQIECBAgAABAgQIECBAgEBDBczYbejAaTYBAgQIECBAgAABAgQIECBAgAABAp0rILDbuWOv5wQIECBAgAABAgQIECBAgAABAgQINFAgkjAI7DZw4DSZAAECBAgQIECAAAECBAgQIECAAIHOFhDY7ezx13sCBAgQIECAAAECBAgQIECAAAECBBom0NXVZcZuw8ZMcwkQIECAAAECBAgQIECAAAECBAgQICCw6x0gQIAAAQIECBAgQIAAAQIECBAgQIBA0wSkYmjaiGkvAQIECBAgQIAAAQIECBAgQIAAAQIdLyCw2/GvAAACBAgQIECAAAECBAgQIECAAAECBJomILDbtBHTXgIECBAgQIAAAQIECBAgQIAAAQIEOlpgxowZqauVS0cr6DwBAgQIECBAgAABAgQIECBAgAABAgQaJmDGbsMGTHMJECBAgAABAgQIECBAgAABAgQIECAgsOsdIECAAAECBAgQIECAAAECBAgQIECAQMMEBHYbNmCaS4AAAQIECBAgQIAAAQIECBAgQIAAAYFd7wABAgQIECBAgAABAgQIECBAgAABAgQaJBDLpgnsNmjANJUAAQIECBAgQIAAAQIECBAgQIAAAQIR2O3Kf7RQECBAgAABAgQIECBAgAABAgQIECBAgEBzBMzYbc5YaSkBAgQIECBAgAABAgQIECBAgAABAgQKAYFdLwIBAgQIECBAgAABAgQIECBAgAABAgQaJiCw27AB01wCBAgQIECAAAECBAgQIECAAAECBDpboLu72+Jpnf0K6D0BAgQIECBAgAABAgQIECBAgAABAk0T6OrqEtht2qBpLwECBAgQIECAAAECBAgQIECAAAECnS0gsNvZ46/3BAgQIECAAAECBAgQIECAAAECBAg0VECO3YYOnGYTIECAAAECBAgQIECAAAECBAgQINC5AgK7nTv2ek6AAAECBAgQIECAAAECBAgQIECAQEMFBHYbOnCaTYAAAQIECBAgQIAAAQIECBAgQIBA5woI7Hbu2Os5AQIECBAgQIAAAQIECBAgQIAAAQINFRDYbejAaTYBAgQIECBAgAABAgQIECBAgAABAp0rILDbuWOv5wQIECBAgAABAgQIECBAgAABAgQINFCg1Wolgd0GDpwmEyBAgAABAgQIECBAgAABAgQIECDQuQJdXV0Cu507/HpOgAABAgQIECBAgAABAgQIECBAgEBTBczYberIaTcBAgQIECBAgAABAgQIECBAgAABAh0p0N3dnbpyPoZWR/ZepwkQIECAAAECBAgQIECAAAECBAgQINBQATN2Gzpwmk2AAAECBAgQIECAAAECBAgQIECAQOcKCOx27tjrOQECBAgQIECAAAECBAgQIECAAAECDRSIJAwCuw0cOE0mQIAAAQIECBAgQIAAAQIECBAgQKCzBQR2O3v89Z4AAQIECBAgQIAAAQIECBAgQIAAgYYJdHV1mbHbsDHTXAIECBAgQIAAAQIECBAgQIAAAQIECAjsegcIECBAgAABAgQIECBAgAABAgQIECDQNAGpGJo2YtpLgAABAgQIECBAgAABAgQIECBAgEDHCwjsdvwrAIAAAQIECBAgQIAAAQIECBAgQIAAgaYJCOw2bcS0lwABAgQIECBAgAABAgQIECBAgACBjhaYMWNG6mrl0tEKOk+AAAECBAgQIECAAAECBAgQIECAAIGGCZix27AB01wCBAgQIECAAAECBAgQIECAAAECBAgI7HoHCBAgQIAAAQIECBAgQIAAAQIECBAg0DABgd2GDZjmEiBAgAABAgQIECBAgAABAgQIECBAQGDXO0CAAAECBAgQIECAAAECBAgQIECAAIEGCcSyaQK7DRowTSVAgAABAgQIECBAgAABAgQIECBAgEAEdrvyHy0UBAgQIECAAAECBAgQIECAAAECBAgQINAcATN2mzNWWkqAAAECBAgQIECAAAECBAgQIECAAIFCQGDXi0CAAAECBAgQIECAAAECBAgQIECAAIGGCQjsNmzANJcAAQIECBAgQIAAAQIECBAgQIAAgc4W6O7utnhaZ78Cek+AAAECBAgQIECAAAECBAgQIECAQNMEurq6BHabNmjaS4AAAQIECBAgQIAAAQIECBAgQIBAZwsI7Hb2+Os9AQIECBAgQIAAAQIECBAgQIAAAQINFZBjt6EDp9kECBAgQIAAAQIECBAgQIAAAQIECHSugMBu5469nhMgQIAAAQIECBAgQIAAAQIECBAg0FABgd2GDpxmEyBAgAABAgQIECBAgAABAgQIECDQuQICu5079npOgAABAgQIECBAgAABAgQIECBAgEBDBQR2Gzpwmk2AAAECBAgQIECAAAECBAgQIECAQOcKCOx27tjrOQECBAgQIECAAAECBAgQIECAAAECDRRotVpJYLeBA6fJBAgQIECAAAECBAgQIECAAAECBAh0rkBXV5fAbucOv54TIECAAAECBAgQIECAAAECBAgQINBUATN2mzpy2k2AAAECBAgQIECAAAECBAgQIECAQEcKdHd3p66cj6HVkb3XaQIECBAgQIAAAQIECBAgQIAAAQIECDRUwIzdhg6cZhMgQIAAAQIECBAgQIAAAQIECBAg0LkCArudO/Z6ToAAAQIECBAgQIAAAQIECBAgQIBAAwUiCYPAbgMHTpMJECBAgAABAgQIECBAgAABAgQIEOhsAYHdzh5/vSdAgAABAgQIECBAgAABAgQIECBAoGECXV1dZuw2bMw0lwABAgQIECBAgAABAgQIECBAgAABAgK73gECBAgQIECAAAECBAgQIECAAAECBAg0TUAqhqaNmPYSIECAAAECBAgQIECAAAECBAgQINDxAgK7Hf8KACBAgAABAgQIECBAgAABAgQIECBAoGkCArtNGzHtJUCAAAECBAgQIECAAAECBAgQIECgowVmzJiRulq5dLSCzhMgQIAAAQIECBAgQIAAAQIECBAgQKBhAmbsNmzANJcAAQIECBAgQIAAAQIECBAgQIAAAQICu94BAgQIECBAgAABAgQIECBAgAABAgQINExAYLdhA6a5BAgQIECAAAECBAgQIECAAAECBAgQmHDNNddQIECAAAECBAgQIECAAAECBAgQIECAAIGGCEyYMCGZsduQwdJMAgQIECBAgAABAgQIECBAgAABAgQIhECr1UpdU6ZMaeEgQIAAAQIECBAgQIAAAQIECBAgQIAAgWYIzDHHHGbsNmOotJIAAQIECBAgQIAAAQIECBAgQIAAAQIvCEjF8IKFLQIECBAgQIAAAQIECBAgQIAAAQIECIx7ga6uLjN2x/0oaSABAgQIECBAgAABAgQIECBAgAABAgRqAtOnTxfYrXnYJECAAAECBAgQIECAAAECBAgQIECAwLgXkGN33A+RBhIgQIAAAQIECBAgQIAAAQIECBAgQKBdQGC33cMeAQIECBAgQIAAAQIECBAgQIAAAQIExr1Aq9WSimHcj5IGEiBAgAABAgQIECBAgAABAgQIECBAoIfAHD327RIgQIAAAQIECBAgQIAAAQIECBAgQIDAOBbo6uoyY3ccj4+mESBAgAABAgQIECBAgAABAgQIECBAYCaB7u7uNGGmow70K3D77ben2267LZ1//vn9XjfUk6usskraeuutU3yORbnxxhuLatdaa62xqF6dBAgQIECAAAECBAgQIECAAAEC/yMBcZ//Efz/+LFSMQxxAP7yl7+MelA3mlAGjIfYHJcTIECAAAECBAgQIECAAAECBAgQINCBAmbsDnHQIwAb5aCDDhrinf1f/tWvfrUIGMesXYUAAQIECBAgQIAAAQIECBAgQIAAAQJ9CbRaLTl2+8JxnAABAgQIECBAgAABAgQIECBAgAABAuNRIBZPG9UZu6OdpqDMN/uRj3xkPPppEwECBAgQIECAAAECBAgQIECAAAECvQiUccKI75VrS/VymUPDFJhjjjlGL7D705/+tMgTO8y29HpbmfYgXgQpCnolcpAAAQIECBAgQIAAAQIECBAgQIDAuBIog7rRqIjvlTE+8b3RG6YZM2aMXmC3HCC5Z0dvgDqlpj//+c8pXsbBlvhHYO65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LgFKuxAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACVYdAkyZNpLFbdbmmCAsBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh0OgRkCmGRl8EBIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAtWEwLfffiuN3WrKMMVVCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIFMMKgNCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAiBKkOgadOm0titsjxTdIWAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQaOQIrFy5UsRuIy8DSr4QEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAlWGgDR2qyzDFF0hIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISANk9TGRACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAhUGQIQu82rLM6Kbh0jsOdv59fxG/W6hojAC5d2bojJUpqEgBAQAkJACAgBISAEhIAQEAJCQAgIASFQbwg0nzhxYr29XC+uBgTWroZIKo4VjoDqmQrPIEVPCAgBISAEhIAQEAJCQAgIASEgBISAEKgqBFq0aKHN06oqxxRZISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEQAqBJil7DN8KCSEgBISAEBACQkAICAEhIAQqE4FRo0b5iPXq1asyI6hYCQEhIASEgBAQAkJACNQ5Ak2bNpXGbp2jrhcKASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAESkAAXd2mJfiXVyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQqAcEROzWA+h6pRAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQqBYBFatWiWN3WLBkz8hIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBIRAfSDQrFkzEbv1AbzeKQSEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAECgWAdnYLRY5+RMCQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAjUIwKysVuP4OvVQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgUIRaNKkiWteqCe5FwKNDYGVK1fWSDJ2TCRCQAgIASEgBISAEBACQkAI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z4+j4/4crx3nHDJkiBKfJ06cKMnJ9jmqIGB36pT5E9sPPPCAzJgxQ9auXWsKunp8qwMkuFavXl0OHjyoq+2OjRs3FojqtMwJgKePoe5ezrwJa0ggcwJ46yCmMKxkQEZWyMx7sIYESIAESIAESIAESCCnBODdCsssvhw8XwubpaamKnEX4jAEYYRsoJEACZAACRRNAtYv8gr7DlNSUiQhIUGFDIAoiURjRd2QSA1xdREmoWLFilK5cuVsE6LlhElaWpocOXJEJWzDOWLtwvMXgrg327x580yvZng49+jRo8CXiy/Q6bFb4NiLzoT4ZoCCbtG5n9wJCZAACZAACZAACRQUAQi5NWrUKKjpOA8JkAAJkAAJeIQAvFUz+6LVIxN44SAQr/NTwEZoCn4myN2Nv3TpEj12c4eOvUiABEiABEiABEiABEigYAgURY/dgiHHWUiABEiABLyBQFHy2PUGnlxD0ScAb2B3PIARUsO36OPgDkmABEiABEiABEiABEiABEiABEiABEiABEiABEjAuwlYQzxkt1KESKWwmx0l1pMACZAACZAACZAACZAACZAACZAACZAACZAACZBAPhLIiaiLZVDYzcebwaFJgARIgARIgARIgARIgARIgARIgARIgARIgARIIDsCORV19Xj02NUkeCQBEiABEiABEiABEiABEiABEiABEiABEiABEiCBAiSQW1HXx8eHoRgK8D5xKhIgARIgARIgARIgARIgARIgARIgARIgARIgARJQBHIr6mp89NjVJHgkARIgARIgARIgARIgARIgARIgARIgARIgARIggQIgkFdRlx67BXCTOAUJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJaAJ5FXUxDpOnaZo8kgAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEA+E/CEqKuXWKxDMexZvkdejHxB3un0P83jqhx/HT1TrWP+B/OvyvyclARIgARIgARIgARIgARIgARIgARIgARIgARIIH8JeFLUTU9PF7/8Xa53j55+KV0tMOVMylVd6MXUS2r+S6kXr+o6ODkJkAAJkAAJkAAJkEDhI3D27NnCt2iumARIgARIgARIgASKIYEePXoIXp6wEiVKSLH22PUERI5BAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAgVJgDF2C5I25yIBEiAB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dq0KlYHhe/To4eFZrv5wCF+BF8wxRMTVXx1XQAIkQAIkQAL5Q4DCbg64+pbICElc0vB+0IbHfbRZz3UZjyRAAiRAAiRAAiRAAiRAAiRwNQjMmzdPYmJizKnbtGkjiK9blK106dJFeXvcGwmQAAmQAAmYBBhj10TBExIgARIgARIgARIgARLwPgJ5ibHrfbvhigqawKpVq1TyvKCgIKlXr556FfQaOB8JkAAJkAAJkIDnCSBWP4Vdz3PliCRAAiRAAiRAAiRAAiTgMQIUdj2GkgORAAmQAAmQAAmQQJEhkJ6eLhmxBYrMtrgREiABEiABEiABEiABEiABEiABEiABEiABEiABEii6BHx9fSnsFt3by52RAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAkUVQL02C2qd5b7IgESIAESIAESIAESIAESIAESIAESIAESIAESKLIEKOwW2VvLjZEACZAACZAACZAACZAACZAACZAACZn4i/gAAEAASURBVJAACZAACRRFAoyxWxTvKvdEAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRQpAn4+Pgwxm6RvsPcHAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQJEjQGG3yN1SbogESIAESIAESIAESIAESIAESIAESIAESIAESKA4EGCM3eJwl7lHEiABEiABEiABEiABEiABEiABEiABEiABEiCBIkXAr0jthpshARIgARIgARIgARIgARIgARIggVwSmHbPsFz2dN1t0Nffu65gKQmQAAmQAAl4gAA9dj0AkUOQAAmQAAmQAAmQAAmQAAk4E7iUnCx/16+uXuf3xjk38IKSFQOvV+tLmDrJC1ZTdJaw9YWnFNfYD98pOpsqgju5adDt0qpDd1mxak0R3B23RAIkQAJFnwA9dov+PeYOSYAESIAESIAESIAESOAqEbhszns5/ZJ57k0nl5LPq+Wkp6V607IK/VrSU20801NTCuVeumxakad1/9P8mjz1L6jOycaXL7CLFy8W1JSchwRIgARIwIME6LHrQZgcigRIgARIgARIgARIgARIgARIgARIgARIgARIgAQKggCF3YKgzDlIgARIgARIgARIgARIgARIgAQ8RuCjjz7y2FgciARIgARIgAQKI4HLly8LQzEUxjvHNZMACZAACZAACZAACZBAISRwPn6vnFiz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lCtXNrOmqhxxfBHXGInXIP5aY+9m2bGAKxFy5KDxZQKEb8TORfI4R1G1gJfE6UiABEiABEggUwIbN25UdVFRUZm2sVa88847cuRIRqira665RgYMyPjC29qW5yRAAiRAAiRAAiRAAoWTACRdCruF895x1SRAAiRAAiRAAiRAAsWEQE6F3aVLl4r22k1KSlKU7rrrLmncuHExIcZtkgAJkAAJkAAJkEDxIMAYu8XjPnOXJEACJEACJEACJEACxYRAx462EFrw4njjDSM56OnTsnv3bgq7xeT+c5skQAIkQAIkQALFh4DngoAWH2bcKQmQAAmQAAmQAAmQAAl4PQGEGapRo4Za54kTJ7x+vVwgCZAACZAACZAACZBAzghQ2M0ZL7YmARIgARIgARIgARIggUJDwN/fX62VSdQKzS3jQkmABEiABEiABEjAbQIUdt1GxYYkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIk4B0EKOx6x33gKkiABEiABEiABEiABEgg3wikpKTk29gcmARIgARIgARIgARI4OoQoLB7dbhzVhIgARIgARIgARIgARLIdwJBQUFqjvj4eElPT8/3+TgBCZAACZAACZAACZBAwRGgsFtwrDkTCZAACZAACZAACZAACRQogZo1a6r5IOpu3ry5QOfmZCRAAiRAAiRAAiRAAvlH4PLly+Jj/Licf1NwZBIgARIgARIgARIgARIggbwQ2Lhxo+oeFRWV42HwUf/HH3+U9evXq74hISFSoUIFiYyMlB49euR4PHYgARIgARIgARIgARLwHgL02PWee8GVkAAJkAAJkAAJkAAJkIBHCfj4+Ei3bt2kWbNmatzjx4/L7t271cujE3EwEiABEiABEiABEiCBAifgV+AzckK3CHw54Xv59fdZqu1Pk76WUqVKqfMHRz4hBxMPSVSzpvLaS8+6NRYbkQAJkAAJkAAJkAAJFE8CR48elbFjx6rNw1u3f//+EhoaKgEBAcUTCHdNAiRAAiRAAiRAAkWEAEJtUdj10pt54sQJOXAwUa0uPT0jWgZEXZSHVq7kpSvnskiABEiABEiABEiABLyFgA7BgPXce++9UrlyZW9ZGtdBAiRAAiRAAiRAAiSQBwK+vr7CUAx5AMiuJEACJEACJEACJEACJODNBJKSktTyypcvT1HXm28U10YCJEACJEACJEACuSBAYTcX0NiFBEiABEiABEiABEiABAoDATyiB6tatWphWC7XSAIkQAIkQAIkQAIk4CYBJMmlsOsmLDYjARIgARIgARIgARIgARIgARIgARIgARIgARIgAW8hQGHXW+4E10ECJEACJEACJEACJEACHiaQnJysRvTx8fHwyByOBEiABEiABEiABEjgahLA5zsKu1fzDmQxd0CpjEzF1g/igYGlVa8yZcpk0ZtVJEACJEACJEACJEACxZ1Aamqq7N27V2EIDQ0t7ji4fxIgARIgARIgARIocgR8jHgMl4vcrrghEiABEiABEiABEiABEigiBDZu3Kh2EhUV5daOfvnlF9mzZ48cOXJEdIzdESNGSO3atd3qz0YkQAIkQAIkQAIkQAKFg4Bf4VgmV0kCJEACJEACJEACJEACJOAOgdjYWCXqom1wcLD07NmToq474NiGBEiABEiABEiABAoZAXrsFrIbxuWSAAmQAAmQAAmQAAkULwI59djVcXVLl7aF8CpetLhbEiABEiABEiABEig+BOixW3zuNXdKAiRAAiRAAiRAAiRQDAhQ0C0GN5lbJAESIAESIAESKPYELl26xORpxf5dQAAkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAKFikCJEiUo7BaqO8bFkgAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkIBBwJcUSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEChcBCruF635xtSRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAj12+B0iABEiABEiABEiABEiABEiABEiABEiABEiABEigMBG4fPkyhd3CdMO4VhIgARIgARIgARIgARIgARIgARIgARIgARIgARKgsMv3AAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAkUMgK+vr702C1k94zLJQESIAESIAESIAESIAESIAESIAESIAESIAESIAEKu3wPkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEBhI+Bb2BbM9ZIACZAACZAACZAACZAACZAACZAACZAACZAACZBAcSaQnp4ufsUZAPdOAiRAAiRAAiRAAiRAAoWFwMaNGwvLUrlOEiABEiABEiABEiCBfCbg5+fHUAz5zJjDkwAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJ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czfQQq7JOnfOiwRIgARIgARIgASSnQCF3WQ/wyHO75xHuwteNBIgARIgARIgARIggeQhgFAMeMHKlw9/nYfkIcGZkAAJkAAJkAAJkEByEcjMzJTU5JoSZ0MCJEACJEACJEACJEACJKAE1qxZo0mpUqWKnWaCBEiABEiABEiABEgg8QlQ2E38c8gZkAAJkAAJkAAJkAAJkIAngVWrVpl8LKRWtGhRzzrMJAESIAESIAESIAESSEwCFHYT87xx1CRAAiRAAiRAAiRAAiSQLYENGzaYOqVLl862LiuQAAmQAAmQAAmQAAkkDoHDhw8zFEPinC6OlARIgARIgARIgARIgATCI1CoUCHTAALv7t27w2vM2iRAAiRAAiRAAiRAAnFLIDU1lcJu3J4dDowESIAESIAESIAESIAEckigWbNmgi/9sKeeekpef/11mTp1ag57ZXMSIAESIAESIAESIIG8JpCSkkJhN69PAo9PAiRAAiRAAiRAAiRAArlFoECBAlKqVCnTPVZORszdHTt25Nbh2C8JkAAJkAAJkAAJkECMCBw6dEjSY3QsHoYESIAESIAESIAESIAESCCGBBB6YeDAgQJBt2zZstKhQwezrVixYgxHwUORAAmQAAmQAAmQAAnkBgE8lUVhNzfIsk8SIAESIAESIAESIAESyGMCf/zxhxF109PTZcCAAaLxdvN4WDw8CZAACZAACZAACZBAFAhg8bSUGTNmHI5CX+yCBEiABEiABEiABEiABEiABEiABEiABEiABEiABEggBgTw471vJYUYHIyHIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESiA6BFGvxBHrsRocleyEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBXCeQkpJCj91cp8wDkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkECUCTAUQ5SBsjsSIAESIAESIAESIAESIAESIAESIAESIAESIAESyE0C9NjNTbrsmwRIgARIgARIgARIgARIgARIgARIgARIgARIgARygcDhw4cZiiEXuLJLEiABEiABEiABEiABEiABEiABEiABEiABEiABEshVAgzFkKt42TkJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJRJdAZmYmPXaji5S9kQAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEDuEkhLS6Owm7uI2TsJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJRJcAY+xGlyd7IwESIEDKKmAAAEAASURBVAESIAESIAESIAESIAESIAESIAESIAESIIGYEGCM3Zhg5kFIgARIgARIgARIgARIgARIgARIgARIgARIgARIIDoEUlJSGIohOijZCwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAnEhgBDMcSGM49CAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAlEjkJmZSY/dqNFkRyRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQAwJpaWkUdmPAmYcgARIgARIgARIgARIgARIgARIgARIgARIgARIggagSSI9qbyF29ssvv8ivv/4qtWrVMq8uXbqE2JLVSIAESIAESIAESIAESIAESIAESIAESIAESIAESCB/E8DiaTEXdlXUBfqlS5eaF9IUd0GBRgIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQALBCRw8eDD2wi48dd2GvEQTdvft2yf//POPLFy4UBYsWCCrVq2SSpUqSbVq1aRVq1bSpEkT9zSTdn/UqFGCN1Pz5s2lYsWKSTtPTowESIAESIAESIAESIAESIAESIAESIAESCD/EHjnnXeMZomoA+EYnFnh3HrVVVeF0yysuqmpqZKyY8eOw2G1ymHl++67L0sPgJObE81ywBxmLFu2TB544AFZuXJlwJ5atmwpt9xyixF6A1ZKkoKOHTuamTz55JPSpk2bJJkVp0ECJEACJEACJEACJEACJEACJEACJEACJJBfCUDUhUALg24ZqriLNmgLy03NM08WT+vcubOZmPNPqGCcbfIqDbX98ssvt0XdevXqSa9eveS2226Tvn37yjHHHGOGNmXKFLn55ptl48aNeTVUHpcESIAESIAESIAESIAESIAESIAESIAESIAESCBMAk5RF03d+4G6c4q6qOPeD9QukvzDhw9LaiQNc9IGIRec4i7SiRKGYfXq1fLYY4+Z6RctWlReeOEFeeutt+TGG2+U7t27S//+/eWjjz6S66+/3tTZunWrPPTQQznBxbYkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIxJOClVWYn7gYScb36itZUYr54GgaOCeXmpKIFx92PulEj/7XXXvN0wYYbdO/evWX9+vUyZMgQmTdvnom/W7VqVXd33CcBEiABEiABEiABEiABEiABEiABEiABEiABEogzAhpCwakFYojY9wrLEEjU9aobrammpKTEfvG0aA0+1v1gkbTffvvNHPa8887zFHWdY0IdCLuw8ePHy0UXXeQslokTJ8qECROM8Lt27Vo59thjpWHDhnL66adL3bp1/epCHP7666+lQoUKcs0118iPP/4oCPWAF+y4446TPn36SNOmTf3aYWfy5MkybNgws9DbmjVrpHz58lKzZk1zHHhLQ4h225IlS2TEiBFmUbhFixZJ5cqVpUGDBnLyySdL27Zt3dWD7iMe8Q8//CBz586VFStWSOPGjc0iax06dLDDVgTtgIUkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkEGMCoYq7eSHqAkVmZmbsF0+L8TmI2uGGDh0qL730kunv008/DUmUPHTokJh4F9YqdVipDrZ3714ZNGiQfP/992bf6w9i8/bs2dMuGjt2rDz44INmIbYWLVoIxuJljz76qLRv394uQliId9991953J7p16yZ33nmnQOFX++677+TFF1/U3SxbtMH4ChcubJcFWjwNgvKzzz5r13MmEMri1VdfNYK2M59pEiABEiABEiABEiABEiABEiABEiABEiABEogXAsGEW4zR7dWLvNz01EX/MHrs+jiE9HflypWmHgRJXSAtu4Ze3rAffvihLeqqpy08cfEmef31181iawMHDjTeuW7vWIwBr1atWsmFF14opUuXNp6/n332mezevVvefvttW9jdsmWLLeq2bt1aLr30UuOtu2HDBvnkk09k0qRJMnz4cIFQ26RJEzMV5KmoW6ZMGbnhhhukTp06gjY4xowZM0ybYsWKyYABA4JOf9asWbaoi+MjPEVGRobxHMY8EX8YsYkhPpctWzZoXywkARIgARIgARIgARIgARIgARIgARIgARIggbwgEMxz12s8sRB19bh5EmP3l19+kV9//dWEMwCcRIi3izACsOrVqyu7sLcIuQBvX9gpp5wi8LBV8RccINhiAbaNGzcar14IogUKFPA7Tps2beTxxx+3PYARtgFewe+9954RfXfs2CElSpSQ+fPn2+0QvqF27dpmv1KlStKoUSO54IILjLg6c+ZMI+zCuxgetDCIuh988IGULFnS7GNsLVu2NMdFOIqv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eJuRkWGLrcGOh7mtWrXKhGpQoTdY/WBl27ZtMyIxwkugrwIFCgSrzjISIAESIAESIAESIAESIAESIAESIAESIAESyDMCzji52Ym6zkE6PXcDib3O+pGmU1NTJebCroq6zkF37tw5ocVd51yYJgESIAESIAESIAESIAESIAESIAESIAESIAESSHwCEHfhkAqBNhyDuAsN1GthtXD6CVYXoRhiLuwi7quXPfHEE17ZzCMBEiABEiABEiABEiABEiABEiABEiABEiABEiABEnAQiJsYu+Gq3o45MEkCJEACJEACJEACJEACJEACJEACJEACJEACJEAC+YpAZmZm7BdPQ9gFt1HYdRPhPgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAl4E0hLS4u9sIu4FE5xl/F1vU8Oc0mABEiABEiABEiABEiABEiABEiABEiABEiABEjAi8Dhw4djH2PXayDMIwESIAESIAESIAESIAESIAESIAESIAESIAESIAESCI1A3MTYDW24rEUCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEBhl+8BEiABEiABEiABEiABEiABEiABEiABEiABEiABEkgwAgjFkJpgY+ZwSYAESIAESIAESIAESIAESIAESIAESIAESIAESCBfE8jMzKSwm6/fAZw8CZAACZAACZAACZAACZAACZAACZAACZAACZBAwhFIS0ujsJtwZ40DJgESIAESIAESIAESIAESIAESIAESIAESIAESyPcEGIoh378FCIAESIAESIAESIAESIAESIAESIAESIAESIAESCCRCHDxtEQ6WxwrCZAACZAACZAACZAACZAACZAACZAACZAACZAACVgEDh48yFAMfCeQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQCIRSE1NpbCbSCeMYyUBEiABEiABEiABEiABEiABEiABEiABEiABEiABCrt8D5AACZAACZAACZAACZAACZAACZAACZAACZAACZBAghE4fPiwpCfYmEMe7qmPbA65LismH4HRD5VNvklxRiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRwhED633//naQwyiXpvDitUAgk7/s6lNmzDgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQDITKFSoEGPsJvMJ5txIgARIgARIgARIgARIgARIgARIgARIgARIgASSj0BmZqak7Nix43DyTY0zIgESIAESIAESIAESIAESIAESIAESIAESIAESIIHkJJCSkkKP3eQ8tZwVCZAACZAACZAACZAACZAACZAACZAACZAACZBAMhNITebJcW4kQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkGwEDh8+TI/dZDupnA8JkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEByE2AohuQ+v5wdCZAACZAACZAACZAACZAACZAACZAACZAACZBAEhJITU2lx24SnldOiQRIgARIgARIgARIgARIgARIgARIgARIgARIIIkJHDp0iMJuEp9fTo0ESIAESIAESIAESIAESIAESIAESIAESIAESCAJCdBjNwlPKqdEAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQ3ASweFp6ck+RsyMBEiABEiCB/E2gePHi+RsAZ08CJJD0BHbu3Jn0c+QESYAESIAESIAESMBNAMJuqjuT+yRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAvFNgMJufJ+fqI3u77//FrxoJEACJBAvBHhdCu1MkFNonFiLBEiABEiABEiABEiABEggeQnwvijruU1JSaHHblYszCEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB+CbAGLvxfX44OhIgARIgARIgARIgARIgARIgARIgARIgARIggTggsHTpUnnnnXc8R9K5c2fp0qWLZ1luZNJjNzeosk8SIAESIAESIAESIAESIAESIAESIAESIAESIIGkI/DLL78EnBNE31gaFk+L2GP3vvvui+VY7WM98cQTdjreEji5ehJ1W6tWLTNMVex1P97GzvGQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlERkC1wMhaR9YqYmE3ssMlXytV6n/99VfPyelJVTdtCLsQeSnweuJiJgmQAAnEnACu00uWLMly3GOPPdbk8XqdBQ0zSIAESIAESIAESIAESIAESCBfElCdLx4mn5mZGbnHrk4gkAetevQGKtf2oW61v1Drx6IeRN1Agm6g4+MNAJE31nE3Ao2H+SRAAiSQHwlk96McmDiv7/xRLj++SzhnEiCB/EZgxowZsmnTpizTTk9Pl4oVK0qlSpWkdOnSgnh2uWGzZs0SrPi9Y8cOqVOnjrRv3z43DuPZJ469YcMGqVatmtSvX9+zTqiZ27Ztk8mTJ5vqmEPBggVDbZon9caMGSMHDx6U4447TipUqJAnY+BBSYAESIAE4ouA3i/C2cfp6KP5wUaLOvrUvtZDHvTAq666SrOisk1LS8u5sBuVkSRgJzgpzpv+cKeAtrlxUsMdR07r40vb9u3bpXbt2lKzZs2cdsf2JEACJJCrBCK9duuPchR4c/X0sHMSIAESyFMC3333naxZsybbMbRr10569uwpRYsWzbZuqBW+/vprGTVqlF195cqVMRV2f/zxR1m+fLmcdNJJfsJuJN/1IRB/9dVXZi6tW7eOe2H3s88+M2MtWbIkhV37HcgECZAACeRfAs57Rmh3uAfEK1QNUPU+FYSd7dC3W/TNCekcxdjNyYETvS08bnGT7zZ44brVfK2Hk6dpbYf9aJ9U7TtW2yFDhsiWLVvk9NNPp7AbK+g8DgmQQEQEnB/QEXVgNcJ1G58B+JCO9q+tkY4pGu3gXTVlypSQu2rWrJlkZGTIvHnzZO3atVK1alVbCAAjhLYoVqyYEQhC7pQVSYAESCCOCMBDV23//v2ydetW3ZVx48bJxIkT5YorrpAWLVrY+ZEm9u3bZ+4J0L5MmTJywgknSPHixSPtLqrt+F0/qjjZGQmQAAmQQJwTwL2MU4jFcJGHVzgWqA36duuG4fTrVZcxdr2oBMnzEmhRPVBoBVXoIQDgxGqsXT2EvmGiqdhr39ySAAmQAAn4CAT6QU754BoOw7VYP7QDXe9RT6/nySLurlq1SsaPH4+phWR4HBnCLrzL/v33X/PUhj66O2fOHJk2bZrx0ILnlxoeb8ajvjDlrWXckgAJkEA8EcDj+I8++qjfkOARA0/U4cOHG1H3wIED5ns9bs4gxubE8GMYYuTBrr/+eqlRo0ZOumNbEiABEiABEiCBCAngHjC3DZ/7qhXm9FgIDxVzYRc3w9GaQE4BhNseY1ch1t1W84MJtJg3Yg67BYZQ2rqPx30SIAESyCmBSDxYcR1LNDHTfc11cvP6UU4/o/QHuUACr4q7uO5rG2ffiZpGLMQCBQoEHX6RIkWClnsVrlixwni5oYzCrhch5pEACcQzAdw4wYsXXroNGjSQwYMHGzEW2//85z85GjpEYzWnp7DmcZscBPLL967kOFucBQmQQH4kgPs7vHLboqkB5kkoBtxge91I5za4aPSfnXIf6smBWBCPi8GFw+j111+XPXv2GE8ttPvzzz9NXK7U1FS59dZb/bpCbC484ov/IFgMoly5ckYE6dChg/HyclZGbK9vvvnGZA0YMEBGjBhhHvVdvXq1YOEKiCdY2KBjx465tnCFczxMk0AyE4AgqdetUOcZ7MerUPuIVT0VXgMdL5TPIlxzcM0OdDOmx0CdZBF3u3XrJscff3wgbH75p512mvkcqFKlil8+d0iABEggmQmcfPLJ5okFfD9dsGCB8eR1L7qF7774fozPCYRygGdv48aNpW3btiZUDfgsW7ZMEOpg48aNNq6BAwea77z4nqxhHlD+888/C56IwFMS8O4tVKiQWWCta9eudigcdILF14YNG2b6uPnmm+1+NbF371554403TB+XXXaZlC9fXov8tuF81/drGMJOKGzgHf3xxx+b3s4880xp2LBhlp4RCkjj41544YUmLJBWCuUYWjfQdvr06ebzH0+14L4HzMELMZbxwoI14Viyf+8KhwXrkgAJkEA8EshO83OOGfd+eOHzXQ3t8bkfioVaL7u+8J0g5h67GBSEBEwikbycMF43eJxEd56KJNmJHxAUtK4yya5Ndic0luV4nFYfGcNxIdjii6TTEC/s/fffF3wpchq+qOE1adIkOeecc+Tss8+2ixHnUft5/PHHTT0txCNviOeIF1YtvuGGG8wXLC3nlgRIIHwC7mtRsB5QN5HEy2AfzJiH85qLazkeidHrspbrfFFXy7wY4VgQd/ObNWrUKL9NmfMlARIgAUMA32EhkMIgMKqwi++r8OKFsOg0fL/Fa8yYMXL//fcbcRft9Huv1l28eLFJwisYBvH3mWee8fvejXx8z547d655wRkCjg8wrH3h7tMUHPmza9cumT9/vtnbvXu3s8gvHcp3fb8GIeyEwwbhLRYuXGjmjadIvIRdCOeYKxxL1NM5nGMEG/KXX35pxz3WemAOkRdiMkR2cIcndziWzN+7wuHAuiRAAiQQjwRw7+fW+LzGiWu5815S6wRzCNI6utX7TN2PdIsfGfNE2MWAASuRvXdxEgKdNL359zrRerJQBgbONw2EgWBttG08bK+88krZuXOnfPHFF+YLV926daVly5bmi5WOD2Uq6uLLVvfu3c2v3PDKxcq/+HL0ww8/GA9eZxxGbQ/xF4/7nnvuuUZMwj68FbBKMLwj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eHPjQzc2s0qOo0DIDeSBlhwz5CxIgARIgARIgARIgARIgASSjUCs7yMPHTqUc2FXY98GOhnZlQdqlwj5UOERWDmcR3oh6MLcCn4izDcWYyxXrpzUtBZHg7kf4zWZ/EMCJEACuUgg1h/EuTgVdk0CJEACJEACJEACJEACJEACJBBlArhnVIegKHcddnf02A0bWdYGOKEasxGlEHlhepJVJMCWYq5BE/QP4oc5F9sJWpmFJEACJEACJEACJEACJEACJEACJEACJEACJBAjAsGEXdUAYzQUwUKhKdbqqodjdUAeJ+8IxGr1wLybIY9MAiSQaAR4XQrtjOWUU/HixUM7EGuRAAmQQIIS2LlzZ4KOnMMmARIgARIgARIIlUBO74tCPU6i1UtNtAFzvCRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQ3wnQYze/vwM4fxIgARIggaQmQI/dpD69nBwJkIBFgB67fBuQAAmQAAmQAAnkRwIpKSlCj938eOY5ZxIgARIgARIgARIgARIgARIgARIgARIgARIggYQmQGE3oU8fB08CJEACJEACJEACJEACJEACJEACJEACJEACJJDfCNBjN7+dcc6XBEiABEiABEiABEiABEiABEiABEiABEiABEgg4QkcPnxY0hN+FpwACZAACZAACZBAQAKMPRkQDQtIgARIgARIgARIgARIgARIIKEJMBRDQp8+Dp4ESIAESIAESIAESIAESIAESIAESIAESIAESCC/EcjMzOTiafntpHO+JEACJEACJEACJEACJEACJEACJEACJEACJEACiU0gLS2Nwm5in0KOngRIgARIgARIgARIgARIgARIgARIgARIgARIIL8RQIxdhmLIb2ed8yUBEiABEiABEiABEiABEiABEiABEiABEiABEkh4AhR2E/4UcgIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAL5iUBKSoqkL168OD/NmXMlARIgARIgARIgARIgARIgARIgARIgARIgARIggYQmkJ6ezlAMCX0GOXgSIAESIAESIAESIAESIAESIAESIAESIAESIIF8RwAxdlOsP4fz3cw5YRIgARIgARIgARIgARIgARIgARIgARIgARIgARJIYAKMsZvAJ49DJwESIAESIAESIAESIAESIAESIAESIAESIAESyJ8EKOzmz/POWZMACZAACZAACZAACZAACZAACZAACZAACZAACSQwAQq7CXzyOHQSIAESIAESIAESIAESIAESIAESIAESIAESIIH8RyAzM5OLp+W/084ZkwAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJJDKBlJQUCruJfAI5dhIgARIgARIgARIgARIgARIgARIgARIgARIggfxHgMJu/jvnnDEJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEASEGCM3SQ4iZwCCZAACZAACZAACZAACZAACZAACZAACZAACZBA/iJAYTd/nW/OlgRIgARIgARIgARIgARIgARIgARIgARIgARIIAkIUNhNgpPIKZAACZAACZAACZAACZAACZAACZAACZAACZAACeQvAun5a7qcrZvA/gMH3FmSnpYuqakpWfKZQQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkEB8Eks5j95Y77pU33hkcEl2ImnPmzpevhnwnPwwbIUuXLZfMzMMhtU2GSnv37pOTO3TN8ho7fkJcTO+aG2+TFm06m3MTFwNyDeKVQW+b8T3wyFOuEu7mhMDwkaMM1/7X3ZyTbvK07aHdu2X48XXNa/7zT+fpWEI5+JzHHjBjXTjo5YDVE21OASfCAhIgARIgARIgARIgARIgARIgARJIEgJJ57G7b98+ObA/qxeq+3ytXrNWrr7hVlm/YaNfUds2J8n/nnhIChUq5JefFzu//T5eRoz6RRo2qCeXX3px1IeQmpYqrVo0s/udPHW6SR+OE217/779ZjyHDh2yxxhPiQMHfe8zvOdo0SNw6KDvfCcy18OHM48CyYzP9+/RAYpk7vf9X8s84Ns6yzSdaHPScXNLAiRAAiRAAiRAAiRAAiRAAiRAAslI4LAl4CWNsAvxb9LkqbJm7TpJT0+XcRP+lOrVqppXSop/WIHNm7fI5VcPkC1b/5WiRYvKOd1Ol12798iPw0fK+D8myu3/fVBeffGZPD/ny5avkNG//i77j4gu0R5QwQIF5I1Xnre77d6rj0DwppEACZAACZAACZAACZAACZAACZAACZAACZAACcQvAeidURV2V69eLVWqVInpjCHofvblEPn0i69t71uIk39OmmzGAeH25x++liJFCtvjGjZilBF1kfHeGwOlbp1jTVnTRg3lqedeMm3nzv9bGjesb7dhggRIgARIgARIgARIgARIgARIgARIgARIgARIgATihUDUhN1JkybJ5MmTpVWrVtK6deuYze+dwR/LW+9+YI53zllnyF+W127NmtWlxQnHW167E2X23HlW3Nyjj0XDTXnoD8NM/d69etiiLjKWLFtm8vFn2E8joybs4pjTps+UxUuXyYaNm6R48WJSsXx5adH8BKlQvpx9TCQWLV4iW//dZvKWr1xltvAw1jAJJsP608QSoVWsXrhoify7bZuUzciQY2vV0Cp+2yVLl8vmLVukdKlSfnP2qxTmzgprfP8sXGzmVaY0+q0txzdtbC28Fv3Qzf9aTKbNmCX/LFpseWFXsY7TRKocU9lzxAcOHJRZs+fI0uUrZeOmTVLC4l2rZk2pX6+2lCtb1rONMxM88V5YZrUvbIXkqFG9qpzculVY4Tnw4wK8x2EN69cz59x5jAV/LzTvzW3bd0jTxg3NfDZt3myd+3+lQrlyUrFiBWd1k9bzXK1qFalklW/ZslUmT5suS5Ysk0qVKkqHtm0kI6OMXzu892dbcaTxvkL9KlUqS4N69TzfJ3ifzpo9V7BtYI25cOFCfn2B/e5du40XvPM4f/+zULbv2Ck1a1SXUiVLyDzrR5EZs+ZYnvNp0rRJY/Oe8OvIsbN23XqZMXO24L1e59ha0vyE4xyl+Se5d91a2bVimRQoVUZK1m8gh/bskS3TJsu/s2ZIgZKlpGzrk6VEnXpZgOzfsln+nTtbdiz82ypLkZL16kuZZi0lvVixLHU1Y/uCefLv7Jmyz2pb5rgTrPottIhbEiABEiABEiABEiABEiABEiABEiCBBCEAzScqwi48dSHqwrBds2aNnHfeebmOAQudffzZV+Y411/TX666/FK57qbbpVGD+nKllcYLC6KpAIqKENuWr/AJpie2OipoQAD+4uuh9pjHjJ0gd92W88WbsEDZNQNuFXgAe9mgl5+V1o5xvP7W+zJmnP/iZWiLeTnt08FvWkJlXZM1+tcxAoEbQufQLz+2hFX/0BMQ6m69814TZqF/vz45Fnax6Nzrb70nH37yhXNIJg0B9NEH75GMMqWzlEWasdASJZ8f+LrsthakctpjD90j3bqe5sySmZYw2f/am/zynDtebbQcwueTz74oiG3sNnh+v//mQKlT2+fd7S537s+dt0Cuu/kOM95OHdrKk48+YBfjP90rr7+dhd3xxzUxzHBsxFO+6Yar7TaaeOX1t2TCn3+ZsoOWeP362+9rkdk+Ls/LxN9/lgIFfP+tMZ/7H31SJv011a8ednCM66+5woQt0cIDBw+KLlj2xUfvZJnrI0/8TyBIP3TfXdLd+hFF7dkXX5Xpljh743VXWezGZXmvX3NlP7nWernt59G/yT0PPuaXDc7Ovv0Kk3hnzchhsuCFZ6R8m3ZSq99V8te1WXmd/MEXUuaE5jaF1T8OlZn33Wnva6Jo1WrS7LlXpFTDxppltoetWL9/v/ycLBn8jl9+qcbHSSHrxwQaCZAACZAACZAACZAACZAACZAACZBA4hCAY2VUhF2EX4Cnroq7EHq//fbbXBd3d+3eZYt9gTz9atX092DdsnWrfYbqHhHpDlqC1qNPPmvy4UU7ddoME9YBgqg7Pq/dOMTEZ19+Ywtdvc47x3hvQhidt+Af+WHYiCzxc7udeZrl5djI9D7xrynGUxeCbc9zz/Y7YnnL41ft7G5djbALL9GZlqdqs+ObapHZzpozz46de/aZp/uVRbJzryXGqfjZ45xu0sTyON20abN8+OmXJozFHfc8KO8MejmLwBzJsdDm86++NU0hSsPj9qeRo4236wOPPCXHVKokJzjmu3PnLlMX4TVOObm1VKtyjBy0FuOaMHGSjB3/p6BNelq6nH5qJ1NP/0CAv7T/dXY4D/BuUL+u7Ni5U6ZMnWHmBe/a7Azep1def4upBtH54fvvkrS0NLvZp198Y4u6HdudYjyBFy1ZKl8N+c6uk11i1C9jjMBasUJ5OenEllKiRAmZO2++EVd1gSsV8/UHhUsvvtAS/ivJVMtzHHGbB3/8mfGoxQ8i0bJX3/AJhhCNsbDct98PN/8/4VF/1hmnSVXrXKjNsbyIVdRFyJNuZ5wuW63/m/iB4vOvhmi1HG23b1glo178T8h9NOtxjRzb2v+HgpAbuyqmpBz1Wk8t6O/57Krqt7tj8UKZdtsNJq/y6d2kaNWqlifvclk3eqS1wNk+u+7yzz+WuU89YvbLnXyKVOx4qmDhs5VDvpKdSxbJpCv7SIcfRkuhskcF26UfvW+Luui7bKvWsm3eHFn5re/HMbvzAIlI5xSgO2aTAAmQAAmQAAmQAAmQAAmQAAmQAAnkkEBUhF2MQcMvxFLcLVG8uFn8DJ6cw376Oegj38pp69ZtmrQe0S9u0hDbEKoAQts5Z3U1wi4KIOqVtESzSA3emSp2wZvxir6X+HV1y4BrJNUhAKGwS8f2dh2IcwjBUPvYmnL5ZRfb+e4EHs1v1aKZqYsF4NzC7vARP5smyK9RvZq7eVj7WKBORd2Xn3tS2rY5yW4PsbTnRf1kpvUY/qhff5Oup3a2y3KaeHvQS/Zj+j3OOVOuvsHnBf3eh5/IwOeftrtHKIr33nwly3uhV8/uxhsVY/vym6FZhN0PP/ncFnUHv/2qFR7BJ66jYwiV8KIuVzbDPo5X4q8p0+R6y1MXdl73s+Teu/7jF5YC4vEHlqAKg3CMcv3hAAv9Pf/ya6Ysuz/wmj21cwfjOVu0SBG7OrxmsXAgDDGmVdR1nqcLz+8hAwe9ZY3jcyOiXnzh+VLaCqMRLfv8w3dsj/CrrrhMzjrvYiPuQlS/pPf59mHe//BTk4Z4/tZrL9lhH+DxrcK4XTnCxL6d22TlrAkht67ZCu/X6Ai7aZbncbeZC0M+tlbcu36dFKtRS9p++a4l6h79v7pr2VJJP3K92r91i/w98DnTpHb/a6Q+3nNHFoisfsHFMu78s2T3qpWy8PWB0uT+R029Q3v3yKI3XzXpGhdfJo2tBSLVcJy/X3lBdwNuI51TwA5ZQAIkQAIkQAIkQAIkQAIkQAIkQAIkEDEB6IZH3coi7uZoQ4i78NxVg+fuq6++KtjmlvW95ELT9dAfhssZ3S8w4ub69RutmJ/e3pVOj91ixYoaT9aXX3vT9HHX7TfbYi8yENc1JwbAeLQcVrBgwSxdlSldWkqVKpklP5IM9egFB2fIAoiJX3/7g+myZw9/r99IjvPlkXAVp3Xp6Cfqoi+Ixgg9AJvwxySzjcYfiKxOj+xCVtzbPhdfYLpGaALnfCtbsWYR59fLup1+qslevmJlluKPjoT0gIjrFHW1IkT/YKL4+D8m2qIuBMx777rNT9RFP7PmzLUX7YNQr6IuyiAEh2P33HGrOEVdtIVwr/GNVXyHcOoU31EP3rtqk6ZkDdOgZeFuITbrQoRoix9F2h0R/tdv2Gh3h/ekhhvpc1EvW9RFBXhfu3+YsBuGmShZsZp0HvB0yK9aLbuEeYTcqd743of9RF0cpVjNWla4hPLmgGtG/CgHd+2Sghllpd4AyyP5iKiLwrTCRaTWZf1NvXW/+H7Qwc6/M6ebNkhrOdKwGhdd6kvwLwmQAAmQAAmQAAmQAAmQAAmQAAmQQEIRiJrHrs7a7bmLfA3LgJAN0TY8no/QBu998Iktmg0fOUrwghfrbbfcIPWsRb3U1KMR+wjB8MzzL5uie+78j+DRdqfo53yEXtuHs0X77pYHMEIJvDBwkCUirxHE9W3csIGUL1c2nK6yrduhXRvbe/lXK06rhlwYO/4Pu22n9u3sdKQJxLuFIRzAsuUrsnSzeo1vwbD5f/+TpSzSjBbNj8/SFIvHqUE0dIbcgHCI84+wCIipvG37dlN1l7XwF2zL1n/NVv9gX8Xhjh1O0eyQt7+MGSt4wfAe+s9N13uGoVi3foOpg/jD7oXfEAcacXbhUZydQUDNzstNMdL4AAAg9klEQVR29dq1ppuWVmgRt+H48GyGl/q6db4xuetEso/Fz9xWrpzPy1nPAcqxoJ0a/i+4DeFQ4H2cUytUrKQc161vTruJaXsselbupDZBj7lzyWJTjoXTxl98Xpa6B7b53t8oxwsC8J51vv+XSBetUtWvTXrxElLaWkQNC7XRSIAESIAESIAESIAESIAESIAESIAEEoMAHAajLuxi6rEUdyGeDrj2SvOYNx6Ff/nVN+1H6hHG4OK+V8t7bww0ohnGBi9ZNcQ1hccnBLWe5/o8JjVGq69uzh9Rx6PvMyyxDo/PY3E2XaCt9Ykt5Nr+/exx6Zgi3cKLFXPAYnJDvx9mC7vfW3F8Yb179fBbRC6S40AIRxxftYWLfCKv7ju3+/btd+7mKJ1RpkyW9qVKHvV03rBxky3sYrG8aywvRrd4C89pFW/dnUFwV6tYoYImI9pCZP7syyECT1S3rT8i7JYNENKhTKnQ3m9VjznG3XWW/VWrfHMqm+EdPgLzhLC7dt36LG0jzfASm/WHlMxDh+xuN1iM1Ep7zLlsRtbzrfWTfVuses1sp4iwDGo7/lmgSc/twT17BM8K7Fnnez8ULO3NtnC5nL3vPQ/OTBIgARIgARIgARIgARIgARIgARIggVwlkCvCLkZc1Vr0R+Pt5uoMjnQOwRYxXb/9bpic2fVU6dj+FLMgGsSrp557SRD7EwZvRbUXX3nDJO+/+3b7EXanZ6GGUdD6kWzx+P7H771hCciTZLwVngAetBD/Jv011byc8U8j6d/ZpvtZZxhhF96OK1etNuEfEGsVhgXWcmqpqWl2Fw/fd5cVj/gMez83ExCU3Yb4xWqFLVFb7aHHnjaiLjxi/3vHLdZj/cfZgrYzBq7WxxaiuNr+/ZEJ0g/893aL+RqzKBm8sxE6omGDetqt2RY5Eg939+49fvm6gwXHQrESJXyxoYPVLVQIcp7IAcub3cvg5Q7Tel513HmHHOKsuwz7Kda/UMzJ26vP/fu9xxxK3846OzetlTFv3O/MCppuann31mjeIWid3C4s4PjhKdCx0o68X6t27ynHPfZMoGp++WmFC5v9wwHOIRZeo5EACZAACZAACZAACZAACZAACZAACSQWgVwRdidNmpRF1D3vvPMkN0IxeOGGKzLipPa9pLc8/MT/BJ6leDy/cOFCUr68fwiE66663DyWrv3MnD3XJGtU939c2S63vG/1sXvkNW92vFl0Tcu9thgP4pzidddtN1uPmc+S/97/iBEgf/r5lywxUL36CCWvtvUoPOY9e+48KxTBaClyRMxB3NNGDeqH0oWps8daaMnLUlNTTAxV8Ny8ZatXlWzzXnvzXdm3b59d74ZrrvSLsWoXOBKbNm927PmSmzZvsfMqWOEPYBs3bbYXDHvikfuyxMpFWAY1xD/WGLdVLRFYDR7JVatk7xGr9bFF/N0eVoxciKUTJ08x3tl3W+f3sw/eFsRxVqtcuaJJ4hgQq9WbVctXrfZ5Vep+wG0I+inmgB81NjjCHjj7W3fEU7dypUp2dlrq0ZDb+zzEVQ2zAXY5MT1f6APvowyXhy7OYzRsz/YtsujPn0LuqnKjlnku7Ka4FlP0Gnzx2nVkw7gxsndj6N7WRSr53uP7NlmhN3D+HHF5cYw91qJtNBIgARIgARIgARIgARIgARIgARIggcQiEHVh1y3qQsw98cQTc0XUhcC0Z+/eLItI6SnwCgdQrmxZO5YpPHL7WYtY/b+9Ow+Tq6oSAH6rOwsSQgyLbAGyEJBFQZKI60wQQQGRRQQRZBEYUOBD3HEcHMVR8QMFEQRRgiBBUMeRRVEhYRMUEhRkESGQEIIKJCSBhJCY7nnnNa9S3ek1XQ1Vxe9+X3W95b737vu9Sv44dercoq1Y8a9s0q8/5Kt7vjTRVrGveI+g5uU/+VmxmgcHI7DX2xbB0QlZMPhDHzwgnf/9i9Odd3U9edU66wzLTzu/IojZ03U+kE2QFoHdn2VlJooM0WJitZ6O3XSTjfNSC/f+5YG013t277R7BIjD4Lrrf5sOP/TgcqZzp5072Rj1hitLIhx9xGE9BnZvnH5LVrf24+3q1haZyHGJeKbRKs+71tC2DMV8x0t/rv3VbypXy8vxOYgM3wi4RnmOXbI6yH1pRS3mIYMHp699+YvpgA8dkZ8r6jd/5bRTy6caN2Z0efm2LIO78nMz67HZWX3nJ8r7+7uwxeZtX0xMy+w+e8pJqRhjnHfWo4+VS2pstmlFYDcra1KUrPh7VpN1+21XfRkQtacrffszvspSC/EcKydca2lpTdNvvrU/py8fO3zDTdPbj1jlX97RxcIWO/1bF3tqa/Pw8W3P5Zk7fp9e+PuT6TWb9PxFxNqjtshvIiZdW/iXe/KausVdvfDkvNRTSYeir3cCBAgQIECAAAECBAgQIECgdgRWpehVYUydBXUHMlN38eLn0nv2+WD63kVTUtRZLVprFhyK4ObUq9oCsJEpG9m6Rdt/n73yxQhU3Tjt5mJz+s75F5Zrs0Y5h/62pVl9y2+f+730yEsTjhXni5/7X/+7G/PVN+6wfbF5tfdNNm7L8Lz/wYeyMg5/yH5Wv3pJgo4H7ZZNrBUtaswW9XD32G3Xjt06Xd9m663y7TdOvzlFfeLO2pEvBcIjG/Ts717QLvs2+kcAMEpczLi7ehMxRemKH19xVXk4kdl6yWVT8/WoZTt4cNv3E4VX7PjF1demolxDfAFwyWVXdDsh1wnHH52fb3o28dwlP74iO3ZVVuoLLyzL7+n+B/6a9+nuT5Te+K9TP513ue7632UB8N+Vu4/ecov0b+94a77+zbO+kyKYG23RosXp9K+dmS9X68++72v7jMfn4PsXX1o+bdzLWVmpiGgx0dtb3jypvC8WiiDr1Ct/Xq5VnR9zznnt+vVnJYLMRxz2ofwUl029Mi8bUpxv6pU/K39ui21r+r7W8JFp0kEn9fq14diu/y2u6RgG4rhN9tgrDdtyTH7qe0/7fJa5m2XhVrTlCxemxy6bkmZfseq5j9huhzRi27b7e+icM9PK7P+maK1Z5viDZ3294miLBAgQIECAAAECBAgQIECAQD0IRHnLtohYFUbbVVC3Cqfu9hQRnP3BlMvyV5FtGEHJCM5Fi+DVFz7ziXbn2D0LdP7y2l/ngb4vfvlr6aIpl+alGiKAGO3Iww7p88/x213gpZUV2c/ZYzKzeEVph/FbjUtLlixNldmmnzjp+M4OzbdN3PlN+fhjXCd/+gt5NmWRYXnGV7+UnXPz1Y5dO6vjeuAB788ydq/O9707C/R2NqnVagdmGz588IH5WCMYePxJn8qvt1ZWq/XAA/ZNxx19RH5IZIKefMJx6ZzzLswzl3+dlXzYbtvX59m0EdQtsk7fsMO2nV1ijbfF9X5zw7QU2Z5/uue+PHs0nneMuWhDhmRj3X+f9LNfXJNPUve7G29KE3beKf3t4UfycUV95Y6TqhXHRvD7+qwsxi233ZHOPf+idFU20V0EuiOoGYH1+JwVQdnimK7e98u+OLg9m5QvSnac9pWvZyUhtk1FBm1M9Dfj7nvyoOlBh340r/lcjKm78XV1ra62jx2zZYpx/N81v8r/bUzLxhLlGe67/8GywYkfO6YcFC/O84H99kn3ZOVG4rXXfgfnfo9lAehlVZwML6518IH7Z9nRV+dj2e+gj6S37jIpPZsFJGOSQa17gabsc77DaaenPx59WJp/5x1p2rvfntafuEuK+rwvzHsiLXrwpXIyh3xk1Ymy0gtbn3hKuuuEY9L8GX9M0/faNb32DTumxX99IC1ThmGVkyUCBAgQIECAAAECBAgQIFAnApE4V5WM3Xnz5rWrqRvlFyJTd6DbiBHr5pOifew/Ppp2efOEFEHIosX6t874arrm51PTRhu1n/E9snfP/dYZabfJbT+9jmBkBE8jUPixY49KJ3382OI0q72XslIKla2poi5p5fZYjkBj8XP7uMYNWXZwEdSNn/6f+fWvpM1HbdbxsPJ6jPOi889Ohx1yUB4AjOBilEGIV3cTTO3xrsnlc7x/7z3Lyz0tRBD8qssvTm9/65vLP8mPoGNct7JFCYYLzj0rD1bH/sgmjoBo3GMYxkRt24xvy/6tPK6z5Y6elX2amts+np86+YQ88BdBv99nAdMYTwTKL59yQdq4w7M9+cTj84BmnCfGFsHdGFdM9HbmN04vn76or1tsiPWzvvHVdOpnTsnvIT4PcU/xJUFcL55jx2dV1EPt7B6+mE2mVkzUd2oWhCvaVuPGpqmXXJgHicMqxrjjG3dIZ51xeh5EjX6V2eXFcfFeXK+pF3VYo/9/fu6T6cTjj4nFvN5u3E9cL8b1nbO+0Wm5jffu/q68TEh+UPZn5t1tmdcxyd/rtxmfb27KrCpbU/YfSbTOHIoJ1Yo+xXHxWQuHCEBHi38X8XwnTXhTXoc6tlXW/I31Rm6l4v+R4r2Hm41A7uRrb0wbvPXtec8I1v7jht+Ug7obvuPf00aT393uLLFt0nk/SIOGDUvLF8xPT908LQ/qjjn86DRq3wNe6tv+2bY7gRUCBAgQIECAAAECBAgQIECgpgRK2c/UV/3mvB9DKzJ2J02alHbZZZd+nKl/hx7zsZPTjm/YodvgbOUVYiKvRx6dnQeFx4zess81YyvP1dVyTJQVZRGezYJqEcDZcIP180zcyrqnXR27Jtt/9OOfZGUlvp8H8K6/+qft6quuyfm6O2bxc8+luXPn5ZOBxSRYG2+00WpZoN0d35d9kdE5Z87ctGkWFH/dhht0e2gEMOc9+WSKurdjx4zp85hiAq8ns2c2KDs+JleLLxGq3aJUxMqVLeWxHXnsiXkJkajLu/d7O69xvCZjiNT8uU/MyzJiF6Wooxx2HQPbHc8bfnFMZEj3dTK5jufqaT3KqIT1FlkGehEM7+kY+1cJrHxxWVo6Z3Zakf1bHDJyZHrNxpum5uxLg65aa/a5W/r4nLRi8aIU9Xqbsyx/jQABAgQIECBAgAABAgQIEKg/gUHVGnIEc0eNGjUgk6T1ZYwdMwN7Onbo0KHtJonqqf+a7B80aFBeNqGz0glrcr7ujom6vkU92oM+sN+ABnVjHOsOH5623+713Q2pavtGZj81j1dvWgQI+xMkjOB7vAaiRf3emEQvsr2LjO8I/Edd6Gijs1q81WzxBUKcM/veotetv369vlDWMQLNPQXq+3K+V1vf5myiwOFb9/7fYHy5NGx0W43eV5uV+yVAgAABAgQIECBAgAABAo0kULXAbqBECYaaaK/CXxPfOePuPCv4F7+8Nv+5fTyH/ffduyYeh0GsEnjobw+nUz77xRS1bCe8acc0MgtAPz73iXySvegVtWa333abVQdYIkCAAAECBAgQIECAAAECBAgQINBBIIowVK0UQ4dzv2Krs+c8nl6z1lqr1dV9xQb0Ml14970PKAd045Lf/ub/9Hqyr5dpiC6TCURg98NHHtepxfitxuZ1lwe69EGnF7eRAAECBAgQIECAAAECBAgQIECgbgSixGfDBXbrRr/KA51y6dT03PPPp5iUbeLOO+WlH6p8CaergsDyFSvSjGxCtnvveyD9459PpaVLluaTso0bNzrtsduuKcp2aAQIECBAgAABAgQIECBAgAABAgR6EhDY7UnIfgIECBAgQIAAAQIECBAgQIAAAQIECNSYQFONjcdwCBAgQIAAAQIECBAgQIAAAQIECBAgQKAHAYHdHoDsJkCAAAECBAgQIECAAAECBAgQIECAQC0JRI1dgd1aeiLGQoAAAQIECBAgQIAAAQIECBAgQIAAgR4ESqWSwG4PRnYTIECAAAECBAgQIECAAAECBAgQIECgpgQEdmvqcRgMAQIECBAgQIAAAQIECBAgQIAAAQIEeiegFEPvnPQiQIAAAQIECBAgQIAAAQIECBAgQIBAzQgI7NbMozAQAgQIECBAgAABAgQIECBAgAABAgQI9E5AYLd3TnoRIECAAAECBAgQIECAAAECBAgQIECgZgQEdmvmURgIAQIECBAgQIAAAQIECBAgQIAAAQIEeicgsNs7J70IECBAgAABAgQIECBAgAABAgQIECBQMwICuzXzKAyEAAECBAgQIECAAAECBAgQIECAAAECPQu0trYmgd2enfQgQIAAAQIECBAgQIAAAQIECBAgQIBAzQiUSiWB3Zp5GgZCgAABAgQIECBAgAABAgQIECBAgACBXgrUdcbuwoUL0+TJk/PXlClTyrc8ffr08vZ77rmnvL2WFpbOeyJdt9P4/PWvJc+Xh1bP91S+CQsECBAgQIAAAQIECBAgQIAAAQIECAyYQEtLSxo0YGd/GU68YsWKNHfu3PxKzz77bPmKS5YsKW9ftmxZeXstLbS2rCwPpzV7EEWr53sq7sE7AQIECBAgQIAAAQIECBAgQIAAAQIDJ9DU1KQUw8DxOjMBAgQIECBAgAABAgQIECBAgAABAgQGRmDASjEsWLBgYEbsrAQIECBAgAABAgQIECBAgAABAgQIEHgVC7S2tg5MKYZZs2alRx99NI0dOzaNGzeuZonnz7wzpZUr04jt35AGDVsnLZn9WHrmztvT8qysw7DRY9JGk3dLzUPXajf+KJuw6MH70nOPPJxemDc3rT1qizRiux3S8K22btevcmXF4kVpwZ9mpsV/fSCtteHr0no7T0qpecBi6pWXtkyAAAECBAgQIECAAAECBAgQIECAQAMKVL3G7owZM1JR7zaCuyNHjkzrrbdeTdL94ehD83G95YeXp1k/vCA9ffut7ca54dvemd58/sXlbS8+83S657TPrdYvOow78ti09QmnpKbBg8v9Y2Hx3/6a7jrp2LTsn/9ot338cSe2W7dCgAABAgQIECBAgAABAgQIECBAgACB3giUSqXqZuxWBnVjAJGxO5BB3ebm5vJ9Dh06tLw8aNCqeHXlcrlDh4UHz/xaloV7fxqx7fZp5E4TUspSmZ++47b0r6VLyz1j+ZaD9knLF8zPsnuHpdGHHJ7W3nRUWpRl4c65KgsMX3JRKmVB3W2y4G7R4pg7jvpQ+lc2mduQ9dZPYz58RB74nfPTqenhC79bdGv3Xq17andSKwQIECBAgAABAgQIECBAgAABAgQINJRAKavH0FqNO+osqFvLZRjinq/baXz51l//ic+mcUcck1IW7Y7WmpVoWPiXP7cFerP1v33vnDwYG0Hdd151bVp7s1F5v/gz95c/T/d+6fP5+q7XTS/vm33Fpen+M05v237ttKxsw+b58ovzn0m3fPB9eZA4Nuxx68w0ePi6+T5/CBAgQIAAAQIECBAgQIAAAQIECBAg0JNAvwu9xiRp9RjUrYSJLN0opVAEdWNfKcsGzrN3YyWLfRcZttt+8vPlwG3sirbZnvvkWbyxPP+uP8Rb3p78za/y9833/2A5qBsbhq6/QRp98GH5Pn8IECBAgAABAgQIECBAgAABAgQIECDQV4FVNQv6emTWP4K6M2fObHdkZxOmRb+otxttoMsztBtML1c22+v93fZc9vRT5f0PnXd2mnPl5eX1YiHKLUR77uGHik1pyeOz8+WRO+5c3lYsjNxp9W3FPu8ECBAgQIAAAQIECBAgQIAAAQIECBDoTmCNA7udBXUnTJjQaU3dCOpWTqg2kHV3u7vZrvatvelmXe3Kty99Ym55f9TYjVdXrWX5i/mulhUryv0GjxixWvchI2tzQrnVBmoDAQIECBAgQIAAAQIECBAgQIAAAQI1JbAyKyO7xoHdzu4kgre1FrTtbJwdtw0aPrzjpnbrTUOHlNcnX3NDGrb5luX1rhailEO5taxexrhlxfLybgsECBAgQIAAAQIECBAgQIAAAQIECBDorUBzFntc4xq7EcCNDN3KFpm5s2bNqtyUL0f5hZEjR+avWK63VhnI7S5bt/K+Sk1N5bq6L85/unJXvvziM8+sts0GAgQIECBAgAABAgQIECBAgAABAgQI9EZgjQO7cfLeBnej38SJE/NXPWb0Dl53RBqy3vq555O/vrY3rnmf4ePG5+//vGX6asc8dfO01bbZQIAAAQIECBAgQIAAAQIECBAgQIAAgd4I9CuwGxeIQO3uu++eZ+MWF+wqc7fYX4/v233q1HzYs39yWZp33S/b30Jra1ow8670p1M/mVYsXlTet8WBh+TLT992c/pnRSB3wZ9mpMf/98pyPwsECBAgQIAAAQIECBAgQIAAAQIECBDoi0CpNWt9OaC7vjNmzChPkhb9ouzCuHHjujvkFd133U5tGbVv+9GVaeSOO3c7ltaWljTj5OPSU7felPcbtuWYFBm5K7PJ0hY9cF95orR333B7GrrBhnmfOOb2Iw9OC+/9c76+3s4TU6mpOc2f8cd8vfizx60z0+Dh6xar3gkQIECAAAECBAgQIECAAAECBAgQINClQIR0+52xW3n2KLcQtXSLFpm7CxYsKFZr9r1U6pkhauZOPOfCtMMX/jsNGjYsLZnzWPrHtN+myMaNurtrbbRxGnv40WnQOuuU7zOO2eWCH6VNdt8z37bg7hl5UDf6Tjz7gnb9yisWCBAgQIAAAQIECBAgQIAAAQIECBAg0I1ABHarmrFbXCsmUIugbq1n7BbjXZP3ZU8/lV6YNzfPwB36uo3Sa7JgbSqVujzViucWp+cffSSv1Vs5GVuXB9hBgAABAgQIECBAgAABAgQIECBAgACBLgQGJLAb14pM3XqcKK0LJ5sJECBAgAABAgQIECBAgAABAgQIECBQMwIDFtitmTs0EAIECBAgQIAAAQIECBAgQIAAAQIECDSYQM/FZRvsht0OAQIECBAgQIAAAQIECBAgQIAAAQIE6lmgpaWlupOn1TOGsRMgQIAAAQIECBAgQIAAAQIECBAgQKAeBErZXF8yduvhSRkjAQIECBAgQIAAAQIECBAgQIAAAQIEXhIQ2PVRIECAAAECBAgQIECAAAECBAgQIECAQB0KyNitw4dmyAQIECBAgAABAgQIECBAgAABAgQIvLoFBi1atOjVLeDuCRAgQIAAAQIECBAgQIAAAQIECBAgUEcCzc3NauzW0fMyVAIECBAgQIAAAQIECBAgQIAAAQIECKSWlpZUas0aCwIECBAgQIAAAQIECBAgQIAAAQIECBCoHwE1duvnWRkpAQIECBAgQIAAAQIECBAgQIAAAQIEcgGBXR8EAgQIECBAgAABAgQIECBAgAABAgQI1JFAFGEQ2K2jB2aoBAgQIECAAAECBAgQIECAAAECBAgQKJVKArs+BgQIECBAgAABAgQIECBAgAABAgQIEKg3ARm79fbEjJcAAQIECBAgQIAAAQIECBAgQIAAgVe1QEtLSypl9Rha61Eh0o2j1enw65HcmAkQIECAAAECBAgQIECAAAECBAgQqBEBGbs18iAMgwABAgQIECBAgAABAgQIECBAgAABAr0VENjtrZR+BAgQIECAAAECBAgQIECAAAECBAgQqAGBqGIgsFsDD8IQCBAgQIAAAQIECBAgQIAAAQIECBAg0BcBgd2+aOlLgAABAgQIECBAgAABAgQIECBAgACBV1gg5h8T2H2FH4LLEyBAgAABAgQIECBAgAABAgQIECBAoK8CVQ3s3vvY8r5eX38CBAgQIECAAAECBAgQIECAAAECBAgQ6KNA1QK7P572fPrclIUp3jUCBAgQIECAAAECBAgQIECAAAECBAgQGDiBUjaDWmt/Tx+ZuhHULdobxwxJZxz12mJ1QN6jjkS0Kgx/QMbnpAQIECBAgAABAgQIECBAgAABAgQIEBgogapk7EYg99DJa5fH2DHQW95hgQABAgQIECBAgAABAgQIECBAgAABAgT6JbBy5crqTZ522LvWEdzt1+NwMAECBAgQIECAAAECBAgQIECAAAECBHoWaG5uTlUpxVB5qaixe/lNSys35WUZIqu3mk0phmpqOhcBAgQIECBAgAABAgQIECBAgAABAvUkUJVSDJU33DFzN/ZF/d0oz6ARIECAAAECBAgQIECAAAECBAgQIECAQP8Fqh7YjSEJ7vb/wTgDAQIECBAgQIAAAQIECBAgQIAAAQIEuhIYkMBuXKzapRe6ugHbCRAgQIAAAQIECBAgQIAAAQIECBAg8GoSaG1tTYMG4oZfrjq7AzF25yRAgAABAgQIECBAgAABAgQIECBAgEAtCwxIYLdjUDcydw+dvLYM3lr+JBgbAQIECBAgQIAAAQIECBAgQIAAAQJ1I9DU1FTdjN3OgrpnHPXaugExUAIECBAgQIAAAQIECBAgQIAAAQIECNSDQNVq7Arq1sPjNkYCBAgQIECAAAECBAgQIECAAAECBBpBoCqB3XsfW54uv2lp2SPKL8jULXNYIECAAAECBAgQIECAAAECBAgQIECAQNUEWlpaUlUCu0Ud3RhZ1NMV1K3aM3IiAgQIECBAgAABAgQIECBAgAABAgQItBMolUqplM2g1tpuaz9WInM3grwvR4vBR6vi8F+OYbsGAQIECBAgQIAAAQIECBAgQIAAAQIE+i1Q1cBuv0fThxMI7PYBS1cCBAgQIECAAAECBAgQIECAAAECBBpKoCqlGBpKxM0QIECAAAECBAgQIECAAAECBAgQIECgxgUEdmv8ARkeAQIECBAgQIAAAQIECBAgQIAAAQIEOgoI7HYUsU6AAAECBAgQIECAAAECBAgQIECAAIEaFxhU4+PrcngmTeuSxg4CBAgQIECAAAECBAgQIECAAAECBBpcQMZugz9gt0eAAAECBAgQIECAAAECBAgQIECAQOMJCOw23jN1RwQIECBAgAABAgQIECBAgAABAgQINLBAVDMQ2G3gB+zWCBAgQIAAAQIECBAgQIAAAQIECBBoPIFSqSSw23iP1R0RIECAAAECBAgQIECAAAECBAgQINDoAjJ2G/0Juz8CBAgQIECAAAECBAgQIECAAAECBBpKoKWlJZWyegytDXVXboYAAQIECBAgQIAAAQIECBAgQIAAAQINLiBjt8EfsNsjQIAAAQIECBAgQIAAAQIECBAgQKDxBAR2G++ZuiMCBAgQIECAAAECBAgQIECAAAECBBpYIIowCOw28AN2awQIECBAgAABAgQIECBAgAABAgQINKaAwG5jPld3RYAAAQIECBAgQIAAAQIECBAgQIBAgwqUSiUZuw36bN0WAQIECBAgQIAAAQIECBAgQIAAAQINLCBjt4EfrlsjQIAAAQIECBAgQIAAAQIECBAgQKAxBQR2G/O5uisCBAgQIECAAAECBAgQIECAAAECBBpY4P8B1/hmuRp89xAAAAAASUVORK5CYII="/><use stroke="#979797" xlink:href="#rect-1"/></g><path id="Rectangle" stroke="#EE6B47" stroke-width="2" d="M4 393h209v53H4z"/><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#D60000" d="M80.703 319.786a230.957 230.957 0 012.035 3.992l.273.553c.743 1.514 1.326 2.773 1.702 3.694.138.339.08.706-.104 1.1-.094.203-.221.41-.373.619a5.679 5.679 0 01-.503.605l-.147.151h-2.273l-4.2-8.574-5.613 5.727v-23.878l15.69 16.01h-6.487z"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="699" height="450" viewBox="0 0 699 450"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h699v450H0z"/><path id="path-2" d="M72 305v21.429l5.25-5.358L81.625 330h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H86L72 305z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0.0941176471 0 0 0 0 0.0901960784 0 0 0 0 0.0901960784 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="domconsole0.svg"><g id="Bitmap"><image width="699" height="450" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXYAAAOECAYAAAAFQmncAAAMSWlDQ1BJQ0MgUHJvZmlsZQAASImVVwdUU8kanltSSWiBCEgJvYlSpEsJoUUQkCrYCEkgocSYEETsyqKCaxcRsKGrIoquBRA79rIodtfyUBaVlXWxYEPlTQro6nnvnfefM3e+/PPP95fMnTsDgE41TyrNRXUByJPky+IjQljjUtNYpA5AACZAG7gCLx5fLmXHxUUDKAP9P+XtLYAo++suSq4fx/+r6AmEcj4ASBzEGQI5Pw/iAwDgxXypLB8Aog/UW0/LlyrxBIgNZDBAiKVKnKXGxUqcocYVKpvEeA7EuwAg03g8WRYA2k1QzyrgZ0Ee7TsQu0oEYgkAOmSIA/kingDiSIiH5eVNUWJoBxwyvuHJ+gdnxiAnj5c1iNW5qIQcKpZLc3nT/89y/G/Jy1UM+LCDjSaSRcYrc4Z1u5MzJUqJaRB3SzJiYiHWh/i9WKCyhxilihSRSWp71JQv58CaASbErgJeaBTEphCHS3JjojX6jExxOBdiuELQQnE+N1Ezd5FQHpag4ayWTYmPHcCZMg5bM7eeJ1P5VdqfVuQksTX8d0RC7gD/myJRYoo6ZoxaIE6OgVgbYqY8JyFKbYPZFIk4MQM2MkW8Mn4biP2EkogQNT82KVMWHq+xl+XJB/LFFonE3BgNrswXJUZqeHbxear4jSBuEkrYSQM8Qvm46IFcBMLQMHXu2FWhJEmTL9YuzQ+J18x9Jc2N09jjVGFuhFJvBbGpvCBBMxcPzIcLUs2Px0jz4xLVceIZ2bzRcep48EIQDTggFLCAArYMMAVkA3Frd2M3/KUeCQc8IANZQAhcNJqBGSmqEQl8JoAi8BdEQiAfnBeiGhWCAqj/PKhVP11Apmq0QDUjBzyBOA9EgVz4W6GaJRn0lgz+gBrxD975MNZc2JRjP+rYUBOt0SgGeFk6A5bEMGIoMZIYTnTETfBA3B+Phs9g2NxxH9x3INqv9oQnhDbCY8JNQjvh7mTxfNl3+bDAGNAOPYRrcs74NmfcDrJ64iF4AOSH3DgTNwEu+EjoiY0HQd+eUMvRRK7M/nvuf+TwTdU1dhRXCkoZQgmmOHw/U9tJ23OQRVnTbyukjjVjsK6cwZHv/XO+qbQA9lHfW2KLsP3YOewkdgE7gjUCFnYca8IuY0eVeHAV/aFaRQPe4lXx5EAe8Q/+eBqfykrKXetcu1w/qcfyhYXK/RFwpkiny8RZonwWG+78QhZXwh8+jOXu6uYLgPI7ot6mXjNV3weEefGrbsEGAAIO9Pf3H/6qi2oGYH8ZANTbX3X2s+B2cBKA81V8haxArcOVDwKgAh34RhkDc2ANHGA+7sAL+INgEAZGg1iQCFLBJFhlEVzPMjANzATzQAkoA8vBGlAJNoItYAfYDfaBRnAEnARnwSVwFdwE9+Dq6QTPQQ94C/oQBCEhdISBGCMWiC3ijLgjPkggEoZEI/FIKpKOZCESRIHMRBYgZchKpBLZjNQivyKHkJPIBaQNuYs8QrqQV8hHFENpqAFqhtqhI1AflI1GoYnoRDQLnYoWocXoUrQCrUF3oQ3oSfQSehNtR5+jvRjAtDAmZom5YD4YB4vF0rBMTIbNxkqxcqwGq8ea4f98HWvHurEPOBFn4CzcBa7gSDwJ5+NT8dn4ErwS34E34Kfx6/gjvAf/QqATTAnOBD8ClzCOkEWYRighlBO2EQ4SzsC3qZPwlkgkMon2RG/4NqYSs4kziEuI64l7iCeIbcQOYi+JRDImOZMCSLEkHimfVEJaR9pFOk66RuokvSdrkS3I7uRwchpZQp5PLifvJB8jXyM/JfdRdCm2FD9KLEVAmU5ZRtlKaaZcoXRS+qh6VHtqADWRmk2dR62g1lPPUO9TX2tpaVlp+WqN1RJrzdWq0NqrdV7rkdYHmj7NicahTaApaEtp22knaHdpr+l0uh09mJ5Gz6cvpdfST9Ef0t9rM7SHa3O1BdpztKu0G7Svab/QoejY6rB1JukU6ZTr7Ne5otOtS9G10+Xo8nRn61bpHtK9rdurx9Bz04vVy9NbordT74LeM32Svp1+mL5Av1h/i/4p/Q4GxrBmcBh8xgLGVsYZRqcB0cDegGuQbVBmsNug1aDHUN9wpGGyYaFhleFRw3YmxrRjcpm5zGXMfcxbzI9DzIawhwiHLB5SP+TakHdGQ42CjYRGpUZ7jG4afTRmGYcZ5xivMG40fmCCmziZjDWZZrLB5IxJ91CDof5D+UNLh+4b+rspaupkGm86w3SL6WXTXjNzswgzqdk6s1Nm3eZM82DzbPPV5sfMuywYFoEWYovVFsct/mQZstisXFYF6zSrx9LUMtJSYbnZstWyz8reKslqvtUeqwfWVGsf60zr1dYt1j02FjZjbGba1Nn8bkux9bEV2a61PWf7zs7eLsVuoV2j3TN7I3uufZF9nf19B7pDkMNUhxqHG45ERx/HHMf1jledUCdPJ5FTldMVZ9TZy1nsvN65bRhhmO8wybCaYbddaC5slwKXOpdHw5nDo4fPH944/MUImxFpI1aMODfii6una67rVtd7bvpuo93muzW7vXJ3cue7V7nf8KB7hHvM8WjyeDnSeaRw5IaRdzwZnmM8F3q2eH728vaSedV7dXnbeKd7V3vf9jHwifNZ4nPel+Ab4jvH94jvBz8vv3y/fX5/+7v45/jv9H82yn6UcNTWUR0BVgG8gM0B7YGswPTATYHtQZZBvKCaoMfB1sGC4G3BT9mO7Gz2LvaLENcQWcjBkHccP84szolQLDQitDS0NUw/LCmsMuxhuFV4VnhdeE+EZ8SMiBORhMioyBWRt7lmXD63ltsz2nv0rNGno2hRCVGVUY+jnaJl0c1j0DGjx6wacz/GNkYS0xgLYrmxq2IfxNnHTY07PJY4Nm5s1dgn8W7xM+PPJTASJifsTHibGJK4LPFekkOSIqklWSd5QnJt8ruU0JSVKe3jRoybNe5SqkmqOLUpjZSWnLYtrXd82Pg14zsneE4omXBrov3EwokXJplMyp10dLLOZN7k/emE9JT0nemfeLG8Gl5vBjejOqOHz+Gv5T8XBAtWC7qEAcKVwqeZAZkrM59lBWStyuoSBYnKRd1ijrhS/DI7Mntj9ruc2JztOf25Kbl78sh56XmHJPqSHMnpKeZTCqe0SZ2lJdL2qX5T10ztkUXJtskR+UR5U74BPLBfVjgoflI8KggsqCp4Py152v5CvUJJ4eXpTtMXT39aFF70ywx8Bn9Gy0zLmfNmPprFnrV5NjI7Y3bLHOs5xXM650bM3TGPOi9n3m/zXeevnP9mQcqC5mKz4rnFHT9F/FRXol0iK7m90H/hxkX4IvGi1sUei9ct/lIqKL1Y5lpWXvZpCX/JxZ/dfq74uX9p5tLWZV7LNiwnLpcsv7UiaMWOlXori1Z2rBqzqmE1a3Xp6jdrJq+5UD6yfONa6lrF2vaK6IqmdTbrlq/7VCmqvFkVUrWn2rR6cfW79YL11zYEb6jfaLaxbOPHTeJNdzZHbG6osasp30LcUrDlydbkred+8fmldpvJtrJtn7dLtrfviN9xuta7tnan6c5ldWidoq5r14RdV3eH7m6qd6nfvIe5p2wv2KvY++ev6b/e2he1r2W/z/76A7YHqg8yDpY2IA3TG3oaRY3tTalNbYdGH2pp9m8+eHj44e1HLI9UHTU8uuwY9Vjxsf7jRcd7T0hPdJ/MOtnRMrnl3qlxp26cHnu69UzUmfNnw8+eOsc+d/x8wPkjF/wuHLroc7Hxktelhsuelw/+5vnbwVav1oYr3learvpebW4b1XbsWtC1k9dDr5+9wb1x6WbMzbZbSbfu3J5wu/2O4M6zu7l3X/5e8Hvfvbn3CfdLH+g+KH9o+rDmX47/2tPu1X70Ueijy48THt/r4Hc8/0P+x6fO4if0J+VPLZ7WPnN/dqQrvOvqn+P/7Hwufd7XXfKX3l/VLxxeHPg7+O/LPeN6Ol/KXva/WvLa+PX2NyPftPTG9T58m/e2713pe+P3Oz74fDj3MeXj075pn0ifKj47fm7+EvXlfn9ef7+UJ+OpjgIYbGhmJgCvtgNATwWAcRWeH8ar73kqQdR3UxUC/wmr74Iq8QKgHnbK4zrnBAB7YbMLhtywVx7VE4MB6uEx2DQiz/RwV3PR4I2H8L6//7UZACR4nvks6+/vW9/f/3krDPYuACemqu+XSiHCu8GmYCW6aTSpGnwn/wZ3TIEEcU5bKwAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAFdqADAAQAAAABAAADhAAAAACFpCFXAABAAElEQVR4AezdCdxmU/0A8PMy9n3fTXYRFSlLRCpp06aUUmjfVYhkKSpLK1JUKkK0WBIihP6UrEX2fd/GGGObmff5n9/Nve7zzrsv03vn+Z7P553nruee8z13pvze8/xOVyuXpBAgQIAAAQIECBAgQIAAAQIECBAgQIBAYwTmaExLNZQAAQIECBAgQIAAAQIECBAgQIAAAQIECgGBXS8CAQIECBAgQIAAAQIECBAgQIAAAQIEGiYgsNuwAdNcAgQIECBAgAABAgQIECBAgAABAgQICOx6BwgQIECAAAECBAgQIECAAAECBAgQINAwAYHdhg2Y5hIgQIAAAQIECBAgQIAAAQIECBAg0NkCM2bMSF2tXDqbQe8JECBAgAABAgQIECBAgAABAgQIECDQLAEzdps1XlpLgAABAgQIECBAgAABAgQIECBAgACBJLDrJSBAgAABAgQIECBAgAABAgQIECBAgEDDBAR2GzZgmkuAAAECBAgQIECAAAECBAgQIECAAAGBXe8AAQIECBAgQIAAAQIECBAgQIAAAQIEGiQQy6YJ7DZowDSVAAECBAgQIECAAAECBAgQIECAAAECEdjtyn+0UBAgQIAAAQIECBAgQIAAAQIECBAgQIBAcwTM2G3OWGkpAQIECBAgQIAAAQIECBAgQIAAAQIECgGBXS8CAQIECBAgQIAAAQIECBAgQIAAAQIEGiYgsNuwAdNcAgQIECBAgAABAgQIECBAgAABAgQ6W6C7u9viaZ39Cug9AQIECBAgQIAAAQIECBAgQIAAAQJNE+jq6hLYbdqgaS8BAgQIECBAgAABAgQIECBAgAABAp0tILDb2eOv9wQIECBAgAABAgQIECBAgAABAgQINFRgXObYnT59enrggQcaSjq+mv3kk0+myZMnj69G5dY8++yz6eGHHx537WpKg26++eZ0xx139Ntcvv3yOEmAAAECBAgQIECAAAECBAgQaLTAhOG2/uyzz06XXnrpcG+v7lt44YXTl770pfT444+nCy64IJ155pnp5JNPTjvssEM6+uijq+tsDF7g7rvvTn/+85/TGWeckU477bR0/PHHpx133HHwFYzRlY8++mg6//zzU7w7p5xySvrMZz6TvvnNb47R02avaqdNm5b+/ve/p3POOaf4+3HTTTelgw8+OO2xxx5VR6dOnZouuuiidNZZZ6U//OEPaemll05XXHFFdd4GAQIECBAgQIAAAQIECBAgQIDA7CMw7MBuBA6/973vjVhioYUWSuutt17aZpttRlyXClLaf//90wEHHDDuKA477LC0++67j7t2NaFBkyZNShMnTkxTpkzps7mHHnpoW5A3LozArkKAAAECBAgQIECAAAECBAgQIDB7Cgw7FcPTTz9diXz4wx9Op59+errssstSzCS88MILq3Oxsd9++6X46viVV16Zzj333PStb32rCjpFsGrrrbdOt956a9p+++3b7rMzdIE999wzXX311WnNNdcc+s1jeMenP/3pdN1116XNNttsDJ8ye1a92GKLpcceeyzdcsstaf311++1k7vttltxzXgM6vfaYAcJECBAgAABAgQIECBAgAABAgRGJDDswG587TvKkUcemY499tj01re+Nb3qVa9Ka6yxRlp99dXbGrX88ssXx17+8pen173udekrX/lK+tvf/lZdM+ecc6ZVV101vfOd76yOjceNyPv7hje8Ydw0Lb6KHykN6mW++eZLL33pS9NrX/va+uH/+Xa0a5111knbbrvt/7wto9GA+OVFpBCZVWXChAlptdVWS1tuuWWvj4zzEQB+xzve0et5BwkQIECAAAECBAgQIECAAAECBGYvgWEHdp955pli1u0nPvGJYYlE8DdyrEaJxdKiRFqG8VpmzJiRdtppp3TNNdeMiyZGPuIIkPf19fzIXTwey3ht11CsIsD/3ve+93+y+Nuiiy7ab1Pnnnvufs87SYAAAQIECBAgQIAAAQIECBAg0HyBVquVhh3Yfeqpp9K73vWuNMccw66imOUbjM8999y41/z6179epJEYDw29995703bbbTcemtJxbYhfQrzvfe9LDz30UMf1XYcJECBAgAABAgQIECBAgAABAgTGh0BXV1ca9uJpsXDaAgssMKKexNfKIyXD/PPPP2A9EVCLn3nnnXfAa0f7gh/84AcpAruDLTGLtj77OILgkYogwEda7rvvviIdRF8zdQdTf8y2jq/ux89olPgNwcMPP5yeeOKJ9KIXvWjY9Y6kXTGjOlJ6jGWJX0B86EMfmimH9Gg8MwxH4/0YjbaogwABAgQIECBAgAABAgQIECBAYPwLDHu6beTSjdy5IynxtfFNN920zyq6u7vTb37zm/TKV74yzTXXXEVw9NWvfnWR07fPm/KJWGQqFhGLa+Or//ETuXFPOumk/m7r9dz++++fvvCFL1TnYqbmFltsUfxstdVWKYK2USKweP7556cdd9yxeF4sLvevf/2rSN8QAfC11147fepTn0rrrrtu28/ZZ59d1R3B457n456yRL8ij/H1119fHioWpivbc8wxx1THe248+eST6ZBDDinytEaQOTzf9ra3teU67nnPQPs33nhjkZIgZm0vs8wyRX7lqHeTTTZJ55133kC3F+fD78ADD2xrV4zVH/7wh37vjyDwd7/73fTud787rbTSSkUwea211ir8f/GLX6R4d+rlzDPPnMn2oIMOqi7p7fyGG25Y1RPtfPvb3972Dp166qnVu/DJT36yqmuwG5FOI+6LnMhhGP14z3vek/75z38OtopBXxe/FIn2v+Utb5np57Of/eyg63EhAQIECBAgQIAAAQIECBAgQIDA/14gYl/DDuyOdfOnTZuWIn/vDjvskC6//PLqcTHDd5dddkm///3vq2P1jQiUbrDBBimCe5HHN9JFRDn33HOLr9BHYOvZZ5+t39LndrTh2muvTZtttlnbNYsvvniKn1is6vHHHy+CyBHk3nrrrdMJJ5xQXPuf//ynuO+4444r9m+66aZixvHhhx9eBGYjOBs/jz76aFX3brvtVrQ7AtHl+QieliUCfhFsrM8GXnrppYu2RHsiYNtbiWB0LKYWwe7bbrutuuSMM84oFjOLgPFQSyweFsHqk08+OUW777rrrhQpIiJIeNlll6XXv/71KYKl/ZVHHnkkxYJ6X/va19raFWMVC+nF8ZjJ2rNcd911RYA7Fi+bNGlSEdyOIO0iiyxS+O+8887FWNx6663VrbFo24knnljM+C5t77zzzup8tDfeqQhKl+evvPLK6vlRV/wiYs0116zuieeV78JQcgdHn7797W8XY3LRRRcV70ksenbPPfcUi+FttNFGRbC7etAobMTs7Jh5HiXGJX6WXHLJIjD++c9/fhSeoAoCBAgQIECAAAECBAgQIECAAIFZJVCkx81BplEvOUAV0bjq5yc/+cmgnvHHP/6xuqe8f999923loGjxs/3221fnV1xxxZnqLO9fZ511Wjk1QHU+By5bOQBa3ZsDhtW5wWzkQGJ1b8/n5qBpKwcVWzngV10Tbc/B19Zb3/rWVg4YVse/9a1vFY/L+XGrY8cff/xMTcgByOp8DsjOdD4Hu6vzOZA80/k4sMcee1TXRHui/8cee2wrBzNbOVDe1t6PfexjvdbR18Ec8G7zzIHy6tI8M7ToezwzTHqWH/7wh23tiuvC6Tvf+U7rox/9aHVvHI+fU045pa2Km2++ubr/zW9+cyv/dqI6n2dNt+q2MQY5cF6dj43vf//71f3xvJ4lB6ir8/H86E+9xLtctm2obmU9OcBe1PHBD36wrf7y/S3rP+ecc8pbqs/4+1CeP/jgg6vj5cYNN9xQnc+/4CgPF585cF2ci3HJv7BoO2eHAAECBAgQIECAAAECBAgQIECgWQLjdsZuDl6lv//97+mAAw4ovuIfqR9y8C8OFyVmN0Z6gbJE/tPPfe5zxe7PfvazYjZieW611VYr0iCU+9/4xjeK2aXl/lA+Y9ZmvSy11FJp7733TvG1+np52cteluKr+n/+85/TpZdeWswWjZmtUWKmb39l0UUX7e9027nB5GVdf/31i5nHH/7wh9PKK6+cXvGKVxSuZUVXXXVVuTmoz7vvvrtt8bBIv1CWyHMbM3mjxCzl+ozk8pryM2YbxzWnn356+uIXv5iOPvrodMkll5Sni8+YZVxfXO8zn/lMdT5moNb7H7+piBnSq666anFN5CHOAe7q+tgYTfviNyNttQ+8E7Ojc0C2mHWdg8RteYFzoLptdvhopkg48sgji1nQ22yzTTEDfr311hu4sa4gQIAAAQIECBAgQIAAAQIECBAYlwI5BD1+UzHkmZdFbt26XOQgjWBgWeppCn7+859XX+ePVAXl1+nLz/jKfL1E/tvRLD3zDUdAsQz8bbzxxkVKiXnmmWc0Hznouj7ykY8UOXDrN0QKhLJEqoueOWnLc719rrLKKmnLLbcsTkUKg3pwNQ7WU0U89thjxXW9/RGB5gjY10sEofPM4upQpI64+OKLi/2zzjor5VmsxXYEKCNg37PEs8sAepyLIP9oj3XPZw5l/6tf/WpxeQT+b7/99pne04kTJ1bVRdB7JIvkRUUxrvEuRkA8UphE+o2hpI2oGmODAAECBAgQIECAAAECBAgQIEBgXAlMGFetGURjIiBZBvdyuoXqjvoiZC95yUuq431t5K/0pze+8Y19nR7W8QgqloG4nnl5h1XhGN4U+YfrZerUqW0B2fq53rZjhnLk1F1uueWq05GzNmbM1nMixyJyfZUlllii11ORFzny5JYl8ttG/uKY+VyW3oK65blYUK0+2/Waa65J42GGavwmJXISR4lgdSyUN1CJGb71IPxA19fPx4z2WMwvFg2MwG5OgzFTEL5+vW0CBAgQIECAAAECBAgQIECAAIFmCMREy8YFdmMRqN5KOSszFp6qz/js7do4tsIKK/R1atjHY/GyMrA77EqGeGPP2bKDvT1SJoy0lIZ/+ctfioW5YjZozLgdqUEEyGPG9mmnnVY0sVzcLRayK8uLXvSicnOmz2WXXbZYQC8WP4sSi62NRRmq/X333Vc1IwKtsTjgQKW+WNtA1/Y8HzN+4ydKzA6OwPJQ29yzTvsECBAgQIAAAQIECBAgQIAAAQLjQ6D3KOn4aNugW5EX76rSMERO18HMhBx05eP8wjLdw/+imf/4xz/Sl7/85WL26eabb54uvPDC9JrXvKaYXXv++eePqEllntyoJC9gVtQVuX3LEmPeX4l0EWVgN2b8jkUZapC0DFBHWyJFwqx8T88888wit+9ee+01FhTqJECAAAECBAgQIECAAAECBAgQmMUC43rxtMFa1GefRk7WgYJ+g623t+v6mjHc27Wz87ETTzwxvepVryqCupErN2btRlB3tEo9J/I666xTVLvMMstU1d91113Vdm8b9RQRK664Ym+XjPjYUIPq9RzLkft5rMsGG2xQpF8onxOL/I004F7W5ZMAAQIECBAgQIAAAQIECBAgQOB/KzBbBHYj2FoG/4LzlFNO6Vf1ueeeS9/97ndHnDKg34fMopNDnTU6Gs2KReve//73F1VF6oVYuG6uueYajaqrOu6///5quxzbep7cK664ojrf28bkyZOrw+X91YH/0UY9L3DMbh5oJnEEr3/yk5+MqLWR8mH77bev6nj729+e7rnnnmrfBgECBAgQIECAAAECBAgQIECAQDMFxiSwG7k8Z3WpL5gWXzd/5plnem1CtO2Tn/xk+t73vpfqMyh7vbiXg2VagF5ODetQPQA5nApGuz2DacMxxxxTXRYLnY1FcDkWPIsS+XYjeBylHtiNNAv/+c9/iuO9/XHHHXdUh8v7qwPPbzz++OM9Dw1pf6j2Sy21VNsCdfvuu2+fz3viiSfSW9/61vS3v/2tz2sGcyLGJsarTG0R+Y/f+c53pqeeemowt7uGAAECBAgQIECAAAECBAgQIEBgHArMmDEjjUlg98knn2zr7tNPP92239dOPVBW365fXz8eHSjLxz72sXKzmJEYM0p7C5p++9vfLmaY7rPPPmnuueeu7ulvY4EFFqhOR6qHyI86krLYYotVt5eLvpUHIvD85z//udztdXZlBDvLcu+995abbZ/Tpk2r9uvb5cGewfe6a3lNX5/1oOkDDzzQdlkE1P/9739Xx/oKsFcX9LIRi6SVAc0jjjgiLbjggsVVEUQuA5Rx4Fe/+lUvd6f08MMPFyki4uS2226bXvnKV1bXLbzwwtV2b7N+zzvvvOp8bERd9VJ/F+o5f+vX9Lf9xS9+sTp9wgknpIMOOijV3+M4GeMV72847LHHHtX1w91YZJFF0u9///vq9ssvvzztuuuuxWJq1cEeGzGrN2a1h8dI3/ceVdslQIAAAQIECBAgQIAAAQIECBAYoUCkph2TwG7Pr3oPlA+17MekSZPKzRSLoPVW6oG2xx57rLpk6623Tptttlm1/4c//CFFjtEDDzwwnX766UUQMK6JPKNvfvObi8BWdfEAGyussELbFeecc06x/5vf/CbtuOOOxXYESh966KHqup4Bz+pE3lh77bWr3R//+Mfpd7/7XRGEjoBuBC9jNnFZbrrpphQLX9VnWK6xxhrl6RT9jKBs2L3lLW9JsaBZlLpN3bW8MWaE1ktv19TP17cjUFiWo446Kh155JHF7NnweN3rXtfmcPbZZ6dI3RA5eHuW3gKjMaM00gdEifH8wAc+UN0233zzFbNPywMRpL/kkkvK3erzZz/7WbVdt4yDa665ZnUugvQxazasIsi75557FrNZqwvyxtFHH50eeeSR6lA9ncJFF12U7rvvviIwGwHYcBiofO5zn2u7JH7BsNVWW6XDDz+8GOcIZMf7EWMe/avPRI8b6+9/b7+4qP9SJd7HMij70pe+tM3upJNOSp///Od7De5GjuoNN9wwfelLX0qvf/3rB0xt0tYhOwQIECBAgAABAgQIECBAgAABArNGIAckR61MnTq1ddlll7VyQC5yMVQ/eYZp69RTT23loFSfz8qBxtZrX/va6p64/+9//3vb9Zdeemnb+W222aYVzyzLDTfc0MozOtuuqbcjtjfaaKNWDoiVtwz6M+6r17X00ksX+znI28qBsFYO0LadzzMuW9GeHFib6Rk56NsKk3p95XYcP/nkk2c6lxcoq+o566yz2s6XdeWAdSvPjm7l3K1t9edgZivP7K3uzzNEW3k2Zlsd++23X69trW6qbfR8ftn2+Nxuu+1au+22W1vdcfywww4ragiv+vU5LUbxbuSAdOvYY49t5WB8cT78crC59tQXNnOwtqoj+n7uuecWY5BnuraOP/746lw49iw5CD7Te1ZvTw7OzvQO5cXXWmEWJf/Coaq/vC/aEO/d7bffXlwz0B/5Fw0z1VHWVX5+4hOfmGk8rrvuurZxzbmDWw8++GD1uHgPe9r/8pe/rM7Hxjve8Y62Z+f8u638i5i2a3IajLZroi0KAQIECBAgQIAAAQIECBAgQIDA+BKIGXujUvKs3LZgUBmg6vmZZ9DO9Lwzzjijz3vzjMHi+i233LLPayIQVZYIdEXAt+dzYz/PgGzlhdPKS4f0Gc8oA6hRVwR2I4idUwb0+qzy+TvssEOvz4mgdQTmyuviM/oYz4lAW+xvvPHGrR/96EetO++8c6Y6dtlll7Z7I/gWfcv5hduO1+sP+zz7tK0f9fPRpzKAOdMDexzIM0vbnhPBz5/+9KdFMDLPhC0C6FF31BnPrdcbffzQhz40UwA1ro/AbgR4Byr//Oc/WxGwrre/HJ+cU7eV8+/2WUWeZdvK+Wvb7o3AbE5XUNwT29GfAw44oHX11VfPFGDNi8W13Ru/yIhg/VBKTocwU/tLr9NOO62tqghYR3vqfa1vx3uTUzr0eT5crr/++tbXv/71Pq+J96YsMVb1dzOnYyhP+SRAgAABAgQIECBAgAABAgQIEBgnAl3Rjhwkmu1KpC7IQbkiLUB8/T7SF8w111wj6mfkPo0FuyI371prrTXiRcMihcLNN9+cIi3Ccsstl1ZeeeWiffGcSF9R/9p/bw2PNACRYze+up+Dd71dMqbHwviWW25Jkbc22j7HHO2ZPfIM1uJ45Pzoq0QKiEiJUJoONu9xWV+kc8iB4hR5f8PrZS97WWFZnu/vM4zDMHIex70TJkwoLo/UEfG+9OxPva4Ys7gu0nQsv/zy9VND2o40D7EQXA6mphe/+MVp4sSJI36vhtSAPi7OvyRI//d//1fkNC7fyz4udZgAAQIECBAgQIAAAQIECBAgQGAWC0RId7YN7M5iS48jQIAAAQIECBAgQIAAAQIECBAgQIDALBGIdZUEdmcJtYcQIECAAAECBAgQIECAAAECBAgQIEBg9ATavzs/evWqiQABAgQIECBAgAABAgQIECBAgAABAgTGSEBgd4xgVUuAAAECBAgQIECAAAECBAgQIECAAIGxEhDYHStZ9RIgQIAAAQIECBAgQIAAAQIECBAgQGAMBCLHrsDuGMCqkgABAgQIECBAgAABAgQIECBAgAABAmMl0NXVJbA7VrjqJUCAAAECBAgQIECAAAECBAgQIECAwFgICOyOhao6CRAgQIAAAQIECBAgQIAAAQIECBAgMMYCUjGMMbDqCRAgQIAAAQIECBAgQIAAAQIECBAgMNoCArujLao+AgQIECBAgAABAgQIECBAgAABAgQIjLGAwO4YA6ueAAECBAgQIECAAAECBAgQIECAAAECoy0gsDvaouojQIAAAQIECBAgQIAAAQIECBAgQIDAGAsI7I4xsOoJECBAgAABAgQIECBAgAABAgQIECAw2gICu6Mtqj4CBAgQIECAAAECBAgQIECAAAECBAiMoUCr1UoCu2MIrGoCBAgQIECAAAECBAgQIECAAAECBAiMtkBXV5fA7mijqo8AAQIECBAgQIAAAQIECBAgQIAAAQJjLWDG7lgLq58AAQIECBAgQIAAAQIECBAgQIAAAQKjKNDd3Z26cj6G1ijWqSoCBAgQIECAAAECBAgQIECAAAECBAgQGGMBM3bHGFj1BAgQIECAAAECBAgQIECAAAECBAgQGG0Bgd3RFlUfAQIECBAgQIAAAQIECBAgQIAAAQIExlAgkjAI7I4hsKoJECBAgAABAgQIECBAgAABAgQIECAwFgICu2Ohqk4CBAgQIECAAAECBAgQIECAAAECBAiMkUBXV5cZu2Nkq1oCBAgQIECAAAECBAgQIECAAAECBAiMmYAZu2NGq2ICBAgQIECAAAECBAgQIECAAAECBAiMjYDA7ti4qpUAAQIECBAgQIAAAQIECBAgQIAAAQJjJiCwO2a0KiZAgAABAgQIECBAgAABAgQIECBAgMDYCAjsjo2rWgkQIECAAAECBAgQIECAAAECBAgQIDAmAjNmzEhdrVzGpHaVEiBAgAABAgQIECBAgAABAgQIECBAgMCYCJixOyasKiVAgAABAgQIECBAgAABAgQIECBAgMDYCQjsjp2tmgkQIECAAAECBAgQIECAAAECBAgQIDAmAgK7Y8KqUgIECBAgQIAAAQIECBAgQIAAAQIECIydgMDu2NmqmQABAgQIECBAgAABAgQIECBAgAABAqMuEMumCeyOOqsKCRAgQIAAAQIECBAgQIAAAQIECBAgMHYCEdjtyn+0xu4RaiZAgAABAgQIECBAgAABAgQIECBAgACB0RYwY3e0RdVHgAABAgQIECBAgAABAgQIECBAgACBMRYQ2B1jYNUTIECAAAECBAgQIECAAAECBAgQIEBgtAUEdkdbVH0ECBAgQIAAAQIECBAgQIAAAQIECBAYQ4Hu7m6Lp42hr6oJECBAgAABAgQIECBAgAABAgQIECAw6gJdXV0Cu6OuqkICBAgQIECAAAECBAgQIECAAAECBAiMoUAEdieMYf2q7kfg4Ves3s9ZpwgQIECAAAECBAgQIECAAAECBAgQmJ0FlvrnLSPqnhy7I+JzMwECBAgQIECAAAECBAgQIECAAAECBGa9gMDurDf3RAIECBAgQIAAAQIECBAgQIAAAQIECIxIQGB3RHxuJkCAAAECBAgQIECAAAECBAgQIECAwKwXENid9eaeSIAAAQIECBAgQIAAAQIECBAgQIAAgREJCOyOiM/NIxGY0Urp6qeeTVNmdPdZzbRWK03u53yfNw7yxN3PTR/klS4jQIAAAQIECBAgQIAAAQIECBAgMH4EBHZ7GYtJkyalAw44IH3uc5/r5eysPXTF1GfSOtfckR6YNnsEICOIe87kqWn3ux5O6117R3rDf+5JNz3zXBvqw9NmpN8+9mT65O0PprVy33/wwKS286OxMz0HjLe54Z604b/uLD5jXyFAgAABAgQIECBAgAABAgQIECDQBIFWjmVNaEJDZ1UbJ0+enI444oh08MEHpylTpqQ3v/nNs+rRfT7npw9NTo9Mn5F+9fATaY/lF+/zuiacuOiJp9O7b76v36Z+8JYHisBvvxeNwsl/P/1cumrqs0VN8XlF/nnVgvOOQs2qIECAAAECBAgQIECAAAECBAgQIDC2Al1dXcmM3Wz85JNPpkMOOSSttNJKaZ999imCumNLP7jaY5bu7/LM1Sg/zgHep7ubPat084XnS/dvsFo6ba3l+wT42WrLpGvWn5i2WWSBPq8ZjROrzDNXWzUvnm/utn07BAgQIECAAAECBAgQIECAAAECBMazgMBuHp0f/vCH6cEHH0wnnnhi2mabbcbNeB3/yJSqLU/mFAZ/eD7IWx1s2EZXbu+c+Y9NFpwvrTZve2C17Mrc+bcNy801IW29yPzloTH5XGTOOdLV601MP3zR0sXnwnlfaaZA5Gr+8K0PJPmSmzl+Wk2AAAECBAgQIECAAAECBAgMXaC7u1sqhmDbe++9K72HHnoonXPOOdX+/2rjuZwn4+d5lm69HP7gpPS+JRdKESBtelliwpzp1jStz25EgHesy/JzT0g7LLHQWD9G/WMs8P2cg/lPj09N+6ywxBg/SfUECBAgQIAAAQIECBAgQIAAgfEhMMccc0jF0HMo5p9/bGeK9nxeX/tnTppa5NZdsDaT9NZnpqWLc55ahQCB/wpc+MRT6eD7HsNBgAABAgQIECBAgAABAgQIEOg4Ad8/H6dDfvTzs3X/vPaKqR7cPeqhx4fc4ul59m/81EvMCJ7W41j9/HC3258y3Fpm7X29+fRsweM5Fcak6d09D49o/4lc5y05WD+auZPD/8FpM0a1zhF18vmbw/je56YXP4N9RyLFQt0m7qvv//3JZ9Iutz04Gs1TBwECBAgQIECAAAECBAgQIECgUQKtHGuZ0KgWd0hjr37q2XTF1GfSmxZdIK2ec9F+YulF0mH3Typ6/5fJT6WbnnkurTlv/4t9ReD2kilPpz/lmb+/n/RkOjznkt0m5609NW/H19b/mI9HwPjN+Rl7Lb94irQEwykRbPvNo1PSX/PMyUtzoO2+HLxbK7dtk4XmTV9abvG0zFxzDqfaPu+5Mff96/c82uv5bXNfPrDkwr2e6+3gv7Lz73Pe4l8+8kQ6brVl02YLzdd2WRge/eDk9KMHHy9mT8fJJXMKiVgE7pEcPA3TobpFgPiInDrg5w8/kSJvclnC7ANLLZw+nsd6OOWR6TPSQfc+ln6d+1KWiXmBuC1yn+7Li/CduPpy5eHiMwKk506emk7MY7dAnrr/01WXSbc/Oy0dn+//vynPFO9ftGnnpRdOOy+1SJH+I34RcFp+f36R237908+leXO6jK3yOxXv53rzz9NWf7lzUZ5h/q08ozbe57LEe7fJgvOmg1deKq3Yy3sXiwaemsflZ/k571l8wbTbcosVz/zZw5NTzFoPoy0Wnj/teMv9ZZXF50dueyCVuZL3X3HJtMECvbep7SY7BAgQIECAAAECBAgQIECAAIGGCgwvmtfQzjal2WVu3V1yQC3K+3Owsgzsxv7PHnoiB8WWjM1eSwQi9+8R/IxA5Htvvj9dnIO9ZYnAYgRlY9boaWstn4aa1zbu/8KdD6fTc7Bv8xxAjMDqdTlYelkO8EYA9rc5OHfMKsuM6kJoq+Zg5QE5aPeGG+4pAqMRaH1XDv5tnJ8fwcKBSrQ5fE7JbbszBzL7KhGw/tTtDxV9226xBdPnll20CBqenL0OfT7I/lQOjg6lRMDyjTfcWwS/w+uglZZMy+bA5lk50P75Ox5KX7v7kTwreEb6Sg60D6VMzn3aNtcb/dkj3xt5g+NYpCg4Lgdq6zO+45rvP/B4EaAtA8tvzOP28xw0/cpdj7Q9NsYwjkU335mNd8oLlP0jj21Znswbp2SPC/IvG8578YozBbl/mJ9z4L3/DcIfmYPgr1tkgfRo7t8X7nwoB5WfSlf95570p7VXSC/KYxoljv00z1S/IP+SoCwR+v5afpd/Vss3/ZO8PT0fj3afne3KslT+JcJ8OUgdZa6xT9FcPtYnAQIECBAgQIAAAQIECBAgQGCWC3TlCXdSMcxy9v4fGDMvT8rBspht+eo8MzRKzGp8y2ILVDcem4NwEQDsq0SAdf8Vl2gL6O1+18PpP3mW5b55gam/5CDcT3LAtSwxm/L0PIN3KCW+Jr99DhRHUPewiUul3625fPpWDlSevtYKRRA06orA4Udvf7BIDTCUuvu7ds780p7w6H9nu8aM5r+tu3L6Rn5uzDxePAd5ByoRio1g6vsGWDTt0hwAj75FOSQH0WNGaozJ7jlw+sU8gzTKUFNZHJADlDGjOcpXV1g8rT3f3GnRPHs12vK2HDyO8t0cNI5UCkMpEQyNgO36uY1fzm2L92XdXHfMwu05CzlqXiX3Y+V8TVkiOBoB3A/nGcO/z+N4wTorpe1rPnvngPM2OXB8T257vFcX5fMx3uVs5Xhnj8jB8nqJWeVlUHfrPKs36ltswhzFDPRD80zdKHFfmXIk9p/NEeSJ87zQrjj2newRv3z4xDKLtr3P8R7/Ks+yrgetvzdx6eJYHO9rBnHUqRAgQIAAAQIECBAgQIAAAQIEZgcBgd1xNoonPjKlaNFH89fN64NTzt4tm/vr568r9+ufEbj7VA6Ebfl8YDjOxdfqY1blZ/LM0wh6vSPPwNyxlrbgxhz0HUr5w6QpxdfrI2i3U62eqKMMfMZ2BHe/n1MPjEaJ1AifzTNbj8gzQb+w7GLp5zmAF8HCoZSFciA12httDJO+SuRvLUsEk+slUhNEGWpgN1JVlKXnXN+YiVyWq2ppC8pj/X3+3/OzsOfq0c6Ygf2R/B6VM3OjjnhOzD7eOwdG6+XHOdB/SA64vjrPJI6g8GF5O2ZDl2WR7Bb5nuO9ioB0zDj+YQ6klqVsQ7l/bZ65XZaeE5tXrgVv6/fFLy+iDbvmNtfLL/M4fz0HlK9eb2L6YZ75G8H8+eZoH5O4fuYj9VpsEyBAgAABAgQIECBAgAABAgRmL4GhRcVmr76Pu97EAlNHPT/zcfvFF2prX8y8XC3n2y1LpBMYKLC4zFwvzH581xILVjMsyzo2WuCF1AXxtfvBlphZue/d//2K/do5OBr31n/uzjM7Y3ZrWa4cYqCyvK/+GakF3pdnCMdX/2OG8N55xutIX96l+8n/W48b7plnO0/tfiEfbuQNjvQP89Yvqje2j+0y/28ETOuB3Li8HqiclPs6lFI2I2ZeR5qCetD4tTkXbczk7Vki+F+WCHBHqoV6ifZsme8tS8yY7ekVAd6yPNRjlnEEiMvAcM9Zw/PUAtA974v6Vq+1LdoeQeQokT830kysUft7UJx4/g+B3bqGbQIECBAgQIAAAQIECBAgQGB2F3gh8je797QB/Tsn5xiNr6d/MM8o7TkTNYJWn1h60RQpFaLEdWfmr9C//fmv8BcHe/wxUKBr1VqAbOoQgonxNft4fpQjc4A5fvorV019YfZmf9f1de6OnGbgLTkVQASP42v2kVt1rMtLa8HQ3+V8vLGgXcwmLYOMR9VSWQy2LZEmIdIdRICyzGf8RHY/I6d8OPmx/87UjrqeqQWRB1P3hjlA/9e8SFmUyNN7Uc5RG+kpIngcAdqYqd2zDPRuxPU9A7k964ictmUp34dyf9n8S4Vr1p+YHpve3baAXrwLJ+ZUGmV5Jv8yo2epB8y3qM0673mdfQIECBAgQIAAAQIECBAgQIBAJwsI7I6j0Y9cqVEigLlvj8XP4vjjzwdTYztKzO7tL7D736v6/nMwwb3e7r41B1rLEoti9TYjtDwfn3OVU0rrB4ew/cda/t/bas8eQhVDvvQ1ebbqVvmnXMjr1rzA3Ltuuq84FouerV4Lig+l8nIW6825vliwLBYFi2ML5GDvcMvHc+qCXz38RBVsj0XIzp18V5HSYM+cEzjy+A6nzD/AuMX7Ezlu66ke6s+J1BAxuzlSaJyWg+MxmzhSNLw+p+/or3QNM6lCbSJwf9U7R4AAAQIECBAgQIAAAQIECBBovMCMGTOSwO44Gcbrc47bvz2fK/UfORdr/AxUYvbj5fm6jRZ8IaXCQPeMxvkIcpZlnhz8W6v2lfzy+Fh97p8D3i9fYJ60yYL//Xr+WD0ngpa/yLODP33Hg6keWI5A76bX3VXM3o3Zt0MtD0ybnr5572PFAnmx+Fjkto3cspFaI44PpyyWA8Nnrb1C2uGW+1N9bCJoHAHVY3M/XjWMd2SOUYiU/iE//4B7/7toXMxEj/5GGojlrrx1OF3t957h/qKi30qdJECAAAECBAgQIECAAAECBAiMQ4E555xTYHe8jMuxefZmlFgcqr9UA5Gvdoeca7YsR+fg3awO7Na/Kh8zT8e6xIJdkY7hTzn1RJRdb30wXbDOSm1f8R+LNkQag5+vumw6PadK+Mpdj1QzYuNZe+SUGAvO2ZXe3SMXcn/tiOD9u/Os30hbELOcT1h9uQHTHfRXX/1c5DT+azY5Mi8s9637XggQx7PelwO+Z621wiwNwEeW4H1yWohyFvqhOY3Fh54PhM+YOftCvSu2CRAgQIAAAQIECBAgQIAAAQIEBiEwvO9oD6Jilwxe4NEcfPtl/ip9fK09UivEV+f7+onFsNapzZA9LQcd78mLlc3KUl/466S8mNlAi7hdlmcVX5hnug63REaAH+SAd7kgWwQrP3rbAwM+d7jPi/vCNGbXRnlbHpPL11s57Z5z5NbLp25/qEgzUD/W13YsOPehWx+ogsMnrTF6Qd1/5fQGT+f6I2/vbrmNV643MW1Xy70cqRJ6S+3RV1tH4/jJ+b0og7qfzIH5Mqg7GnX3VcdwUzj0VZ/jBAgQIECAAAECBAgQIECAAIHxLCCwOw5GJ/KjRvlA/qp6fTZsX037RA6U1Us527d+bCy364HdO/NM2t/kIF5f5T95lurbbrw33ffcfxdb6+u6gY4vkoPdP191meqyCBbv10se4uqCEW5EwPqYPBu6LAvMMUfaPeer/d2ayxcB+PL4NYNcGO7CKU+lsIqycU6LUObaLesZyedX88zY/3s+jUfUs2JO8XBMttpvxSWqaiOFROS6nVXlx7UF9d4wQE7d0WrT9FnYv9Fqs3oIECBAgAABAgQIECBAgAABAsMVENjtIdcaRnBo+vTp6cwzz0w/+MEP0gMPPNCjxv53Y6bl4c8Hwd67xEL9X/z82fpszDh0bA4MT86zMnuWgcJ4M4bR13hG5NR9ZS1na8wG/XNesKtniRmvkQYggpjvXmLBnqeHvL9eTl9w2MSlqvtiRmjMdB5uqc807i09wOl50baexzdfaL70ybxYWVmeGaThvbVZ1Q/nGcc9R+vqWoA43omhlj8+n6aift+n8y8A6uPUsy/1a3vbfqb7hVYONWh6V4/+1uu/IS8OWJaYTdxfbwfiXTgH/Mvy4LSR/fKgrMcnAQIECBAgQIAAAQIECBAgQGC8C0QM84WoyHhv7Sxq36OPPlo9aerU/+Z0rQ70sXH00Uent7zlLekLX/hCes1rXpOGEhyOmY0R3Iqybi3FQh+PKg5H7td3LP5CoDTuL7/2Xr9v8vQXAnMP9xL0eqx2/tbnZ5PW7+9ve888e7Us8fwP5ADup+94KJ2YZ7qenYOMh+Y8r5ted3eeqTs9/Twv3hVpAuqlHoSb8nz/6+en1IKKj+VAaFl2yrOa63ltd8+5bk/N6SiGUybV+v94XkmwZ4kZtsc/MnPg+OlatHHDvJDbYMpCecZvWWKBsz1zuyPnbqSo+Fx2K/MHxzUX59m3ERT/fV54bLDl17md1+X6epZnng8SxyzheG/K8kStv/fmZ73wppRXpCptRBy5Lqd76Fki2Fu+u3GuPk7z1sZ775yfOAL/MXv7FzkQv33OM1wvl+T+XvTE0+n259/BetvKdBj16+vbL679nfnT4//1iudse8O96anaO1S/xzYBAgQIECBAgAABAgQIECBAoOkCArs9RvDWW29NEaQty4UXXpiuvPLKcrfPz/PPP786d9NNN6V777232u9rI/LqHnjvo20LXf32sSlFrtS+7onjMbvx/hyIu7FHEO/gHEiN4F45czeChmdPfiEw/YccJIzctGWJHLK/fOSFVAMRgI0gY3+zJ8t74zNmrn6pR87ZU3JQ9/M5SLlTziV76P2TiqDfj1ZZukg9UN4b9Z+RA7FlWoI4/rvctshBW5bHc6A3rinLCY9MSbfUFmk7dOKSbakMPnbbg+mw/LyhzHT9Ww4m3libOfrb3IbeAoEROP55XtguApgx4zXui+BklG+ttGSavxawLdvb2+fmC8/XlsIhZhpvef3d6T15IbzL84J43155yeq2v+Qg6PrX3pld+k5xUV1c23hrTnkRAdKYiRx9iaD0tc8HZPdf8YX6ox/xPpQl+nZVbkO9RJA1ZiyX5ezcpkm19yeO9wyo/yo/rxzHHXMAvizx3kXg/zW5v7Ho3M55EbUINJflXTnQ++6b7ysCw3fn9zDGoizxbkRQeGofQdqXzPdCYP2HeeG4da65o3jO63P6h8GOTfksnwQIECBAgAABAgQIECBAgACBpgjMkWNSXTm6+0JErSktH+V2nnrqqWmnnXZKU6b0HkhbaKGF0o477piOOuqoXp/8u9/9Lr373e8uzm2++ebpoosu6vW6+sHtFl8oB85eCGDVzz204Wr13bbtCJrGjNi+ytY5oLVBTlkQgdXeyj4rLJE2yUG1N+cgYG8l0kEcnhcqG2yJXLR75xyv9Zmbce+GC8ybvpfTJqxdm1EZi3xtl4N4Pa8tn/XlHCi+Kl8Tgc3eSiyedvlLVk7vzcHQyBnbWzlu9WXTNoss0Nup4tgVOYC5fb6/rzZEsDpmI0egOAKrMeu5HhCPSpbPOWy/nvPXxqJqQymRB/cjOQhd1heL5e261CLpC8stmubJM1w/mRdji8XwouyQx+HAHDiupxro61mRw/jZ/Nf45hz87tmvCKB+I9fz0vxORDk323789gdnui7OxaJ856y9YjHzuq9381M5vcPHl1kkbZZnY/d8VtQR5eJ1V0ovmnuu4r04Lgd7yxJpIfbKtpvlXwrELxG+cOfDxYzuteadO+21wuLFLyaifX2VC9dZqW3hwLgu2hCzc+tB+kjXETO7FQIECBAgQIAAAQIECBAgQIDAeBZY6p+3jKh5Arsj4nvh5ltuuSXdf//9aZNNNkkTJkx44UQfWw+/YvU+zjTz8F15hmfMEo5AZOTgXSLn1W1yiRmvc6auNE9OXxApG+58blpOsZHSMnPNmZbNgd0XEisMrZeRvuCOZ6cXM6MnzjNhphQVkXpgkTnnbEubMNATon2LTvhvix7M9z+Q025EW6P+xf/H4xBtuyfbLZfNei4YFzOLIyVHLPY2khK/mbo5z76enjfWmHeuNFctDcRI6nUvAQIECBAgQIAAAQIECBAgQGAsBQR2x1J3DOue3QK7Y0ilagIECBAgQIAAAQIECBAgQIAAAQKzncBIArvdeVLicCceznaQOkSAAAECBAgQIECAAAECBAgQIECAAIEmCHTlbywL7DZhpLSRAAECBAgQIECAAAECBAgQIECAAAECzwsI7HoVCBAgQIAAAQIECBAgQIAAAQIECBAg0EABM3YbOGiaTIAAAQIECBAgQIAAAQIECBAgQIBAZwsI7Hb2+Os9AQIECBAgQIAAAQIECBAgQIAAAQINFBDYbeCgaTIBAgQIECBAgAABAgQIECBAgAABAp0t0NXKpbMJ9J4AAQIECBAgQIAAAQIECBAgQIAAAQLNEjBjt1njpbUECBAgQIAAAQIECBAgQIAAAQIECBBIArteAgIECBAgQIAAAQIECBAgQIAAAQIECDRIIJIwCOw2aMA0lQABAgQIECBAgAABAgQIECBAgAABAl1dXQK7XgMCBAgQIECAAAECBAgQIECAAAECBAg0TcCM3aaN2GzY3ltuuWU27NXYdum+++5Lzz333Ng+ZDatfXawu/nmm9Mdd9wxm46QbhEgQIAAAQIECBAgQIAAAQIDCXR3d5uxWyLdfffdac8990xbbbVVWmaZZdKGG26YPvKRj6SzzjqrvMTnKAlEQPKSSy5J++23X1prrbXSGmusMUo1d0Y1X/rSl9IKK6yQVlpppSQoPrQxb6rdtGnTir8zX/va14q/M2uuuWY6+eST++z81KlT09Zbb53iaxn77rtvn9c5QYAAAQIECBAgQIAAAQIECDRTYI455khdOdFuq5nNH71WH3LIIUVQt68aP/jBD6ajjjoqLbDAAn1d4vggBa6//vq07rrrznS113Amkl4PzJgxI02YMKE6d9BBB6W999672rfRt0BT7SZNmpQmTpyYpkyZ0ta5gw8+OO2xxx5tx8qd+IXUm970pnI3Pfroo2nxxRev9m0QIECAAAECBAgQIECAAAECzRfo+FQMxx13XFtQN2bC9SxxzV577dXzsP1hCKyzzjrpySefTL/85S+ruxdaaKFq20b/AnPOOWfabLPNqos22WSTattG/wJNtVtsscXSY489VszOXn/99fvv5PNnr7766rbrHnroobZ9OwQIECBAgAABAgQIECBAgECzBWKSZEcHduNr7DvttFMxiieccEJ69tln04033pjia8/HHHNM2+gefvjh6fLLL287Zmd4AjHzedtttx3eze4q0oMcf/zx6YorrihShyAZvEDMZG2iXczSXm211dKWW245qM5GELte4t82hQABAgQIECBAgAABAgQIEJi9BF74Tvfs1a9B9ebEE08srrv22mvTeuutV90TQZTIr7vUUkult7/97dXxCy+8MG200UbVvo3hC8w777zVzfPNN1+1bWNggZjhvOOOOw58oStmEmi63aKLLjpTn3o7sPTSS7cd7rnfdtIOAQIECBAgQIAAAQIECBAg0DiBWFeno2fs/uIXv0iRo7Qe1K2P4nbbbZc233zz6lAEgBUCBAiMd4HIyVsvsSCkQoAAAQIECBAgQIAAAQIECMxeAh0b2L3rrruKXK+f+MQn+h3RTTfdtN/zTTo5ffr0dPfddxc/Q1ms7JlnnmnrZixC9dRTT7UdG8xO5NZ9+umnB3PpsK6JFBpPPPHEsO4dzk299aXnAlf91TvS+6Pugb5iP1pjN3Xq1GGNeX/9j3PxHkb+10iLEu/nYMussBtsW0Zy3XD7P9AzV1555eqSVVddNcVKmQoBAgQIECBAgAABAgQIECAwewl07H/tR+DjwQcfHHCl+IUXXrga8b5m9lYXjNON8847L8UiW3PNNVeKfsfPIosskt7ylrekO++8c6ZWR7Dpn//8Z/ra175W5PXcc889i2siFcUnP/nJtPzyy6fIk/umN70pXXLJJTPdXz9w8803F2ktIj9ofA1+/vnnT1tssUU69dRT65cNe/uBBx5IX/7yl9OrX/3qNPfccxf9ijF7z3vek6688sqq3jPPPDOtu+66bT8xW7ssvZ3fcMMNU3d3d3lJ8Xnbbbel73//+4Xny172suJY5GX+6le/mtZaa60Uz477jj322Lb7yp2R3h/1xC8lvvOd7xTPO/jgg8uqi8/RHLuw3XnnnYt3YMEFFyzGPPr2uc99LsWCgv/6179SBHwjmB5B9aGUMHvve99bBBxjNukaa6xRvJ/xnsb72lsZa7t4Zoz3RRddVLyz5SzXyZMnp0MOOaR43+NrDiuttFL6/Oc/X/S9bOdf//rXIm1L3BPvwNve9rb029/+tjw90+dw+j9TJf0ciDaWJWwVAgQIECBAgAABAgQIECBAYDYUyIEgpR+B97///a087MXPOeec08+V4/PUt771rar9v/rVr1qPPvpo64YbbmhtttlmxfGce7OVZ0tWjf/LX/7SimNln+MzB3Nbu+++e9ux8nwO1rbuuOOO6v76xrnnntuK83FtDg63zj///FbUv80227TVteKKK9ZvG/T2BRdcULX1wAMPbMXzfvazn7XVnRfKKurLs4xb11xzTWuDDTaozn/0ox+tnpVnvhYuu+66a3U+2p1nkRbX3Hfffa3111+/7dyaa67Zynma246VLvF5xhlnVPWP9P6o6Cc/+Uk1buVzDjjggOoZozl2l156aTV2e+21V2G777779tnXvLhg1Y6BNmLcyvbvttturRyobt17772tz372s9XxP/7xj1U1s8Iuz0Bv7b333q14F8u2xWcO2FbvWP14bOdULa0c0G5rd89revs3Y6j9ryDyRn0MclC/fmqm7bIvH/vYx2Y65wABAgQIECBAgAABAgQIECDQfIH4KrTSj0D+GnMR6ImgXhnk6+fycXXq+uuvr4JU2267bVvbcr7g6lwE1Mry8MMPtyIYWva7Hqj64he/2Lr44ouLn/r5eoC0rCfPuqzqj2BrvUSQtR7cHU5g96yzzirqj8Dx5ZdfXq++td9++1XPjvbnr+1X5/Ns2+pcb+2OIGO9z+WYP/fcc60//elPrde//vVt5+Pad73rXa3T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QIAAAQIECBDoRIHOnJLYiSOtzwQGIfCBD3ygCOrm1AIDBnWjupjVnL/qL6g7CFuXECBAgAABAgQIECBAgAABAgRGU0BgdzQ11UWgwQJ5cbeU8y4XPYjUHY8++mi/vbnkkkvSzjvvnHbaaad+r3OSAAECBAgQIECAAAECBAgQIEBg9AWkYhh9UzUSaKzAWmutVeRDjg5E7twI3Ebe4jXWWCMtscQSRbD31ltvTSeeeGK6+OKL05577pm++c1vzpQjt7EAGk6AAAECBAgQIECAAAECBAgQaIiAwG5DBkozCcwKgeuuuy699rWvLRZL6+95Eezdf//90/ve977+LnOOAAECBAgQIECAAAECBAgQIEBgjAQEdscIVrUEmirw9NNPp5NOOinFwmgxO/emm25Kq666ajFrN2b0xmJpm266aerq6mpqF7WbAAECBAgQIECAAAECBAgQINBogVarlQR2Gz2EGk+AAAECBAgQIECAAAECBAgQIECAQCcKWDytE0ddnwkQIECAAAECBAgQIECAAAECBAgQaLSAwG6jh0/jCRAgQIAAAQIECBAgQIAAAQIECBDoNIHu7m6pGDpt0PWXAAECBAgQIECAAAECBAgQIECAAIHmC5ix2/wx1AMCBAgQIECAAAECBAgQIECAAAECBDpMQGC3wwZcdwkQIECAAAECBAgQIECAAAECBAgQaLZAq9VKArvNHkOtJ0CAAAECBAgQIECAAAECBAgQIECgAwUEdjtw0HWZAAECBAgQIECAAAECBAgQIECAAIHmCnR1dZmx29zh03ICBAgQIECAAAECBAgQIECAAAECBDpVwIzdTh15/SZAgAABAgQIECBAgAABAgQIECBAoLECAruNHToNJ0CAAAECBAgQIECAAAECBAgQIECgUwUEdjt15PWbAAECBAgQIECAAAECBAgQIECAAIHGCgjsNnboNJwAAQIECBAgQIAAAQIECBAgQIAAgU4UmDFjRupq5dKJnddnAgQIECBAgAABAgQIECBAgAABAgQINFXAjN2mjpx2EyBAgAABAgQIECBAgAABAgQIECDQsQICux079DpOgAABAgQIECBAgAABAgQIECBAgEBTBQR2mzpy2k2AAAECBAgQIECAAAECBAgQIECAQMcKCOx27NDrOAECBAgQIECAAAECBAgQIECAAAECTRSIZdMEdps4ctpMgAABAgQIECBAgAABAgQIECBAgEDHCkRgtyv/0epYAR0nQIAAAQIECBAgQIAAAQIECBAgQIBAAwXM2G3goGkyAQIECBAgQIAAAQIECBAgQIAAAQKdLSCw29njr/cECBAgQIAAAQIECBAgQIAAAQIECDRQQGC3gYOmyQQIECBAgAABAgQIECBAgAABAgQIdK5Ad3e3xdM6d/j1nAABAgQIECBAgAABAgQIECBAgACBJgp0dXUJ7DZx4LSZAAECBAgQIECAAAECBAgQIECAAIHOFRDY7dyx13MCBAgQIECAAAECBAgQIECAAAECBBosIMdugwdP0wkQIECAAAECBAgQIECAAAECBAgQ6EwBgd3OHHe9JkCAAAECBAgQIECAAAECBAgQIECgwQICuw0ePE0nQIAAAQIECBAgQIAAAQIECBAgQKAzBQR2O3Pc9ZoAAQIECBAgQIAAAQIECBAgQIAAgQYLCOw2ePA0nQABAgQIECBAgAABAgQIECBAgACBzhQQ2O3McddrAgQIECBAgAABAgQIECBAgAABAgQaKtBqtZLAbkMHT7MJECBAgAABAgQIECBAgAABAgQIEOhMga6uLoHdzhx6vSZAgAABAgQIECBAgAABAgQIECBAoMkCZuw2efS0nQABAgQIECBAgAABAgQIECBAgACBjhPo7u5OXTkfQ6vjeq7DBAgQIECAAAECBAgQIECAAAECBAgQaLCAGbsNHjxNJ0CAAAECBAgQIECAAAECBAgQIECgMwUEdjtz3PWaAAECBAgQIECAAAECBAgQIECAAIGGCkQSBoHdhg6eZhMgQIAAAQIECBAgQIAAAQIECBAg0LkCArudO/Z6ToAAAQIECBAgQIAAAQIECBAgQIBAAwW6urrM2G3guGkyAQIECBAgQIAAAQIECBAgQIAAAQIdLmDGboe/ALpPgAABAgQIECBAgAABAgQIECBAgEDzBAR2mzdmWkyAAAECBAgQIECAAAECBAgQIECAQIcLCOx2+Aug+wQIECBAgAABAgQIECBAgAABAgQINE9AYLd5Y6bFBAgQIECAAAECBAgQIECAAAECBAh0sMCMGTNSVyuXDjbQdQIECBAgQIAAAQIECBAgQIAAAQIECDROwIzdxg2ZBhMgQIAAAQIECBAgQIAAAQIECBAg0OkCArud/gboPwECBAgQIECAAAECBAgQIECAAAECjRMQ2G3ckGkwAQIECBAgQIAAAQIECBAgQIAAAQKdLiCw2+lvgP4TIECAAAECBAgQIECAAAECBAgQINAogVg2TWC3UUOmsQQIECBAgAABAgQIECBAgAABAgQIdLpABHa78h+tTofQfwIECBAgQIAAAQIECBAgQIAAAQIECDRJwIzdJo2WthIgQIAAAQIECBAgQIAAAQIECBAgQCALCOx6DQgQIECAAAECBAgQIECAAAECBAgQINAwAYHdhg2Y5hIgQIAAAQIECBAgQIAAAQIECBAg0NkC3d3dZux29iug9wQIECBAgAABAgQIECBAgAABAgQINE2gq6tLYLdpg6a9BAgQIECAAAECBAgQIECAAAECBAh0toDAbmePv94TIECAAAECBAgQIECAAAECBAgQINBQATl2Gzpwmk2AAAECBAgQIECAAAECBAgQIECAQOcKCOx27tjrOQECBAgQIECAAAECBAgQIECAAAECDRUQ2G3owGk2AQIECBAgQIAAAQIECBAgQIAAAQKdKyCw27ljr+cECBAgQIAAAQIECBAgQIAAAQIECDRUQGC3oQOn2QQIECBAgAABAgQIECBAgAABAgQIdK6AwG7njr2eEyBAgAABAgQIECBAgAABAgQIECDQQIFWq5UEdhs4cJpMgAABAgQIECBAgAABAgQIECBAgEDnCnR1dQnsdu7w6zkBAgQIECBAgAABAgQIECBAgAABAk0VMGO3qSOn3QQIECBAgAABAgQIECBAgAABAgQIdKRAd3d36sr5GFod2XudJkCAAAECBAgQIECAAAECBAgQIECAQEMFzNht6MBpNgECBAgQIECAAAECBAgQIECAAAECnSsgsNu5Y6/nBAgQIECAAAECBAgQIECAAAECBAg0UCCSMAjsNnDgNJkAAQIECBAgQIAAAQIECBAgQIAAgc4WENjt7PHXewIECBAgQIAAAQIECBAgQIAAAQIEGibQ1dVlxm7DxkxzCRAgQIAAAQIECBAgQIAAAQIECBAgILDrHSBAgAABAgQIECBAgAABAgQIECBAgEDTBKRiaNqIaS8BAgQIECBAgAABAgQIECBAgAABAh0vILDb8a8AAAIECBAgQIAAAQIECBAgQIAAAQIEmiYgsNu0EdNeAgQIECBAgAABAgQIECBAgAABAgQ6WmDGjBmpq5VLRyvoPAECBAgQIECAAAECBAgQIECAAAECBBomYMZuwwZMcwkQIECAAAECBAgQIECAAAECBAgQICCw6x0gQIAAAQIECBAgQIAAAQIECBAgQIBAwwQEdhs2YJpLgAABAgQIECBAgAABAgQIECBAgAABgV3vAAECBAgQIECAAAECBAgQIECAAAECBBokEMumCew2aMA0lQABAgQIECBAgAABAgQIECBAgAABAhHY7cp/tFAQIECAAAECBAgQIECAAAECBAgQIECAQHMEzNhtzlhpKQECBAgQIECAAAECBAgQIECAAAECBAoBgV0vAgECBAgQIECAAAECBAgQIECAAAECBBomILDbsAHTXAIECBAgQIAAAQIECBAgQIAAAQIEOlugu7vb4mmd/QroPQECBAgQIECAAAECBAgQIECAAAECTRPo6uoS2G3aoGkvAQIECBAgQIAAAQIECBAgQIAAAQKdLSCw29njr/cECBAgQIAAAQIECBAgQIAAAQIECDRUQI7dhg6cZhMgQIAAAQIECBAgQIAAAQIECBAg0LkCArudO/Z6ToAAAQIECBAgQIAAAQIECBAgQIBAQwUEdhs6cJpNgAABAgQIECBAgAABAgQIECBAgEDnCgjsdu7Y6zkBAgQIECBAgAABAgQIECBAgAABAg0VENht6MBpNgECBAgQIECAAAECBAgQIECAAAECnSsgsNu5Y6/nBAgQIECAAAECBAgQIECAAAECBAg0UKDVaiWB3QYOnCYTIECAAAECBAgQIECAAAECBAgQINC5Al1dXQK7nTv8ek6AAAECBAgQIECAAAECBAgQIECAQFMFzNht6shpNwECBAgQIECAAAECBAgQIECAAAECHSnQ3d2dunI+hlZH9l6nCRAgQIAAAQIECBAgQIAAAQIECBAg0FABM3YbOnCaTYAAAQIECBAgQIAAAQIECBAgQIBA5woI7Hbu2Os5AQIECBAgQIAAAQIECBAgQIAAAQINFIgkDAK7DRw4TSZAgAABAgQIECBAgAABAgQIECBAoLMFBHY7e/z1ngABAgQIECBAgAABAgQIECBAgACBhgl0dXWZsduwMdNcAgQIECBAgAABAgQIECBAgAABAgQICOx6BwgQIECAAAECBAgQIECAAAECBAgQINA0AakYmjZi2kuAAAECBAgQIECAAAECBAgQIECAQMcLCOx2/CsAgAABAgQIECBAgAABAgQIECBAgACBpgkI7DZtxLSXAAECBAgQIECAAAECBAgQIECAAIGOFpgxY0bqauXS0Qo6T4AAAQIECBAgQIAAAQIECBAgQIAAgYYJmLHbsAHTXAIECBAgQIAAAQIECBAgQIAAAQIECAjsegcIECBAgAABAgQIECBAgAABAgQIECDQMAGB3YYNmOYSIECAAAECBAgQIECAAAECBAgQIEBAYNc7QIAAAQIECBAgQIAAAQIECBAgQIAAgQYJxLJpArsNGjBNJUCAAAECBAgQIECAAAECBAgQIECAQAR2u/IfLRQECBAgQIAAAQIECBAgQIAAAQIECBAg0BwBM3abM1ZaSoAAAQIECBAgQIAAAQIECBAgQIAAgUJAYNeLQIAAAQIECBAgQIAAAQIECBAgQIAAgYYJCOw2bMA0lwABAgQIECBAgAABAgQIECBAgACBzhbo7u62eFpnvwJ6T4AAAQIECBAgQIAAAQIECBAgQIBA0wS6uroEdps2aNpLgAABAgQIECBAgAABAgQIECBAgEBnCwjsdvb46z0BAgQIECBAgAABAgQIECBAgAABAg0VkGO3oQOn2QQIECBAgAABAgQIECBAgAABAgQIdK6AwG7njr2eEyBAgAABAgQIECBAgAABAgQIECDQUAGB3YYOnGYTIECAAAECBAgQIECAAAECBAgQINC5AgK7nTv2ek6AAAECBAgQIECAAAECBAgQIECAQEMFBHYbOnCaTYAAAQIECBAgQIAAAQIECBAgQIBA5woI7Hbu2Os5AQIECBAgQIAAAQIECBAgQIAAAQINFGi1Wklgt4EDp8kECBAgQIAAAQIECBAgQIAAAQIECHSuQFdXl8Bu5w6/nhMgQIAAAQIECBAgQIAAAQIECBAg0FQBM3abOnLaTYAAAQIECBAgQIAAAQIECBAgQIBARwp0d3enrpyPodWRvddpAgQIECBAgAABAgQIECBAgAABAgQINFTAjN2GDpxmEyBAgAABAgQIECBAgAABAgQIECDQuQICu5079npOgAABAgQIECBAgAABAgQIECBAgEADBSIJg8BuAwdOkwkQIECAAAECBAgQIECAAAECBAgQ6GwBgd3OHn+9J0CAAAECBAgQIECAAAECBAgQIECgYQJdXV1m7DZszDSXAAECBAgQIECAAAECBAgQIECAAAECArveAQIECBAgQIAAAQIECBAgQIAAAQIECDRNQCqGpo2Y9hIgQIAAAQIECBAgQIAAAQIECBAg0PECArsd/woAIECAAAECBAgQIECAAAECBAgQIECgaQICu00bMe0lQIAAAQIECBAgQIAAAQIECBAgQKCjBWbMmJG6Wrl0tILOEyBAgAABAgQIECBAgAABAgQIECBAoGECZuw2bMA0lwABAgQIECBAgAABAgQIECBAgAABAgK73gECBAgQIECAAAECBAgQIECAAAECBAg0TEBgt2EDprkECBAgQIAAAQIECBAgQIAAAQIECBCYcM0111AgQIAAAQIECBAgQIAAAQIECBAgQIAAgYYITJgwIZmx25DB0kwCBAgQIECAAAECBAgQIECAAAECBAiEQKvVSl1Tpkxp4SBAgAABAgQIECBAgAABAgQIECBAgACBZgjMMcccZuw2Y6i0kgABAgQIECBAgAABAgQIECBAgAABAi8ISMXwgoUtAgQIECBAgAABAgQIECBAgAABAgQIjHuBrq4uM3bH/ShpIAECBAgQIECAAAECBAgQIECAAAECBGoC06dPF9itedgkQIAAAQIECBAgQIAAAQIECBAgQIDAuBeQY3fcD5EGEiBAgAABAgQIECBAgAABAgQIECBAoF1AYLfdwx4BAgQIECBAgAABAgQIECBAgAABAgTGvUCr1ZKKYdyPkgYSIECAAAECBAgQIECAAAECBAgQIECgh8AcPfbtEiBAgAABAgQIECBAgAABAgQIECBAgMA4Fujq6jJjdxyPj6YRIECAAAECBAgQIECAAAECBAgQIEBgJoHu7u40YaajDvQrcPvtt6fbbrstnX/++f1eN9STq6yyStp6661TfI5FufHGG4tq11prrbGoXp0ECBAgQIAAAQIECBAgQIAAAQL/IwFxn/8R/P/4sVIxDHEA/vKXv4x6UDeaUAaMh9gclxMgQIAAAQIECBAgQIAAAQIECBAg0IECZuwOcdAjABvloIMOGuKd/V/+1a9+tQgYx6xdhQABAgQIECBAgAABAgQIECBAgAABAn0JtFotOXb7wnGcAAECBAgQIECAAAECBAgQIECAAAEC41EgFk8b1Rm7o52moMw3+5GPfGQ8+mkTAQIECBAgQIAAAQIECBAgQIAAAQK9CJRxwojvlWtL9XKZQ8MUmGOOOUYvsPvTn/60yBM7zLb0eluZ9iBeBCkKeiVy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nBPv0/hKAatGmja+ZOeXYmYR6lJFnHdp5iK/vJErISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh0JgRWLVqlZPGbmMuAUq7EBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJVh0CTJk2ksVt1uaYICwEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASHQ6BGQKYZGXwQEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBAC1YTAt99+K43dasowxVUICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgUwwqA0JACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICIEqQ6Bp06bS2K2yPFN0hYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBBo5AisXLlSxG4jLwNKvhAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACVYaANHarLMMUXSEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIA2T1MZEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACFQZAhC7zasszopuHSOw52/n1/Eb9bqGiMALl3ZuiMlSmoSAEBACQkAICAEhIASEgBAQAkJACAgBIVBvCDSfOHFivb1cL64GBNauhkgqjhWOgOqZCs8gRU8ICAEhIASEgBAQAkJACAgBISAEhIAQqCoEWrRooc3TqirHFFkhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBIRACoEmKXsM3woJISAEhIAQEAJCQAgIASEgBCoTgVGjRvmI9erVqzIjqFgJASEgBISAEBACQkAI1DkCTZs2lcZunaOuFwoBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIARKQABd3aYl+JdXISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBCoBwRE7NYD6HqlEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCoFgEVq1aJY3dYsGTPyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhEB9INCsWTMRu/UBvN4pBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQKBYB2dgtFjn5EwJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACNQjArKxW4/g69VCQAgI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IASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBLIgUOcau3FxWX+j9R2/5cuWe9u7cW6Kubfxdj1dh/U6uEVzFrkHTn3AsRnamhuu5YM68sYj3do91y4m2EQ/O/xoB/f6Xa+5JfOXuHuOv9u/r3mr5m6bY7dxu/10d7dBjw3cehuu57pu2DUxDD0QAkJACAgBISAEhIAQEAJxCGipfxwqlXRPphgqKTcUFyEgBISAEBACjQGBppWUyJatWrrNBm2WjlKTpk3S59GT8FnSZmctWrdwpzz4Y7fjKTu6tp3buuVLlru5E+b438qvV6SDNP8Wph3TDlInds/chs/sHBL5J8+c7TbZtY8ndXkfJO/yxV97J13W7yJS18DSUQgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAiBohCAo2zybUqK8i1PQkAICAEhIASEgBAQAkJACNQ6AqNGjfLv6NWrV62/Sy8QAkJACAgBISAEhIAQqA4EmjVr5ipKY7c6YFMshYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAvWHwMqVK0Xs1h/8erMQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkKgcASaNm0qYrdw2ORDCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhUH8IYF23ef29Xm8WAkJACAgBISAEhIAQEAJCoFQE2rVrV2oQ8i8EhIAQEAJCoNYQWLx4ca2FrYCFQGNGAGJXNnYbcwlQ2oWAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQqEoEROxWZbYp0kJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAINFYEmjRpIo3dxpr5SrcQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAtWLgDR2qzfvFHMhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBBohAtLYbYSZriQLASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBIVDdCGjztOrOP8VeCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICIFGioBMMTTSjFeyhYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBCoTgRWrVqlzdOqM+sUayEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEGisCzZo1E7FL5t938r3uN70vce8+9G7VlYXrd7vOx33Kq1MqMu4z3pnhPnztQ/flp1+m47fym5U+zmD+2ZRP0/er4WTBxwvScV++eHk1RFlxFAJCQAgIASEgBISAEBACQkAICAEhIASEgBBoYAhgY7d5A0tTUcn5Ztk33h+EY7XJ11997aO8qgLjPnfCHHfnUXf4+J35xFmufZf2/pyCZ7Jq5ffndq+Sj98G8f12VXXFvZJxVdyEgBAQAkJACAiB2kVgyZIlbvz48Xm/pE+fPq5Dhw5u+vTpbt68ea5Lly6ue/fu3v/s2bPdrFmzXOvWrV3//v3zDlMOhYAQEAJCQAgIASHQUBB48cUX3UsvveSTs/vuu7s99tijXpImYrdeYG8cL331jtd8Qnvv3Nt17de1cSRaqRQCQkAICAEhIASEQAUi8Omnn7qHHnoo75ideeaZnth9+eWXPSG8yy67pIndyZMnuyeffNJ17do1g9hduHCh4xkyZMiQvN8lh0JACAgBISAE6gKBFStWuGHDhqVfdcopp7htttkmfa2T4hC45ZZb3Pvvv1/Dc8uWLd2NN95Y475ulA+BJk2aSGO3fHAqpBABTBaMemz1h73z6buEj3QuBISAEBACQkAICAEhUI8IrLvuuq5NmzZZY9CqVausz+MezpkzJ00eb7XVVo7BhkQICAEhIASEQKUisHJl9a3arkQsv/lm9Sr4aNyS7kfd6bp4BBqtKYYZU2a4Vq1buXU3WLcGeiuWr3CzxsxyM1O2YZu2aOY23GJD133L1cvOajhO3WA5/idjP3GfTprrIDPX2rCT22Dg+q5Ln5ph4x/Q506Y62aP+8QtnLPIB9ml9zre/do91/bXcf9WrljpZr47080aPcs1adrEdd+qu+u2ebc4p27M22Ncr769XJt22TvssZ5z3FyyeImbNmGaGzBkQFaXb9z9hn++weYbuI232zir26ULl7qPRqbSNuYT126ddq7XDr1cp406Jfr5Zuk37uPRH6cw/9R9teCrFHZdfD51WLdDrB9MbMxMhT/vw3kpW7+LXMv2rRyYr9e3a9o8RJxH4jXz3RmpvJrt2qfC3mjIRq5ps6Y1nH615Cs3Y9IMt8mATVzzFlKCrwGQbggBISAEhIAQEAIVhcBBBx3kevfunVecdtttN699u8466+TlXo6EgBAQAkJACAiBxoUAfYqvv15tJpRJ3i+//H6PpcaFRN2ndtWqVY1HY3fJl0vcuHfHuemTpjvU7/tu0bcGsbvsy2XuzqPv8ORpmB27/XQ3t9tPdw9v+XM2BHv0gkfclP/W3Lhsp9N2dnuct4drliKHTb5e+rW7fuh1bsn8JXYr47jDj3Z0e/1yL9es+fd+cADB+PefPOimvjE1w/02x8YvGRj7zlhP7q7ZeU3Xb4t+bqNNNipJYwIyesbkGe6D9z5wX8z/woeVjdglfW/eu5rY3eWM7Nq6EOJ3/M/tbvmSzI3Ijrv9ONdnt00z0svFx6M+dv849yG34KMFNZ4dfu3hbvODBmXch9Al/CQ5LOVnUMQPbrEPfP+P73eLviPfzf/Qs3ez0/RxyaIl7r033nPvv/m+69q9qxuw1QC39nrJJH3ao06EgBAQAkJACAgBIVDhCPTo0aPCY6joCQEhIASEgBAQAvWJwH777ef4If/617+8uab6jE9jenezZs0aNrELITlt0jQ3/r3xbuHnCzPytl37dhnXXLxwzfP+3s6n7+xWfr3SvfvQu55wfPnGl92ggwe7Tt2/1yJl07Kbf3iTJ2lbtm3ptj1hu5S27lpeE3fEX0e4V2/7ryd1IXdNVq1Y5d237dzWDdx/oOuc0tBt0bJFSuN3lsPP63e95lYs/8Yd8Nsfmhd//Of5/0yTujudupPruMGabvyzH3g/GQ6/u1ij1Rpu+dLlnoR9/YXX3Vsvv+V69Onh+m/Z37XrWDPdcWFwb/HCxW7cyNVkeLhEgfCzCWlBOm+8ttt0j82yOXX/OO8f3t1OB+/k5k6c68Y+Pda7f+ryp1zvXTbJ0JBFy/m2w271z8F666O3di3btXITX57oJqV+//zZP12bFLa9d/peA2V5iqxH1t1sPddnaB+fh2jwTh4+2U18aYJ7OOWnWfOmbkAqP0zI2zuOvMPnPXm1/Unbu6Ypsv3tv41w//nTy+YsfVyj5Rpei9prb8/4xH2S+qER3mdgH7fp5pu6Fmu0SLvViRAQAkJACAgBISAEqgmBV155xX388cdus802c1tuuWVs1KdMmeJGjBjhsLFr8re//c0rA2yxxRaub9++dtstXbrUvfrqq35TtpkzZ/pN2dD06dcvpYyw0UZpd5y8+eabburUqW7gwIFuwIAB7r333nOTJk3yv3POOcd17Ngxw70uhIAQEAJCQAgUisAXX3zhRo8e7TcF7datm9t2223dGmvEcx5sRIot+enTp7vly5f7dmuTTTZxnTt3znjtZ5995thoFGnaNMU3pNqwUL766itH22lCO5jLRJK5revjJ5984qZNm+Y++ugjBy+09tpre/v6YFUuWbZsmRs5cqRjP4BFixa5du3aubXWWsuxkev6669fkqJiueJYyeE0yHXjXy780o17J0VITp7uUEs2gWzr3b+3J9tatmpptzOOw54c5klAbu76k6Huul2u9QTfxBcnuO1P3iHt9tXbX02Tumc9Ncyt1W2t755tlTLFsIF79MJH3fCb/uO2PGLL9LMWrVu4o285JqWJ2idDKxc3bTq19aQhpOgPLtjbrdFmdUUy+4PZKRJykg/7yD8d6frvu7pCgNT862l/TT9LRyx1ctjJh7nZH832hPbcWXP9x/fh+A8dvw5rdfBavBv32diTkaE/ziEnp06c6sa/P94tWrDaVAT3sZGG6Qo0nbtumLwRGpq3r9+5etO0XVIEeZzpAsIzgaA9/ZHTXauUeQRkm+O3dXcdfafXyJ0zfo5bf8D6/j4kPWQvsvG2G7vj7jjegSey9TFbu0d++Yh7/5H33FO/fcqd/e+z0+9dp3cX9+OHTq1hTgNt5zuOvN2bt3jrgbcyiN2R/xyZ1iA+7Z+ne8Ke9ww+ZLC7af8/19C47tipozvytCPd1AlT3cTRE/0kwrKly9zoEaO95jS49d+qfw0NccKUCAEhIASEgBAQAkKgkhH48MMP/eZpHTp0SCR2P//88xqbpowaNcona8MNN0wnDyL3/vvvzyCAGSjyY5O2Y445xg0ePDjtnoEzm7FgE/iFF15wzz+/WgkDB/QNJUJACAgBISAEQGDGjBnu0UcfTYMBObv99tunr5NO8HfPPfdkPH766afdpZde6qK25iF/b7vtNhdnN/bAAw/0GqtmWx7SNgz38ssv922Zveitt95yDz74oF26q6++uuKIXYhrJmmZZI3KI4884gYNGuTOOuus6KOCr2nnb7311gzuLgxk7733doceemh4S+cBAg1q8zQIyQ8npDqeKe1ciF0TZke69ezm+g3u5zp1+V7j1p6HR0hTNDtNWnds7UnYMU+OyViST0fSNDf3/tU+aeLW/A08cHP39O+e9uTgtDemubWOWE36YmKh717fayyYe4799+mfDnPxvMVp7eAJL4z3zjqslyJk9+6f9gJhivau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BoFZmz7XR6vICSESAnBe91S9enU9nXnU+0Zytatlbdu2lb179wqS233yySfSokULFY4BIrcWxT2xNojnELaRcA1Crk6QBk9pHRvZE2EY8nqfcrJXJMHTSQHRLzo6Wrp3756TIdiWBEiABEiABAo9AXwJTmG30N9GboAESIAESIAESIAESIAEbAQQe1UbhNusLCUlJavqLOus82iROLMOOi6srreKltprVR+tdZcuXVJdrHPlZk9BQUF6avOo59Pis1lRgCfNmzeX1atXS1xcnIotjPjCMCS4u/766wXCr5VHXpYG4faHH35QntrJycnKOxcetrDAwECxxuXN7Tx5vU85mffee+9VIUUgJs+YMUOFlEDs5Oeff17Kli2bk6HYlgRIgARIgAQKNQEKu4X69nHxJEACJEACJEACJEACJJBBAI/wwxo0aCAQv/LL9DwYH/F1q1Spkl9TiZ4rt3uyhqPIt0XmYmB4KSO2LjxpIbIibi48oeFVjfACKB88eHAuRnbuAhH5p59+Up7aSGoHoXfVqlWqIcJmeIJRXu+T86ozL0E4DbzgjQzv648++kiFIIG46wnv48xnZg0JkAAJkAAJeA8B/P6msOs994MrIQESIAESIAESIAESIIE8EYDAikfUT506letxrF6imXn1WoVceNFar3M9cSYdPbGnTIZ2q1jH+s2uMURZxH7VVr58eenbt6++zPSIMAk6BvDBgwflxx9/VOEnkNhs4MCBHvHahYdy69atVTI7hGNAeIrz58+rNV1zzTWZrk1XaOFXh/LQ5dbj1bpPYAcvZ6zt+PHj1iXxnARIgARIgASKPAEmTyvyt5gbJAESIAESIAESIAESKC4EatasqbaKR9QRQzU3Zn2UHWECXBm8JXU8XO356aqdJ8o8saecrgNCpha43Y3De/bsWRUSAIIsXmvXrs3ptEpwveGGG1Q/hLiwhjewDla6dGnzMiux1WxknHTs2FFd4n0xbdo0dV6rVi0JDg62NnN5DpEaltn7AXVX4z5hXphOvqfDd9hK+ZMESIAESIAEij4BCrs5uMenTp2Wmwbdrl6Tp0w3ey5ZtsIs37otbxmGzUF5QgIkQAIkQAIkQAIkQAI5JNCuXTsVMxXdJkyYICdOnLAbAeLj33//LXPmzLErt15AsNXJxRYtWmQm2LK2wfmNN96oivD4O7xArQYv1+3bt8v48ePFXWHU2t967ok9Wcdz91wL3P/880+uRfKs5po5c6Zs3bpVhRDQ7cBNC+W4DyEhIbrK7mgtx73U3rd2jRwu4FGrPau16N+hQweHVq4vtWgLERnvCYjOjna17pPjOnhNAiRAAiRAAsWJAEMx5OBu4wPMgYOJqof18bZzxmNMutzdb8xzMC2bkgAJkAAJkAAJkAAJkIBbBCAGDhkyRL755hs5fPiwjBkzRnkzIkEWRF79GTYqKirL8RBCYMqUKcpj9L333jO9c4cOHSrNmjVTfRGbFfFaEfrhl19+kdmzZ0vlypWV6Ie5tfjnmDwty4ldVHpqTy6GzrIIoidCKyCp2VtvvaUe90dcXCQau/XWW7Ps607l5s2bZenSpYotBFeMjbl0QjcI5yhzZfCYrlOnjuzZs0cWL16sXkgSBy/jnj17SmbhFRB/dvp0m4MKuOp76WoOaxneL3/88Ycg7Mbvv/+uXuiPGLeIsQy7WvcJc2tOSAxHIwESIAESIIHiRIAeu8XpbnOvJEACJEACJEACJEACRZ5Ao0aNZNSoUVK1alW1VzzOv3fvXlPUrVGjhrRo0SJLDq1atVICsfYMhUirX7ojwhWMHDlSrrvuOiUowmsUwuSBAwdUW4htGAeiMkzHadUhDlCmz/URZdp0e1znZk+6vz7qcXHUZa7m1e26dOkigwYNUuIlyuDAAWEzsziuekzdP7tjw4YNlRiqnEcMZghzAFEXa7r22msFwnlWdueddyoRV/OFNzbWl5WHdHR0tDlky5YtBbF33TGs6bHHHlP3QYuoWLejkJqb++TO/Nm10e/T2NhY8wuF7PqwngRIgARIgAQKOwGEIPIxHve5XNg3UlDrT0o6Lr37DVLT3XfXMBlx/z3q/O+58+W5F19X5+M/HiutWmb9Qbmg1st5SIAESIAESIAESIAECj8BhDqAZedl62qnqampynMXYh9CC8DDEomm8sOQPAwiMsRCxGSF2JZTsdOddRXkntxZT17a4E8xCMXwpoZQini3uEdaPM3L2K76QvhEeAwYhNpq1aq5auaRsoK8Tzt27JCvvvpKrRuew/Acb9CggVx//fUe2QsHIQESIAESIAFvJcBQDN56Z7guEiABEiABEiABEiABEsgjAQiEYWFheRzFve4Qc3WSLfd65K5VQe4pdyt0vxeEbwi5eBWEIb4yDMJnfoq6mKMg7xNEXISuWLhwocBzOTExMd/EceyNRgIkQAIkQALeQoDCrrfcCa6DBEiABEiABEiABEiABEiABDxMYN++fUroXLt2rQqVgeF79Ojh4Vmu/nAIX4EXzDFExNVfHVdAAiRAAiRAAvlDgMJuDrj6lsgISVzS8H7Qhsd9tFnPdRmPJEACJEACJEACJEACJEACJHA1CMybN09iYmLMqdu0aSOIr1uUrXTp0kV5e9wbCZAACZAACZgEGGPXRMETEiABEiABEiABEiABEvA+AnmJset9u+GKCprAqlWrVPK8oKAgqVevnnoV9Bo4HwmQAAmQAAmQgOcJIFY/hV3Pc+WIJEACJEACJEACJEACJOAxAhR2PYaSA5EACZAACZAACZBAkSGQnp4uGbEFisy2uBESIAESIAESIAESIAESIAESIAESIAESIAESIAESKLoEfH19KewW3dvLnZEACZAACZAACZAACZAACZAACZAACZAACZAACRRVAvTYLap3lvsiARIgARIgARIgARIgARIgARIgARIgARIgARIosgQo7BbZW8uNkQAJkAAJkAAJkAAJkAAJkAAJkAAJmfiL+AAAQABJREFUkAAJkAAJFEUCjLFbFO8q90QCJEACJEACJEACJEACJEACJEACJEACJEACJFCkCfj4+DDGbpG+w9wcCZAACZAACZAACZAACZAACZAACZAACZAACZBAkSNAYbfI3VJuiARIgARIgARIgARIgARIgARIgARIgARIgARIoDgQYIzd4nCXuUcSIAESIAESIAESIAESIAESIAESIAESIAESIIEiRcCvSO2GmyEBEiABEiABEiABEiABEiABEiCBXBKYds+wXPZ03W3Q19+7rmApCZAACZAACXiAAD12PQCRQ5AACZAACZAACZAACZAACTgTuJScLH/Xr65e5/fGOTfwgpIVA69X60uYOskLVlN0lrD1hacU19gP3yk6myqCO7lp0O3SqkN3WbFqTRHcHbdEAiRAAkWfAD12i/495g5JgARIgARIgARIgARI4CoRuGzOezn9knnuTSeXks+r5aSnpXrTsgr9WtJTbTzTU1MK5V66bFqRp3X/0/yaPPUvqM7JxpcvsIsXLxbUlJyHBEiABEjAgwTosetBmByKBEiABEiABEiABEiABEiABEiABEiABEiABEiABAqCAIXdgqDMOUiABEiA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10ECJEACJEACJEACJJAHAr6+vsJQDHkAyK4kQAIkQAIkQAIkQAIk4M0EkpKS1PLKly9PUdebbxTXRgIkQAIkQAIkQAK5IEBhNxfQ2IUESIAESIAESIAESIAECgMBPKIHq1q1amFYLtdIAiRAAiRAAiRAAiTgJgEkyaWw6yYsNiMBEiABEiABEiABEiABEiABEiABEiABEiABEiABbyFAYddb7gTXQQIkQAIkQAIkQAIkQAIeJpCcnKxG9PHx8fDIHI4ESIAESIAESIAESOBqEsDnOwq7V/MOZDF3QKmMTMXWD+KBgaVVrzJlymTRm1UkQAIkQAIkQAIkQALFnUBqaqrs3btXYQgNDS3uOLh/EiABEiABEiABEihyBHyMeAyXi9yuuCESIAESIAESIAESIAESKCIENm7cqHYSFRXl1o5++eUX2bNnjxw5ckR0jN0RI0ZI7dq13erPRiRAAiRAAiRAAiRAAoWDgF/hWCZXSQIkQAIkQAIkQAIkQAIk4A6B2NhYJeqibXBwsPTs2ZOirjvg2IYESIAESIAESIAEChkBeuwWshvG5ZIACZAACZAACZAACRQvAjn12NVxdUuXtoXwKl60uFsSIAESIAESIAESKD4E6LFbfO41d0oCJEACJEACJEACJFAMCFDQLQY3mVskARIgARIgARIo9gQuXbrE5GnF/l1AACRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAoWKQIkSJSjsFqo7xsWSAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgEHAlxRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgAQKFwEKu4XrfnG1JEACJEACJEACJEACJEACJEACJEACJEACJEACJECPXb4HSIAESIAESIAESIAESIAESIAESIAESIAESIAESKAwEbh8+TKF3cJ0w7hWEiABEiABEiABEiABEiABEiABEiABEiABEiABEqCwy/cACZAACZAACZAACZAACZAACZAACZAACZAACZAACRQyAr6+vvTYLWT3jMslARIgARIgARIgARIgARIgARIgARIgARIgARIgAQq7fA+QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQGEj4FvYFsz1kgAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEBxJpCeni5+xRkA904CJEACJEACJEACJEAChYXAxo0bC8tSuU4SIAESIAESIAESIIF8JuDn58dQDPnMmMOTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgEcJIHkaPXY9ipSDkQAJkAAJkAAJkAAJkED+EGjcuHH+DMxRSYAESIAESIAESIAECh0BHx8feuwWurvGBZMACZAACZAACZAACZAACZAACZAACZAACZAACRRrAhR2i/Xt5+ZJgARIgARIgARIgARIgARIgARIgARIgARIgAQKKwHfwrpwrpsESIAESIAESIAESIAESIAESIAESIAESIAESIAEiiOB9PR0hmIojjeeeyYBEiABEiABEiABEiABEiABEiABEiABEiABEijcBOixW7jvH1dPAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRQDAn4FcM9e/2W0y+lC15W8/H1kRJ+JaxFPCcBEiABEiABEiABEiABlwQuXLggeDlacHCwINEGjQRIgARIgARIgAQ8SeDSpUuSnJzsNGTp0qWlRAnqWU5gPFBw+fJlobDrAZCeHmLhxwtl4UcL7IatHBkqI/8aaVfGCxIgARIgARIgARIgARJwReD999+XCRMmOFWtWrVKypUr51TuqiAxMVG6deumqhYtWiShoaGumnmkLDU1Vf7880/Zvn27+qPw4sWL0qdPH+ncubNHxucgJEACJEACJEAC+Utgw4YNMmXKFKdJbr/9domKinIqL+iC8+fPy8svv6ymffTRR6VGjRoFvQSPz+fr60th1+NUPTBghZoVpE77OmqkU4dOS1LcMQ+MyiFIgARIgARIgARIgASKCwGIt7169VLbhVi6f/9+CQsLc1vURccdO3ao/mXKlJHKlSur8/z68f3338vu3bvV8H5+fgLPYqyXRgIkQAIkQAKFicA333yjnpjBl5O1a9f2qqWfOHFCfvzxR7Wme+65R0qVKuXx9UVERKgxz5w5I8ePH1fn4eHhHp8nNwMmJCSY3fL7c405US5OcnKf8BQWPXZzATm/u0QPjBa8YJt/3yw//d/U/J6S45MACZAACZAACZAACRQhAg899JC5m9dee00mTZokLVu2NMvcOYFnC/o0atQoX8M3HDhwwBR1hw0bpuZzZ31sQwIkQAIkQALeRODs2bMSExOjllSyZElvWppay969eyUuLk7g5env7+/x9bVq1Urwgq1evVp+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hsfs4L6DZePijWYfavyi8Yvkk2s+NvsIw3DK1W1NunDJwtLlP11Mev7P8+T7+7+zRWGEe5j00ST55YXRpjzQn0ZHFlHbtXmXTP9muql2fI/jA1WPWX4kPGI2OB6IBEiABEiABEiABEiABEiABEiABEiABEiABGJIIMeLp4U71ozqvlABWAzrpc4vmubXfnudVGlaJdyuErI+RFqIu7BiZYsJxFO15he08Au5AO/dTjd3kt8G/iZr566RV7oONG0O7j1owiNou57P9hTE5VU76fKTZckfS2TppKUy5fMp5lXSWoDNuQCZ1vXaYhG15tYian9asXZhtdvWljJVy3hVjWlepDxiOkgejARIgARIgARIgARIgARIgARIgARIgARIgARiQAChXCPy2E1Lj6iZNO7WRLBAF7xM1dLS00wy0j61H92meowtNS2y8WqfOdnq/Dre1EnOvL+bPXcVdRE/9twnzpUeT/XIcphON3eWvoP7ScUjIRbQBuIwDILrzT/fIg0tD1ungW3fD/pJu+vaGyEYZSrqlq1VTi7/6AqpclxwIf34c4966Dbv1cLZfZ6mI+GhA061wlvklaWnFzCHLlDAt3WPA67zNBIgARIgARIgARIgARIgARIgARIgARIgARIIlcDBgwclxXLbPRxqA9bLOQGEntiybLPs2bFXyllCq9PbNljviMW7eelmQTgLLJIWqli9Y8MOI+yWrVVWCpcoHOwQdtncn+bIFzd9YUTouybeLfDijTeLlEek89i5c2ekTXO1XfHiXL0zVwGzcxIgARIgARKIAwIzZ/rWPWjUyP8H/TgYGodAAiRAAiRAAiRAAiSQhwTS8/DY+fLQEGTL1S4f9twLFC4glRoeXRwt1A5KVCgheIVjEz+caKo369U8LkVdDC5SHuFwYF0SIAESIAESIAESSFQC48ePl59++knS09OlTJky0q5dO2nRIn6exEpUrhw3CZAACZAACZAACcQLgdTUVKGwGy9nI4/HsWbOGkkvmCZzR8yV5ZOXm9Gc1PekPB4VD08CJEACJEACJEACJBAJgX379knBggVl//79snHjRhkyZIiULVtWatasGUl3bEMCJEACJEACJEACJBBnBGK+eFqczZ/DcRAY/fwoWTRukZ1zUr+TTcgHO4MJEiABEiABEiABEiCBhCHQpUsXwWv9+vUycOBAM+7ly5dT2E2YM8iBkgAJkAAJkAAJkEBwAlg8jR67wRnlm1Is4oaF1wqVKCQn9DhBOt7cKd/MnRMlARIgARIgARIggWQlULFiRdtzN9BCrsk6d86LBEiABEiABEiABJKdAIXdZD/DIc7vnEe7C140EiABEiABEiABEiCB5CGAUAx4wcqXD3+dh+QhwZmQAAmQAAmQAAmQQHIRyMzMlNTkmhJnQwIkQAIkQAIkQAIkQAIkoATWrFmjSalSpYqdZoIESIAESIAESIAESCDxCVDYTfxzyBmQAAmQAAmQAAmQAAmQgCeBVatWmXwspFa0aFHPOswkARIgARIgARIgARJITAIUdhPzvHHUJEACJEACJEACJEACJJAtgQ0bNpg6pUuXzrYuK5AACZAACZAACZAACSQOgcOHDzMUQ+KcLo6UBEiABEiABEiABEiABMIjUKhQIdMAAu/u3bvDa8zaJEACJEACJEACJEACcUsgNTWVwm7cnh0OjARIgARIgARIgARIgARySKBZs2aCL/2wp556Sl5//XWZOnVqDntlcxIgARIgARIgARIggbwmkJKSQmE3r08Cj08CJEACJEACJEACJEACuUWgQIECUqpUKdM9Vk5GzN0dO3bk1uHYLwmQAAmQAAmQAAmQQIwIHDp0SNJjdCwehgRIgARIgARIgARIgARIIIYEEHph4MCBAkG3bNmy0qFDB7OtWLFiDEfBQ5EACZAACZAACZAACeQGATyVRWE3N8iyTxIgARIgARIgARIgARLIYwJ//PGHEXXT09NlwIABovF283hYPDwJkAAJkAAJkAAJkEAUCGDxtJQZM2YcjkJf7IIESIAESIAESIAESIAESIAESIAESIAESIAESIAESCAGBPDjvW8lhRgcjIcgARIgARIgARIgARIgARIgARIgARIgARIgARIgARKIDoEUa/EEeuxGhyV7IQESIAESIAESIAESIAESIAESIAESIAESIAESIIFcJ5CSkkKP3VynzAOQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQJQJMBRDlIGyOxIgARIgARIgARIgARIgARIgARIgARIgARIgARLITQL02M1NuuybBEiABEiABEiABEiABEiABEiABEiABEiABEiABHKBwOHDhxmKIRe4sksSIAESIAESIAESIAESIAESIAESIAESIAESIAESyFUCDMWQq3jZOQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlEl0BmZiY9dqOLlL2RAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQO4SSEtLo7Cbu4jZOwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlElwBj7EaXJ3sjARIgQMoqYAAAQABJREFUARIgARIgARIgARIgARIgARIgARIgARIggZgQYIzdmGDmQUiABEiABEiABEiABEiABEiABEiABEiABEiABEggOgRSUlIYiiE6KNkLCZAACZAACZAACZAACZAACZAACZAACZAACZAACcSGAEMxxIYzj0ICJEACJEACJEACJEACJEACJEACJEACJEACJEACUSOQmZlJj92o0WRHJEACJEACJEACJEACJEACJEACJEACJEACJEACJBADAmlpaRR2Y8CZhyABEiABEiABEiABEiABEiABEiABEiABEiABEiCBqBJIj2pvIXb2yy+/yK+//iq1atUyry5duoTYktVIgARIgARIgARIgARIgARIgARIgARIgARIgARIIH8TwOJpMRd2VdQF+qVLl5oX0hR3QYFGAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAsEJHDx4MPbCLjx13Ya8RBN29+3bJ//8848sXLhQFixYIKtWrZJKlSpJtWrVpFWrVtKkSRP3NJN2f9SoUYI3U/PmzaVixYpJO09OjARIgARIgARIgARIgARIgARIgARIgARIIP8QeOedd4xmiagD4RicWeHcetVVV4XTLKy6qampkrJjx47DYbXKYeX77rsvSw+Ak5sTzXLAHGYsW7ZMHnjgAVm5cmXAnlq2bCm33HKLEXoDVkqSgo4dO5qZPPnkk9KmTZskmRWnQQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkF8JQNSFQAuDbhmquIs2aAvLTc0zTxZP69y5s5mY80+oYJxt8ioNtf3yyy+3Rd169epJr1695LbbbpO+ffvKMcccY4Y2ZcoUufnmm2Xjxo15NVQelwRIgARIgARIgARIgARIgARIgARIgARIgARIIEwCTlEXTd37gbpzirqo494P1C6S/MOHD0tqJA1z0gYhF5ziLtKJEoZh9erV8thjj5npFy1aVF544QV566235MYbb5Tu3btL//795aOPPpLrr7/e1Nm6das89NBDOcHFtiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAjEk4KVVZifuBhJxvfqK1lRivngaBo4J5eakogXH3Y+6USP/tdde83TBhht07969Zf369TJkyBCZN2+eib9btWpVd3fcJwESIAESIAESIAESIAESIAESIAESIAESIAESiDMCGkLBqQViiNj3CssQSNT1qhutqaakpMR+8bRoDT7W/WCRtN9++80c9rzzzvMUdZ1jQh0Iu7Dx48fLRRdd5CyWiRMnyoQJE4zwu3btWjn22GOlYcOGcvrpp0vdunX96kIc/vrrr6VChQpyzTXXyI8//igI9YAX7LjjjpM+ffpI06ZN/dphZ/LkyTJs2DCz0NuaNWukfPnyUrNmTXMceEtDiHbbkiVLZMSIEWZRuEWLFknlypWlQYMGcvLJJ0vbtm3d1YPuIx7xDz/8IHPnzpUVK1ZI48aNzSJrHTp0sMNWBO2AhSRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQYwKhirt5IeoCRWZmZuwXT4vxOYja4YYOHSovvfSS6e/TTz8NSZQ8dOiQmHgX1ip1WKkOtnfvXhk0aJB8//33Zt/rD2Lz9uzZ0y4aO3asPPjgg2YhthYtWgjG4mWPPvqotG/f3i5CWIh3333X3ncnunXrJnfeeadA4Vf77rvv5MUXX9TdLFu0wfgKFy5slwVaPA2C8rPPPmvXcyYQyuLVV181grYzn2kSIAESIAESIAESIAESIAESIAESIAESIAESiBcCwYRbjNHt1Yu83PTURf8weuz6OIT0d+XKlaYeBEldIC27hl7esB9++KEt6qqnLTxx8SZ5/fXXzWJrAwcONN65bu9YjAGvVq1ayYUXXiilS5c2nr+fffaZ7N69W95++21b2N2yZYst6rZu3VouvfRS4627YcMG+eSTT2TSpEkyfPhwgVDbpEkTMxXkqahbpkwZueGGG6ROnTqCNjjGjBkzTJtixYrJgAEDgk5/1qxZtqiL4yM8RUZGhvEcxjwRfxixiSE+ly1bNmhfLCQBEiABEiABEiABEiABEiABEiABEiABEiCBvCAQzHPXazyxEHX1uHkSY/eXX36RX3/91YQzAJxEiLeLMAKw6tWrK7uwtwi5AG9f2CmnnCLwsFXxFxwg2GIBto0bNxqvXgiiBQoU8DtOmzZt5PHHH7c9gBG2AV7B7733nhF9d+zYISVKlJD58+fb7RC+oXbt2ma/UqVK0qhRI7nggguMuDpz5kwj7MK7GB60MIi6H3zwgZQsWdLsY2wtW7Y0x0U4iq+++krOPfdcCRQ3GH1hYTlYu3btzDzVKxhhIJo3by59+/Y1YvTIkSPlkksuMXX5hwRIgARIgARIgARIgARIgARIgARIgARIgATijUAgcdc9zliKuiZKgHsAub2voi6OAy9VCLzIi3eDBywMHruRGmLqqsHjVUVdzYMgq56wiIeLuL5uu/zyy21RV8uc4Rd0nDVq1NBiI/pCLFZLT0+XN954Q95//33p2rWryV68eLERhrEDT10VdbUNxnrdddfprowbN85OuxPLly8XxNaF4Q2toq7JsP6UK1fOFnO//fZbzeaWBEiABEiABEiABEiABEiABEiABEiABEiABOKSgIq7gQYXS1EXY8iTUAwQct2GvHj32kX4BYif69atcw8/5P1Vq1aZutWqVQsYzgHerGqrV6823rW6j61TsNX84sWLa1LgLQuDNy08c7HwGgRlvLAAGvpHCAgstFaxYkW7HYRkNcTx9TLUh+cvOOhcvOpp2AqUIdSCxhd21lUPaAjOCCORE8Hc2S/TJEACJEACJEACJEACJEACJEACJEACJEACJJDsBKC35UkoBjdYKN7xbhBjYRBAIZ66vW29xo+FwzZv3iwNGzaUfv362aIwwiEEMnjKQuSE2OkUW7V+oUKFNJntFuEQBg8ebGL6or8FCxaYl4aDQNzbK6+8UgoWLGji6GqHiIUbyMDB6d3rVQ+CtNro0aM1GXC7bds2CrsB6bCABEiABEiABEiABEiABEiABEiABEiABEggrwkEWkRNx4VF1GLptQt9MubCbufOnU34BZ00tokg7DoXTIP3qzP8gXMumkas22HDhpndxo0bm62GN0BZINu/f78RdVGOxdFyYoULFzbhE/Cmgucu4ulOnz5dpk2bZrr94osvTJzde++9V5xev8E8aDXUQzDx11n23//+N+gU4DaOmL40EiABEiABEiABEiABEiABEiABEiABEiABEohHAtmJujrmWIq7eeKxqyEXNCQDhF7NUwjxuD3ppJPsYcHjNTth1xlP94QTTjBt1esXnrN79+4VCK9uwxtFLdDiZFoebLt9+3aBCFukSBETcgHhF/C67LLLTBiF+++/38TB/fnnn+W2226TKlWq2N0tWbLELKhmZxxJQHRetGiR2fMKCaH1nQvMYQE4L+EW4jbCWsBb2IuD9sUtCZAACZAACZAACZAACZAACZAACZAACZAACeQVgUCiLhwpYRBznRYrcTdPFk/DRCHkPvHEE+aVCKIuxowFvy6++GIkTTiDt99+WzIzM82++8+mTZtk4MCBJhuiZv369U26SZMmdtVvvvnGTjsTWNBMrU6dOpoMeztkyBDBQmt33HFHlrYQjM8//3w7f+fOnXLsscfa+wjf4GVDhw61vYnVC9mrXs2aNe3QCoEWR/vf//4nV199tTz00ENeXTCPBEiABEiABEiABEiABEiABEiABEiABEiABPKUQDBRFxEI8FKB1zlQiLtO501nWbTSeSbsRmsCse4HMWl1ka9PPvlEHn30UZk/f77AkxWGLTx1IVginAHswQcfNF6pSDdr1kxatWqFpEAYRiiEAwcOmH14sELsnDhxotlH7NtSpUqZdCR/sDgaDAuZvfXWW7Jnzx67m61bt8ovv/xi9suXL29E6xIlSsi1115r8qZMmSJPPvmkaMiIgwcPCoTiQYMGmXJ4IJ944ol2f+4EGMEzGPbhhx/Kxx9/bDyUsY8+IfaOGzcOu3LGGWeYLf+QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQLwQyE7U1XHmpbibYglth3Ug3GZPAAuDQazFAmJOQwxe92JnEHj79OnjrCZof+edd/rVdbdt3ry5EVY1RMHYsWPNMdHRmDFj/PrDDjyEe/XqZfLfe+89432LAMr33XefLRSjEJ60yIfYq4axnHXWWWZ33759ghANkydP1mJxjw1C8PPPPy/OcAsdO3Y09SEGt2nTxqQRauKuu+6SWbNm2X2h7caNG+19eDCjr3AWhLMbM0ECJEACJEACJEACJEACJEACJEACJEACJEACuUAgVFHXeehI2jjbh5vGulWp4TbK7/URi/a1116TCy+80IieysMp6iKW7bvvvptF1EVdtIc7dvfu3W3vX20L4RNes88995xf3Nn09PDXuEtLSzNhDiAsq5fxsmXLbFG3Xr168vDDD9uiLsYGgfWZZ56RG2+8UTAWmI4NfUAARqgIp6hrKh35g2OqQZR+8cUXpX///naMXaeoe8kll8jTTz9NUVeBcUsCJEACJEACJEACJEACJEACJEACJEACJBAXBPRJd+dgEHIB3rmBLJDnrldfgfoINz9PPHYxISyehgnjlShxdr3gIrQAFhvDYmXwbsULC5aFavC2heCJuLcIh5AbhlAKOA4WU4N4m5GRYYutwY6Hua1atcqEalChN1j9YGXbtm0zIjHCS6CvAgUKBKvOMhIgARIgARIgARIgARIgARIgARIgARIgARLIMwLOOLnZibrOQTo9dwOJvc76kaZTU1Ml5sKuirrOQXfu3DmhxV3nXJgmARIgARIgARIgARIgARIgARIgARIgARIgARJIfAIQd+GQCoE2HIO4Cw3Ua2G1cPoJVhehGGIu7CLuq5c98cQTXtnMIwESIAESIAESIAESIAESIAESIAESIAESIAESIAEScBCImxi74arejjkwSQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAL5ikBmZmbsF09D2AW3Udh1E+E+CZAACZAACZAACZAACZAACZAACZAACZAACZAACXgTSEtLi72wi7gUTnGX8XW9Tw5zSYAESIAESIAESIAESIAESIAESIAESIAESIAESMCLwOHDh2MfY9drIMwjARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIjUDcxNgNbbisRQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQGGX7wESIAESIAESIAESIAESIAESIAESIAESIAESIAESSDACCMWQmmBj5nBJgARIgARIgARIgARIgARIgARIgARIgARIgARIIF8TyMzMpLCbr98BnDwJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEDCEUhLS6Owm3BnjQMmARIgARIgARIgARIgARIgARIgARIgARIgARLI9wQYiiHfvwUIgARIgARIgARIgARIgARIgARIgARIgARIgARIIJEIcPG0RDpbHCsJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJWAQOHjzIUAx8J5AACZAACZAACZAACZAACZAACZAACZAACZAACZBAIhFITU2lsJtIJ4xjJQESIAESIAESIAESIAESIAESIAESIAESIAESIAEKu3wPkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkECCETh8+LCkJ9iYQx7uqY9sDrkuKyYfgdEPlU2+SXFGJEACJEACJEACJEACJEACJEACJEACJEACJHCEQPrff/+dpDDKJem8OK1QCCTv+zqU2bMOCZAACZAACZAACZAACZAACZAACZAACZBAMhMoVKgQY+wm8wnm3EiABEiABEiABEiABEiABEiABEiABEiABEiABJKPQGZmpqTs2LHjcPJNjTMiARIgARIgARIgARIgARIgARIgARIgARIgARIggeQkkJKSQo/d5Dy1nBUJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEAyE0hN5slxbiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQbAQOHz5Mj91kO6mcDwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQHITYCiG5D6/nB0JkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEASEkhNTaXHbhKeV06JBEiABEiABEiABEiABEiABEiABEiABEiABEggiQkcOnSIwm4Sn19OjQRIgARIgARIgARIgARIgARIgARIgARIgARIIAkJ0GM3CU8qp0QCJEACJEACJEACJEACJEACJEACJEACJEACJJDcBLB4WnpyT5GzIwESIAESIIH8TaB48eL5GwBnTwIkkPQEdu7cmfRz5ARJgARIgARIgARIwE0Awm6qO5P7JEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC8U2Awm58n5+oje7vv/8WvGgkQAIkEC8EeF0K7UyQU2icWIsESIAESIAESIAESIAESCB5CfC+KOu5TUlJocduVizMIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH4JsAYu/F9fjg6EiABEiABEiABEiABEiABEiABEiABEiABEiCBOCCwdOlSeeeddzxH0rlzZ+nSpYtnWW5k0mM3N6iyTxIgARIgARIgARIgARIgARIgARIgARIgARIggaQj8MsvvwScE0TfWBoWT4vYY/e+++6L5VjtYz3xxBN2Ot4SOLl6EnVbq1YtM0xV7HU/3sbO8ZAACZAACZAACZAACZAACZAACZAACZAACZAACURGQLXAyFpH1ipiYTeywyVfK1Xqf/31V8/J6UlVN20IuxB5KfB64mImCZAACcScAK7TS5YsyXLcY4891uTxep0FDTNIgARIgARIgARIgARIgARIIF8SUJ0vHiafmZkZuceuTiCQB6169AYq1/ahbrW/UOvHoh5E3UCCbqDj4w0AkTfWcTcCjYf5JEACJJAf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JEACJEACJEACJBBtAoGeCMQ9YSDHTR2D+75R7yd1q/WiscUPvBR2IySJkxyKUh+oe4q6gcgwnwRIgARiQwAfrO4PbBV4c+NDNzazSo6jQMgN5IGWHDPkLEiABEiABEiABEiABEiABJKNQKzvIw8dOpRzYVdj3wY6GdmVB2qXCPlQ4RFYOZxHeiHowtwKfiLMNxZjLFeunNS0FkeDuR/jNZn8QwIkQAK5SCDWH8S5OBV2TQIkQAIkQAIkQAIkQAIkQAIkEGUCuGdUh6Aodx12d/TYDRtZ1gY4oRqzEaUQeWF6klUkwJZirkET9A/ihzkX2wlamYUkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkECMCwYRd1QBjNBTBQqEp1uqqh2N1QB4n7wjEavXAvJshj0wCJJBoBHhdCu2M5ZRT8eLFQzsQa5EACZBAghLYuXNngo6cwyYBEiABEiABEgiVQE7vi0I9TqLVS020AXO8JEACJEACJEACJEACJEACJEACJEACJEACJEACJJDfCdBjN7+/Azh/EiABEiCBpCZAj92kPr2cHAmQgEWAHrt8G5AACZAACZAACeRHAikpKUKP3fx45jlnEiABEiABEiABEiABEiABEiABEiABEiABEiCBhCZAYTehTx8HTwIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkN8I0GM3v51xzpcESIAESIAESIAESIAESIAESIAESIAESIAESCDhCRw+fFjSE34WnAAJkAAJkAAJkEBAAow9GRANC0iABEiABEiABEiABEiABEggoQkwFENCnz4OngRIgARIgARIgARIgARIgARIgARIgARIgARIIL8RyMzM5OJp+e2kc74kQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAKJTSAtLY3CbmKfQo6eBEiABEiABEiABEiABEiABEiABEiABEiABEggvxFAjF2GYshvZ53zJQESIAESIAESIAESIAESIAESIAESIAESIAESSHgCFHYT/hRyAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAvmJQEpKiqQvXrw4P82ZcyUBEiABEiABEiABEiABEiABEiABEiABEiABEiCBhCaQnp7OUAwJfQY5eBIgARIgARIgARIgARIgARIgARIgARIgARIggXxHADF2U6w/h/PdzDlhEiABEiABEiAB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bEK2e+97IP3jn0+lpUuW5pOyjRs3Ou2x264pynZoBAgQIECAAAECBAgQIECAAAECBHoSENjtSch+AgQIECBAgAABAgQIECBAgAABAgQI1JhAU42Nx3AIECBAgAABAgQIECBAgAABAgQIECBAoAcBgd0egOwmQIAAAQIECBAgQIAAAQIECBAgQIBALQlEjV2B3Vp6IsZCgAABAgQIECBAgAABAgQIECBAgACBHgRKpZLAbg9GdhMgQIAAAQIECBAgQIAAAQIECBAgQKCmBAR2a+pxGAwBAgQIECBAgAABAgQIECBAgAABAgR6J6AUQ++c9CJAgAABAgQIECBAgAABAgQIECBAgEDNCAjs1syjMBACBAgQIECAAAECBAgQIECAAAECBAj0TkBgt3dOehEgQIAAAQIECBAgQIAAAQIECBAgQKBmBAR2a+ZRGAgBAgQIECBAgAABAgQIECBAgAABAgR6JyCw2zsnvQgQIECAAAECBAgQIECAAAECBAgQIFAzAgK7NfMoDIQAAQIECBAgQIAAAQIECBAgQIAAAQI9C7S2tiaB3Z6d9CBAgAABAgQIECBAgAABAgQIECBAgEDNCJRKJYHdmnkaBkKAAAECBAgQIECAAAECBAgQIECAAIFeCtR1xu7ChQvT5MmT89eUKVPKtzx9+vTy9nvuuae8vZYWls57Il230/j89a8lz5eHVs/3VL4JCwQIECBAgAABAgQIECBAgAABAgQIDJhAS0tLGjRgZ38ZTrxixYo0d+7c/ErPPvts+YpLliwpb1+2bFl5ey0ttLasLA+nNXsQRavneyruwTsBAgQIECBAgAABAgQIECBAgAABAgMn0NTUpBTDwPE6MwECBAgQIECAAAECBAgQIECAAAECBAZGYMBKMSxYsGBgRuysBAgQIECAAAECBAgQIECAAAECBAgQeBULtLa2DkwphlmzZqVHH300jR07No0bN65miefPvDOllSvTiO3fkAYNWyctmf1YeubO29PyrKzDsNFj0kaTd0vNQ9dqN/4om7DowfvSc488nF6YNzetPWqLNGK7HdLwrbZu169yZcXiRWnBn2amxX99IK214evSejtPSql5wGLqlZe2TIAAAQIECBAgQIAAAQIECBAgQIBAAwpUvcbujBkzUlHvNoK7I0eOTOutt15N0v3h6EPzcb3lh5enWT+8ID19+63txrnh296Z3nz+xeVtLz7zdLrntM+t1i86jDvy2LT1CaekpsGDy/1jYfHf/pruOunYtOyf/2i3ffxxJ7Zbt0KAAAECBAgQIECAAAECBAgQIECAAIHeCJRKpepm7FYGdWMAkbE7kEHd5ubm8n0OHTq0vDxo0Kp4deVyuUOHhQfP/FqWhXt/GrHt9mnkThNSylKZn77jtvSvpUvLPWP5loP2ScsXzM+ye4el0YccntbedFRalGXhzrkqCwxfclEqZUHdbbLgbtHimDuO+lD6VzaZ25D11k9jPnxEHvid89Op6eELv1t0a/derXtqd1IrBAgQIECAAAECBAgQIECAAAECBAg0lEApq8fQWo076iyoW8tlGOKer9tpfPnWX/+Jz6ZxRxyTUhbtjtaalWhY+Jc/twV6s/W/fe+cPBgbQd13XnVtWnuzUXm/+DP3lz9P937p8/n6rtdNL++bfcWl6f4zTm/bfu20rGzD5vnyi/OfSbd88H15kDg27HHrzDR4+Lr5Pn8IECBAgAABAgQIECBAgAABAgQIECDQk0C/C73GJGn1GNSthIks3SilUAR1Y18pywbOs3djJYt9Fxm2237y8+XAbeyKttme++RZvLE8/64/xFvenvzNr/L3zff/YDmoGxuGrr9BGn3wYfk+fwgQIECAAAECBAgQIECAAAECBAgQINBXgVU1C/p6ZNY/grozZ85sd2RnE6ZFv6i3G22gyzO0G0wvVzbb6/3d9lz29FPl/Q+dd3aac+Xl5fViIcotRHvu4YeKTWnJ47Pz5ZE77lzeViyM3Gn1bcU+7wQIECBAgAABAgQIECBAgAABAgQIEOhOYI0Du50FdSdMmNBpTd0I6lZOqDaQdXe7u9mu9q296WZd7cq3L31ibnl/1NiNV1etZfmL+a6WFSvK/QaPGLFa9yEja3NCudUGagMBAgQIECBAgAABAgQIECBAgAABAjUlsDIrI7vGgd3O7iSCt7UWtO1snB23DRo+vOOmdutNQ4eU1ydfc0MatvmW5fWuFqKUQ7m1rF7GuGXF8vJuCwQIECBAgAABAgQIECBAgAABAgQIEOitQHMWe1zjGrsRwI0M3coWmbmzZs2q3JQvR/mFkSNH5q9YrrdWGcjtLlu38r5KTU3lurovzn+6cle+/OIzz6y2zQYCBAgQIECAAAECBAgQIECAAAECBAj0RmCNA7tx8t4Gd6PfxIkT81c9ZvQOXndEGrLe+rnnk7++tjeueZ/h48bn7/+8Zfpqxzx187TVttlAgAABAgQIECBAgAABAgQIECBAgACB3gj0K7AbF4hA7e67755n4xYX7Cpzt9hfj+/bferUfNizf3JZmnfdL9vfQmtrWjDzrvSnUz+ZVixeVN63xYGH5MtP33Zz+mdFIHfBn2akx//3ynI/CwQIECBAgAABAgQIECBAgAABAgQIEOiLQKk1a305oLu+M2bMKE+SFv2i7MK4ceO6O+QV3XfdTm0ZtW/70ZVp5I47dzuW1paWNOPk49JTt96U9xu25ZgUGbkrs8nSFj1wX3mitHffcHsausGGeZ845vYjD04L7/1zvr7ezhNTqak5zZ/xx3y9+LPHrTPT4OHrFqveCRAgQIAAAQIECBAgQIAAAQIECBAg0KVAhHT7nbFbefYotxC1dIsWmbsLFiwoVmv2vVTqmSFq5k4858K0wxf+Ow0aNiwtmfNY+se036bIxo26u2tttHEae/jRadA665TvM47Z5YIfpU123zPftuDuGXlQN/pOPPuCdv3KKxYIECBAgAABAgQIECBAgAABAgQIECDQjUAEdquasVtcKyZQi6BurWfsFuNdk/dlTz+VXpg3N8/AHfq6jdJrsmBtKpW6PNWK5xan5x99JK/VWzkZW5cH2EGAAAECBAgQIECAAAECBAgQIECAAIEuBAYksBvXikzdepworQsnmwkQIECAAAECBAgQIECAAAECBAgQIFAzAgMW2K2ZOzQQAgQIECBAgAABAgQIECBAgAABAgQINJhAz8VlG+yG3Q4BAgQIECBAgAABAgQIECBAgAABAgTqWaClpaW6k6fVM4axEyBAgAABAgQIECBAgAABAgQIECBAoB4EStlcXzJ26+FJGSMBAgQIECBAgAABAgQIECBAgAABAgReEhDY9VEgQIAAAQIECBAgQIAAAQIECBAgQIBAHQrI2K3Dh2bIBAgQIECAAAECBAgQIECAAAECBAi8ugUGLVq06NUt4O4JECBAgAABAgQIECBAgAABAgQIECBQRwLNzc1q7NbR8zJUAgQIECBAgAABAgQIECBAgAABAgQIpJaWllRqzRoLAgQIECBAgAABAgQIECBAgAABAgQIEKgfATV26+dZGSkBAgQIECBAgAABAgQIECBAgAABAgRyAYFdHwQCBAgQIECAAAECBAgQIECAAAECBAjUkUAUYRDYraMHZqgECBAgQIAAAQIECBAgQIAAAQIECBAolUoCuz4GBAgQIECAAAECBAgQIECAAAECBAgQqDcBGbv19sSMlwABAgQIECBAgAABAgQIECBAgACBV7VAS0tLKmX1GFrrUSHSjaPV6fDrkdyYCRAgQIAAAQIECBAgQIAAAQIECBCoEQEZuzXyIAyDAAECBAgQIECAAAECBAgQIECAAAECvRUQ2O2tlH4ECBAgQIAAAQIECBAgQIAAAQIECBCoAYGoYiCwWwMPwhAIECBAgAABAgQIECBAgAABAgQIECDQFwGB3b5o6UuAAAECBAgQIECAAAECBAgQIECAAIFXWCDmHxPYfYUfgssTIECAAAECBAgQIECAAAECBAgQIECgrwJVDeze+9jyvl5ffwIECBAgQIAAAQIECBAgQIAAAQIECBDoo0DVArs/nvZ8+tyUhSneNQIECBAgQIAAAQIECBAgQIAAAQIECBAYOIFSNoNaa39PH5m6EdQt2hvHDElnHPXaYnVA3qOORLQqDH9AxuekBAgQIECAAAECBAgQIECAAAECBAgQGCiBqmTsRiD30Mlrl8fYMdBb3mGBAAECBAgQIECAAAECBAgQIECAAAECBPolsHLlyupNnnbYu9YR3O3X43AwAQIECBAgQIAAAQIECBAgQIAAAQIEehZobm5OVSnFUHmpqLF7+U1LKzflZRkiq7eaTSmGamo6FwECBAgQIECAAAECBAgQIECAAAEC9SRQlVIMlTfcMXM39kX93SjPoBEgQIAAAQIECBAgQIAAAQIECBAgQIBA/wWqHtiNIQnu9v/BOAMBAgQIECBAgAABAgQIECBAgAABAgS6EhiQwG5crNqlF7q6AdsJECBAgAABAgQIECBAgAABAgQIECDwahJobW1Ngwbihl+uOrsDMXbnJECAAAECBAgQIECAAAECBAgQIECAQC0LDEhgt2NQNzJ3D528tgzeWv4kGBsBAgQIECBAgAABAgQIECBAgAABAnUj0NTUVN2M3c6Cumcc9dq6ATFQAgQIECBAgAABAgQIECBAgAABAgQI1INA1WrsCurWw+M2RgIECBAgQIAAAQIECBAgQIAAAQIEGkGgKoHdex9bni6/aWnZI8ovyNQtc1ggQIAAAQIECBAgQIAAAQIECBAgQIBA1QRaWlpSVQK7RR3dGFnU0xXUrdozciICBAgQIECAAAECBAgQIECAAAECBAi0EyiVSqmUzaDW2m5rP1YiczeCvC9Hi8FHq+LwX45huwYBAgQIECBAgAABAgQIECBAgAABAgT6LVDVwG6/R9OHEwjs9gFLVwIECBAgQIAAAQIECBAgQIAAAQIEGkqgKqUYGkrEzRAgQIAAAQIECBAgQIAAAQIECBAgQKDGBQR2a/wBGR4BAgQIECBAgAABAgQIECBAgAABAgQ6CgjsdhSxToAAAQIECBAgQIAAAQIECBAgQIAAgRoXGFTj4+tyeCZN65LGDgIECBAgQIAAAQIECBAgQIAAAQIEGlxAxm6DP2C3R4AAAQIECBAgQIAAAQIECBAgQIBA4wkI7DbeM3VHBAgQIECAAAECBAgQIECAAAECBAg0sEBUMxDYbeAH7NYIECBAgAABAgQIECBAgAABAgQIEGg8gVKpJLDbeI/VHREgQIAAAQIECBAgQIAAAQIECBAg0OgCMnYb/Qm7PwIECBAgQIAAAQIECBAgQIAAAQIEGkqgpaUllbJ6DK0NdVduhgABAgQIECBAgAABAgQIECBAgAABAg0uIGO3wR+w2yNAgAABAgQIECBAgAABAgQIECBAoPEEBHYb75m6IwIECBAgQIAAAQIECBAgQIAAAQIEGlggijAI7DbwA3ZrBAgQIECAAAECBAgQIECAAAECBAg0poDAbmM+V3dFgAABAgQIECBAgAABAgQIECBAgECDCpRKJRm7Dfps3RYBAgQIECBAgAABAgQIECBAgAABAg0sIGO3gR+uWyNAgAABAgQIECBAgAABAgQIECBAoDEFBHYb87m6KwIECBAgQIAAAQIECBAgQIAAAQIEGljg/wHX+Ga5Gnz3EAAAAABJRU5ErkJggg=="/><use stroke="#7E7C7B" xlink:href="#rect-1"/></g><path id="Rectangle" stroke="#C06334" stroke-width="2" d="M4 393h209v53H4z"/><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#A7333A" d="M71.5 303.775l15.69 16.01h-6.488c.886 1.695 3.06 5.91 4.01 8.24.318.776-.979 2.324-.979 2.324h0l-2.42.151-4.2-8.574-5.613 5.727v-23.878z"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/domconsole1.svg b/2-ui/1-document/02-dom-nodes/domconsole1.svg index db92359d5d..d7f32debba 100644 --- a/2-ui/1-document/02-dom-nodes/domconsole1.svg +++ b/2-ui/1-document/02-dom-nodes/domconsole1.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="696" height="512" viewBox="0 0 696 512"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h696v512H0z"/><path id="path-2" d="M66 424v21.429l5.25-5.358L75.625 449h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H80L66 424z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="domconsole1.svg"><g id="Bitmap"><image width="696" height="512" xlink:href="data:image/png;base64,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AQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYgAJux6gMKAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhgsAQUcAfL27NJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEuiYwOwzzzyz48AGlIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQggcER0AN3cKw9kwQkIAEJSEACEpCABCQgAQlIQAISkIAEJCCBrgjMuvXWW+/vag8DS0ACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQwEAI6IE7EMyeRAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpBA9wQUcLtn5h4SkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABAZCQAF3IJg9iQQkIAEJSEACEpCABCQgAQlIQAISkIAEJCCB7gko4HbPzD0kIAEJSEACEpCABCQgAQlIQAISkIAEJCABCQyEgALuQDB7EglIQAISkIAEJCABCUhAAhKQgAQkIAEJSEAC3RNQwO2emXtIQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEhgIAQXcgWD2JBKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEuieggNs9M/eQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJDAQAgq4A8HsSSQgAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJdE9gdve7zOw9LrvssnTppZemE044oa8gHvKQh6QnPOEJieVU2AUXXJAPu9FGG03F4T2mBCQgAQlIQAISkIAEJCABCUhAAhKQwDQRUPeZJvADOq0euF2CPv744/su3hKFEIa7jI7BJSABCUhAAhKQgAQkIAEJSEACEpCABCQggTEmoAdulxcXoRX7yEc+0uWerYO/973vzcIwXriaBCQgAQlIQAISkIAEJCABCUhAAhKQgAQkIAEI6IFrPpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAQkMKQE+uqB2+/pBWI+2Ne85jVDis9oSUACEpCABCQgAQlIQAISkIAEJCABCUhAAlUCoROi78W7n6ph/N8Zgb4JuAcffHCex7Wz03YWKqYr4II7tUBnzAwlAQlIQAISkIAEJCABCUhAAhKQgAQkIIHpJBDiLXFA3wuNT31vclelbwJuXAjnhp3chZjJe/3qV79K9957b8cIuNkXXXTRdPrpp6drr702rbPOOmnTTTfteH8Djj+BO++8M11yySXp0ksvzcvrr78+rbTSSmm11VZLD3vYw9LGG288/hD+m8Lf/OY36Z577kkPfehD0yqrrDJj0t0soTfddFM68cQT09VXX53IF7Nnz85cKEfmzp2bllxyyWa7un5MCdx3332Nl5Mut9xyaZtttmmZ0quuuirxht/FF188bbfddi3DjvPGyy+/PF188cVp6aWXTo9+9KPHOamNtFF2NKuvzJo1K6244orpwQ9+cH7W8H9QdtZZZ+U8eeutt6b1118/bb/99oM6tecZQwJlPl9vvfUSn3ZGvet3v/tdI9hmm22W74PGCn+MLYF4JpJAPOvmzJkzNGm9+eab05///OccH8pF2o/Y73//+3THHXcMXd24WXxzpP2SwIgSOOGEExaIOetGTcDFYZU4xywBCySqyQp0UkTsfs0q0DcBt0l8XS2BlgRoCB1wwAEtw1Q3Pvaxj80P4O9+97vpj3/8Y9pll11mrICLMPfrX/86I3rUox6VVlhhhSquGff/yiuvTJ/97GfTvHnzJqT9hhtuyA1cBM011lgjvfrVr05rrrnmhDDj+Ofb3/52Ttayyy47owXc+++/P33rW9+a0MCM6/2Pf/wjnXHGGemnP/1peuELX5h22GGH2ORyBhC4++670/e+971GSpdaaqmWzxQafpQjiy22WM8CLuXSmWeemc89ahVZ4v3zn/88IXrPBAEXof873/lOI5+0+rHyyiun3XbbrSPhq9VxOtn2/e9/Px133HGNoIgpCrgNHP6YBIEyn6+66qrpAx/4QNujIJKV5SjlI53m2vgToG4Vjlw4CnzoQx8amkTTUR/5knZSCLhHHHFEjuN01I1pu5100kn5/I94xCPS8ssv3+DVLL6NAP6QwJgQ6FYEne5kx2wDLBFiO40/ZSP7YLFvr2lRwO2VoPv3jQDi41prrdX2eAsvvHDbMDMlwF133ZU+9rGP5eR+8YtfnPEC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U6Lb8nZM1jASWdZJLyqG1zFi38IzFmIq4trCsxle0ggLgPShQ4d6UbNzEYjF06ZNU57X2FwOgu7q1atVRoS78AWjzM6Tc6/dpyAMBg54F8Ob+sMPP1ShQyDi+sKb2H3LfEICJEACJEACOUOAAm7OcGerJEACJEACJEACJEACJOBzAhBSsbT89OnTXtdt9fp056VrFWzhFWu997phNwV9MSY3VXuUrGPxppcZ4itis2orWbKk9OnTR9+6PSO8gY7Re+jQIZkyZYoKG4ENxgYPHuwTL1x4HLdo0UJtKocwCggrceHCBdWnG264wW3f9AMt8OoQHDrdes6peQI7eC2jbydPnrR2idckQAIkQAIkEDAEuIlZwEwlB0ICJEACJEACJEACJJDXCVSpUkUhwNJyxDj1xqxL0LG835XB+1HHq9WenK7y+SLNF2PKaD8gWGoh29M4uefOnVNL+SG84li7dm1Gm1XCar9+/VQ5hKawhiWwVlakSBHzNi1R1cxkXLRr107d4nUxffp0dV2tWjUpUaKENZvLa4jRMHevBzzLiXlCuzC9CZ4Ou5GSyp8kQAIkQAIkEDgEKOBmYC5Pnz4jNw65VR2Tp/5ollz210ozfeu2zO3oa1bKCxIgARIgARIgARIgARLIIIHWrVurmKYoNnHiRElISHCoASLjnDlzZN68eQ7p1hsIs3qTryVLlpgbXVnz4Lp///4qCcvW4dVpNXitxsTEyPjx48VTAdRa3nrtizFZ6/P0WgvZf/75p9dieFpt/fzzz7J161a19F/nAzctiGMewsLC9COHszUdc6m9aR0y2W7gIas9pbW437ZtW1su17danIVYjNcExGW75dQ82fvBexIgARIgARIIRAIMoZCBWcUfKgcPxasS1mVp543lRzrd02/AM9Ass5IACZAACZAACZAACZCARwQg+g0bNky++uorOXLkiLzxxhvKOxEbVUHM1X/DNmnSJM36sPR/6tSpygP0vffeM71thw8fLo0aNVJlETsV8VQRsuGnn36SuXPnStmyZZW4h7a1yGffxCzNhl089NWYXFSdZhLETYREwOZib775plqmj7i12PDrlltuSbOsJw83b94sy5cvV2whrKJutKU3VoNAjjRXBg/oGjVqyO7du2Xp0qXqwGZt8Bru3r27uAuLgPiwP/6Y4ogCrnouXbVhTcPrZdasWYJwGb/99ps6UB4xaBEDGZZT84S2NSds0EYjARIgARIggUAkQA/cQJxVjokESIAESIAESIAESCDPEqhXr548/vjjUqFCBcUAy/D37t1rireVK1eWpk2bpsmnefPmSgjWnp4QY/WhCyLMwNixY6VXr15KOIQXKATIgwcPqrwQ1VAPxGOYjqOqQxMgTV/rM9K06fy492ZMurw+63px1mmu2tX5OnXqJEOGDFEiJdLgqAEB012cVV2nLp/euW7dukr0VE4iBjOEJ4B4iz517NhRIJCnZbfffrsSazVfeFejf2l5PEdFRZlVNmvWTBAb1xNDnx555BE1D1osRb/tgqk38+RJ++nl0a/T2NhY84uD9MrwOQmQAAmQAAnkJgL5jGU613JTh3OyrydOnJSeA4aoLtxzx0h5YNRd6nrO/IXyzAuvquvx/3tXmjdL+w/inBwD2yYBEiABEiABEiABEshdBBCiAJae16yrUV2+fFl54kLUQ0gAeExiw6esMGziBbEYoiBipkJUy6io6Um/snNMnvQnM3nwUQyCMLyjIYgiHi3mSIukmanbVVkInAhrAYMgW7FiRVfZfJKWnfO0fft2+fLLL1W/4QkMT/A6depI3759fTIWVkICJEACJEACOU2AIRRyegbYPgmQAAmQAAmQAAmQAAlkEQEIgVWrVs2i2h2rhWirN7tyfOLbu+wck2977lwbBG4ItjiywxD/GAaBMyvFW7SRnfMEsRYhJxYvXizwRI6Pj88yERxjo5EACZAACZBAdhOggJvdxNkeCZAACZAACZAACZAACZAACWQTgX379ilBc+3atSrEBZrt1q1bNrWefc0g7AQOmD20Q/b1gi2RAAmQAAmQQNYQoICbAa75C6SGDC5keDNowzIdbdZrncYzCZAACZAACZAACZAACZAACeQEgQULFkh0dLTZdMuWLQXxbwPZihQpEsjD49hIgARIgATyIAHGwM2Dk84hkwAJkAAJkAAJkAAJ5B4CmYmBm3tGyZ5mFYHVq1erTexCQ0OlVq1a6siqtlgvCZAACZAACZBA1hCggJs1XFkrCZAACZAACZAACZAACfiEAAVcn2BkJSRAAiRAAiRAAiSQawmkxgTItUNgx0mABEiABEiABEiABEiABEiABEiABEiABEiABEggMAlQwA3MeeWoSIAESIAESIAESIAESIAESIAESIAESIAESIAEAoAABdwAmEQOgQRIgARIgARIgARIgARIgARIgARIgARIgARIIDAJUMANzHnlqEiABEiABEiABEiABEiABEiABEiABEiABEiABAKAAAXcAJhEDoEESIAESIAESIAESIAESIAESIAESIAESIAESCAwCVDADcx55ahIgARIgARIgARIgARIgARIgARIgARIgARIgAQCgAAF3ACYRA6BBEiABEiABEiABEiABEiABEiABEiABEiABEggMAkUDMxhcVQkQAIkQAIkQAIkQAIkkDcJHDhwQJKTk6V48eLqKFiQf/LnzVcCR00CJEACJEACJBAoBPjXXKDMJMdBAiRAAiRAAiRAAiRAAgaBKVOmyNGjR00WN9xwgwwaNMi85wUJkAAJkAAJkAAJkEDuIsAQCrlrvthbEiABEiABEiABEiABEkiTQJs2baR58+ZSunRplW/lypWybdu2NMvwIQmQAAmQAAmQAAmQgP8SoAeu/84Ne0YCJEACJEACJEACJEACGSbQrl07VebatWvy2muvyZkzZ2TXrl1Sv379DNfFAiRAAiRAAiRAAiRAAjlPgB64OT8H7AEJkAAJkAAJkAAJkAAJ+JxAvnz5pHLlyqrehIQEn9fPCkmABEiABEiABEiABLKHAAXc7OHMVkiABEiABEiABEiABEgg2wkEBQWpNrGpGY0ESIAESIAESIAESCB3EqCAmzvnjb0mARIgARIgARIgARIgARIgARIgARIgARIgARLIAwQo4OaBSeYQSYAESIAESIAESIAE8jaBxMTEvA2AoycBEiABEiABEiCBXEyAAm4unjx2nQRIgARIgARIgARIgATSIhAaGqoex8XFydWrV9PKymckQAIkQAIkQAIkQAJ+SoACrp9ODLtFAiRAAiRAAiRAAiRAApklUKVKFVUFxNvNmzdntjqWJwESIAESIAESIAESyAEC+a4ZlgPtskkSIAESIAESIAESIAESIAEPCGzcuFHlatKkiQe5HbPgT/0pU6bI+vXr1YOwsDApVaqUREZGSrdu3Rwz844ESIAESIAESIAESMAvCdAD1y+nhZ0iARLwBwLYsftyUpLDceXKFX/oGvtAAiRAAiRAAh4RyJcvn3Tp0kUaNWqk8p88eVJ27dqlDo8qYCYSIAESIAESIAESIIEcJ1Awx3vADjgQSEpKlnUbUrwsHB6kcVMrsqaE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BJiAwwggHiFuvOEhhglf8MI2hgWzMQEmwASYABPAYPE5c+bIydoQ1xTephj2/++//1JsbKwENGPGDAblIALwMo2OjpYhCeB9Cw9weLWqUB8OaoarqQMBFnDrAI+LMgEmwASYABNgAkyACTABJlBzAhjmiLiGkZGRhDi8GA5qaXKRmtfMJZgAE2ACTKApEECYBIRc2Lt3r3zpjwneyZhU62x6Yerbb4rrBw4cMJq4FN7i9957r+YB3RSP+Vw7Jo6Be66dMe4vE2ACTIAJMAEmwASYQLMi0BRj4DarE8gHywSYABNgAjUmgDineMgXExMj4wCXlpbKycwwadewYcMaRUzfGh9UIy4A1nghxBEeqIaFhRFCFbA1HgIs4Daec8E9YQJMgAkwASbABJgAE2ACZgRYwDVDwglMgAkwASbABJgAE2hWBJya1dHywTIBJsAEmAATYAJMgAkwASbABJgAE2ACTIAJMAEmwATOIQIs4J5DJ4u7ygSYABNgAkyACTABJsAEmAATYAJMgAkwASbABJhA8yLAAm7zOt98tEyACTABJsAEmAATYAJMgAkwASbABJgAE2ACTIAJnEMEWMA9h04Wd5UJMAEmwASYABNgAkyACTABJsAEmAATYAJMgAkwgeZFwLl5He65cbQV5RWEl95aOLWgls4t9Um8zgSYABNgAkyACTABJsAEmAATYAJMgAkwASbABJhAEyfAAm4jPMHrP1xP6z/416hnft070P0r7zdK4w0mwASYABNgAkyACTABJsAEmAATYAJMgAkwASbABJo2ARZwG+H59e7iTV1HdJU9y03No6z4zEbYS+4SE2ACTIAJMAEmwASYABNgAkyACTABJsAEmAATYAL1TYAF3PomXIv6B109iPCCHfzzIP3y0M+1qIWLMAEmwASYABNgAkyACTABJsAEmAATYAJMgAkwASZwrhNgAfdcP4PcfybABJgAE2ACTIAJMAEmwATOOoGKkhIqLyk2a9fF04uoRQuz9KaeUFhYRGXlZUaH6eTkRB7u7kZpvMEEmAATYAJMgAnUnAALuDVnZrVEYUEhxR+Op75D+xrlwYRkx/cfp7QjaVSYWUDeQT7UqU8AIa6tI+zgzoPULbwbubm7OaI6roMJMAEmwASYABNgAkyACZxVAgfuv4sy162mbo/MpuA7/s9i2yUpJ2jLpBFy36h/d5Br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LsC7dOlSa9++vXXt2tUOP/xw69SpU666CgK/+uqr1rhxY7vooovsnXfeMaVo0I/KXnvtZWeeeab17Nkz135aGDdunL377rtuwLUlS5bYHnvsYW3btnXnUe9nBZyjy5w5c+yDDz5wg7PNmjXLmjVrZnvuuaftt99+dsABB0RXT7isfMFvv/22TZ8+3RYsWGDdu3d3g50ddNBBQbqJhAdgIwIIIIAAAggggAACCCCAAAIIIIAAAqUskGwQt6SDt7rsUh/ErJSti+10b7zxht1zzz3ueM8//3xSwcft27fbzp07rWLFiu5HO2/evNkeeOABe+utt+K2TblzTzzxxGD7F198YTfeeKMbEK1fv36mtsQqt9xyiw0aNCjYpHQOjz/+eLAcPXP00UfbtddeaxUqVAg2vfnmm3b33XcHy9Ez2kftq169erAp3iBmChz/4x//COqFZ5SC4j//+Y8LXIfXM48AAggggAACCCCAAAIIIIAAAggggEC6CCQK0KqN0b10ta64et7qWCr0wM1xyPf3woULXR0FHv1AZfntFKt369NPPx0Eb33PWfWs1T+GBx980A16du+997rettG9XdUG/QwYMMBOOeUUq1+/vuvJ+8ILL9jGjRvt0UcfDQK4q1atCoK3++yzj5111lmu9+3y5cvtueees7Fjx9p7771nCsj26NHDXYrW+eBtgwYN7LLLLrOOHTua9tE5Jk+e7PapVauWXX755Qkvf+rUqUHwVudXWomsrCzXE1jXqfzAyh2sIHPDhg0THouNCCCAAAIIIIAAAggggAACCCCAAAIIpEIgUU/cWO0p7uCtzpGSAO6IESNs5MiRLg2BEDIhH64e/1dp3bq1mxbml1IlqPeuyv7772/qMeuDvHJQYFYDoa1YscL10lXgs0qVKrlONXDgQLv11luDHr1Kt6Bevk888YQL7q5bt87q1KljM2bMCPZT2oUOHTq45aZNm1q3bt3s5JNPdkHUKVOmuACuegurR6yKgrf//e9/rW7dum5Zbevfv787r9JIvPLKK3b88cdbvLy+OpYGeFM58MAD3XX6Xr5K39C3b18bPny4Czp/+OGHdsYZZ7i6/EIAAQQQQAABBBBAAAEEEEAAAQQQQCDdBOIFcaPbWRLBW52jYvSJSnrZB291HvU6VSBX69K9qEerinrgFrYo560v6sHqg7d+nQKvvmer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"/><use stroke="#979797" xlink:href="#rect-1"/></g><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#979797" d="M74.703 438.786a230.957 230.957 0 012.035 3.992l.273.553c.743 1.514 1.326 2.773 1.702 3.694.138.339.08.706-.104 1.1-.094.203-.221.41-.373.619a5.679 5.679 0 01-.503.605l-.147.151h-2.273l-4.2-8.574-5.613 5.727v-23.878l15.69 16.01h-6.487z"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="696" height="512" viewBox="0 0 696 512"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h696v512H0z"/><path id="path-2" d="M66 424v21.429l5.25-5.358L75.625 449h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H80L66 424z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0.0941176471 0 0 0 0 0.0901960784 0 0 0 0 0.0901960784 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="domconsole1.svg"><g id="Bitmap"><image width="696" height="512" xlink:href="data:image/png;base64,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AhKQgAQkIAEJSEACEhgsAT1wB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JiAAm7HqAwoAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSGCwBBRwB8vbs0lAAhKQgAQkIAEJSEACEpCABCQgAQlIQAIS6JjA7DPPPLPjwAaUgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJCCBwRHQA3dwrD2TBCQgAQlIQAISkIAEJCABCUhAAhKQgAQkIIGuCMy69dZb7+9qDwNLQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpDAQAjogTsQzJ5EAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkED3BBRwu2fmHhKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEBkJAAXcgmD2JBCQgAQlIQAISkIAEJCABCUhAAhKQgAQkIIHuCSjgds/MPSQgAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJDISAAu5AMHsSCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQALdE1DA7Z6Ze0hAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISGAgBBdyBYPYkEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAS6J6CA2z0z95CABCQgAQlIQAISkIAEJCABCUhAAhKQgAQkMBACCrgDwexJJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQl0T2B297vM7D0uu+yydOmll6YTTjihryAe8pCHpCc84QmJ5VTYBRdckA+70UYbTcXhPaYEJCABCUhAAhKQgAQkIAEJSEACEpDANBFQ95km8AM6rR64XYI+/vjj+y7eEoUQhruMjsElIAEJSEACEpCABCQgAQlIQAISkIAEJCCBMSagB26XFxehFfvIRz7S5Z6tg7/3ve/NwjBeuJoEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQjogWs+kIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQwpAT66oHb7+kFYj7Y17zmNUOKz2hJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACVQKhE6LvxbufqmH83xmBvgm4Bx98cJ7HtbPTdhYqpivggju1QGfMDCUBCUhAAhKQgAQkIAEJSEACEpCABCQggekkEOItcUDfC41PfW9yV6VvAm5cCOeGndyFmMl7/epXv0r33ntvxwi42RdddNF0+umnp2uvvTats846adNNN+14fwOOP4E777wzXXLJJenSSy/Ny+uvvz6ttNJKabXVVksPe9jD0sYbbzz+EP6bwt/85jfpnnvuSQ996EPTKqusMmPS3SyhN910UzrxxBPT1VdfncgXs2fPzlwoR+bOnZuWXHLJZru6fkwJ3HfffY2Xky633HJpm222aZnSq666KvGG38UXXzxtt912LcOO88bLL788XXzxxWnppZdOj370o8c5qY20UXY0q6/MmjUrrbjiiunBD35wftbwf1B21lln5Tx56623pvXXXz9tv/32gzq15xlDAmU+X2+99RKfdka963e/+10j2GabbZbvg8YKf4wtgXgmkkA86+bMmTM0ab355pvTn//85xwfykXaj9jvf//7dMcddwxd3bhZfHOk/ZLAiBI44YQTFog560ZNwMVhlTjHLAELJKrJCnRSROx+zSrQNwG3SXxdLYGWBGgIHXDAAS3DVDc+9rGPzQ/g7373u+mPf/xj2mWXXWasgIsw9+tf/zojetSjHpVWWGGFKq4Z9//KK69Mn/3sZ9O8efMmpP2GG27IDVwEzTXWWCO9+tWvTmuuueaEMOP459vf/nZO1rLLLjujBdz7778/fetb35rQwIzr/Y9//COdccYZ6ac//Wl64QtfmHbYYYfY5HIGELj77rvT9773vUZKl1pqqZbPFBp+lCOLLbZYzwIu5dKZZ56Zzz1qFVni/fOf/zwhes8EAReh/zvf+U4jn7T6sfLKK6fddtutI+Gr1XE62fb9738/HXfccY2giCkKuA0c/pgEgTKfr7rqqukDH/hA26MgkpXlKOUjneba+BOgbhWOXDgKfOhDHxqaRNNRH/mSdlIIuEcccUSO43TUjWm7nXTSSfn8j3jEI9Lyyy/f4NUsvo0A/pDA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AQkMjsDswZ3KM0lgNAnce++9C0R84YUXXmCdKyQgAQlIQAISkIAEJCABCUhAAhKQgAQk0G8CIyng/v3vf0/3339/WmGFFdLSSy/dNZOLLroo/eMf/0iIcNttt13X+7tD/wicddZZ6aabbkqLL754etSjHtW/A/fpSFdddVW69NJLFzjaNttsk5ZccskF1rtCAhKQgAQkIAEJSEACEpCABCQgAQlIQAL9JDByAi7C7SWXXJIZrLrqqmmjjTbqmsd9992X9+FY023/+te/0oUXXphmzZo1lALmVPOJaxDLbs935plnpttvvz2tttpqaZ111ul297bhF1tssTR79gO3CXGs88ZtexADSEACEpCABCQgAQlIQAISkIAEJCABCUhgkgRGTsCdZDqHdrc77rgj3XnnnUMbv2GP2G233ZbuueeexHIqbJVVVkl8sFtvvTWddtppU3EajykBCUhAAhKQgAQkIAEJSEACEpCABCQggVoCvsSsFosrJSABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlMP4Gh9MBlftpFFlkkPehBD+qZ0C233JKuu+66NG/evLTMMsvkofbtDspQ+WuvvTb9+9//TnfddVee63TFFVdMK620UrtdE+djWgS8NZmqgXlS11hjjQnzpbLt5ptvzseKJX+Y27e05ZZbLseZdbEP8/YyXUCdkUbmk2U6Bs6JMb3AjTfemOf7ZcoJWNxwww15G3MIc6yFFmqu4//nP/9J//znP3O62Ik4cZxFF100H6OfX3Anrtdff326++6787nWXnvtBeJ39dVX5zmQOXdMh0E8S36kafXVV29EjzxFWOLPvLb8hhEMrrjiinytuVZz5sxZ4HyNg3Tw48orr8zXjONqEpCABCQgAQlIQAISkIAEJCABCUhAAhLolcDQCLgIcJdddlkW8BDyHvzgB/cs4F588cUJsS8MsRSRr9WLz4jH6aefnoflx34IuQiAyy67bNpyyy1rBT7mRj377LOzEBj7sYx9EUo33HDDvAmRL0TUMmzM7RvrELA33XTT/JfjxMu0EBoRIqt27rnnJuKPyBsCLoItAiUGC0TeMMTSyy+/PG299daJuV6rxty811xzzYTViNPss/HGGzemFpgQoIc/f/nLX3L84xCkmTg/+tGPzmmK9VzXqpHuKr9SwOXFdVUj/bBkX4zzkUfgMVmDF/mY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RXiD0qVLS9myZdPdmCwjTJKSkuTo0aNq4zRcIxYuPHkhfPuzLViwwPRShsdyt27dsrS79MDNUryBXTm+OaFwG9hzzNGRAAmQAAmQAAmQQFYQgGBbuXLlrKiadZIACZAACZBAlhGA96m7L1SzrNEcrhgidVYK1Qgpwb8J0p9keuCmz4g5SIAESIAESIAESIAESCDHCASiB26OwWTDJEACJEAC2U4gkDxwsx0eG8yTBODda/fozZ8nSXDQJEACJEACJEACJEACJEACJEACJEACJEACJEACJOBHBKyhGazdooBrpcFrEiABEiABEiABEiABEiABEiABEiABEiABEiABEshmAu7EW3SDAm42TwabIwESIAESIAESIAESIAESIAESIAESIAESIAESIAFNIC3xFnko4GpSPJMACZAACZAACZAACZAACZAACZAACZAACZAACZBANhJIT7xFVyjgZuOEsCkSIAESIAESIAESIAESIAESIAESIAESIAESIAESAAFPxFvko4ALCjQSIAESIAESIAESIAESIAESIAESIAESIAESIAESyCYCnoq36A4F3GyaFDZDAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAhkRb0GLAi5fMyRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQDQQyKt6iS3lawN29Yre8EPm8vN3+P9kwPe6b+OW5n1U/Fr6/0H0mPiEBEiABEiABEiABEiABEiABEiABEiABEiABEsi1BLwRbzHYgrl2xD7o+NUrV1UtiWcTfVCb91UkX76iCl+5nOx9JSxJAiRAAiRAAiRAAiSQJwmcO3cuT46bgyYBEiABEiABEiCB3EagW7dugiOjlqc9cDMKi/lJgARIgARIgARIgARIgARIgARIgARIgARIgARIIDsJUMDNTtpsiwRIgARIgARIgARIgARIgARIgARIgARIgARIgAQyQCBPhVA4f+687InZIw1bNHRCdO3qNTm05ZDsWxsnCGlQuXFlCW8eLgWD3CM6uvOoxG+Ll4R9J6VomVApX6e8VGlSRfIXcK+LI/+BDQfk/IlzUiWqqkQ0j3DqCxJOx5+WE3tPSMHgghLeLNxlnrNHz8qxXcdUe9VaVZPDBw5L4qVEiYh0XafLSphIAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiTgtwTcq5NZ2OVd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BMi1Q2DHSYAESIAESIAESIAESIAESIAESIAESIAESIAESCAwCVDADcx55ahIgARIgARIgARIgARIgARIgARIgARIgARIgAQCgAAF3ACYRA6BBEiABEiABEiABEiABEiABEiABEiABEiABEggMAlQwA3MeeWoSIAESIAESIAESIAESIAESIAESIAESIAESIAEAoAABdwAmEQOgQRIgARIgARIgARIgARIgARIgARIgARIgARIIDAJUMANzHnlqEiABEiABEiABEiABEiABEiABEiABEiABEiABAKAAAXcAJhEDoEESIAESIAESIAESIAESIAESIAESIAESIAESCAwCRQMzGFxVCRAAiRAAiRAAiRAAiSQNwkcOHBAkpOTpXjx4uooWJB/8ufNVwJHTQIkQAIkQAIkECgE+NdcoMwkx0ECJEACJEACJEACJEACBoEpU6bI0aNHTRY33HCDDBo0yLznBQmQAAmQAAmQAAmQQO4iwBAKuWu+2FsSIAESIAESIAESIAESSJNAmzZtpHnz5lK6dGmVb+XKlbJt27Y0y/AhCZAACZAACZAACZCA/xKgB67/zg17RgIkQAIkQAIkQAIkQAIZJtCuXTtV5tq1a/Laa6/JmTNnZNeuXVK/fv0M18UCJEACJEACJEACJEACOU+AHrg5PwfsAQmQAAmQAAmQAAmQAAn4nEC+fPmkcuXKqt6EhASf188KSYAESIAESIAESIAEsocABdzs4cxWSIAESIAESIAESIAESCDbCQQFBak2sakZjQRIgARIgARIgARIIHcSoICbO+eNvSYBEiABEiABEiABEiABEiABEiABEiABEiABEsgDBCjg5oFJ5hBJgARIgARIgARIgATyNoHExMS8DYCjJwESIAESIAESIIFcTIACbi6ePHadBEiABEiABEiABEiABNIiEBoaqh7HxcXJ1atX08rKZyRAAiRAAiRAAiRAAn5KgAKun04Mu0UCJEACJEACJEACJEACmSVQpUoVVQXE282bN2e2OpYnARIgARIgARIgARLIAQL5rhmWA+2ySRIgARIgARIgARIgARIgAQ8IbNy4UeVq0qSJB7kds+BP/SlTpsj69evVg7CwMClVqpRERkZKt27dHDPzjgRIgARIgARIgARIwC8J0APXL6eFnSIBEvAHAtix+3JSksNx5coVf+ga+0ACJEACJEAC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AAIIIIAAAggggEAmCRDAzaS7RVsRQAABBBBAAAEEEEAAAQQQQAABBBBAoFwJEMAtV7ebi0UAAQQQQAABBBBAAAEEEEAAAQQQQACBTBIggJtJd4u2IoAAAggggAACCCCAAAIIIIAAAggggEC5EiCAW65uNxeLAAIIIIAAAggggAACCCCAAAIIIIAAApkkQAA3k+4WbUUAAQQQQAABBBBAAAEEEEAAAQQQQACBciVAALdc3W4uFgEEEEAAAQQQQAABBBBAAAEEEEAAAQQySYAAbibdLdqKAAIIIIAAAggggAACCCCAAAIIIIAAAuVKgABuubrdXCwCCCCAAAIIIIAAAggggAACCCCAAAIIZJJA5VQ0dsSIETZy5Ehr166d+xkyZEgqmsE5EUAAAQQQQAABBBBAAAEEEEAAAQQQQACBtBYo9QCuD95KZe7cue5H8wRxpUBBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQR2C5R6AFc9b6OL1mVaAHfLli32ww8/2I8//mgzZ860RYsWWdOmTa1Vq1Y2YMAA69GjR/Rlltnljz/+2LKzs61v377WpEmTMnudXBgCCCCAAAIIIIAAAggggAACCCCAQPkReOyxx1zMUlkEClLUaVWdWC+44IKC7Ba3boV169btjLu1BDZcf/31eY4qhOK6oDwHL4EV8+bNsz//+c+2cOHCuEfv37+/XXXVVS6gG7dSGdkwePBgdyW33367DRw4sIxcFZeBAAIIIIAAAggggAACCCCAAAIIIFBeBRS8VSBWRXHLZIO42kf7qhRXzLPUBzE75JBD3AWEfyULEN4nVfOKnp9zzjlB8LZz5842bNgwu+aaa2z48OHWvHlz17Tx48fblVdeaStWrEhVUzkvAggggAACCCCAAAIIIIAAAggggAACCBRQIBy81a7Ry/EOFw7eqk70crz98ltf6gFcpUoIB3E1nynpExYvXmx//etfnWnNmjXtrrvuskceecSuuOIKO+644+y8886zZ555xi699FJX55dffrGbbropv3vAdgQQQAABBBBAAAEEEEAAAQQQQAABBBBIE4FYscr8grjxgrWxjlXQyyz1HLhqoBpeHI0v6MUWtb7v/qzj3H///TG7TleqVMlOPfVU++mnn+y1116z7777zuXHbdmyZVFPz/4IIIAAAggggAACCCCAAAIIIIAAAgggUMICPvVBOBaoU2o5VjqFeMHbWHUL0/SUBHAL09BU76PByj799FPXjKFDh8YM3obbqDoK4KqMHj3aTjvttPBmGzNmjH355ZcuwLt06VJr3769de3a1Q4//HDr1KlTrroKAr/66qvWuHFju+iii+ydd94xpWjQj8pee+1lZ555pvXs2TPXfloYN26cvfvuu27AtSVLltgee+xhbdu2dedR72cFnKPLnDlz7IMPPnCDs82aNcuaNWtme+65p+233352wAEHRFdPuKx8wW+//bZNnz7dFixYYN27d3eDnR100EFBuomEB2AjAggggAACCCCAAAIIIIAAAggggAACpSyQbBC3pIO3uuxSH8SslK2L7XRvvPGG3XPPPe54zz//fFLBx+3bt9vOnTutYsWK7kc7b9682R544AF766234rZNuXNPPPHEYPsXX3xhN954oxsQrV+/fqa2xCq33HKLDRo0KNikdA6PP/54sBw9c/TRR9u1115rFSpUCDa9+eabdvfddwfL0TPaR+2rXr16sCneIGYKHP/jH/8I6oVnlILiP//5jwtch9czjwACCCCAAAIIIIAAAggggAACCCCAQLoIJArQqo3RvXS1rrh63upYKvTAzXHI9/fChQtdHQUe/UBl+e0Uq3fr008/HQRvfc9Z9azVP4YHH3zQDXp27733ut620b1d1Qb9DBgwwE455RSrX7++68n7wgsv2MaNG+3RRx8NArirVq0Kgrf77LOPnXXWWa737fLly+25556zsWPH2nvvvWcKyPbo0cNditb54G2DBg3ssssus44dO5r20TkmT57s9qlVq5ZdfvnlCS9/6tSpQfBW51daiaysLNcTWNep/MDKHawgc8OGDRMei40IIIAAAggggAACCCCAAAIIIIAAAgikQiBRT9xY7Snu4K3OkZIA7ogRI2zkyJEuDYEQMiEfrh7/V2ndurWbFuaXUiWo967K/vvvb+ox64O8clBgVgOhrVixwvXSVeCzSpUquU41cOBAu/XWW4MevUq3oF6+TzzxhAvurlu3zurUqWMzZswI9lPahQ4dOrjlpk2bWrdu3ezkk092QdQpU6a4AK56C6tHrIqCt//973+tbt26bllt69+/vzuv0ki88sordvzxx1u8vL46lgZ4UznwwAPddfpevkrf0LdvXxs+fLgLOn/44Yd2xhlnuLr8QgABBBBAAAEEEEAAAQQQQAABBBBAIN0E4gVxo9tZEsFbnaNi9IlKetkHb3Ue9TpVIFfr0r2oR6uKeuAWtijnrS/qweqDt36dAq++Z6vy1SrvbnQ555xzguCt3xZOm+Db2aZNG7/ZBXcVFPalcuXK9tBDD9mTTz5pRxxxhFs9e/ZsFwDWgnre+uCt30dtveSSS/yijRo1KpiPnpk/f74p962K/uH64K1bEfnVqFGjIGj7+uuv+9VMEUAAAQQQQAABBBBAAAEEEEAAAQQQSEsBH8SN17iSCt7qfKXeA1cB2+iideneC1dpExTkXLZsWXTzk15etGiRq9uqVau4aRjUO9WXxYsXu96yflnTcGDWr69du7afNfV+VVHvWPW01QBoChzrRwOR6fhK3aABz5o0aRLsp4CxL8qzG6uovnryysFfS6x6Pt2EtilFgnIARxffo1mBZaV/KEpgPPrYLCOAAAIIIIAAAggggAACCCCAAAIIIFBWBEo9gBsLThHsdC8Kuqoo0KkgaXTv2Vjt1wBeK1eutK5du9rZZ58dBH+VxiBeUc9XBTMV1AwHVX39atWq+dl8p0pj8NRTT7mcuzrezJkz3Y9P46C8tOeff75VrVrV5bn1B1Su2nhFDuHeurHqKfDsyyeffOJn407XrFlDADeuDhsQQAABBBBAAAEEEEAAAQQQQAABBFItEG8wM98uDWZWUr1wSz2Ae8ghh7i0Cf7iNM2EAG544DL1Zg2nLQhfi59XLtp3333XLXbv3t1NfVoCbYtXtm7d6oK32q5ByopSqlev7tIe6B+PeuIq3+2kSZNs4sSJ7rAvvfSSy4P7pz/9ycK9eBP1iPUpGhIFecPb/vCHPyS8BKVXUM5dCgIIIIAAAggggAACCCCAAAIIIIAAAukokF/w1re5pIK4pR7A9akSfCoFBXT9On+x6Tjdd999g2apB2t+AdxwvtvevXu7fX0vXvWE3bx5synAGl30D8KXeIOE+e2JpmvXrjUFW2vUqOFSJShtgn5+/etfu/QHN9xwg8tT+9FHH9k111xjLVq0CA43Z84cN7BZsGLXjILLs2bNckuxUjn4+uGB3jQQW6wArYLYSkeh3r+xHPyxmCKAAAIIIIAAAggggAACCCCAAAIIIJAqgXjBW3WYVFHQNlxKIoibNzlp+IwlNK+A7W233eZ+MiF4KwYNvHX66ac7EQVgH330UduxY0dMoZ9//tnuvfdet03Byy5durj5Hj16BPX/97//BfPhGQ0s5kvHjh39bIGnr732mmnAs//7v//Ls68CwyeddFKwfv369da+fftgWWkXYpU33ngj6B3sexXHqte2bdsgJUK8QcruvPNOu/DCC+2mm26KdQjWIYAAAggggAACUXmGtgAAQABJREFUCCCAAAIIIIAAAgggkFKBRMFbZRSIN7CZgrjhTppFvYiUBHCL2uhU7a+csX6wreeee85uueUWmzFjhqlnqoqm6nmrwKTSEKjceOONrpep5vv06WMDBgzQrAsAK4XBtm3b3LJ6pCqoOWbMGLes3LT16tVz84X5pUHKVDSg2COPPGKbNm0KDvPLL7/YiBEj3PIee+zhgtN16tSxiy++2K0bP3683X777eZTPWRnZ5sCwg888IDbrh7Fe++9d3C86BkZqaevytNPP23PPvus63GsZR1TQd1Ro0Zp0Y488kg35RcCCCCAAAIIIIAAAggggAACCCCAAALpIpBf8Na3szSCuBUiAbWd/oRM8xfQAF0Kymogr3BRjtzoQccUyD3zzDPD1Uz7X3vttbnqRu/bt29fF0D1qQW++OILd04d6LPPPst1PC2ox++wYcPc+ieeeML1ptVAa9dff30QENZG9YzVegV1fVFbjjnmGLe4ZcsWU2qFcePG+c0W3TYFfP/1r39ZOE3C4MGDXX0FfQcOHOjmlSLiuuuus6lTpwbH0r4rVqwIltUjWccqyMBswc7MIIAAAggggAACCCCAAAIIIIAAAgggUAICyQZvw6cuzD7h/RPN0wM3kU6MbcoVe//999spp5zigpu+Sjh4q1yzjz/+eJ7grepqf3WjPu6444LevH5fBTjVC/af//xnrrywlSsXPFVxpUqVXHoCBZB9r+F58+YFwdvOnTvbzTffHARv1TYFUu+44w674oorTG1R8W3TMRToVYqHcPDWVdr1S+f0RcHnu+++284777wgB244eHvGGWfY3//+d4K3HowpAggggAACCCCAAAIIIIAAAggggEBaCPgn18ONUc5b9baNV+L1xI11rHjHiLc+JT1w1XANYqYL00+m5MGNhaiUABr0S4OGqbeqfjRwWLJFvWcV2FReWqUxKImiFAg6jwY1U5A2KysrCKomOp+ubdGiRS7Fgg/oJqqfaNuaNWtcMFhpIXSsKlWqJKrONgQQ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"/><use stroke="#7E7C7B" xlink:href="#rect-1"/></g><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#7E7C7B" d="M65.5 422.775l15.69 16.01h-6.488c.886 1.695 3.06 5.91 4.01 8.24.318.776-.979 2.324-.979 2.324h0l-2.42.151-4.2-8.574-5.613 5.727v-23.878z"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/elk.svg b/2-ui/1-document/02-dom-nodes/elk.svg index 19ea221d29..1797a099ff 100644 --- a/2-ui/1-document/02-dom-nodes/elk.svg +++ b/2-ui/1-document/02-dom-nodes/elk.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="698" height="249" viewBox="0 0 698 249"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h698v249H0z"/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="elk.svg"><g id="Bitmap"><image width="698" height="249" xlink:href="data:image/png;base64,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eeaZ3HbMEHr99dd3u+66q2NZChs/frw/7EYbbVSKw+uYIiACIiACIiACIiACIiACIiACIiACIiACTURAuk8TgW+i08pDN0fwTz/9dNHFXKJgQnGO0VFwERABERABERABERABERABERABERABERABERCBGiIgD90cbzbCK/anP/0pxz3TB//d737nhWK8dGUiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEEdAHrpxVLROBERABERABERABERABERABERABERABERABERABMqQQFE9dIs9HIGNJ3vMMceUITpFSQREQAREQAREQAREQAREQAREQAREQAREQAREII4AOqH1dC/lvFFx5672dUXz0L3++uuLPrYsN50PCUAmAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQ/gTQ85555hmv6/Eb3VD6XvHuW9E8dLk5mMaWLd7NqZUj/e9//3NLly7N+nJp1WnVqpV7++233ezZs916663n+vbtm/X+Clj9BBYvXuwmT57spkyZ4pcff/yx69Spk+vSpYvbbLPN3MYbb1z9EL69wueee84tWbLEbbLJJq5z5841c91JF/r555+7Z5991s2cOdORLlq0aOG5kI8MHjzYrbzyykm7an2VEli2bFmqQbpDhw5uq622Snul77//vmMG4TZt2rhBgwalDVvNG6dNm+YmTZrk2rVr57bddttqvtTUtZF3JJVXmjVr5jp27OjWWmst/67hf2PZqFGjfJr88ssvXa9evdxOO+3UWKfWeaqQQJjON9hgA8cnk1HuevHFF1PB+vXr55+D1Ar9qFoC9k7kAuld27Nnz7K51rlz57o33njDx4d8kfoj9tJLL7lFixaVXdk4Kb4+0voSgQolUC3iLUJ0Pt7F5qBaqlEHiiboVmj6UrSbmAAVowsuuCCnWGy//fb+hXzXXXe51157zQ0dOrRmBV2Euqeeesrz22abbdzqq6+eE8tqDDxjxgz3t7/9zS1YsKDe5c2ZM8dXeBE41113XXfUUUe5rl271gtTjX/+/e9/+8tq3759TQu6y5cvd3fccUe9Cqfd7w8//NC988477uGHH3Y/+tGP3JAhQ2yTljVA4JtvvnH33HNP6kpXWWWVtO8UKoLkI61bty5Y0CVfGjlypD83hcRKMuL92GOPOUTwWhB0Ef7vvPPOrG7RGmus4Y4++uishLCsDpgm0L333uuefPLJVAjEFQm6KRz6kQeBMJ2vvfba7rzzzst4FESzMB8lf6QRXVb9BChbmWMXjgN/+MMfyuaiabi3dEk9yQTd2267zcexKcrG1N2ef/55f/4tttjCrbbaaileSfFNBdAPEagSApZnVMrlIOYSZ5YIszY0bKb42z6Es30z7ZPrdgm6uRJT+JIRQIzs1q1bxuOvtNJKGcPUSoCvv/7a/fnPf/aXe+WVV9a8oPvCCy940c7uP2lqww03dOuss4777LPPfCv9woULvXcm3M4991xHxVtW/QSooJr3EBXNrbfe2gvcX331lRf68eY2wWbNNdd0/fv3r34ousJYAhS4LrzwQi/YxgYo4koaoO6++25/xF122cU1pldnES+j5g7VsmVL741rF06DEd6xvF8whPq//vWvvsG6lA2teEWa5wvn2XTTTb3HtMVLSxEolAA94fgg7KYzvHpltUfg008/TYm5XD2CJI1K2dTnao/Wiium7mbvfeonoaBbq0zyuW6cMLAf/vCHsbtn2h67k1aWhADiZ1TArSQnBhNzDY4Js5lE3VDMZV/7X2xPXQm6dme0bHIC++67r/vZz37W5PFQBCqTAF6WeAlgzZs3dyeccIIbOHBgvYs55JBD3EMPPeQef/xxh1feZZddVvRhYuqdUH/KggBCCx6VGN7Zv/nNb1JeGn5l3de4ceN8euD/jTfe6C699FLbpGWNEcC7H6/Hww47rMauXJebLYEddtjB8T6JGnnNv/71LzdixAjfQERPIt5FpTJriOL4J554oh+CqlTn0nFrlwCN5fReSbJPPvnEffDBB0mbtb6KCZinKY1cGGVrxsr86U9/WtZXTX2TRvzevXuXVTwpox5xxBG+cZfeQrJ4Aoi1JtgSIirqZtoef1StLRUBxFuG7rEGaITQTGJoqeKSz3GJPyJuaJlEXRNvw334XQohW4JulPK3/7kJFJR5KcXZ7373u3qrSZTcoEpKnPUuQH9EoMIJ2NACXAaCHWOiRg2hd7/99nNUPt58803vRYUQTAu5rHoJTJw4MXVxBxxwQAMxl42Mq/z973/fMaY3gt68efMcXfFktUkAAWO77bZrlC7ztUm4Oq961VVXdccee6x/BzEWImMMl9LwDDZj7F6ZCBSTAGUmRC+GmTn44IMTexCQX2IWvphx0LHKlwD5j917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VWTLIDJMmMnEZ7lOJMjEiQxdpeGCyuAmKgoikCMBHDejAq7pfDkeSsFjCBRV0I05ftpV3MhM41eFNzv8nfbA2igCIiACIiACIiACIiACIiACIiACJSLA5F58ZNkRYCK0fGy77bZzfGQiIAKVR8A0Pxt6Ia53fuVdVfnEuFndDNbLyyc65ROTcCa7xooViTvJW7nQOJTjbIeFXpP2FwEREAEREAEREAEREAEREAEREAEREAERcE66T22lgua1dbnZXy0tCdFxfbPfO/eQnEseyLlz0x4iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUEsE5KFbS3db1yoCIiACIiACIiACIiACIiACIiACIiACIiACIlDRBOShW9G3T5EXAREQAREQAREQAREQAREQAREQAREQAREQARGoJQISdGvpbutaRUAEREAEREAEREAEREAEREAEREAEREAEREAEKpqABN2Kvn2KvAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIQC0RkKBbS3db1yoCIiACIiACIiACIiACIiACIiACIiACIiACIlDRBCToVvTtU+RFQAREQAREQAREQAREQAREQAREQAREQAREQARqiYAE3Vq627pWERABERABERABERABERABERABERABERABERCBiiYgQbeib58iLwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUEsEJOjW0t3WtYqACIiACIiACIiACIiACIiACIiACIiACIiACFQ0gRYVHXtFvuQEvnfepyU/h05Q/QSeOqdT9V+krlAEREAEREAEREAEREAEREAEREAEREAEGoFAi/HjxzfCaXSKyiWwRuVGXTEvGwLKZ8rmVigiIiACIiACIiACIiACIiACIiACIiACFU5AQy5U+A1U9EVABERABERABERABERABERABERABERABERABGqHQLPldVY7l6srFQEREAEREAEREAEREIHKIjBy5Egf4Z49e1ZWxBVbERABERABERABERCBkhCQh25JsOqgIiACIiACIiACIiACIiACIiACIiACIiACIiACIlB8AhJ0i89URxQBERABERABERABERABERABERABERABERABERCBkhCQoFsSrDqoCIiACIiACIiACIiACIiACIiACIiACIiACIiACBSfgATd4jPVEUVABERABERABERABERABERA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X9aKrWP/954b9fC7bp3+67gdj98xm11yCtNspWZug+02SO0z5dUpK37XzTopEwEREAEREAEREAEREAEREAEREAEREAEREAEREIFiEyhrQbfQi/1kyhw35vHRbsni/AThTOdv0aqF+9ltR6aCXTbkUvf5+5+n/uuHCIiACIiACIiACIiACIiACIiACIiACIiACIiACBSTQPNiHkzHEgEREAEREAEREAEREAEREAEREAEREAEREAEREAERKB2BsvLQXTB/gZs6bqrrv2X/2Cue++FcN/2NaW7OtE9dpx6dXO/BvV3bDm3rhf1o/EduwWcL/LpPp87xy/lzvnSp4RC+Dd11066uVdtW/t/HEz5y8z9d4NbYYA03ffg092nd8devG0phvS3Xcx+O/tBNenGia9O+reu3Zz+3SsdVvj1C7ovZH8x2ixctduv1Wi/3nbWHCIiACIiACIiACIiACIiACIiACIiACIiACIhAzRNockF3ed14s9MnTnfvvf2e++LTL1yzZs1iBd13H3nX3fPLu+vdsPZrt3dH/eto17F7x9T6py972o17amzqPz9mjprpbj78pnrrTnzoJNelbxe/7pkrnnXv/XdMve3u8mfcDkfv4F6+4eXU+tdve90Ne3SYa75Sfo7Ns2bMcmPfGetef+Z116N3D9dvizqBeNX8BeJUxPRDBERABERABERABERABERABERABERABERABESgJgg0maA7f+58N2bEGDdtwjS3dOnSFOxWbVZ4zaZW1P1YvGCxF3OZgKznDj3d+GfHuxlvzXDzZs9zL1z9vNvvwv1TwTfdb6DrVud9i01+ebL3zF292+puy6FbpsLwo/1a7ev9tz9Mnjb6sdF+LFzE3DV7dXa9d97QC7ufTPrYe+x2Hbji+LZPtstV2q8Qb5csWeImvTfJfzp07OD6btbXC7yI2TIREAEREAEREAEREAEREAEREAEREAEREAEREAERSCLQqILu8mXL3ZTxU7yX6rzP56XihJC51rpruT6b9XFduq3wmk1t/PbHgL0HuIMuPdg1a97M7XjCTu75q55zeOOOuGeE2/eC/bxnL0H77tEvtevyul8MtdB5w7X8PqkNCT8GnzzE7XLKLm6D7Xu6W356sw912DWHuY7rdfRDMox88B03e+xsl6+g27t/bz/cwvhR492kMZPcooWL3NzP5rpXn37VDX9uuN/Wb8t+btUOqybEUKtFQAREQAREQAREQAREQAREQAREQAREQAREQARqmUCjCLqIt6PfGu1mTJrhli1bluKNcLlh/w1dr369XIsW6aOyU52Ii5hr1nf3vl7Q5f+iuYtc29Xqj6Vr4XJZ2tANHbp0SO22WtfV/G+8fLFF8xb6Zb5frdu0dptsvYn/fPbxZ+69d95zH0z5wHspI3bzab9ae7fxphu7nhv3rHfN+Z5T+4mACIiACIiACIiACIiACIiACIiACIiACIiACFQHgfQqapGu8aX/veTHx+VwCLeMH8swA+06tMv6DJ3qJiwLbZVO3+27sE5kLYag27LNChwt27ZMncrGy23ResW2xQu+Tm0r9EfHzh3doO8PcnguT5s4zY0bOc59PudzN++Led5jd7WOq7k11q5/3YWeU/uLgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhULoH8Zvcq4HqZBI0xc8NxczMdrvUqrV2LVvW159BbF0G0GLZSy5X8YUzE5bxmK7VYgWrZku/G+7VthS6XLV/mlnyzxC1b+p33cqHH1P4iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIALVR6C+Slqi6xu812D33oj33JRxUxwTgk0dP9V/Vl5lZT/cQu8BvV2r1g0nQytRdDIetrEmJ/to5kdu7Ntj3az3ZzmEbrOOa3Z0fTfvK+9cA6KlCIiACIiACIiACIiACIiACIiACIiACIiACIiAJ9Aogu7K7VZ2W+60pf+8P/l9N+btMY7xY79a8JUbNXyU/3Tq3MmPG9u9Z/fUBGeVeo++XvhNYtQXfLnATwo3ddxU980334Vr0bKF69mnpxdy265c+HjAiRHQBhEQAREQAREQAREQgYok8L3zPq3IeNdKpJ86p1OtXKquUwREQAREQAREoIkJNIqgG15jt57dHJ+FXy303qmT35vshc1PP/7Uvfy/l93wlsPdwcceHO6S9+82q7bx+86f82Xex8hlx9W7ru4+f/9z9/6IGW7gvgMb7MoYuSNeHlFvPWPk4o3btUfXeuv1RwREQAREQAREQAREQAREoHIIjB8/vnIiq5iKgAiIgAiIgAhUNIFGF3SNFl6om++wuf98OP1DN/qt0W7O7Dl+SAYLU+hytXU6+EPMHDXTTXh2vOs5qJezcXILPXbc/mv36eKmvDrFjfnvGNd3j35ug+02qBds4YKF/n/LVi39UBN9Nu3j2rRdITrXC6g/IiACIiACIiACIiACIiACIiACIiACIiACIiACIhBDoMkE3TAu66y3juOzeNFiP7ZuuK2Q3+tvu4Frv3Z7N2/2PHf7sbc7Jjlbrdvq/pBDrxjq1thgjUIO32Df7Y/a3r1y48tuwacL3M2H3+TP16JNC7f1YVu7Ib/Yxa3bY123dre1XZduXRrsqxUiIAIiIAIiIAIiIAIikI6AuvSno1MO2zTkQjncBcVBBERABERABGqBQPNyusjWbVq7jQdunIpSs+bNUr+jP8JtSZOYtWzb0h195zFuh6N3cKt0WsUtXrDYfTRutv8s/XpJ6pC2vx3TlqkAdT9snYUNt9lvxOOfP36y23Dn3l7M5XyIu4vnf+2DdF6ns8Rcg6WlCIiACIiACIiACIiACIiACIiACIiACIiACIhAzgSaLa+znPfSDiIgAiIgAiIgAiIgAiIgAo1CYOTIkf48PXv2bJTz6SQiIAIiIAIiIAIiIALlTaCsPHTLG5ViJwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAJNS0CCbtPy19lFQAREQAREQAREQAREQAREQAREQAREQAREQAREIGsCEnSzRqWAIiACIiACIiACIiACIiACIiACIiACIiACIiACItC0BFo07el1dhEQAREQAREQAREQAREQgUIItGvXrpDdta8IiIAIiIAIlJTA/PnzS3p8HVwEapGAPHRr8a7rmkVABERABERABERABERABERABERABERABERABCqSgATdirxtirQIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEAtEpCgW4t3XdcsAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQkQQk6FbkbVOkRUAEREAEREAEREAEREAEREAEREAEREAEREAEapGABN1avOu6ZhEQAREQAREQAREQAREQAREQAREQAREQAREQgYokIEG3Im+bIi0CIiACIiACIiACIiACIiACIiACIiACIiACIlCLBCTo1uJd1zWLgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhUJAEJuhV52xRpERABERABERABERABERABERABERABERABERCBWiQgQbfurt965C3u973Odm/d/VbFpYHLhlzq4z7ppUllGffpb053k1+e7L78+MtU/JZ+s9THGeafTPo4tb4Sfnz+weepuC+ev7gSoqw4ioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVBGBFlV0LXlfyjeLvvH7IjRWmn391dc+ysvKMO4fjZvtbvjx9T5+Jz50klu186r+9/Lly1OYly397ndqZRn/WB7Ed/myyop7GWNV1ERABERABERABEpMYMGCBW7s2LFZn6V3796uffv2btq0aW7OnDmuc+fOrnv37n7/WbNmuZkzZ7q2bdu6fv36ZX1MBRQBERABERABERCBaiHw9NNPu2eeecZfzi677OJ23XXXRr00CbqNiru2TvbS9S/7C+61Yy/XpW+X2rp4Xa0IiIAIiIAIiIAIlBGBjz/+2N19991Zx+jEE0/0gu6zzz7rheCddtopJehOnDjRPfLII65Lly71BN25c+c6tmFbbrll1udSQBEQAREQARFoDAJLlixxw4YNS53q6KOPdltvvXXqv37kR+Dqq69277zzToOdW7du7a644ooG67WiOAQk6BaHo44SIcDQBCMfXPFA73j8TpGt+isCIiACIiACIiACItBUBNZaay238sorpz19mzZt0m6P2zh79uyUaLzFFlu4Zs2axQXTOhEQAREQAREoCwJLl1ZeL+2yABeJxDffrOj1HlntktZHw+l/fgRqUtCdPmm6a9O2jVtr3bUaUFuyeImb+e5MN6Nu7NfmLVdy3Tbr5rpvvqJ7WYPAdSvodv/h6A/dxxM+coiYq3fr6NYdsI7r3Lvhsdmf4QY+GveRmzXmQzd39jx/yM691vTh19hgDf8/7mvpkqVuxlsz3MxRM12z5s1c9y26u66bdI0L6t59413Xs09Pt3K79AX12J0zrFwwf4GbOm6q679l/7QhX73pVb993U3Wdetvu37asAvnLnTvj6i7tnc/dO3WbOd6bt/TdVyvY+I+3yz8xn0w6oM65h+7rz7/qo5dZ3+f2q/VPnYfhtKYUXf8OZPn1I3lO8+1XrWNg/nafbqkhoGI25F4zXhret29muVWrTv2eluu55qv1HDY6a8WfOWmT5juNuy/oWvRsiYfqTh8WicCIiACIiACIlCmBPbdd1/Xq1evrGI3ZMgQ72275pprZhVegURABERABERABGqLAGWKr79eMRwojbtffvndHEq1RaJxr7Zm1KcFXy5wY94a46ZNmOZws++zWZ8Ggu6i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9d53331Sv359dzFzjPAFpUuXFsSCVYuKivLqAKjns2PrHp/72N3m4MGDjeg8evRoOXHCcw0qCNfduvl+Qvvee++VCRMmSHR0tC3kav1Ox0dwrV69uuzdu1dPe2ybNWsmENNp3gmEWIs5nfN+iqkkkD4BvHUQMxgWWiJ1lcf0S/EsCZAACZAACZAACZBAIATgzQrzFT8Onq75zZKSkoyoC1EYQjBCM9BIgARIgAQKJgHnDbz8PsJTp07J7t27TWgAiJFYQKygGxZIQ9xchEOoVKmSREREZLjQWSBMkpOTZd++fWYhNuwjli48fSGE52WbPn267cUMj+aePXvmaHfpoZujuAtWY7izQiG3YM0pR0MCJEACJEACJEACOUEAAm6NGjVyoim2QQIkQAIkQAJBIwDvVF83WIPWSB6rCKJ1dgrXCEHB3wSBTzo9dANnxhIkQAIkQAIkQAIkQAIkkGMECqKHbo7BY0MkQAIkQAK5TqAgeejmOkx2oFAQgPdvRh6/RQoFCQ6SBEiABEiABEiABEiABEiABEiABEiABEiABEiABPIwAWcoh/S6SUE3PTo8RwIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQALZTMBfMRfdoKCbzZPB6kmABEiABEiABEiABEiABEiABEiABEiABEiABEjAF4FAxFzUQUHXF0mmkwAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEA2EghUzEVXKOhm44SwahIgARIgARIgARIgARIgARIgARIgARIgARIgARLwRiAzYi7qKbYmLtlbfUwjARIgARIgARIgARIgARIgARIgARIgARIgARIgARLIBgKZFXPRFXroZsOEsEoSIAESIAESIAESIAESIAESIAESIAESIAESIAES8EYgK2Iu6qOg640q00iABEiABEiABEiABEiABEiABEiABEiABEiABEggyASyKuaiO4Va0I2L3ibjur4iv137XpCnJrDq/nnrd9OP1V/ODKwgcwdMYOXSJfLbzz/4Xe7okcOybvUK+WfhPNm6aYMcP3bM77LMSAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAJKIBhiLuoqphUWxu25M2fNsJOOnczV4Z9JOmPaP5ucss3VzhTwxvfFxUiFiuEZjvL06dMy9++psm3zpjR5rxpwg1SOrJImnQkkQAIkQAIkQAIk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AAmQAAmQAAmQAAmQQIEkUKxAjoqDIgESIAESIAESIAESIIFCSmD37t1y+vRpKVeunHkVK8af/IX0rcBhkwAJkAAJkAAJFFAC/HVXQCeWwyIBEiABEiABEiABEiicBH744QfZt2+fPfgLL7xQrrvuOvuYOyRAAiRAAiRAAiRAAvmbAEMu5O/5Y+9JgARIgARIgARIgARIwINA586dpV27dlKpUiWTvnDhQlm7dq1HHh6QAAmQAAmQAAmQAAnkXwL00M2/c8eekwAJkAAJkAAJkAAJkEAaAl27djVp586dk9dee02OHDkiW7ZskWbNmqXJywQSIAESIAESIAESIIH8R4AeuvlvzthjEiABEiABEiABEiABEsiQQEhIiNSoUcPkS0hIyDA/M5AACZAACZAACZAACeQPAhR088c8sZckQAIkQAIkQAIkQAIkEDCBsLAwUwaLpNFIgARIgARIgARIgAQKBgEKugVjHjkKEiABEiABEiABEiABEiABEiABEiABEiABEiCBQkCAgm4hmGQOkQRIgARIgARIgARIoHATOHXqVOEGwNGTAAmQAAmQAAmQQAEiQEG3AE0mh0ICJEACJEACJEACJEACTgJlypQxhzt27JCzZ886T3GfBEiABEiABEiABEggnxKgoJtPJ47dJgESIAESIAESIAESIIGMCNSsWdNkgZi7atWqjLLzPAmQAAmQAAmQAAmQQD4gUCwf9JFdJAESIAESIAESIAESIAESyASBtm3bysaNG2XZsmUyZswYmTx5slSsWFEaNmwoPXv2zESNLEICJEACJEACJEACJJDbBOihm9szwPZJgATyLAGsCJ6UnOzxOnPmTJ7tLztGAiRAAiRAAm4CISEhcskll0jLli3NqYMHD8qWLVvMy52XxyRAAiRAAiRAAiRAAvmDAD1089g8JSeflqXLVwTUq0YNG0h4xQqybMUq+dfQh8z+tD9+CagOZs4cga9Hfy8fffalXNnnMnnlhaczV0k2lrrn349K9NLl8tKzT8pVV/bJxpYKZtXgt2Llao/B3XTDQHn0wfs90pwHH37yhYz6bqz0vfwyefXFvPeecPaV+yRAAiRAAgWfwP79++Wdd94xAw0PD5f+/ftLZGSklChRouAPniMkARIgARIgARIggQJKgIJuHpvYhEOH5P6HngioV28Of1F6XXqxqOfgyVNJAZXP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JJCNBIL3THg2dpJVkwAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJWCE2CYEESIAESIAESIAESIAESIAESIAESIAESIAESIAESCB/ECiWP7rJXpIACZAACZAACZAACZBA4SagoRcKNwWOngRIgARIgARIgARIgB66fA+QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQD4hQA/dfDJR7CYJkAAJkAAJkAAJkEDhJtCsWbPCDYCjJwESIAESIAESIAESMAToocs3AgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAnkEwIUdPPJRLGbJEACJEACJEACJEACJEACJEACJEACJEACJEACJEBBl+8BEiABEiABEiABEiABEiABEiABEiABEiABEiABEsgnBCjo5pOJYjdJgARIgARIgARIgARIgARIgARIgARIgARIgARIgIui5dH3wJejvpNff59sevfTmJFSvHhxs3/fsMdkb0ystG7ZQl598ek82nt2iwRIgARIgARIgARIgARIgARIgARIgARIgARIIDsIUNDNDqpBqDMhIUH27I0xNZ09e86uEWIu0iMjKttp3CEBEiABEiABEiABEiABEiABEiABEiABEiCB3CJw5swZOXHiRJrmS5YsKUWLFk2TzoSsEaCgmzV+LE0CJEACJEACJEACJEACeY7AzJkz5b777pNKlSrJvHnzcq1/q1atkkGDBpn2V69eLcWK5f7lx4YNG2T69OkSHx8vSUlJUqRIEXn55ZdzjREbJgESIAESIIGCQGD58uUybty4NEO56aabpHXr1mnSczohMTFRXnrpJdPsQw89JDVq1MjpLgS1vdz/RRXU4bAyEiABEiABEiABEiABEiCBtWvXGgiNGjXKVRjr1q0z7Tds2DBPiLk7d+6U0aNH20xKlSoltWvXto+5QwIkQAIkQAJZIfD111/LyZMnpU+fPlKvXr2sVBX0sngS/IcffjD13nnnnXZoz2A2VKdOHVPd0aNH5eDBg2Y/r3zP7t692x5qRESEvZ/XdvydJwq6eW3m2B8SIAESIAESIAESIAESyCKBNWvWmBpatmyZxZqyVhxeubDc7oeOYsqUKWYXXjn/+te/JCwsTE9xSwIkQAIkQAJZInDs2DHRG5mhoaFZqis7Cm/fvl22bdtmnkzJju+/du3aCV6wJUuWyE8//WRu5lasWDE7hhNwnbt27TJlypUrl6e///2dpyIBE2ABEiABEiABEiABEiABEiCBPE0Ajz3CmjRpkqv9XLFihWm/RYsWudoPNI7wCrhIgl166aV5+mLOdJL/kQAJkAAJ5CsCKhii09WqVctzfcdTKrDIyEgJCQnJ1v7p921eCmug489LffI2CdrPjOaJHrre6OWBtBLFS9i9cP6hlSpV0qSXLl3aPs8dEiABEiABcf046gAAQABJREFUEiABEiABElAC+/fvN/FhcQxBd/369bJs2TLz6CNCH1xyySXpipl4VBSetYh/m5ycLPXr15fu3bun+2gmyqCNpUuXmph0nTp1EnjkIF4trHHjxmaLuLWbNm0ShDpo1aqVSXP/t2fPHsFFMWLbduzY0X0608d6cYkKMCYaCZAACeQUATx6Hhsbaz776tat69EsFpGC1ySu+5s2bepxTg/i4uJky5Yt5rMdn8vly5cXPNqOzzJ8Vnqz48ePmzL62QcRC3FM04tlDu/Sc+fOmVABJUqUMH3G5/ihQ4ekatWqxvsyGJ6n+C7YvHmz+V5CXFOMB4/lX3DBBd6GYqfhUXR8Px0+fNh8r2D86BteZcuWNUKlnfn8zunTp2Xr1q0CDggDAKG1efPmpk13Xtz4Q79g+P48cuSI+R4Df5RBe059Bvl27NghYA3D9yAMjPX7zyRY/+H7N1hesVh8DKGV9u3bZ8aOuULM/GbNmgm8T9Uwl+oxjDT8HoBhDjU0kx5riCbw2rhxo8mH725vi5lhzvR9hbASWPTMbXre/X5359PjQOZJy2CLvwv8bsB7Cn2tUKGCYCzeBHUV3PFew98dfo/gbw9/S5jf9N7bmfl78ndMmZknjD3EKngOO3nFJsyPN125tkulvNIl9oMESIAESIAESIAESIAEco2AerniQs0fwyJod911l8l64403yvfff+9RDPUgxh8uoN32559/yqOPPupOFlyQffLJJ16FUGd7zoLPPfecDB8+3CQtXrzYXGTOnj1b7rnnHoFzwj///JPmwhgXqddcc425oIbw/OmnnzqrzNL+X3/9JX///bcZ95NPPpmluliYBEiABAIhMH78eMHnYK1atWTYsGEeRaOjo81CUhBm33jjDY/PxVOnTsl3332XRhzUChDO5pZbbtFDe4s68bj72bNn7TTslClTxnwGQ5x1G8RStA+7++67TZ8gaDoNIidir2bFXn/9dSNCeqsD/QIft7CGcXz77bei4YS0LERSnINgi0f9Bw8erKfMFjFTR44cKQiF4DSwvuGGG6RNmzbOZCN+4vsRhu+iSZMmeZyHcPr44497iKbPP/+8YJ4yMnwnOsXWjPL7Oo+brT/++KPPNp9++mlzQxXlIXK++eabvqqy0/G+eOGFF8yxc+EwzAXes24bM2aM4LcJhGuM3y3o4rsc/YDddtttRix11+E8DnSeUBY3SL755hv7BrazPuwPHDjQ46YwxHrMAax3794yY8YMgeDqNLy3vT3ZlJm/p0DGlJl5Qr/poeucPe6TAAmQAAmQAAmQAAmQQD4n4PTGgZjbs2dPgcfszJkzZf78+cYrZ8SIEfLEE094jBQLpejqz126dBG84An1v//9z3ji4GIPF9RO7yTUp+IxhAW0Ba+kyZMn22IuLgb1IlYvlODpAk8Z90IpEyZMsL2jgi26qreQt4tTDxA8IAESIIEgE9BHqN2feWhGvQarVKni8fmKc1999ZX5/MU+bqzB8xAiGuqDuIlHst2GG3P4vIehPXj9wgsRXpcQNiFw/uc//0nj2av9QLlx48YZ71R4OVavXt14tqJ85cqVcTrTpt60xYsXN/1C/9UjFAIYRDp851x11VV2GxBsIbKqxyvGg34gRqt60yKzmy28UTFWGL6DOnToYDx7EZIIbeI7D0zh0anmZAAxFx65qBdtx8TEmMXO5syZI1deeaUpAv/Izp07G69mJMyaNcukN2jQQGrWrGn28R/mTL8H7cRM7KB/+B6GQYSFBy08ryHGQ2CFAO+8WQvh+uKLLzb5wV5vEOM3AcRpNafAjydocA5P3uB95v7O3Lt3r10POLjFXNQJVmruedF03WZmniCgf/DBB2YewRZ/F2AOr1u8T8HJ/V7F+0tt6tSpxqMZ4aDgfa2ey/jtor9TNG9m/p4CHVNm5gn9o6Crs8QtCZAACZAACZAACZAACRQAAk4Ppocffljuu+8+M6pbb73VeFZBhMXFjFPQxUXxSy+9ZPJBoHWeg3cYPG3hUYsLOY09h4s99TSDN+1HH31kP5oJL+C3337b1IdHfNVw8Q7vXAi6uEB2Xugh7d133zVZsWBZMFcHh7cQHouFwaOLRgIkQAI5RQCiHx6Nhzk/87R9X2IvvPb0RhQ+E93hCBA+AJ9tTsOj5yrmXn755eYmm57H5zxu5kHYg8ALAcxpTjETgtm9997rkQeiIT73s2LwvIUXJIRI583BPn36yPvvv28enXeKtGhrwYIFtpiLp07Uq7Zv377y7LPP2l7ITuER3pj6dAo+8/G9pqED+vfvbzw1IRTj+xD1qOlc4HjAgAHmZij2r7jiCnnxxRfN+A8cOIAkYxiDlodnqwq6GA8e4w+2LVy40FQJof2hhx7yEOX79esnEC0hDqoh9JGKzytXrrSF2Ouuu86Dv+bXLVgiHAG+N7t27arJZgtvcxiEcNz49Wb6fQthGKEwfFlm5wmhLSDKY6zPPPOMEbe1DbzvIShHRERoktk6BV38LhkyZIjNavTo0eYGNkKjOC0zf0+ZGVNm5yl1pp295j4JkAAJkAAJkAAJkAAJkEC+JKAx/HChpWKuDkQvvnDh7hQC4AUGa9u2rXmcVPNjq2Ww77wgghcVRFjYW2+9ZV8s4xgxd9UQl85pGhfXGb8P5+GBBQEDgi/CMgTTIGDj4h3mb+iKYLbPukiABAovAYhE+vnj9NpUIrhRBnOLvRBe1bytoQOhzOldijbUexPxVLH4o9Mg4MIzFgZPWLc5xUwIyG7BF6KTt7ik7nrSO8Y44AHpFHM1vy6eqayQDjF8+vTpJgs8bFXMRQIEWo37imNn33777TcjvkLwQ2gFFXORD3FsNVaxm4N+x0EEhherGvqr9Ts9W/U8tloW+/Bqzg5Tz1d4xTqFW7SFPjpFbXf7Or8ZLbSFcvpe1DJaF24Y6zivv/56r/OIvHojIr3+IF9m50mFVzDwFpcYcwXPXaepyIy/gUGDBnnw079L/ftAucz+PWV2TNpXZe7PPHmOUGvglgRIgARIgARIgARIgARIIN8RwEIxeoGKiy236aOYuKjWC1x4jiHUAQyx7twX2k4vF6cIDI8WGOLUuT1wwsPDzTn8pwuiaQIu2hHLFnEA1XCRCg9fGLxtgvFoKjyZ8OgleIALDF5W3oQRc5L/kQAJkEA2EFDPV4hP7sfA4fWqAqZb/IKHJ8rg/Mcff2xurkFkdH4mO7sLz1YVuvC5i9ACboNgBe9bb562KizDezE7vEu1L/i8h9ctvnvQX41jCg9XmPP7Azf+NP6thg7QerDV7x4I2/qdhvoWLVpkskFYxaJZbtPvMicHPK6vfXB7paI8FhyFOcMTmITz/6kQh+9ZdwxgZ76s7EOIhqCKmMH4zsTNU9yk9Kc9FTRVrE2vH5oH8wNWYIv3of5WgLd4ek+7qKCLkBa+LLPzhPpwoxie6Kjjv//9r1x00UXmhnR63+/6dxgVFZVGBEbYBRhEVLXM/D1lZUzabiDzREFXqXFLAiRAAiRAAiRAAiRAAvmcgMYYxDB69OiRZjR6we68ENPYccjs9uhCmj4qjH0VHCAIqIctFhdxm3oRId0t6KqHLDyJ4X0FARmP2sJwDo/DBsMQ59Dp4Yb4vt26dQtG1ayDBEiABPwmoEKSN487FQFRmVNMwjE8DPE4/++//26EKywqiRcEw6uvvloQt9xpzroQSgAvX6ZCqJ6HaIrPdRie1MgOgzCIG4HOOO/ajgrXONawPthXdhizmw/O46kOmFOA1u85pEP8HDt2LHa9mt7kxEn1PMW+O7wF2KiwrN6cyOc05a/fk85zwdqHoL906VIzbrSHxclg7du3Nzcs3fPqbBfhA2Aq1jrPufedYwBPHGMBVF0kDyEbfBlCDuhNVOe8uPNndp5QD+rF7wX8DkFb8IrFCwIyFrNzvoeQH0Kr/h7Q3yBIV/M2d5qGPP7+PWVlTNqXQOaJgq5S45YESIAESIAESIAESIAE8jkBFWdx8eXtsVD1inXGp9WLFngdefPyUW8RoNHHSJ0XLc4LP8UHz1gYHvvFy2kq8OrCaLhAnDhxosmCeIjqZeUsk5l9xMeDGICFc+B9g8d2L7zwQsGCLzQSIAESyCkC+hnrTdzSz1d43ULUdBs8DxFmAEIuYqBClIKAhdAKzhivKKftQMxyh7px1+sMVYBzKpxi330OacEwLEKmYi7ivUI4hkclburBM1bjuDu/U/SGIsI9uA0eo9pvp0ipafgOBL/0DIueqSk/bx62TrHXl6CreZx90bqDtcXTK0899ZR5LyCuPb5rwQH7WMT05ZdfTvOUDdrG9yxETZg//cOCa+rNDS54f2LBMBiYOr2oTaLjP+WAJOdcOrKY3czOk9Zz++23GxEeN28h7EJ0h2cwbhCDkfO3h/Mms7tP4Kc3Bpxs9P0QyN9TVscU6DxR0NV3A7ckQAIkQAIkQAIkQAIkkM8J6IJobu8UDAui5ty5c80Ind67evHl6zHen376yS6jYqtT0HVeNJmM1n/6WKY3Ty/EtsNFPARdCNAaugHhENq1a6dVZHmLi2684I383nvvmfqwEFBGQkeWG2YFJEACJOAgoGFwvAmBepPNKSQ5ippdiHgQQPHCZ9gXX3xhxDmElXHGeVXxEzfNevXq5a4m3WMVohC6wB17NN2Cfp7E5/2KFStMbsQvRTxcpznDQzgFN12ADDFj3QZxWEVKZxl9fB7hLQLhoAKesy5tU/mo0KnpunV68KY3l5o/q9tWrVoJXggTAc9UCLoIH4FQDO7Yx2hL+499XyEjcM5p+B2B+nDTAfMA1hB5vT2V4yynHMHK27xp3szOk5bHFn9TuHkLURY3b3/++WdzevHixcZjWfNqnyDyu8My6N8n8jrnPjN/T1kdU6DzlPYWkI6YWxIgARIgARIgARIgARIggXxFQC+YIRLgAsdp48aNM4e4mLvsssvsU/rIKcrgUUmnwesF8W5hWCRHTYVdHENgcBr6gEdCYbrIjfM8vLFUuH399dfNhSjOP/HEE85sQdt3PoKa3sVl0BpkRSRAAiRwngDCymgoA3dscNzQ0kfT/RUB8XSFhlpwf17rAmnOG27+ToQKXk5By9+y/uRTT2TkxaJoToMoiUU2YRAMIQSqqfgGYdFpCN+gZZCuT49gX715EfPW/T2I875MxTRvc6F8vInyqE+FPOz7K5gib1YN32m4Garmfk9ounqo4vvemye45nNulQM8fxFuAYZQH94WIXOWUyHU+d3rPK/7mZ0nLe/cYky4uaHvHTcHnT9vN7t13nEjw/k3mpm/p6yOKdB5oqDrfBdwnwRIgARIgARIgARIgATyKQF4QOFxQxj2Z82aZfbx3x9//CGffPKJOb733ns9who4HznFBTIECBguoO+++26zj/h8eKk5L2rxGKYuMIOLpvvvv1+zpYmfqydUkFDPmH//+98eF+SaLxhbbQN15eSFdjD6zjpIgATyNwH9PMUoEDdcDZ+VGv8UaW4hFQIaHiV3ClOoCws16Y07/RzVOrUOCMVYFMxZFp/RKPf555/bn9daDlt9UsNbWAhnvszuO28Cqlcy6kIIiU8//dRepM0tuOkxRPEZM2aYMR09etQ82aEiKkQ4p8io308og6dFkN9p+J4Ee6fIDFYaI1c5Osuo6Kcip/Mc9p2Lq7lvcrrzZuYY/UOYDZ0nrQOhKjRkEURNb965yKv9ww0ENw+ty73V94J6QeMpHufvAHd+Pda5hjiJ96svUT0z84Q2fvnlFxNewvm3hT7i70Xn0P23oYKut7nVc/pe03Fo3kD+njI7Jm0z0HliyAUlxy0JkAAJkAAJkAAJkAAJ5GMCGrdWhzB06FAjqOKiVoVepOHxRKdhITRcuOCC9cknn5QPP/xQ4JmiF91Y8RwrrDsNFy2Io4e4jqNGjTKeUrjY0zKa1+2J5S0dIRvuvPNOPRX0rV4A41FLxs8NOl5WSAIkkA4BiGyIN3rw4EFBWAGECcBnkXrmalGEonFadHS0Ee9wMw6frfBUhfCk4hrq7NGjh7OIWdQSQjDy4NFzvPBZje8AxAiFsIa2VXDTwvCQhTAIUxFLzwVrCyEUHpDoGwRIiG/oCxaAcnqMugVTjBGhgtB33HB0euVq31RE02PEAEY94AVhGy8whOiL0AHgAXN6tur3BNLd9aHPOl+++Dg9hL/55hszVv2+efjhh23PUdSfGUP/8P2KF7xQsUAc+qSxX1EnFipzCtvOdrBYGL6vYa+++qphj7zwKH3ggQecWe1991gRKgNP2GRk+N4Hc9iIESPMFnNcpUoVeeSRR8wx/svMPOF9gFAjeOH9pH83KrijXvxmcd6oRhnlpCI18qmpoOt+7+G3UaB/T5kZk/YD20DnqYizMPdJgARIgARIgARIgARIgATyJ4EtW7aYjiNmLEIZwDZs2GDEXFyYPffcc/LQQw+ZdOd/WAgNF13q0YILI1w0QkAYOHCgEWw1LIOzHBZf0Ri58IJFGVxIPf/88yYbyvvyiHVeKGLxEr3wddYfrH29UNcLv2DVy3pIgARIwB8CN910k/1ZCDERQhw+OzW+K8RZt8iK+K8QwSBGwRMVT0xAWEQabqbhsxyCqNPw+P2DDz4oTk9DfP5p6AEIaojD6zb1dEW6s6w7X1aO0bc77rjDhFRAPRDYIObi5iH6rOYW1SBe4gkOZ6x2fK+AqX5v4DvPbbhJGBUVZSeDAdoDf9TZrVs3j4W99FF31ImwD05z8nGLvZoPdWJ84Ic5wlxhgSt4jGrYCM2b2a2GAECdeD+oSAke99xzj3Ts2NFn1Qh/1LdvX9HvcniCon/oqy9DyAQ937RpUyM2+srrTEec+sGDB3u8l/A+1nAEzryBzhP6re9RMMbvFRVzMXcQtW+88UZnE0bE1wRv84f3Bsz93svs31OgY9K+YRvoPIVYbsopz1Q5a8nF/Qnz403r13bxXA03F7vEpkmABEiABEiABEiABEgg1wjo47XNmjULqA+48IGgC2FAL4DSq0CFA1z0wvsHomtG3jgoA8EAMfMQ29F50Z1eW/AQwiOvEIDHjh1rXzSmVyaz5z777DNzwQd+EAFoJEACJJAbBBBeAC98troFXG/9wecrxCYIwPgshqDnTfz1VhaiHz6X8ag+hDmUg0CV2wYRDjcA4RGM76VAxE4N7QN2EFnffvttM5xnn33WFird48P3ILxyEWYAgh9ERWecVHf+vH6MeYWQC34QkTGvgTAMZHxYZEwXRU2PcSB1+sob6DzhfY2/Dcwrbkrjdw7mNaPfLL7azyg9M39PgY4poz54O8+QC96oMI0ESIAESIAESIAESIAE8jkBeG9BMPXX4IkDL9ZAPFlRBl4tbs+W9NrEImsaOxIXieoBlF6ZrJxTEQMLvOHRXYgIGKPbuy0rbbAsCZAACWREAIKsellmlBfn8dkIr1q8AjWIfXjlNcNj8t68JH31EyKuit+6Rd5JkyaZIrj5qF6n3urA53wg7XmrIy+l5dS8QjRGyA5Yz54902UcDD6BzhPCRfhzozoYfUMdmeEe6Jgy01cKupmhxjIkQAIkQAIkQAIkQAIkQAJ+E8AiMVgcBXH1vvvuO1Putttuk1atWvldR2YzYuVrjS+MBdxgt99+u4nfl9k6WY4ESIAESCB7CeBhcoTwQTgg3JyENyrCBOCmoIYYcseEz94eFeza4YW6adMm80QLvHPhIQ6vVw0NUrBHnz9HR0E3f84be00CJEACJEACJEACJEAC+YbAV199JePHj7f7i9i8jz/+uH2cnTtYoAULsaxevdqIAXhU0xnDNzvbZt0kQAIkQAKZI4CwCgjRsGzZMvNy1gLvZSzSlZNems72C+L+ypUrzYJ1OjZ4k99///22h7Smc5t3CFDQzTtzwZ6QAAmQAAmQAAmQAAmQQIEkAE9cXBwizh08rZyL1eTEgNFuD2u1dBoJkAAJkED+IACPXHjg4ukOxBFOTk42cdqxCFiHDh3yREzg/EHSv14idEX79u0N1zp16ghuhiK0AS3vEuCiaHl3btgzEiABEiABEiABEiABEpDMLopGdCRAAiRAAiRAAiRAAgWTQJGCOSyOigRIgARIgARIgARIgARIgARIgARIgARIgARIgAQKHgEKugVvTjkiEiABEiABEiABEiABEiABEiABEiABEiABEiCBAkqAgm4BnVgOiwRIgARIgARIgARIgARIgARIgARIgARIgARIoOARoKBb8OaUIyIBEiABEiABEiABEiABEiABEiABEiABEiABEiigBIoV0HHl62GdPXNW8HJaSJEQKVqsqDOJ+yRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAoWMAAXdPDjhMz+aKTM//NujZxENI2XY/4Z5pPGABEiABEiABEiABEiABEiABEiABEiABEiABEigcBGgoJsH57tizYpSv3N907PDsUckftuBPNhLdokESIAESIAESIAESIAESIAESIAESIAESIAESCCnCVDQzWnifrQXNSBK8IKt+n2V/PTwj36UYhYSIAESIAESIAESIAESIAESIAESIIH/z955wFVZfnH8yBBkDxURlY0MF+6tDTXb2bSpmWnDppXZP21naWY2bFhquyxN03Jl7tybPRQQFRDZMgT8P+e5PC/3ci/IEgF/p8+977PH90W6/O55zwMCIAACINDcCUDQbe53GPsDARAAARAAARAAARAAARCodwKlBQVUUpBvNK6loxNRixZG5SgwJlBYWEgF4lXRHOztBUIwrMgFeRAAARAAARBQBCDoKhL1cM3LzaNjkceoS+8uBqPxAWcnDp2glKgUyjuTS86dXKh9iDtxXNz6sCN7jpBvkC/Z2NnUx3AYAwRAAARAAARAAARAAAQalMDhKRPpzMZ15PvcNPKc8JjJuQtOnaQd1w6QdYP+3U1Wbd1MtmuowriPZlPStwuNphu68whZ2DsYlTf3gk+/+Jq++/FXGj3yGpr5yovV2u7nCxfTT78uM2q7fvXvZG9nZ1Te0AVHwyPokceekdOuXyXWZH/519TQDDAfCIAACIBA4yTQLAXduLg4+uyzz2pF/PHHHydfX99q971w4QIlxCRQ+IFwykzPlN8k6wu6uULA/X3qbxS3Lc5ozCGThtDVz15D5hbmRnU1KTi69yixqOvk6kTBocHk6e+Jb7RrAhBtQQAEQAAEQAAEQAAELiuBjF3b5fw2nrpzJEwtJjc6Qhab29qSVZv6cYwwNU91yywdHanNtaNk89zICMo/kUitOnS6IsVchhAWHilZeHbqKK/VeWPRdviQQbJpTFw8JZ88RR7t3RuFmMuLio6Jl2tzdnaCmCtJ4A0EQAAEQKCxEGiWgi4LsiNHjqR169bV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xLpAAARAAARAAASaFoHExEQqKCig2NhYKeby6nv27Nm0NoHVggAIgAAIgAAIgAAIXJQABN2LIkIDEAABEAABEAABEAABEGjcBDIzM+mLL74wWGRoaCh17tzZoAwZEAABEAABEAABEACBpk8Agm7Tv4fYAQiAAAiAAAiAAAiAwBVOoLS0lFjAtbKyIltbW/L09CRfX98rnAq2DwIgAAIgAAIgAALNkwAE3eZ5X7ErEAABEAABEAABEACBK4iAi4sL3XHHHVfQjrFVEAABEAABEAABELhyCZhduVvHzkEABEAABEAABEAABEAABEAABEAABEAABEAABECgaRGAoNu07hdWCwIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgcAUTgKB7Bd98bB0EQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQKBpEYCg27TuF1YLAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiBwBROAoHsF33xsHQRAAARAAARAAARAAARAAARAAARAAARAAARAoGkRgKDbtO4XVgsCIAACIAACIAACIAACIAACIAACIAACIAACIHAFE4CgewXffGwdBEAABEAABEAABEAABEAABEAABEAABEAABECgaRGwaFrLxWpNEbhw4QKVnC8xqrJoidtrBAUFIAACjY5AaWkpFZcY/g4za9GCLCya7u+w0pJS4pe+tTBrQeYW5vpFSIMACIAACIAACIAACIAACIAACIBAjQk03b+Wa7zV5tshfkc8LXlosdEGX9o9jWxdbI3KTRVkncqiz29dIKue3vAMWdtbm2qGsktE4O335tKyFato4sMP0uRHxl2iWZrXsPeNn0SpqWn01muvUL8+vZrX5i7xbv7ZtIVmzZ5H/v6+9Nm82Zd4tosP/+U339JX4qVvPt6etPSHRfpFVab37DtALAz7eHtRm9auVbatz8qEvQlUXFhMbf3bkn1be23oTZ9sok0f/6vlOdHGry1NWTPFoKyqTPiaMPpz5p/ULqgdPbR4XFVNUQcCIAACIAACIAACIAACIAACIHAFEYCg2wxuto1TK/IZ4CN3UphXSMmHk3W7ulD9zZUWl1Jeep7scKG0Bh2rPwVaVkGg6Px5WXu+SHetoimqygiwmHs2I5OKiorApIYECgoKJbuzZzNq2PPSNPdwb0d9eoXKwVPT0igh8USNJmIhd/KU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paSkqLARiCWLcAVYwAyeuhB17fFl0T4mJsbejUf2dSxia2fwzIWnMRacK87i4uLMImu4BTOTiRIJ6FDSWFSNRgIkQAIkQALnAgEuinYunCU3xpifly95p/KcXgX5BW70wKokQAIkQAIkQAIkQAIkUDECECa1mPr9998LQgfYbf78+fLcc8+plz3kgr1ueffbtGljLtg2b948l9289tpragwvvfSSKu/atavaQnD++eefi7TBXIrrq0hlD2R06dJF9YIF3iA02w2euwsWLFDZCAXhSoC2t/H2/VoBheFAqkJkDWxSTyHZt3aft6Ph+EiABEiABEhAEaCge5bfCJmHMiXujzhJWJvgkZF8OOUDebbzM06vhS/+4pG+2QkJkAAJkAAJkAAJkAAJlJWADnEA79cXX3xR0tLSVNNTp07Jhg0bBEIvDIuzYQGyihjCEsBiY2PlyJEjAq9bWEBAgOiFxrA4GxZG06EUUAdj2L17t6o7ZMgQte3evbu5qNi3334rP/74o2DMMAjPL7/8sgrJoDKq4M/ll19uitKvvvqqWvxMC+RJSUnyxBNPqJAMGMrUqVOrYESVf4h6zRwCK460fvY6qewFzUIiQtSkjiUdk63fbRHG2638c8wjkAAJkAAJVIwAQy5UjF+FW//03E8SvWCbdDo/Ulr3LbrSsLsHaBHVQvxqOU5r8pZkOZl1Uor6Q7jbK+uTAAmQAAmQAAmQAAmQgHsEOnfuLBBJly9fLjt37pR7773XjAere4In72233aZ3y71FmAEsxAZx9v7771f9fPzxx2p76aWXyvr161U5PG7xgherFnZRCTF+L7vsMlUffzCm559/XtWZM2eO4GVvY1au5ETdunVlxowZ8vbbbwu8ht966y0l8CIsBWLrahs6dKh069ZN757T29r1a0un0Z1k58Kdsvyt5erVqF1j8fGrIQNuGiiRYyM9Or/woeES0iFEDscclgVPL1CvgOAAgdA7ceY1Hj0WOyMBEiABEiABTxCgh64nKJazj9T4VCXmovmQWx0eAeXsymx24ZMXydRPblSvbpdVj//QmZNjggRIgARIgARIgARIoEwErLFY/fwKfTis+WXqyKhkbWPtqyztb775Zpk+fboEBgaq6lYBslOnTvLss8+a3rDW/ko7jr184sSJZogHaz9IQ4iFOHvBBRcoQRl5VjF32LBh8uST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dmk3CWhY6M2r2+pt046OEBBpiWmyYe4G6T6+u1jDOUCAhucwvHFbtWslXfp0kQbBxQvEul9uSYAESIAESIAESIAESIAESIAESIAESIAESIAEzg6BGoag51WrXn278ogicfmgRmeHiAeOemDfAfGr6SeIuwtL3JQo7105U6Xv+uVuCQl35KuMYv7kncqTty56S47sSVU1WvVupRZRi1sRZ7a42+ircQl9YRG2ty972/QMRkMssta0Q1OZ+smNciL7hCTtTZJ2ndqJjw/XxzPBMkECJEACJEACJEACXkRg8+bNajTh4eFeNCoOhQRIgARIgARIgARI4GwRoIpXCeSxSJoWc9H9ipkr1FEiR3cuk5iLyn7GYme3fHOLwAsXtm/9PtFibvOoFnL3wntKFHPRxsfXR26afZPAK7h+M0f4hawjWZKVlo1iqR1QWyI6R1DMVTT4hwRIgARIgARIgARIgARIgARIgARIgARIgAS8nwA9dCv5HB3efUjeHPumOsr0r2ZIWI8wt4+Ym5MrqfGHjQXY8qVxm8YlLqjmdudsQAIkQAIkQAIkQAIk4NUE6KHr1aeHgyMBEiABEiABEiCBKifAGLqVjHzVrFXqCK37ti6XmIvGNevUFHjl0kiABEiABEiABEiABEiABEiABEiABEiABEiABP7aBOihW8nnPz8vXwryCtRiZAiBQCMBEiABEiABEiABEiABdwhoD1132rAuCZAACZAACZAACZBA9SVAD91KPre+fr6CF40ESIAESIAESIAESIAESIAESIAESIAESIAESIAEKkqAgm5FCbI9CZAACZAACZAACZAACVQBgc6dO1fBUXgIEiABEiABEiABEiABbyfAGADefoY4PhIgARIgARIgARIgARIgARIgARIgARIgARIgARI4Q4CCLt8KJEACJEACJEACJEACJEACJEACJEACJEACJEACJHCOEKCge46cKA6TBEiABEiABEiABEiABEiABEiABEiABEiABEiABCjo8j1AAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAucIAQq658iJ4jBJgARIgARIgARIgARIgARIgARIgARIgARIgARIwI8ISIAESIAESIAESIAESIAESKAqCRw/flzy8vKcDunj4yP169d3yuMOCZAACZAACZDAuUEgPz9fcnJyigy2Tp064uvrWySfGRUjQEG3YvzYmgRIgARIgARIgARIgAS8jkBmZqb07dtXjeuHH36QiIgIrxrjNddcI7t373YaU+fOneWbb75xyquMnV27dsmiRYvkyJEjcurUKYGQ/Mwzz1TGodgnCZAACZAACfxlCGzatEm+/PLLIvOdMmWKdO/evUh+VWdkZ2fL008/rQ57zz33SMuWLat6CB49HgVdj+JkZyRAAiRAAiRAAiRAAiRw9gnExsaagwgNDTXTZU18/PHHsnHjRhk+fLiMHz++rM3KVO/06dNKYG7btq2qv3LlSsnKyqqSi719+/bJrFmzzHEGBARIq1atzH0mSIAESIAESKAiBD788EM5ceKEjB07VvTvXEX682TbtLQ0+eKLL1SXN910k/j7+3uye9VX69at1RY3lo8eParS3vI7m5SUZM43JCTETHtboqzniYJuKWcu81CmHIo9JH61/KR1X8cbE02WvPm7LH59sfS6qpeMf+HyUnqpvOJ/j3hV0hLT5PqPbpCIwRGVdyD2TAIkQAIkQAIkQAIkcM4Q2Llzpxprx44dpXbt2m6PG56y8GTt37+/221La1CjRg157bXXzGq46IWg27VrVzOvshK//PKL6hpeOTfffLPUqlWrsg7FfkmABEiABP5iBBBOaMeOHWrWNWvW9LrZ7927V/bs2aOeTKmM37/evXsLXrC1a9fK3Llzxc/PT4KCgryCRWJiohoHwjtVxvw9NcmynicKuqUQ/+m5nyR6wTbpdH6kk6Cbn1egWuaddI79VUp3Hi8+lX1K9VmQm+/xvtkhCZAACZAACZAACZDAuUlg+/btauDlEUnhWQQxF9apUye1raw/GRkZggsXGEIuVKYhvII+1siRI736Yq4yObBvEiABEiCByiGgBUP03rx588o5SAV6xVMqsCZNmghurlam6d9bbwproOfvTWNydQ70OEs7TxR0XdE7k5can6rEXOwOuXVICTVZRAIkQAIkQAIkQAIkQALeQwBx7GAQSeH9un79etm6datERUXJwIEDizxmiccQ9aOI+kIC7VNTU2XVqlVIKmvXrp26EMTOgQMHJCEhQVq0aKHaIkRDhw4dBGLpwYMHZdmyZYIFUsaNGyeNGjVydGD7qz2JkR0eHm4r9eyuvrhEr5gHjQRIgASqigAePcf3IsK8tGnTxumwWEQKXpMQ2CIjI53K9E5KSorExcWp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"/><use stroke="#979797" xlink:href="#rect-1"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="698" height="249" viewBox="0 0 698 249"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h698v249H0z"/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="Bitmap"><image width="698" height="249" xlink:href="data:image/png;base64,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AiIgAiIgAiIgAiIgAiIgAhVCQIJuhdwoRVMEREAEREAEREAEREAEREAEREAEREAEREAEREAEWghBbgSmTp3qpkyZ4p555pncdswQev3113e77rqrY1kKGz9+vD/sRhttVIrD65giIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAJNREC6TxOBb6LTykM3R/BPP/100cVcomBCcY7RUXAREAEREAEREAEREAEREAEREAEREAEREAEREIEaIiAP3RxvNsIr9qc//SnHPdMH/93vfueFYrx0ZSIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIQR0AeunFUtE4EREAEREAEREAEREAEREAEREAEREAEREAEREAEypBAUT10iz0cgY0ne8wxx5QhOkVJBERABERABERABERABERABERABERABERABEQgjgA6ofV0L+W8UXHnrvZ1RfPQvf7664s+tiw3nQ8JQCYCIiACIiACIiACIiACIiACIiACIiACIiACIlD+BNDznnnmGa/r8RvdUPpe8e5b0Tx0uTmYxpYt3s2plSP973//c0uXLs36cmnVadWqlXv77bfd7Nmz3Xrrref69u2b9f4KWP0EFi9e7CZPnuymTJnilx9//LHr1KmT69Kli9tss83cxhtvXP0Qvr3C5557zi1ZssRtsskmrnPnzjVz3UkX+vnnn7tnn33WzZw505EuWrRo4bmQjwwePNitvPLKSbtqfZUSWLZsWapBukOHDm6rrbZKe6Xvv/++YwbhNm3auEGDBqUNW80bp02b5iZNmuTatWvntt1222q+1NS1kXcklVeaNWvmOnbs6NZaay3/ruF/Y9moUaN8mvzyyy9dr1693E477dRYp9Z5qpBAmM432GADxyeTUe568cUXU8H69evnn4PUCv2oWgL2TuQC6V3bs2fPsrnWuXPnujfeeMPHh3yR+iP20ksvuUWLFpVd2Tgpvj7S+hKBCiVQLeItQnQ+3sXmoFqqUQeKJuhWaPpStJuYABWjCy64IKdYbL/99v6FfNddd7nXXnvNDR06tGYFXYS6p556yvPbZptt3Oqrr54Ty2oMPGPGDPe3v/3NLViwoN7lzZkzx1d4ETjXXXddd9RRR7muXbvWC1ONf/7973/7y2rfvn1NC7rLly93d9xxR70Kp93vDz/80L3zzjvu4Ycfdj/60Y/ckCFDbJOWNUDgm2++cffcc0/qSldZZZW07xQqguQjrVu3LljQJV8aOXKkPzeFxEoy4v3YY485RPBaEHQR/u+8886sbtEaa6zhjj766KyEsKwOmCbQvffe65588slUCMQVCbopHPqRB4Ewna+99truvPPOy3gURLMwHyV/pBFdVv0EKFuZYxeOA3/4wx/K5qJpuLd0ST3JBN3bbrvNx7EpysbU3Z5//nl//i222MKtttpqKV5J8U0F0A8RqBIClmdUyuUg5hJnlgizNjRspvjbPoSzfTPtk+t2Cbq5ElP4khFAjOzWrVvG46+00koZw9RKgK+//tr9+c9/9pd75ZVX1ryg+8ILL3jRzu4/aWrDDTd066yzjvvss898K/3ChQu9dybczj33XEfFW1b9BKigmvcQFc2tt97aC9xfffWVF/rx5jbBZs0113T9+/evfii6wlgCFLguvPBCL9jGBijiShqg7r77bn/EXXbZxTWmV2cRL6PmDtWyZUvvjWsXToMR3rG8XzCE+r/+9a++wbqUDa14RZrnC+fZdNNNvce0xUtLESiUAD3h+CDspjO8emW1R+DTTz9NiblcPYIkjUrZ1Odqj9aKK6buZu996iehoFurTPK5bpwwsB/+8Iexu2faHruTVpaEAOJnVMCtJCcGE3MNjgmzmUTdUMxlX/tfbE9dCbp2Z7RscgL77ruv+9nPftbk8VAEKpMAXpZ4CWDNmzd3J5xwghs4cGC9iznkkEPcQw895B5//HGHV95ll11W9GFi6p1Qf8qCAEILHpUY3tm/+c1vUl4afmXd17hx43x64P+NN97oLr30UtukZY0RwLsfr8fDDjusxq5cl5stgR122MHxPokaec2//vUvN2LECN9ARE8i3kWlMmuI4vgnnniiH4KqVOfScWuXAI3l9F5Jsk8++cR98MEHSZu1vooJmKcpjVwYZWvGyvzpT39a1ldNfZNG/N69e5dVPCmjHnHEEb5xl95CsngCiLUm2BIiKupm2h5/VK0tFQHEW4busQZohNBMYmip4pLPcYk/Im5omURdE2/DffhdCiFbgm6U8rf/uQkUlHkpxdnvfve7eqtJlNygSkqc9S5Af0SgwgnY0AJcBoIdY6JGDaF3v/32c1Q+3nzzTe9FhRBMC7mseglMnDgxdXEHHHBAAzGXjYyr/P3vf98xpjeC3rx58xxd8WS1SQABY7vt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dteqgEDRBF2Oma9qnbSfibcm5gbxbrSfSR7HjRYBnUgEREAEREAEREAEREAEREAERKCsCCDgMmwAwxkxHAeTv4XjP5dVZMsgMkyYycRnuU4kyMSJDF2l4YLK4CYqCiKQIwEcN6MCrul8OR5KwWMIFFXQjTl+2lXcyEzjV4U3O/yd9sDaKAIiIAIiIAIiIAIiIAIiIAIiIAIlIsDkXnxk2RFgIrR8bLvttnN8ZCIgApVHwDQ/G3ohrnd+5V1V+cS4Wd0M1svLJzrlE5NwJrvGihWJO8lbudA4lONsh4Vek/YXAREQAREQAREQAREQAREQAREQAREQARFwTrpPbaWC5rV1udlfLS0J0XF9s98795CcSx7IuXPTHiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQSwTkoVtLd1vXKgIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUNEE5KFb0bdPkRcBERABERABERABERABERABERABERABERABEaglAhJ0a+lu61pFQAREQAREQAREQAREQAREQAREQAREQAREQAQqmoAE3Yq+fYq8CIiACIiACIiACIiACIiACIiACIiACIiACIhALRGQoFtLd1vXKgIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUNEEJOhW9O1T5EVABERABERABERABERABERABERABERABERABGqJgATdWrrbulYREAEREAEREAEREAEREAEREAEREAEREAEREIGKJiBBt6JvnyIvAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQSwQk6NbS3da1ioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVDSBFhUde0W+5AS+d96nJT+HTlD9BJ46p1P1X6SuUAREQAREQAREQAREQAREQAREQAREQAQagUCL8ePHN8JpdIrKJbBG5UZdMS8bAspnyuZWKCIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVTkBDLlT4DVT0RUAEREAEREAEREAEREAEREAEREAEREAEREAEaodAs+V1VjuXqysVAREQAREQAREQAREQgcoiMHLkSB/hnj17VlbEFVsREAEREAEREAEREIGSEJCHbkmw6qAiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUHwCEnSLz1RHFAEREAEREAEREAEREAEREAEREAEREAEREAEREIGSEJCgWxKsOqgIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIFJ+ABN3iM9URRUAEREAEREAEREAEREAEREAEREAEREAEREAERKAkBCTolgSrDioCIiACIiACIiACIiACIiACIiACIiACIiACIiACxScgQbf4THVEERABERABERABERABERABERABERABERABERABESgJAQm6JcGqg4qACIiACIiACIiACIiACIiACIiACIiACIiACIhA8Qm0KP4hdUQRqC4CS5cubXBBK620UoN1WiECIiACIiACIiACIiACIiACIiACIiACIiACpSZQkYLuBx984JYvX+5WX311165du5wZTZw40X344YcOUW7QoEE5768dikdg1KhR7vPPP3dt2rRx22yzTfEOXKQjvf/++27KlCkNjrbVVlu5lVdeucF6rRABERABERABERABERABERABERABERABERCBUhKoOEEXIXfy5Mmeydprr+022mijnPksW7bM78Oxmto+++wzN2HCBNesWbOyFDRLzcfugS1zPd/IkSPdwoULXZcuXdx6662X6+4Zw7du3dq1aLHiMSGOcd66GQ+iACIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQJAIVJ+gW6brL5jCLFi1yixcvLpv4VFpE5s+f75YsWeJYlsI6d+7s+GBffvmlGzFiRClOo2OKgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIQFYENClaVpgUSAREQAREQAREQAREQAREQAREQAREQAREQAREQASankBZeugyvm3Lli3dmmuuWTChefPmuY8++sgtWLDArbrqqr5rfqaD0rV+9uzZ7osvvnBff/21Hyu1Y8eOrlOnTpl2dZyPYRTw5mRoB8ZZXXfddeuNt8q2uXPn+mPZkj+MDRxahw4dfJxZZ/sw7i/DC8QZ18h4tAzfwDkxhiP49NNP/XjBDFEBizlz5vhtjEHMsZo3T9b1v/rqK/fJJ5/462In4sRxWrVq5Y9RzC+4E9ePP/7YffPNN/5c3bt3bxC/mTNn+jGUObcNn0E8Q35c0zrrrJOKHmmKsMSfcXH5DSMYTJ8+3d9r7lXPnj0bnC91kCx+zJgxw98zjisTAREQAREQAREQAREQAREQAREQAREQAREQgWITKBtBF0Fu6tSpXtBD2FtrrbUKFnQnTZrkEP/MEE8R/dJNpEY83n77bd+N3/ZD2EUQbN++vRs4cGCs4MfYqqNHj/bCoO3H0vZFOO3du7ffhOhnomoY1sYGtnUI2n379vV/OY5NzoXwiDAZtffee88Rf0RfE3QRcBEsMVgg+pohnk6bNs1tueWWjrFio8bYvrNmzaq3GrGafTbeeOPUUAT1AhTw58033/Txt0NwzcR522239ddk67mvUeO6o/xCQZeJ8KLG9cOSfTHORxqBR74GL9Ix4+6Shnv06JEagzffY2o/ERABERABERABERABERABERABERABERABETACTSroItwi2CGyRseRbdu2rcUxryUetibmInDiMYnXJ4JduvFWGSPVJr7Co7dNmzbeO5X44X07atQot+mmmzaI0xtvvJG6BryLEVzxlOVceMnyMVtjjTVSnqXhNryAQyOcWdeuXb1QCDME2k022cQ2+SXXZsJkkmczYi5CIywYuxevX8af5Zq32267esdDHMYzF7N98GrFA5jl2LFjvTCOIFoMs/vPfUdc5j5xrcQPodbEcM6FpzTbMOLDb5hzv8ySvI65J4TjXmIww9uY8DCBEfefNJOPEXeOQ7xJf3w4HxO2ZePhnc85tY8IiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEDtEGgSQReREy9GE+MMNyIaE1Dh1Vhol36OjyHUbbPNNl7w4z+etnHemmzDc9bEXOKACGeG6GnDHiDChoJzKEiHXrW2L964JrayDs9NPlgYnwEDBvh1cV8IkauttppnhicpIibrzMwLl//EPc4QPfF2NbHTPJgZVgJvVRMciauJuXglb7bZZqnDIRy/+uqr/vxjxoxxW221VWpboT+493369PGH4fpeeeUVL4wSt9D69++f+vvyyy/7MAjo/fr1S61P+rH++uu7bt26uXfeeSc17IWJ2c8//7zfDb7GIuk4SesR+0kneDFb+uY/3tuWvokD90ImAiIgAiIgAiIgAuVCgPLWk08+6cswlG0pi9Pja4MNNnC77757veHDShFnyl+UMbFdd9214LpAKeLY1MfEAQJHB3rtsWSYMsqs9ASkvE4POlnTEhg5cqSvR/Hc8KkUe/bZZ1P14GzivNNOO1XtM2osevXqlVivjjLCGYp6PfXMjTbaKLpZ/0VABESgJAQaTdBFoGPsUjwWERDNECUR4xBPESwzWShimjAZ3QfR0c7B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v8GRD7n6UNdntz4N1muFCIiACIiACIiACIiACORKoNLH0M31ehVeBERABERABERABEQgPYGy9tBdtnSZj/2SRQ29YNNf1oqtY//3nhv18Ltunf7ruB2P3zGbXXIK02ylZm6D7TZI7TPl1SkrftfNOikTAREQAREQAREQAREQAREQAREQAREQAREQAREQgWITKGtBt9CL/WTKHDfm8dFuyeL8BOFM52/RqoX72W1HpoJdNuRS9/n7n6f+64cIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIFJNA82IeTMcSAREQAREQAREQAREQAREQAREQAREQAREQAREQAREoHYGy8tBdMH+Bmzpuquu/Zf/YK5774Vw3/Y1pbs60T12nHp1c78G9XdsObeuF/Wj8R27BZwv8uk+nzvHL+XO+dKnhEL4N3XXTrq5V21b+38cTPnLzP13g1thgDTd9+DT3ad3x168bSmG9LddzH47+0E16caJr076t67dnP7dKx1W+PULui9kfzHaLFy126/VaL/edtYcIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEDNE2hyQXd53Xiz0ydOd++9/Z774tMvXLNmzWIF3Xcfedfd88u7692w9mu3d0f962jXsXvH1PqnL3vajXtqbOo/P2aOmuluPvymeutOfOgk16VvF7/umSuede/9d0y97e7yZ9wOR+/gXr7h5dT612973Q17dJhrvlJ+js2zZsxyY98Z615/5nXXo3cP12+LOoF41fwF4lTE9EMEREAEREAEREAEREAEREAEREAEREAEREAERKAmCDSZoDt/7nw3ZsQYN23CNLd06dIU7FZtVnjNplbU/Vi8YLEXc5mArOcOPd34Z8e7GW/NcPNmz3MvXP282+/C/VPBN91voOtW532LTX55svfMXb3b6m7LoVumwvCj/Vrt6/23P0yeNvqx0X4sXMTcNXt1dr133tALu59M+th77HYduOL4tk+2y1XarxBvlyxZ4ia9N8l/OnTs4Ppu1tcLvIjZMhEQAREQAREQAREQAREQAREQAREQAREQAREQARFIItCogu7yZcvdlPFTvJfqvM/npeKEkLnWumu5Ppv1cV26rfCaTW389seAvQe4gy492DVr3szteMJO7vmrnnN44464Z4Tb94L9vGcvQfvu0S+16/K6Xwy10HnDtfw+qQ0JPwafPMTtcsouboPte7pbfnqzD3XYNYe5jut19EMyjHzwHTd77GyXr6Dbu39vP9zC+FHj3aQxk9yihYvc3M/mulefftUNf26439Zvy35u1Q6rJsRQq0VABERABERABERABERABERABERABERABERABGqZQKMIuoi3o98a7WZMmuGWLVuW4o1wuWH/DV2vfr1cixbpo7JTnYiLmGvWd/e+XtDl/6K5i1zb1eqPpWvhclna0A0dunRI7bZa19X8b7x8sUXzFvplvl+t27R2m2y9if989vFn7r133nMfTPnAeykjdvNpv1p7t/GmG7ueG/esd835nlP7iYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVAeB9Cpqka7xpf+95MfH5XAIt4wfyzAD7Tq0y/oMneomLAttlU7f7buwTmQthqDbss0KHC3btkydysbLbdF6xbbFC75ObSv0R8fOHd2g7w9yeC5PmzjNjRs5zn0+53M374t53mN3tY6ruTXWrn/dhZ5T+4uACIiACIiACIiACIiACIiACIiACIiACIiACFQugfxm9yrgepkEjTFzw3FzMx2u9SqtXYtW9bXn0FsXQbQYtlLLlfxhTMTlvGYrtViBatmS78b7tW2FLpctX+aWfLPELVv6nfdyocfU/iIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAtVHoL5KWqLrG7zXYPfeiPfclHFTHBOCTR0/1X9WXmVlP9xC7wG9XavWDSdDK1F0Mh62sSYn+2jmR27s22PdrPdnOYRus45rdnR9N+8r71wDoqUIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAn0CiC7srtVnZb7rSl/7w/+X035u0xjvFjv1rwlRs1fJT/dOrcyY8b271n99QEZ5V6j75e+E1i1Bd8ucBPCjd13FT3zTffhWvRsoXr2aenF3Lbrlz4eMCJEdAGERABERABERABERCBiiTwvfM+rch410qknzqnU61cqq5TBERABERABESgiQk0iqAbXmO3nt0cn4VfLfTeqZPfm+yFzU8//tS9/L+X3fCWw93Bxx4c7pL37zartvH7zp/zZd7HyGXH1buu7j5//3P3/ogZbuC+Axvsyhi5I14eUW89Y+Tijdu1R9d66/VHBERABERABERABERABESgcgiMHz++ciKrmIqACIiACIiACFQ0gUYXdI0WXqib77C5/3w4/UM3+q3Rbs7sOX5IBgtT6HK1dTr4Q8wcNdNNeHa86zmol7Nxcgs9dtz+a/fp4qa8OsWN+e8Y13ePfm6D7TaoF2zhgoX+f8tWLf1QE3027ePatF0hOtcLqD8iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEEOgyQTdMC7rrLeO47N40WI/tm64rZDf62+7gWu/dns3b/Y8d/uxtzsmOVut2+r+kEOvGOrW2GCNQg7fYN/tj9revXLjy27BpwvczYff5M/Xok0Lt/VhW7shv9jFrdtjXbd2t7Vdl25dGuyrFSIgAiIgAiIgAiIgAiKQjoC69KejUw7bNORCOdwFxUEEREAEREAEaoFA83K6yNZtWruNB26cilKz5s1Sv6M/wm1Jk5i1bNvSHX3nMW6Ho3dwq3RaxS1esNh9NG62/yz9eknqkLa/HdOWqQB1P2ydhQ232W/E458/frLbcOfeXszlfIi7i+d/7YN0XqezxFyDpaUIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEDOBJotr7Oc99IOIiACIiACIiACIiACIiACjUJg5MiR/jw9e/ZslPPpJCIgAiIgAiIgAiIgAuVNoKw8dMsblWInAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAk1LQIJu0/LX2UVABERABERABERABERABERABERABERABERABEQgawISdLNGpYAiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIi0LQEWjTt6XV2ERABERABERABERABERCBQgi0a9eukN21rwiIgAiIgAiUlMD8+fNLenwdXARqkYA8dGvxruuaRUAEREAEREAEREAEREAEREAEREAEREAEREAEKpKABN2KvG2KtAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIQC0SkKBbi3dd1ywCIiACIiACIiACIiACIiACIiACIiACIiACIlCRBCToVuRtU6RFQAREQAREQAREQAREQAREQAREQAREQAREQARqkYAE3Vq867pmERABERABERABERABERABERABERABERABERCBiiQgQbcib5siLQIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUIsEJOjW4l3XNYuACIiACIiACIiACIiACIiACIiACIiACIiACFQkAQm6FXnbFGkREAER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69ChQ73w+iMCIiACIiACuRL44osv3KhRo/xkn127dnXbbLONa9UqXvNgglHGip82bZpbvHixf29tuOGGrlOnTvVO+8knnzgmEMWaN6/TG+reYaF99dVXjnenGe/BTEMhWdjGXn744Ydu6tSp7v3333foQmussYYfPx9WxbJFixa5ESNGOMb7nzdvnmvXrp1bffXVHRO0rrPOOgU5KBYrjuV4nKoUdL+c+6Ub82adEDlxmlu2bFmKOyJbr369vMjWuk3r1Prwx7BHhnnxj3U7/3ywu3SnS7ywN/7pcW67I7dPBX3pupdSYu5Jjw5zq3dd/dttW9QNubCue+A3D7jnr3rObX7w5qltLdu2dIdcfWid52nvel64hFm54ypeLEQM/f4Zu7tWK6/IQGa9N6tOfJzgjz3070Ndvz1XZASImXccd0dqWypidT8OPPJAN+v9WV7I/mjmR/6hmzx2suPTfvX23mt3/d7rexEy3I/fiJJTxk9xY98Z6+Z9vmJICNYzBhpDVODZ3KVb8gRneNq+csOKydB2qhPG44Yo4HhmCLPH33+8a1M3DAK29eHbuBsPucF74M4eO9ut038dvx5xHpEXW3+b9d1Prj/cwRPb6tCt3P2/vt+9c//b7tHzHnUn//fk1HnX7NXZHXP3sQ2GzcC7+fqh1/lhLF6//fV6gu6Ie0ekPIaPu/d4L9Rznk3339RdtdeVDTysO3Ts4IYeN9RNGTfFjR813jceLFq4yI0aPsp7SsOt3xb9GniEc0yZCIiACIiACIiACJQzgcmTJ/tJ0dq3b58o6H722WcNJkMZOXKkv6xu3bqlLg8B97bbbqsn/FJB5MPka4ceeqjbdNNNU+GpMDPJCmP+PvXUU+7JJ1c4XxCAsqFMBERABERABCAwffp098ADD6RgIMput912qf9JP9jv5ptvrrf5sccec+ecc46LjiWP6HvttdfGjgu7zz77eA9VGzsesTY87vnnn+/fZXai119/3d15553211100UVlJ+giWNM4S+Nq1O6//343cOBAd9JJJ0U35fyf9/w111xTT7sLD7L77ru7Aw44IFyl398SqBpBFyFy8ri6AmedNy6CrhmtIV036Or6btrXdez8nYetbQ+XiKV4cpq17dDWi6/vPvJuva73FCDNU3P33+6REmxtvwH7bOIe+8NjXhSc+upUt/rBK8RehlLo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/tsWap3lsBgMPHdwYYvHLJ1iLi7YevfubR5N1fq4JQESIAESIAF/COhT15rXfazp7q0zn3Pfna9KlSrGYxU3K92iJmL13nfffVK/fn13MXOM8AWlS5cWxIJVi4qK8uoAqOezY+sen/vY3ebgwYON6Dx69Gg5ccJzDSoI1926+X5C+95775UJEyZIdHS0LeRq/U7HR3CtXr267N27V097bJs1ayYQ02neCYRYizmd836KqSSQPgG8dRAzGBZaInWVx/RL8SwJkAAJkAAJkAAJkEAgBODNCvMVPw6ervnNkpKSjKgLURhCMEIz0EiABEiABAomAecNvPw+wlOnTsnu3btNaACIkVhArKAbFkhD3FyEQ6hUqZJERERkuNBZIEySk5Nl3759ZiE27COWLjx9IYTnZZs+fbrtxQyP5p49e+Zod+mhm6O4C1ZjuLNCIbdgzSlHQwIkQAIkQAIkQAI5QQACbo0aNXKiKbZBAiRAAiRAAkEjAO9UXzdYg9ZIHqsIonV2CtcIQcHfBIFPOj10A2fGEiRAAiRAAiRAAiRAAiSQYwQKoodujsFjQyRAAiRAArlOoCB56OY6THagUBCA929GHr9FCgUJDpIESIAESIAESIAESIAESIAESIAESIAESIAESIAE8jABZyiH9LpJQTc9OjxHAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAtlMwF8xF92goJvNk8HqSYAESIAESIAESIAESIAESIAESIAESIAESIAESMAXgUDEXNRBQdcXSaaTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQDYSCFTMRVco6GbjhLBqEiABEiABEiABEiABEiABEiABEiABEiABEiABEvBGIDNiLuoptiYu2Vt9TCMBEiABEiABEiABEiABEiABEiABEiABEiABEiABEsgGApkVc9EVeuhmw4SwShIgARIgARIgARIgARIgARIgARIgARIgARIgARLwRiArYi7qo6DrjSrTSIAESIAESIAESIAESIAESIAESIAESIAESIAESCDIBLIq5qI7hVrQjYveJuO6viK/XftekKcmsOr+eet304/VX84MrCBzB0xg5dIl8tvPP/hd7uiRw7Ju9Qr5Z+E82bppgxw/dszvssxIAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAkogGGIu6iqmFRbG7bkz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CZAACZAACRRIAhR0C+S0clAkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIFkQAF3YI4qxwTCZAACZAACZAACZAACZAACZAACZAACZAACZBAgSRQrECOioMiARIgARIgARIgARIggUJKYPfu3XL69GkpV66ceRUrxp/8hfStwGGTAAmQAAmQAAkUUAL8dVdAJ5bDIgESIAESIAESIAESKJwEfvjhB9m3b589+AsvvFCuu+46+5g7JEACJEACJEACJEAC+ZsAQy7k7/lj70mABEiABEiABEiABEjAg0Dnzp2lXbt2UqlSJZO+cOFCWbt2rUceHpAACZAACZAACZAACeRfAvTQzb9zx56TAAmQAAmQAAmQAAmQQBoCXbt2NWnnzp2T1157TY4cOSJbtmyRZs2apcnLBBIgARIgARIgARIggfxHgB66+W/O2GMSIAESIAESIAESIAESyJBASEiI1KhRw+RLSEjIMD8zkAAJkAAJkAAJkAAJ5A8CFHTzxzyxlyRAAiRAAiRAAiRAAiQQMIGwsDBTBouk0UiABEiABEiABEiABAoGAQq6BWMeOQoSIAESIAESIAESIAESIAESIAESIAESIAESIIFCQICCbiGYZA6RBEiABEiABEiABEigcBM4depU4QbA0ZMACZAACZAACZBAASJAQbcATSaHQgIkQAIkQAIkQAIkQAJOAmXKlDGHO3bskLNnzzpPcZ8ESIAESIAESIAESCCfEqCgm08njt0mARIgARIgARIgARIggYwI1KxZ02SBmLtq1aqMsvM8CZAACZAACZAACZBAPiBQLB/0kV0kARIgARIgARIgARIgARLIBIG2bdvKxo0bZdmyZTJmzBiZPHmyVKxYURo2bCg9e/bMRI0sQgIkQAIkQAIkQAIkkNsE6KGb2zPA9kmABPIsAawInpSc7PE6c+ZMnu0vO0YCJEACJEACbgIhISFyySWXSMuWLc2pgwcPypYtW8zLnZfHJEACJEACJEACJEAC+YMAPXTz2DwlJ5+WpctXBNSrRg0bSHjFCrJsxSr519CHzP60P34JqA5mzhyBr0d/Lx999qVc2ecyeeWFpzNXSTaWuuffj0r00uXy0rNPylVX9snGlgpm1eC3YuVqj8HddMNAefTB+z3SnAcffvKFjPpurPS9/DJ59cW8955w9pX7JEACJEACBZ/A/v375Z13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Aj4JrFixwpxr3bq1zzw8QQIkQAIkQAIkQAIkUHgIUNAtPHPNkZIACZAACZAACZAACeRDAhR08+GkscskQAIkQAIkQAIkkI0EgvdMeDZ2klWTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlYITYJgQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIIH8QKJY/uslekgAJkAAJkAAJkAAJkEDhJqChFwo3BY6eBEiABEiABEiABEiAHrp8D5AACZAACZAACZAACZAACZAACZAACZAACZAACZBAPiFAD918MlHsJgmQAAmQAAmQAAmQQOEm0KxZs8INgKMnARIgARIgARIgARIwBOihyzcCCZAACZAACZAACZAACZAACZAACZAACZAACZAACeQTAhR088lEsZskQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQEGX7wESIAESIAESIAESIAESIAESIAESIAESIAESIAESyCcEKOjmk4liN0mABEiABEiABEiABEiABEiABEiABEiABEiABEiAi6Ll0ffAl6O+k19/n2x699OYkVK8eHGzf9+wx2RvTKy0btlCXn3x6Tzae3aLBEiABEiABEiABEiABEiABEiABEiABEiABEggOwhQ0M0OqkGoMyEhQfbsjTE1nT17zq4RYi7SIyMq22ncIQESIAESIAESIAESIAESIAESIAESIAESIIHcInDmzBk5ceJEmuZLliwpRYsWTZPOhKwRoKCbNX4sTQIkQAIkQAIkQAIkQAJ5jsDMmTPlvvvuk0qVKsm8efNyrX+rVq2SQYMGmfZXr14txYrl/uXHhg0bZPr06RIfHy9JSUlSpEgRefnll3ONERsmARIgARIggYJAYPny5TJu3Lg0Q7npppukdevWadJzOiExMVFeeukl0+xDDz0kNWrUyOkuBLW93P9FFdThsDISIAESIAESIAESIAESIIG1a9caCI0aNcpVGOvWrTPtN2zYME+IuTt37pTRo0fbTEqVKiW1a9e2j7lDAiRAAiRAAlkh8PXXX8vJkyelT58+Uq9evaxUFfSyeBL8hx9+MPXeeeeddmjPYDZUp04dU93Ro0fl4MGDZj+vfM/u3r3bHmpERIS9n9d2/J0nCrp5bebYHxIgARIgARIgARIgARLIIoE1a9aYGlq2bJnFmrJWHF65sNzuh45i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BZNAkYI5LI6KBEiABEiABEiABEiABEiABEiABEiABEiABEiABAoeAQq6BW9OOSISIAESIAESIAESIAESIAESIAESIAESIAESIIECSoCCbgGdWA6LBEiABEiABEiABEiABEiABEiABEiABEiABEig4BGgoFvw5pQjIgESIAESIAESIAESIAESIAESIAESIAESIAESKKAEihXQceXrYZ09c1bwclpIkRApWqyoM4n7JEACJEACJEACJEACJEACJEACJEACJEACJEAChYwABd08OOEzP5opMz/826NnEQ0jZdj/hnmk8YAESIAESIAESIAESIAESIAESIAESIAESIAESKBwEaCgmwfnu2LNilK/c33Ts8OxRyR+24E82Et2iQRIgARIgARIgARIgARIgARIgARIgARIgARIIKcJUNDNaeJ+tBc1IErwgq36fZX89PCPfpRiFhIgARIgARIgARIgARIgARIgARIggf/P3nnAVVl+cfzIEGQPFRGVjQwX7q0NNdvZtKmZacOmldk/bWdpZjZsWGq7LE3TcmXu3Js9FBAVENkyBPw/57k8L/dyL8gSAX+nz73vs8f3Rbr87nnPAwIgAAIg0NwJQNBt7ncY+wMBEAABEAABEAABEAABEKh3AqUFBVRSkG80rqWjE1GLFkblKDAmUFhYSAXiVdEc7O0FQjCsyAV5EAABEAABEFAEIOgqEvVwzcvNo2ORx6hL7y4Go/EBZycOnaCUqBTKO5NLzp1cqH2IO3Fc3PqwI3uOkG+QL9nY2dTHcBgDBEAABEAABEAABEAABBqUwOEpE+nMxnXk+9w08pzwmMm5C06dpB3XDpB1g/7dTVZt3Uy2a6jCuI9mU9K3C42mG7rzCFnYOxiVN/eCT7/4mr778VcaPfIamvnKi9Xa7ucLF9NPvy4zart+9e9kb2dnVN7QBUfDI+iRx56R065fJdZkf/nX1NAMMB8IgAAIgEDjJNAsBd24uDj67LPPakX88ccfJ19f32r3vXDhAiXEJFD4gXDKTM+U3yTrC7q5QsD9fepvFLctzmjMIZOG0NXPXkPmFuZGdTUpOLr3KLGo6+TqRMGhweTp74lvtGsCEG1BAARAAARAAARAAAQuK4GMXdvl/DaeunMkTC0mNzpCFpvb2pJVm/pxjDA1T3XLLB0dqc21o2Tz3MgIyj+RSK06dLoixVyGEBYe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gtxD24YKXidyTsiOTTtkd/RuJezCi9dqy95eqnZ7XdW7RK9a3WbAdf1l3mPzZOsPW6XH5T2k/bAOquhowlFZ/Poile52aTcJaFjozavb6m3Tjo4QEGmJabJh7gbpPr67WMM5QICG5zC8cVu1ayVd+nSRBsHFC8S6X25JgARIgARIgARIgARIgARIgARIgARIgARIgATODoEahqDnVatefbvyiCJx+aBGZ4eIB456YN8B8avpJ4i7C0vclCjvXTlTpe/65W4JCXfkq4xi/uSdypO3LnpLjuxJVTVa9W6lFlGLWxFntrjb6KtxCX1hEba3L3vb9AxGQyyy1rRDU5n6yY1yIvuEJO1Nknad2omPD9fHM8EyQQIkQAIkQAIkQAJeRGDz5s1qNOHh4V40Kg6FBEiABEiABEiABEjgbBGgilcJ5LFImhZz0f2KmSvUUSJHdy6TmIvKfsZiZ7d8c4vACxe2b/0+0WJu86gWcvfCe0oUc9HGx9dHbpp9k8AruH4zR/iFrCNZkpWWjWKpHVBbIjpHUMxVNPiHBEiABEiABEiABEiABEiABEiABEiABEiABLyfAD10K/kcHd59SN4c+6Y6yvSvZkhYjzC3j5ibkyup8YeNBdjypXGbxiUuqOZ252xAAiRAAiRAAiRAAiTg1QTooevVp4eDIwESIAESIAESIIEqJ8AYupWMfNWsVeoIrfu2LpeYi8Y169QUeOXSSIAESIAESIAESIAESIAESIAESIAESIAESIAE/toE6KFbyec/Py9fCvIK1GJkCIFAIwESIAESIAESIAESIAF3CGgPXXfasC4JkAAJkAAJkAAJkED1JUAP3Uo+t75+voIXjQRIgARIgARIgARIgARIgARIgARIgARIgARIgAQqSoCCbkUJsj0JkAAJkAAJkAAJkAAJVAGBzp07V8FReAgSIAESIAESIAESIAFvJ8AYAN5+hjg+EiABEiABEiABEiABEiABEiABEiABEiABEiABEjhDgIIu3wokQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkcI4QoKB7jpwoDpMESIAESIAESIAESIAESIAESIAESIAESIAESIAEKOjyPUACJEACJEACJEACJEACJEACJEACJEACJEACJEAC5wgBCrrnyIniMEmABEiABEiABEiABEiABEiABEiABEiABEiABEjAjwhI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"/><use stroke="#7E7C7B" xlink:href="#rect-1"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/02-dom-nodes/inspect.svg b/2-ui/1-document/02-dom-nodes/inspect.svg index 658ee5ea26..a894a5c0ea 100644 --- a/2-ui/1-document/02-dom-nodes/inspect.svg +++ b/2-ui/1-document/02-dom-nodes/inspect.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="696" height="379" viewBox="0 0 696 379"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h696v379H0z"/><path id="path-2" d="M142 52v21.429l5.25-5.358L151.625 77h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H156L142 52z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="inspect.svg"><g id="Bitmap"><image width="696" height="379" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXAAAAL2CAYAAADowb7lAAAMSWlDQ1BJQ0MgUHJvZmlsZQAASImVVwdUU8kanltSSWiBCEgJvYlSpEsJoUUQkCrYCEkgocSYEETsyqKCaxcRsKGrIoquBRA79rIodtfyUBaVlXWxYEPlTQro6nnvnfefM3e+/PPP95fMnTsDgE41TyrNRXUByJPky+IjQljjUtNYpA5AACZAG7gCLx5fLmXHxUUDKAP9P+XtLYAo++suSq4fx/+r6AmEcj4ASBzEGQI5Pw/iAwDgxXypLB8Aog/UW0/LlyrxBIgNZDBAiKVKnKXGxUqcocYVKpvEeA7EuwAg03g8WRYA2k1QzyrgZ0Ee7TsQu0oEYgkAOmSIA/kingDiSIiH5eVNUWJoBxwyvuHJ+gdnxiAnj5c1iNW5qIQcKpZLc3nT/89y/G/Jy1UM+LCDjSaSRcYrc4Z1u5MzJUqJaRB3SzJiYiHWh/i9WKCyhxilihSRSWp71JQv58CaASbErgJeaBTEphCHS3JjojX6jExxOBdiuELQQnE+N1Ezd5FQHpag4ayWTYmPHcCZMg5bM7eeJ1P5VdqfVuQksTX8d0RC7gD/myJRYoo6ZoxaIE6OgVgbYqY8JyFKbYPZFIk4MQM2MkW8Mn4biP2EkogQNT82KVMWHq+xl+XJB/LFFonE3BgNrswXJUZqeHbxear4jSBuEkrYSQM8Qvm46IFcBMLQMHXu2FWhJEmTL9YuzQ+J18x9Jc2N09jjVGFuhFJvBbGpvCBBMxcPzIcLUs2Px0jz4xLVceIZ2bzRcep48EIQDTggFLCAArYMMAVkA3Frd2M3/KUeCQc8IANZQAhcNJqBGSmqEQl8JoAi8BdEQiAfnBeiGhWCAqj/PKhVP11Apmq0QDUjBzyBOA9EgVz4W6GaJRn0lgz+gBrxD975MNZc2JRjP+rYUBOt0SgGeFk6A5bEMGIoMZIYTnTETfBA3B+Phs9g2NxxH9x3INqv9oQnhDbCY8JNQjvh7mTxfNl3+bDAGNAOPYRrcs74NmfcDrJ64iF4AOSH3DgTNwEu+EjoiY0HQd+eUMvRRK7M/nvuf+TwTdU1dhRXCkoZQgmmOHw/U9tJ23OQRVnTbyukjjVjsK6cwZHv/XO+qbQA9lHfW2KLsP3YOewkdgE7gjUCFnYca8IuY0eVeHAV/aFaRQPe4lXx5EAe8Q/+eBqfykrKXetcu1w/qcfyhYXK/RFwpkiny8RZonwWG+78QhZXwh8+jOXu6uYLgPI7ot6mXjNV3weEefGrbsEGAAIO9Pf3H/6qi2oGYH8ZANTbX3X2s+B2cBKA81V8haxArcOVDwKgAh34RhkDc2ANHGA+7sAL+INgEAZGg1iQCFLBJFhlEVzPMjANzATzQAkoA8vBGlAJNoItYAfYDfaBRnAEnARnwSVwFdwE9+Dq6QTPQQ94C/oQBCEhdISBGCMWiC3ijLgjPkggEoZEI/FIKpKOZCESRIHMRBYgZchKpBLZjNQivyKHkJPIBaQNuYs8QrqQV8hHFENpqAFqhtqhI1AflI1GoYnoRDQLnYoWocXoUrQCrUF3oQ3oSfQSehNtR5+jvRjAtDAmZom5YD4YB4vF0rBMTIbNxkqxcqwGq8ea4f98HWvHurEPOBFn4CzcBa7gSDwJ5+NT8dn4ErwS34E34Kfx6/gjvAf/QqATTAnOBD8ClzCOkEWYRighlBO2EQ4SzsC3qZPwlkgkMon2RG/4NqYSs4kziEuI64l7iCeIbcQOYi+JRDImOZMCSLEkHimfVEJaR9pFOk66RuokvSdrkS3I7uRwchpZQp5PLifvJB8jXyM/JfdRdCm2FD9KLEVAmU5ZRtlKaaZcoXRS+qh6VHtqADWRmk2dR62g1lPPUO9TX2tpaVlp+WqN1RJrzdWq0NqrdV7rkdYHmj7NicahTaApaEtp22knaHdpr+l0uh09mJ5Gz6cvpdfST9Ef0t9rM7SHa3O1BdpztKu0G7Svab/QoejY6rB1JukU6ZTr7Ne5otOtS9G10+Xo8nRn61bpHtK9rdurx9Bz04vVy9NbordT74LeM32Svp1+mL5Av1h/i/4p/Q4GxrBmcBh8xgLGVsYZRqcB0cDegGuQbVBmsNug1aDHUN9wpGGyYaFhleFRw3YmxrRjcpm5zGXMfcxbzI9DzIawhwiHLB5SP+TakHdGQ42CjYRGpUZ7jG4afTRmGYcZ5xivMG40fmCCmziZjDWZZrLB5IxJ91CDof5D+UNLh+4b+rspaupkGm86w3SL6WXTXjNzswgzqdk6s1Nm3eZM82DzbPPV5sfMuywYFoEWYovVFsct/mQZstisXFYF6zSrx9LUMtJSYbnZstWyz8reKslqvtUeqwfWVGsf60zr1dYt1j02FjZjbGba1Nn8bkux9bEV2a61PWf7zs7eLsVuoV2j3TN7I3uufZF9nf19B7pDkMNUhxqHG45ERx/HHMf1jledUCdPJ5FTldMVZ9TZy1nsvN65bRhhmO8wybCaYbddaC5slwKXOpdHw5nDo4fPH944/MUImxFpI1aMODfii6una67rVtd7bvpuo93muzW7vXJ3cue7V7nf8KB7hHvM8WjyeDnSeaRw5IaRdzwZnmM8F3q2eH728vaSedV7dXnbeKd7V3vf9jHwifNZ4nPel+Ab4jvH94jvBz8vv3y/fX5/+7v45/jv9H82yn6UcNTWUR0BVgG8gM0B7YGswPTATYHtQZZBvKCaoMfB1sGC4G3BT9mO7Gz2LvaLENcQWcjBkHccP84szolQLDQitDS0NUw/LCmsMuxhuFV4VnhdeE+EZ8SMiBORhMioyBWRt7lmXD63ltsz2nv0rNGno2hRCVGVUY+jnaJl0c1j0DGjx6wacz/GNkYS0xgLYrmxq2IfxNnHTY07PJY4Nm5s1dgn8W7xM+PPJTASJifsTHibGJK4LPFekkOSIqklWSd5QnJt8ruU0JSVKe3jRoybNe5SqkmqOLUpjZSWnLYtrXd82Pg14zsneE4omXBrov3EwokXJplMyp10dLLOZN7k/emE9JT0nemfeLG8Gl5vBjejOqOHz+Gv5T8XBAtWC7qEAcKVwqeZAZkrM59lBWStyuoSBYnKRd1ijrhS/DI7Mntj9ruc2JztOf25Kbl78sh56XmHJPqSHMnpKeZTCqe0SZ2lJdL2qX5T10ztkUXJtskR+UR5U74BPLBfVjgoflI8KggsqCp4Py152v5CvUJJ4eXpTtMXT39aFF70ywx8Bn9Gy0zLmfNmPprFnrV5NjI7Y3bLHOs5xXM650bM3TGPOi9n3m/zXeevnP9mQcqC5mKz4rnFHT9F/FRXol0iK7m90H/hxkX4IvGi1sUei9ct/lIqKL1Y5lpWXvZpCX/JxZ/dfq74uX9p5tLWZV7LNiwnLpcsv7UiaMWOlXori1Z2rBqzqmE1a3Xp6jdrJq+5UD6yfONa6lrF2vaK6IqmdTbrlq/7VCmqvFkVUrWn2rR6cfW79YL11zYEb6jfaLaxbOPHTeJNdzZHbG6osasp30LcUrDlydbkred+8fmldpvJtrJtn7dLtrfviN9xuta7tnan6c5ldWidoq5r14RdV3eH7m6qd6nfvIe5p2wv2KvY++ev6b/e2he1r2W/z/76A7YHqg8yDpY2IA3TG3oaRY3tTalNbYdGH2pp9m8+eHj44e1HLI9UHTU8uuwY9Vjxsf7jRcd7T0hPdJ/MOtnRMrnl3qlxp26cHnu69UzUmfNnw8+eOsc+d/x8wPkjF/wuHLroc7Hxktelhsuelw/+5vnbwVav1oYr3learvpebW4b1XbsWtC1k9dDr5+9wb1x6WbMzbZbSbfu3J5wu/2O4M6zu7l3X/5e8Hvfvbn3CfdLH+g+KH9o+rDmX47/2tPu1X70Ueijy48THt/r4Hc8/0P+x6fO4if0J+VPLZ7WPnN/dqQrvOvqn+P/7Hwufd7XXfKX3l/VLxxeHPg7+O/LPeN6Ol/KXva/WvLa+PX2NyPftPTG9T58m/e2713pe+P3Oz74fDj3MeXj075pn0ifKj47fm7+EvXlfn9ef7+UJ+OpjgIYbGhmJgCvtgNATwWAcRWeH8ar73kqQdR3UxUC/wmr74Iq8QKgHnbK4zrnBAB7YbMLhtywVx7VE4MB6uEx2DQiz/RwV3PR4I2H8L6//7UZACR4nvks6+/vW9/f/3krDPYuACemqu+XSiHCu8GmYCW6aTSpGnwn/wZ3TIEEcU5bKwAAQABJREFUeAHs3QW8LVXZOOB14dJIiHRJXRQQEKS7RASkpESR/sBAMei6SqdKSSggDSol0g0fICEhSIOU9KUb93/e+TvzzT65T9x7zr7zrN/vsCfWrFnrWXMv8J613xnRyEpSCBAgQIAAAQIECBAgQIAAAQIECBAgQGDYCUww7HqkQwQIECBAgAABAgQIECBAgAABAgQIECCQCwjgehAIECBAgAABAgQIECBAgAABAgQIECAwTAUEcIfpxOgWAQIECBAgQIAAAQIECBAgQIAAAQIEBHA9AwQIECBAgAABAgQIECBAgAABAgQIEBimAgK4w3RidIsAAQIECBAgQIAAAQIECBAgQIAAAQICuJ4BAgQIECBAgAABAgQIECBAgAABAgQIDFMBAdxhOjG6RYAAAQIECBAgQIAAAQIECBAgQIAAAQFczwABAgQIECBAgAABAgQIECBAgAABAgSGqYAA7jCdGN0iQIAAAQIECBAgQIAAAQIECBAgQICAAK5ngAABAgQIECBAgAABAgQIECBAgAABAsNUQAB3mE6MbhEgQIAAAQIECBAgQIAAAQIECBAgQEAA1zNAgAABAgQIECBAgAABAgQIECBAgACBYSoggDtMJ0a3CBAgQIAAAQIECBAgQIAAAQIECBAgIIDrGSBAgAABAgQIECBAgAABAgQIECBAgMAwFRDAHaYTo1sECBAgQIAAAQIECBAgQIAAAQIECBAQwPUMECBAgAABAgQIECBAgAABAgQIECBAYJgKCOAO04nRLQIECBAgQIAAAQIECBAgQIAAAQIECAjgegYIECBAgAABAgQIECBAgAABAgQIECAwTAWGVQD3k08+SS+++OIwpWqvbr3zzjvpzTffHHad/vDDD9Mrr7wy7PrVLh167LHH0tNPP91jd/n2yOMkAQIECBAgQIAAAQIECBAgQKCtBEb2tbdXXHFFuu222/p6Waf6U001VfrpT3+a3njjjXT99denyy67LJ1//vlps802SyeddFKn+g70LvDss8+mq666Kl166aXp4osvTmeeeWbaYoster9wLNd47bXX0nXXXZfi2bngggvSD37wg3TQQQeN5buOH81//PHH6Y477khXXnll/ufj0UcfTYceemjaddddywG+++676aabbkqXX355uvDCC9MMM8yQ7r777vK8DQIECBAgQIAAAQIECBAgQIAAgfYV6HMANwKERx999IBH/JnPfCZ96UtfSmuuueaA29JASvvvv38aPXr0sKM44ogj0s9//vNh16926NCYMWPSnHPOmd5+++1uu3v44Yc3BXOjYgRwFQIECBAgQIAAAQIECBAgQIAAgfFDoM8pFN5///1y5FtttVW65JJL0u23355iZeANN9xQnouN/fbbL8VXvu+555509dVXp4MPPrgMLkVQarXVVktPPPFE2njjjZuus9N3gd122y3de++9adSoUX2/eCxe8f3vfz89+OCDabnllhuLdxk/m5522mnT66+/nh5//PG08MILdznIXXbZJa8zHIP3XXbYQQIECBAgQIAAAQIECBAgQIAAgT4J9DmAG1/XjnLcccelU089Na277rppqaWWSvPNN1+ad955m24+yyyz5Me+/OUvp9VXXz3tvvvu6dZbby3rTDjhhGnuuedOG264YXlsOG5EXt6vfvWrw6Zr8RX6SEVQLZNNNllaZJFF0qqrrlo9POTb0a8FFlggrbXWWkPel8HoQPySIlJ/jKsycuTINM8886SVV165y1vG+Qj0brDBBl2ed5AAAQIECBAgQIAAAQIECBAgQKC9BfocwP3ggw/yVbQ77rhjv0YeQd7IgRolXloWJdIpDNfy6aefpi233DLdd999w6KLkS84AuHdfa0+cgsPxzJc+9UXqwjkb7rppkPyErZpppmmx65OPPHEPZ53kgABAgQIECBAgAABAgQIECBAoD0F+hzAfe+999JGG22UJpigz5eWQrFqN8pHH31UHhuuG7/4xS/y9A/DoX/PP/98Wm+99YZDV2rXh/hlw+abb55efvnl2o3dgAkQIECAAAECBAgQIECAAAECBIZOoM8vMYsXmE0xxRQD6nF8HTxSKUw++eS9thOBs/iZdNJJe6072BV+/etfpwjgtlpiVWx1NXEEuyOFwIgRI1ptott6L7zwQp7GobuVt91eWDkRq6fjK/fxMxil0Wjkq1Hfeuut9PnPf77f7Q6kX7FCOlJxjM0Sv2j47ne/2ynH82DcMwwH4/kYjL5ogwABAgQIECBAgAABAgQIECBAYPgJ9HkZbeS6jdy2Aynxde9ll1222yb+85//pPPOOy8tueSSaaKJJsqDoMsvv3yec7fbi7IT8bKneJlX1I2v7MdP5K4999xze7qsy3P7779/+vGPf1yei5WXK664Yv6zyiqrpAjORokA4nXXXZe22GKL/H7xkrcHHnggT7sQge4vfOEL6Xvf+15acMEFm36uuOKKsu0IEnc8H9cUJcYVeYYfeuih4lD+griiPyeffHJ5vOPGO++8kw477LA8j2oEk8PzG9/4RlMu4o7X9Lb/yCOP5KkEYhX2jDPOmOc/jnaXWWaZdM011/R2eX4+/A444ICmfsVcXXjhhT1eH8Heo446Kn3zm99Ms88+ex40nn/++XP/0047LcWzUy2XXXZZJ9sDDzywrNLV+cUXX7xsJ/q5/vrrNz1DF110Ufks7LTTTmVbrW5EGoy4LnIWh2GMY5NNNkl33XVXq020XC9++RH9X2eddTr9/PCHP2y5HRUJECBAgAABAgQIECBAgAABAgSGRqDPAdyx3c2PP/44RX7dzTbbLN15553l7WLF7jbbbJP+/Oc/l8eqGxEQXWyxxVIE8SLPbqR5iHL11VfnX32PANaHH35YvaTb7ejD/fffn5ZbbrmmOp/97GdT/MRLo9544408WBzB7NVWWy2dffbZed1//vOf+XVnnHFGvv/oo4/mK4iPOeaYPAAbQdj4ee2118q2d9lll7zfEXAuzkeQtCgR2IugYnV17wwzzJD3JfoTgdmuSgSd46VmEdR+8sknyyqXXnpp/lKxCAz3tcRLvCIoff7556fo9zPPPJMitUMEA2+//fa0xhprpAiK9lReffXVFC+222effZr6FXMVL7SL47EytWN58MEH80B2vERszJgxeRA7grFTTz117r/11lvnc/HEE0+Ul8bL084555x8BXdh+69//as8H/2NZyqCz8X5e+65p7x/tBW/cBg1alR5TdyveBb6kts3xnTIIYfkc3LTTTflz0m8fOy5557LX0q3xBJL5EHt8kaDsBGrrWMleZSYl/j53Oc+lwfAf/SjHw3CHTRBgAABAgQIECBAgAABAgQIECAwVgWyoNKglSwQFVG38ufEE09sqe2//OUv5TXF9fvuu28jC37mPxtvvHF5frbZZuvUZnH9Agss0HjllVfK81mAspEFOstrs8Bgea6VjSxgWF7b8b5ZcLSRBQ8bWWCvrBN9z4KsjSzHbyMLDJbHDz744Px2Wf7a8tiZZ57ZqQtZoLE8nwVeO53Pgtrl+Sxg3Ol8HNh1113LOtGfGP+pp57ayIKWjSwg3tTfHXbYocs2ujuYBbabPLOAeFk1W+mZjz3uGSYdy29+85umfkW9cDryyCMb22+/fXltHI+fCy64oKmJxx57rLx+7bXXbmQrbcvz2SroRtU25iALkJfnY+NXv/pVeX3cr2PJAtHl+bh/jKda4lku+tZXt6KdLJCet/Gd73ynqf3i+S3av/LKK4tLys/481CcP/TQQ8vjxcbDDz9cns9+kVEczj+zAHV+LuYl+8VE0zk7BAgQIECAAAECBAgQIECAAAECw1tg2K3AzYJU6Y477kijR4/Ov5ofKRuyIF8czkusVoy0AEWJ/KQ777xzvvu73/0uX11YnJtnnnny9AXF/i9/+ct8tWix35fPWIVZLdNPP33ac889U3wdvloWXXTRFF+xv+qqq9Jtt92Wr/6MlapRYuVuT2Waaabp6XTTuVbypi688ML5SuKtttoqzTHHHOkrX/lK7lo09Pe//73YbOnz2WefbXqJV6RNKErkoY2VuVFi1XF1hXFRp/iM1cNR55JLLkk/+clP0kknnZRuueWW4nT+GauGqy+5+8EPflCejxWl1fFHGoJY8Tz33HPndSJPcBbILuvHxmDa9+cFfrHaOQu85quos2BwU97eLCDdtNp7MFMbHHfccfmq5jXXXDNf0f6lL32pycUOAQIECBAgQIAAAQIECBAgQIDA8BYYdgHcbCVlnvu2yhY5QiPoV5RqeoHf//735dfwI8VA8TX44jO+6l4tkZ92MEvHfMAROCwCfEsvvXSeCmKSSSYZzFu23NZ2222X56itXhCpC4oSKSo65owtznX1Oddcc6WVV145PxWpB6pB1DhYTfHw+uuv5/W6+kcElCMwXy0RbM5WCpeHIuXDzTffnO9ffvnlKVuVmm9HIDIC8x1L3LsIlMe5COYP9lx3vGdf9vfaa6+8egT4n3rqqU7P6Zxzzlk2F8HtgbysLhqKeY1nMQLfkXok0mb0Jd1D2RkbBAgQIECAAAECBAgQIECAAAECQyowckjv3oebR+CxCOJlaRLKK6svA1tooYXK491tZF/FT1/72te6O92v4xE8LAJuHfPm9qvBsXhR5Aeulnfffbcp8Fo919V2rDiOnLczzzxzeTpyysYK2GrO4niZW3dluumm6/JU5C2OPLZFifyzkV84VjIXpavgbXEuXmxWXb163333peGw4jRbhJ/nDI5+RlA6XljXW4kVu9Vge2/1q+djhXq8VC9e3hcB3Cx9Radge7W+bQIECBAgQIAAAQIECBAgQIAAgeEr0DYB3HgZU1elWGUZL4CqruDsqm4cm3XWWbs71e/j8RKxIoDb70b6eGHH1a+tXh6pDgZaCsNrr702f0FWrO6MFbQDNYhAeKzAvvjii/MuFi9ZixfKFeXzn/98sdnpc6aZZspfZBcvIYsSLz0bG6Wv9i+88ELZjQioxkv6eivVl6b1Vrfj+VjBGz9RYrVvBJD72ueObdonQIAAAQIECBAgQIAAAQIECBAYGoGuo6JD05c+3zV7iVaZPiFyrraysrHPNxmmFxRpGoaie3/729/Sz372s3w16QorrJBuuOGGtNJKK+WrZa+77roBdanIYxuNZC8Sy9uK3LtFiTnvqUSahyKAGyt4x0bpazC0CERHXyK1wbh8Ti+77LI89+4ee+wxNii0SYAAAQIECBAgQIAAAQIECBAgMJYFhl0O3L6Mt7qaNHKm9hbc60vbHet2twK4Y73xff+cc85JSy21VB68jVy2sQo3greDVao5ixdYYIG82RlnnLFs/plnnim3u9qopnaYbbbZuqoy4GN9DZ5XcyBHbuaxXRZbbLE8bUJxn3jZ3kAD60VbPgkQIECAAAECBAgQIECAAAECBMatQFsHcCOoWgT5gu2CCy7oUe+jjz5KRx111IC/6t/jTcbRyb6uAh2MbsXL4771rW/lTUXKhHiB3EQTTTQYTZdt/Pvf/y63i7mt5rG9++67y/Ndbbz55pvl4eL68sAQbVTz9sZq5d5WBkeQ+sQTTxxQbyNVw8Ybb1y2sf7666fnnnuu3LdBgAABAgQIECBAgAABAgQIECDQHgKDGsCNXJvjulRfXBZfE//ggw+67EL0baeddkpHH310qq6I7LJyFweLr/N3capfh6qBxv40MNj9aaUPJ598clktXjg2NoLI8eKxKJEPN4LEUaoB3EiP8M9//jM/3tU/nn766fJwcX154L8bb7zxRsdDfdrvq/3000/f9KK4fffdt9v7vfXWW2nddddNt956a7d1WjkRcxPzVaSkiPzEG264YXrvvfdauVwdAgQIECBAgAABAgQIECBAgACBYSIwqAHcd955p2lY77//ftN+dzvVgFh1u1q/evzTTz8tT+2www7ldqwwjBWiXQVHDznkkHzF6N57750mnnji8pqeNqaYYorydKRoiPylAynTTjtteXnx8rXiQASYr7rqqmK3y9WSEdQsyvPPP19sNn1+/PHH5X51uzjYMchedS3qdPdZDY6++OKLTdUicP6Pf/yjPNZdIL2s0MVGvKysCFwee+yxacopp8xrRbC4CETGgT/84Q9dXJ3SK6+8kqd2iJNrrbVWWnLJJct6U001Vbnd1Srea665pjwfG9FWtVSfhWpO3mqdnrZ/8pOflKfPPvvsdOCBB6bqcxwnY77i+Q2HXXfdtazf342pp546/fnPfy4vv/POO9O2226bv9SsPNhhI/4MxSr18Bjo896habsECBAgQIAAAQIECBAgQIAAAQL9EBjUAG7Hr2j3lq+06O+YMWOKzRQvI+uqVANqr7/+ellltdVWS8stt1y5f+GFF6bIAXrAAQekSy65JA/2RZ3IA7r22mvnAayyci8bs846a1ONK6+8Mt8/77zz0hZbbJFvR0D05ZdfLut1DGyWJ7KNL3zhC+Xub3/72/SnP/0pDzZH4DaClLE6uCiPPvpoihdQVVdMzjfffMXpFOOM4GvYrbPOOileLBalalN1LS6MFZ7V0lWd6vnqdgQEi3LCCSek4447Ll8NGx6rr756k8MVV1yRIuVC5MjtWLoKgMYK0fjaf5SYz29/+9vlZZNNNlm+mrQ4EMH4W265pdgtP3/3u9+V21XLODhq1KjyXATjYxVsWEUwd7fddstXp5YVso2TTjopvfrqq+WhahqEm266Kb3wwgt5ADYCreHQW9l5552bqsQvElZZZZV0zDHH5PMcAet4PmLOY3zVleVxYfX57+oXFNVfnsTzWARfF1lkkSa7c889N/3oRz/qMogbOaQXX3zx9NOf/jStscYavaYkaRqQHQIECBAgQIAAAQIECBAgQIAAgbEjkAUgB1zefffdxu23397IAm+RQ6H8yVaMNi666KJGFnzq9h5ZQLGx6qqrltfE9XfccUdT/dtuu63p/JprrtmIexbl4YcfbmQrNJvqVPsR20sssUQjC3wVl7T8GddV25phhhny/SyY28gCXo0sENt0PltB2Yj+ZAG0TvfIgruNMKm2V2zH8fPPP7/TuexFYWU7l19+edP5oq0sMN3IVjs3styqTe1nQctGtlK3vD5b8dnIVlc2tbHffvt12dfyospGx/sXfY/P9dZbr7HLLrs0tR3HjzjiiLyF8KrWz9JZ5M9GFnhunHrqqY0s6J6fD78sqFy56/9tZkHZso0Y+9VXX53PQbZytXHmmWeW58KxY8mC3Z2es2p/siBsp2coewlaI8yiZL9YKNsvros+xHP31FNP5XV6+0f2C4VObRRtFZ877rhjp/l48MEHm+Y1y+3beOmll8rbxXPY0f70008vz8fGBhts0HTvLD9uI/uFS1OdLH1FU53oi0KAAAECBAgQIECAAAECBAgQIDC0ArESb0AlW2XbFPQpAlEdP7MVsZ3uc+mll3Z7bbYCMK+/8sord1snAk5FiYBWBHY73jf2sxWNjewFZkXVPn3GPYpAabQVAdwIVmdf9e/yXsX9N9tssy7vE8HpCMAV9eIzxhj3iYBa7C+99NKN448/vvGvf/2rUxvbbLNN07URZIuxZfl/m45X2w/7bDVp0ziq52NMRaCy0w07HMhWijbdJ4Kcp5xySh50zFa25oHyaDvajPtW240xfve73+0UKI36EcCNQG5v5a677mpEYLra/2J+spy3jSw/brdNZKtmG1l+2aZrIwCbpRnIr4ntGM/o0aMb9957b6dAavbStqZr4xcWEZTvS8nSGHTqf+F18cUXNzUVgenoT3Ws1e14brJUDN2eD5eHHnqo8Ytf/KLbOvHcFCXmqvpsZmkUilM+CRAgQIAAAQIECBAgQIAAAQIEhkhgRNw3CwqNNyVSDmTBt/zr/PG1+Ug7MNFEEw1ofJGbNF6cFblz559//gG/vCtSHzz22GMp0hnMPPPMaY455sj7F/eJtBPVr+t31fH4+n7kwI2v3GdBuq6qjNVjYfz444+nyCsbfZ9gguZMHNmK1Pz4hBNO2G0/InVDpDIoTFvNS1w0GGkYsoBwiry84bXooovmlsX5nj7DOAwjJ3FcO3LkyLx6pHyI56XjeKptxZxFvUivMcsss1RP9Wk70jPEC9myoGn64he/mOacc84BP1d96kA3lbNfBqT//d//zXMOF89lN1UdJkCAAAECBAgQIECAAAECBAgQGAcC410AdxyYuQUBAgQIECBAgAABAgQIECBAgAABAgTGiUDz0slxcks3IUCAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgMHII7umWBAgMUOCJJ54YYAvj5+XzzDPP+DkwoyJAgAABAgQIECBAgAABAgRqK2AFbm2n3sAJECBAgAABAgQIECBAgAABAgQIEBjuAgK4w32G9I8AAQIECBAgQIAAAQIECBAgQIAAgdoKCODWduoNnAABAgQIECBAgAABAgQIECBAgACB4S4ggDvcZ0j/CBAgQIAAAQIECBAgQIAAAQIECBCorYAAbm2nfugG/umnn6a77rorvfXWW9124uOPP05vvPFGt+cHeuLpp58eaBOuJ0CAAAECBAgQIECAAAECBAgQIDDWBQRwK8RjxoxJo0ePTjvvvHPl6NBs3n777WnGGWdML7zwwtB0YJDvGsHaSy+9NO20005plllmSUsssUR66KGHmu7y0ksvpbPOOittscUWabrppksHH3xw0/nB2Pnkk0/Skksumeaaa678M/YVAgQIECBAgAABAgQIECBAgAABAsNVYORw7di47Nebb76Zjj322HTooYemt99+O6299trj8vZd3uuYY45JL7/8cjrxxBPzoHKXldrk4DXXXJPWWGONHnv7jW98Iw/w9lhpEE7ee++96c4778xbis8IlC+//PKD0LImCBAgQIAAAQIECBAgQIAAAQIECAy+QK1X4L7zzjvpsMMOS7PPPnvae++98+Dt4BP3vcVYdXv22WfnFx599NHpvffe63sjw+iK1VZbLcVK1xtvvLHbXl1wwQXpueeeS+uuu263dQbjxLzzztvUzJe+9KWmfTsECBAgQIAAAQIECBAgQIAAAQIEhpNArQO4v/nNb1J8bf+cc85Ja6655rCZl1NOOaXsS6wIPvfcc8v9dtwYMWJEmnDCCdOKK66YRo0a1eUQJplkkjTrrLOmtdZaq8vzg3VwmmmmSc8++2w69dRT88+pp556sJrWzjgWiFzK3/ve9/LA/zi+tdsRIECAAAECBAgQIECAAAECBMaZQK0DuHvuuWc68sgj85QJm2666ThD7+lGH374YTruuOOaqkRqh0aj0XSsXXemn376HrsegdyxXWabbba01VZbpfhU2lfghBNOSFdddVX66KOP2ncQek6AAAECBAgQIECAAAECBAgQ6EWg1gHcqs3kk09e3R2y7QsvvDDPffuZz3ym7MOjjz6arr322nLfBoG6C9xyyy3pV7/6Vd0ZjJ8AAQIECBAgQIAAAQIECBCogYAA7jCb5F//+td5j+IFW9Ug7lFHHdXnnkbe2fiplljh+/HHH1cPDcp2O64Q7sqnI8aYMWPS66+/3vHwgPbjpXmPPPLIoOY2Dv946d37778/oL4N9sWR5uDf//53/tPqMxLXVMcR11X377rrrvT9739/sLuqPQIECBAgQIAAAQIECBAgQIDAsBQQwB1G0xKBqdtvvz1tsMEGaf7550+77LJL2bvLL788/fOf/yz3u9uIAO0VV1yR/ud//id99rOfTZdcckkexD3zzDPTN7/5zTTppJOm6aabLk8hEC8N62+JoNppp52Wtthii/wlcBNMMEFacMEF85ykEbAb7PLQQw+lddZZp8ufas7gVu7797//Pe266665T6zk7FjCMF5uN+OMM+Z1wiu2N9988xQvZOuPWwSC99hjjzTVVFOlyMP7hS98IU0xxRS52UBWkr722mt5u/PNN19adtllU7yUbZVVVkl77bVX2nbbbTsOLQ+ExrMU5374wx/m5//1r3+lww8/PH8+4iVvX/va11I8L0XANQLdF198cYo0I4ssskhaaqml0s9+9rMUc9JdufXWW/P24jleYYUV8p9FF100bb/99un555/v8rIIQEdu4tVXXz2dfPLJKQK5f/jDH9JXv/rVfFwHHnhguv7669Nmm22W3n333bKNnXfeOZ+bmJ+//e1v5XEbBAgQIECAAAECBAgQIECAAIHxQWDk+DCI8WUMRe7beDFTlAiy/eIXvyiHd+yxx3bKj1uezDYin28E1qrllVdeyV/Qdt1115WH48Vop59+er4K9MYbb0wTTzxxea6Vjbg++nbBBRekVVddNa2//vrpvvvuSzfffHMe1Ivg33nnnTeoLySLAGWMb4kllkhx/xlmmCF961vfygOD8XK03kpcc8QRR+SBySeffLLb6hG0/M53vpOPbZNNNkm77757ihedRSBx9OjR+XXV4GG3DVVOvPDCC3nQMwK/4RWrrOOFbRdddFHaZptt8kB9BGJ/+ctfVq7qffOtt97Kg6TxUrYf/ehHacMNN0xxLNoP/wgQFyXqHH/88emvf/1rGfyMQGnM1f77719Uyz8ff/zx/Nh//vOftO6666Ydd9wx3X333WWdGH/0PeY7ArszzTRTeS42fvvb3+bWsR3mK6+8cr6KOQLYEYC9//77c9855pgjquTHwjfaK0rc+4ADDkhnnHFGcSgP7kYwOfp9zTXXlMc/97nP5b+YiAMTTTRRedwGAQIECBAgQIAAAQIECBAgQGC8EMgCVkomcO6558ZbwvKftddee5ybvPTSS/m955577ka28rC8/0YbbVT2K/r36quvluc6bjz22GONbCVlI0u90HRNFuxsZC9Ca9xzzz2Nc845p+lcFsDr2EyP+1kArbH00kvnbZx44olNdbNgZ9l29CELXDadj53llluurHPbbbd1Ov+73/2uPJ+tki3Ph0nsh0G2QrmRBTzLc61sZGkLGtHfLEhath9tZQHFpstvuOGG8nxH67333js/lwUgm67pbScLNJdtZiusm6pvvPHG5bmuvJoqV3ayIGvjxz/+cX5ttvK5EfvFT7ZSu5Gtkm1kAdzyWBbwbGTB/Ua2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6ad32/QDDzyQpzt47rnnuq3TyokiTUBRN4LCsTJ3bJUY029+85uy+chRu//++6drrrkmD7QXJ+6+++5is8fPq6++OhUvdlthhRU6rejt8eJeTsbq1r/97W9lrVlnnTXv+2677VYeC6+xGfAub/TfjVhJXpTIHTwuyqeffjoubuMeBAgQIECAAAECBAgQIECAAIEhERDA/S97o9Ho8wR88skn+dfXI51BfF28L+W9995Lhx56aH7Jd7/73ZYu3WSTTZrqRT7WN954o+lY7PQ2lv4GvCLn7XLLLVfeL164FrlOO5ZYwfr1r389D1ZuscUWHU/3eT/SD5x44onldfHSt1i53N9SDWjGHHYsF1xwQepoFMHI6gvmYmVtK+WZZ54pq7300kspUgxUy1133VXuxmravpYrrrii0yXbb799WnzxxcvjXY2xPNnFRnV1cV+vffbZZ8sWX3311XI7Nqo5lGN1cE/PaU/noq1YtV6UYnVzse+TAAECBAgQIECAAAECBAgQIDA+CQjg/nc2I2doUSK41EqJFbTrrLNOnu9zpZVW6jEg1bG9eKnT22+/nR9eZJFFOp7ucj9ys2622Wblubg+gpkdSzWoG0HDjqUaWKsG1TrW62p/9OjR5eG4/7rrrpu/8CtWXl588cX5atV42VesvI08spNMMklZPzaqOWzfeuutpnOxUz1W7ecOO+yQvv3tb5f140Vi5513Xrnfl43qXI8ZM6bTpbFi9pRTTul0vBpgXWqppTqd7+rAVFNNVR4O6+9///spcuJGaomtt946RcqBolx77bV5+oZzzjmnONTrZwSb//nPf3aqVwSYl1hiiabV3cUzFxfEXHQMKMfxqk9XuY4juF39M1I1rOZJjly41113XXrkkUfSWWedlbbaaqtoviy33357/tK+IhXIO++8U57r6rktT2Yb1ZehxSrnKHGfZZZZpqlv+Qn/IECAAAECBAgQIECAAAECBAi0s0C20q325fHHH29k+WVjCW75k31FvleXjTbaqKwf12arD3u9Jlst2Nh9992brjvjjDMaWUCsx2uzQFsjC4p26mfcNws2NrIgWn79fffd18hWJ5btzzDDDI0sGFa2nQXLGmussUZ5Pq6/8sorG9F+q2WfffZpur7qVmzHmKol2s+CjU3XZSuPG1lQtKyWvcStka3wbaqTBRDL81nwsRHjKe4Rn1lAuVe7soFs4/rrr2+6fr311mtkgcOySrRXtH/sscc2soByI1uFml9XuGZB87J+bxvPP/9803wUbcfnqFGjGnGP6rHYXnvttXtrthHPbBacza+dYoopGlnqh0ZYZakrGlne27LNP/3pT3ndqJ8FOBtZ0Lg8F/fKguzl+aiTBZEb0V7Rp+wlaY1slXBTnSOPPLI8H/WylBaNBx98MK+z4447Np0r2onPnXfeuexz9Xj04YYbbmhkK7ybrs1+QdLIgt1N944+xk/H+0w33XT5tVlaiV7tVCBAgAABAgQIECBAgAABAgQItJNArBqtbclWP3YbXIsAUwTsIlDUXYnAUxGIyvKbdlet6Xj2YqzymuLa4rOpYoedCDQW9br6XGuttRrZy7a6rXPwwQc3br311m7PRzC1LyVbcdul3dJLL50HEatt3XPPPV3WLcax7777NqL/xX7Hz7nnnjtvbs011+y2ziWXXFK9Zaft2267rcc+RFA6SgRwI7DaMVAcfZptttka2cvjOrXd24EITlbbi+dqjz32aERAOkvn0MhSY5TjylapNrIV1L01mQcxI4Abv3ioBlwLuzh30UUXlcHPk08+uct6UT9bMZ0HYHuag2233TZ/frq6V3HPLJ1D3k72orlyPHEuS+fQyFbg5n3JXn7XyF7ilp+fd955G1kakMYqq6zSVL9or/jM0nSU4ygCuPGLiri+qBOfBxxwQK9uKhAgQIAAAQIECBAgQIAAAQIE2k1gRHQ4C34o/RTIAkr5V9Hjq9sjR47sZyvte9lTTz2V4oVlU089dVpggQXS9NNP376DyXoeqQEmnHDCFKkAshXB+QvI4o/IzDPPnGaZZZY0wQT9yzoSuWSfeOKJPM1GFpBOE088cZNT5A2OF7ZFmoxWSrQVqTLCPcorr7ySIu1A9DVbNZumnXbaVpoZa3WibzGmGWecMWWrY5vuExbR13jp2kBKjDXSXURO4yyYm//5m2eeeQbSpGsJECBAgAABAgQIECBAgAABAsNOQAB32E2JDhHoXSACuEpnAQHcziaOECBAgAABAgQIECBAgAABAu0t0L/lhO09Zr0nQIAAAQIECBAgQIAAAQIECBAgQIBAWwgI4LbFNOkkAQIECBAgQIAAAQIECBAgQIAAAQJ1FBDAreOsGzMBAgQIECBAgAABAgQIECBAgAABAm0hIIDbFtOkkwQIECBAgAABAgQIECBAgAABAgQI1FFAALeOs27MBAgQIECAAAECBAgQIECAAAECBAi0hYAAbltMk04SIECAAAECBAgQIECAAAECBAgQIFBHgRGNrNRx4MZMgAABAgQIECBAgAABAgQIECBAgACB4S5gBe5wnyH9I0CAAAECBAgQIECAAAECBAgQIECgtgICuLWdegMnQIAAAQIECBAgQIAAAQIECBAgQGC4CwjgDvcZ0j8CBAgQIECAAAECBAgQIECAAAECBGorIIBb26k3cAIECBAgQIAAAQIECBAgQIAAAQIEhruAAO5wn6HxuH+PP/74eDy6sTO0F154IX300Udjp/HxvNXxwe6xxx5LTz/99Hg+U4ZHgAABAgQIECBAgAABAgQIVAVqH8B99tln02677ZZWWWWVNOOMM6bFF188bbfddunyyy+vOtkeBIEIPN5yyy1pv/32S/PPP3+ab775BqHV+jTx05/+NM0666xp9tlnT4LffZv3drX7+OOP8z8z++yzT/5nZtSoUen888/vdvDvvvtuWm211dKIESPSvvvu2209JwgQIECAAAECBAgQIECAAIH2ERjRyEr7dHdwe3rYYYflwdvuWv3Od76TTjjhhDTFFFN0V8XxFgUeeuihtOCCC3aqXePHr5NFTwc+/fTTNHLkyLLKgQcemPbcc89y30b3Au1qN2bMmDTnnHOmt99+u2lwhx56aNp1112bjhU78Yunr3/968Vueu2119JnP/vZct8GAQIECBAgQIAAAQIECBAg0H4CtV2Be8YZZzQFb2NlW8cSdfbYY4+Oh+33Q2CBBRZI77zzTjr99NPLqz/zmc+U2zZ6FphwwgnTcsstV1ZaZpllym0bPQu0q920006bXn/99Xy19cILL9zzIP979t57722q9/LLLzft2yFAgAABAgQIECBAgAABAgTaT6CWAdz4+vmWW26Zz9bZZ5+dPvzww/TII4+k+LryySef3DSLxxxzTLrzzjubjtnpn0CsZF5rrbX6d7Gr8rQeZ555Zrr77rvzlB9IWheIlantaBerrueZZ5608sortzTYCFZXS/zdphAgQIAAAQIECBAgQIAAAQLtLfB/38lu73H0qffnnHNOXv/+++9PX/rSl8prI1gS+W+nn376tP7665fHb7jhhrTEEkuU+zb6LzDppJOWF0822WTlto3eBWLF8hZbbNF7RTU6CbS73TTTTNNpTF0dmGGGGZoOd9xvOmmHAAECBAgQIECAAAECBAgQaAuBWq7APe2001LkEK0Gb6uztd5666UVVlihPBSBXoUAAQLDXSBy5lZLvJhRIUCAAAECBAgQIECAAAECBNpboHYB3GeeeSbPxbrjjjv2OHPLLrtsj+fb6eQnn3ySnn322fynLy8N++CDD5qGGS+Deu+995qOtbITuW/ff//9Vqr2q06kvnjrrbf6dW1/LupqLB1fNNVTuwO9Ptru7avxgzV37777br/mvKfxx7l4DiM/a6Qzieez1TIu7Frty0Dq9Xf8vd1zjjnmKKvMPffcaYIJavdXfDl+GwQIECBAgAABAgQIECBAYHwRqN3/3UeA46WXXur1zexTTTVVOcfdrdQtKwzTjWuuuSbFy64mmmiiFOOOn6mnnjqts8466V//+lenXkdQ6a677kr77LNPnndzt912y+tEComddtopzTLLLCny2MZb7m+55ZZO11cPPPbYY3k6isjfGV9fn3zyydOKK66YLrroomq1fm+/+OKL6Wc/+1lafvnl08QTT5yPK+Zsk002Sffcc0/Z7mWXXZYWXHDBpp9YfV2Urs4vvvji6T//+U9RJf988skn069+9avcc9FFF82PRd7kvfbaK80///wp7h3XnXrqqU3XFTsDvT7aiV8+HHnkkfn9Dj300KLp/HMw5y5st9566/wZmHLKKfM5j7HtvPPOKV7s98ADD6QI7EbQPILnfSlhtummm+aBxVgdOt988+XPZzyn8bx2Vca2Xdwz5vumm27Kn9li1eqbb76ZDjvssPx5HzFiRJp99tnTj370o3zsRT9vvPHGPN1KXBPPwDe+8Y30xz/+sTjd6bM/4+/USA8Hoo9FCVuFAAECBAgQIECAAAECBAgQGA8EssCP0oXAt771rUY2vfnPlVde2UWN4X3o4IMPLvv/hz/8ofHaa681Hn744cZyyy2XH89yYzay1Y/lIK699tpGHCvGHJ9Z0Lbx85//vOlYcT4Lyjaefvrp8vrqxtVXX92I81E3CwI3rrvuuka0v+aaaza1Ndtss1Uva3n7+uuvL/t6wAEHNOJ+v/vd75razl5YlbeXrRpu3HfffY3FFlusPL/99tuX98pWsuYu2267bXk++p2tCs3rvPDCC42FF1646dyoUaMaWR7lpmOFS3xeeumlZfsDvT4aOvHEE8t5K+4zevTo8h6DOXe33XZbOXd77LFHbrvvvvt2O9bsJX9lP3rbiHkr+r/LLrs0soB04/nnn2/88Ic/LI//5S9/KZsZF3bZivLGnnvu2YhnsehbfGaB2fIZqx6P7SzFSiMLXDf1u2Odrv7O6Ov4S4hsozoHWfC+eqrTdjGWHXbYodM5BwgQIECAAAECBAgQIECAAIH2E4ivMitdCGRfP84DOhG8K4J5XVQbloceeuihMhi11lprNfUxy+dbnovAWVFeeeWVRgQ9i3FXA1I/+clPGjfffHP+Uz1fDYQW7WSrKMv2I6haLRFMrQZx+xPAvfzyy/P2I0B85513Vptv7LfffuW9o//Z1+3L89nq2fJcV/2OYGJ1zMWcf/TRR42//vWvjTXWWKPpfNTdaKONGpdccknj3nvvzYN6xfXVcQ30+hhAtqo3D1AXQfG4TzWAO1hzl6W6KOc/W8lc2sXG3nvv3TT+CMzvvvvujQj4tlIi4Fn9BUEEzosS1sXYIjhelHFhl60kbhx++OFN81fMY8z5n/70p0b8eYo6xfH4XGCBBfL9cAiDeBarz3Z1HDGe/oy/cIjPvgRwV1111bxv8csNhQABAgQIECBAgAABAgQIEGh/AQHcLuYwVgEWwZpY3dluJfuae9n/CCpVS5artTwXwemO5dhjjy3PR1AtViJWS7XtJZZYonoqD1IVga3sJXBN54qdaK+wrQY6i/M9fcZqySKAfMQRR3SqGiuMi7bjM1Z3FuX0008vz3UVwM3SAZTn49oigFtcH6t4q21HQLhannrqqabz0V61DPT6aCtWrRZ9qAZwi/sMZO6ijeOPP75sv2PwfcyYMeW56EOWpqK4bUufWRqEpuuzlAVN18WzVIzt1VdfbTo3Luxef/318v7Rj7COoGu1RFC76GP82bj99turpxsdn6FY9V6UgYw/2uhLADfL7533M1beKwQIECBAgAABAgQIECBAgED7C9QuB24WgOmxZIG7lK04zetss802afXVV++x/nA8ma3AS9lqx7xrK6+8clMXJ5100nI/cp12LEX+zzieBdXyvLXVOnGsKNmqw/xlVMV+FjBK2WrFfDfypXZV5p133q4Ot3Ts6KOPTpEPNUpXL6GLXLRHHXVUylY/pizAmefsbanhFipNP/30TbV+8IMfNO1//vOfL83jRLycq1oGen20Nd1001Wb7LQ9kLmLxu64446yzY79nWaaaVIWnC/PRy7XvpS55porFc9itrI1RU7ZaskCouVuFkwtt2OjY1/6ah9t9GY37bTT5rmao26ULK1CGjly5P/f+e8/v/rVr5b7m222WVpqqaXK/diIMcSzV5QsgFtspoGMv2ykxY0iD272C5IWr1CNAAECBAgQIECAAAECBAgQGM4CzRGK4dzTcdS33/72t+nRRx9NSy+9dDruuOPG0V0H9zbxsrHnnnsuZSsZ08wzz1w2HgHX7Ov45X6WYqDcLjY6BtaK48VnvJSsWuLlTxNOOGF+6Nxzzy1PfeUrXym3qxvVQF31eCvbxQvQspXD+Yu1uromWzmZ4mewS28ucb+FFlooZfl+81vHS76qZaDXR1u9tdHb+Z7mLtqPl5IVJcs/W2yWn/GLgSJAn63kLo+3upHlgE3ZquimZzJephcvRotnsygdn8vexhXX9WQf51tpY7LJJks9jav4pUi0112JXyLE3x9ROrbV3/F3d6/ujheB2+Kzu3qOEyBAgAABAgQIECBAgAABAu0hYAVuZZ7+9re/pSwvbMq+pp+y3Kapulq1Uq0tNieaaKI8UJblGs0DZIsvvnhacsklU5brdUD97ykQln3VvWy7GjguDw5gI8ufWwb55pxzzgG0VN9Le5q7UPna175W4mQvYiu3i434xUBRFl100WKzT5+zzjprmmCCCVL24rX0jW98I8XK5QsuuKBTsLNPjY6jyhHg7a1U/86IZ7ZjGRfjLwLNcS+FAAECBAgQIECAAAECBAgQaH8BAdz/zmGsDFx33XXzr8Fnb5Dv9LXtdpzqWBEbKQu23HLLFAHcLEdsuvjii8fKULIcqenll18u246Vub2ViSeeuLcq5flYqVmUrlI/FBpdLs4AAEAASURBVOd89l+gmiLgsssuS3//+9+bGste1pbvRxqNL3/5y03nWt2JX5KsuOKKeWqSN954I91www0pAv+xune4l44pFfrT33Ex/kg5ESvdJ5988v500TUECBAgQIAAAQIECBAgQIDAMBMQwM0mJL7q/PWvfz3FV7ezl5blQc9hNk996k4ETyMH7eabb56nUoi0ECeddFKKr3ePrRLBuGqJgPhglurq0fi6feQqVgZXIFbDnnjiiWWjsSL3lltuSTG3p5xySjr//PPzwOBZZ53VKT9s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uDbmVCFAgAABAgQIECBAgAABAgTaW2BEdD8LBij9FMgCkim+Kt1KCoCubtHb9QM5Hy/ziq/yzzrrrCkLijXdPnJ4xlf+i/QHTScHaSdyhsZX8uMFZ1/84hfTBBNMkOKr6llQMi2++OL5/kBuFXlNH3744RRjiRQJkSqilfLMM8/kY5922mnTPPPMU6ZueOSRR/Kcr9HPOpZIIbDWWmvlaROOPPLIlAU387QC8bK4mMv4iVQSkcLi4osvTlkQNcUzFvPbaom24pmOdAxzzDFHp2cg8jfH8Wr6i1bbbod642L8MY/ZL0by1CSR/kIhQIAAAQIECBAgQIAAAQIE2ltAALe950/vCQyKQOR3XWmllfLgbOQIjjy3PZUs5UDaZJNNUrbaeqz+EqCnPjhHgAABAgQIECBAgAABAgQIEKiDQD2XGtZhZo2RQB8Evv3tb+fB2ywlQK/B22g2VilnX9EXvO2DsaoECBAgQIAAAQIECBAgQIAAgf4ICOD2R801BMYjgewlaynLi5yPKFJuvPbaaz2O7pZbbklbb7112nLLLXus5yQBAgQIECBAgAABAgQIECBAgMDABaRQGLihFgi0vcD888+f5yuOgURu2wjQRl7h+eabL0033XR5UPeJJ55I55xzTrr55pvTbrvtlg466KBOOWzbHsIACBAgQIAAAQIECBAgQIAAAQLDTEAAd5hNiO4QGAqBBx98MK266qr5S8t6un8Edffff/+0+eab91TNOQIECBAgQIAAAQIECBAgQIAAgUESEMAdJEjNEGh3gffffz+de+65KV5QFqttH3300TT33HPnq3BjhW68tGzZZZdNI0aMaPeh6j8BAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugl4iVndZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJvAyPvuu69uYzZeAgQIECBAgAABAgQIECBAgAABAgQItIWAFbhtMU06SYAAAQIECBAgQIAAAQIECBAgQIBAHQVGvP322406DtyYCRAgQIAAAQIECBAgQIAAAQIECBAgMNwFrMAd7jOkfwQIECBAgAABAgQIECBAgAABAgQI1FZAALe2U2/gBAgQIECAAAECBAgQIECAAAECBAgMdwEB3OE+Q/pHgAABAgQIECBAgAABAgQIECBAgEBtBQRwazv1Bk6AAAECBAgQIECAAAECBAgQIECAwHAXEMAd7jOkfwQIECBAgAABAgQIECBAgAABAgQI1FZAALe2U2/gBAgQIECAAAECBAgQIECAAAECBAgMdwEB3OE+Q/pHgAABAgQIECBAgAABAgQIECBAgEBtBQRwazv1Bk6AAAECBAgQIECAAAECBAgQIECAwHAXEMAd7jOkfwQIECBAgAABAgQIECBAgAABAgQI1FZgZG1H3seBP/XUU+nJJ59M1113XR+v7Ln6XHPNlVZbbbUUn2OjPPLII3mz888//9hoXpsECBAgQIAAAQIECBAgQIAAAQJDJCDuM0Tw4/i2VuC2CH7ttdcOevA2bl0EhlvshmoECBAgQIAAAQIECBAgQIAAAQIECNRIwArcFic7Aq1RDjzwwBavaK3aXnvtlQeGYxWuQoAAAQIECBAgQIAAAQIECBAgQIAAgaqAFbhVDdsECBAgQIAAAQIECBAgQIAAAQIECBAYRgKDsgJ3sNMLFPlgt9tuu2FEpSsECBAgQIAAAQIECBAgQIAAAQIECPQkUMQJI75XvPupp/rO9S4w4ADuKaeckudx7f1Wrdco0hXEhEst0LqbmgQIECBAgAABAgQIECBAgAABAgSGSqAI3sb9I75XxPjE9wY2IwMO4BYTITfswCaijldfddVV6dNPP2156PGHfeKJJ05///vf04svvpjmnHPOtMACC7R8vYrjv8CHH36YnnjiifTkk0/mny+//HKabrrp0swzz5y+/OUvpy984QvjP8J/R3jDDTekTz75JC288MJphhlmqM24uxvomDFj0vXXX5+ef/75FM/FyJEjc5f4e2TllVdOk08+eXeXOj6eCvznP/8pX0469dRTpyWWWKLHkT777LMp3vA76aSTpuWXX77HuuPzyaeffjo9/vjjacopp0xLL730+DzUcmzxd0d3/70yYsSI9NnPfjbNOOOM+b9rYn9clfvvvz9/Jt9+++0077zzphVXXHFc3dp9xkOB6nM+99xzp/jprcR/d918881ltQUXXDD/c1AesDHeChT/TowBxsq6eeaZZ9iM9c0330x33nln3p/4ezH+/zHKLbfckj744INh99/G3fU377R/EGhTgeuuu65Tz+NYuwVwY8Fq9LnIEtBpUN0ciDhpBLEHO6vAgAO43fTXYQI9CsT/CB100EE91ul4ctlll83/BXzeeeel22+/PW266aa1DeBGYO6aa67JiZZaaqk07bTTduSq3f4zzzyTfvWrX6V33323aeyvvvpq/j+4EdCcddZZ0zbbbJNmm222pjrj484555yTD2uqqaaqdQC30Wiks846q+l/MIv5fuGFF9K9996bLr300rTJJpukVVZZpTjlswYCH3/8cbrgggvKkU4xxRQ9/jsl/scv/h6ZZJJJBhzAjb+X7rvvvvze7fYfstHvv/71rymC3nUI4Eag/9xzzy2fk542Pve5z6Vtt922pcBXT+20cu6Pf/xjuvrqq8uqEUwRwC05bPRDoPqczzTTTGn06NG9thJBsurfo/H3Y/zSXBn/BeK/rYqFXLFQ4Je//OWwGXT8or54LuP/k4oA7hlnnJH3cSj+2zj+3+3GG2/M77/44ounaaaZpvTqrr9lBRsExhOBvgZBh3rY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BG0u+1NG4hJ2eF5oXHIvBISAEBACQkAICAEhIASEgBAQAkKgHAiwGRc/SX4IsHFZMbLbbrs5fhIhIASqDwHj8EwpE0LX7lXf21ROipuldpr+snKS0/ApCXeaq6/UMBORpI1cahoqcTfCUt9J/oWAEBACQkAICAEhIASEgBAQAkJACAgBISAEnBPv0zRKwQZN4zXzf0tmBepTtZu4NBORf/7IpRAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEGhKCEgDtynltt5VCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICIGqQkAauFWVXUqsEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJNCQERuE0pt/WuQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAhUFQIicKsqu5RYISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASaEgIicJtSbutdhYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBCoKgRE4FZVdimxQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAg0JQRE4Dal3Na7CgEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASFQVQiIwK2q7FJihYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBBoSgiIwG1Kua13FQJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkKgqhBoXlWpVWLrDYH9f7Wo3uJSRI0XgWcu7dp4X05vJgSEgBAQAkJACAgBISAEhIAQEAJCQAgIgXpAoPmUKVPqIRpFUX0IbFx9SVaKKw4B1S8VlyVKkBAQAkJACAgBISAEhIAQEAJCQAgIASFQZQjIhEKVZZiSKwSEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBIRA00Gg2ZcpaTqvqzcVAkJACAgBISAEhIAQEALVgcCYMWN8Qvv27VsdCVYqhYAQEAJCQAgIASEgBOoEAWng1gmsClQICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASFQOgIicEvHUCEIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAE6gQBEbh1AqsCFQJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACJSOgAjc0jFUCEJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICIE6QUAEbp3AqkCFgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACpSMgArd0DBWCEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCoE4QEIFbJ7AqUCEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhEDpCDQvPQiFIAQaJwJr166t9WIbbrhhrXu6IQSEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBOoKgaoicD/44AP35Zdfus6dO7v27dsXjMm0adPcvHnzHCTciBEjCvYvD+VDYOzYsW7x4sWudevWbpdddilfwGUK6f3333czZsyoFdpOO+3k2rZtW+u+bggBISAEhIAQEAJCQAgIASEgBISAEBACQkAICIG6QKBqCFyI2/fee89jsNlmm7ltttmmYDzWrVvn/RBWQ8snn3zipk6d6po1a1aRBGZd42N5YMdC4xszZoxbvny56969u9tyyy0L9Z7TfatWrVzz5jWfB2mM08bNGYgcCAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgRIRqBoCt8T3rDjvK1ascCtXrqy4dFVLgpYuXerWrFnjONaFdOvWzfFDPv/8c/f222/XRTQKUwgIASEgBISAEBACQkAICAEhIASEgBAQAkJACGRFQJuYZYVHD4WAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAINh0BFaeBin7ZFixZuk002KRmRzz77zC1YsMAtW7bMdejQwS+1zxUoS+U//PBD9+mnn7pVq1Z5W6ddunRxXbt2zeXVER9mEdDWxFQDdlK32GKLDHupPFuyZIkPy45cYNs3lE6dOvk0c8/8YLcXcwFxwjtiTxZzDMSJYF5g0aJF3t4vJifAYuHChf4ZNoQJa4MNkvn7L774wn388cf+vfBEmginZcuWPoxy/gN30vrRRx+51atX+7h69epVK31z5871NpCJ28xhkM4QP95p8803TyePMoVb0o9dW87BCAxmz57t85q86tu3b6340oHkcTJnzhyfZ4QrEQJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAuVCoMEJXAi4mTNnegIPIm/TTTctmcCdPn26g+wzgSyF5Mu28RnpeOedd/yyfPMHkQsB2LFjR7fddtvFEnzYRh0/frwnAs0fR/MLUdq/f3//CJLPSNTQrdn2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Zcv9dYuWLbzpiIHbD3St29SQzBkOdSEEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAIEKh3AjeI222+5eb+t3LFSm8bN3xWyvlWu/ZxHTfr6D778DN3z2n3ODYl26hnZx/kcdcd5zbus3Epwdfyu/v3dnev3v6KW7ZomRt10h0+vuatm7udv72z2+dH+7otem/hNuu5meves3stv7ohBISAEBACQkAICAEhE36/PgAAQABJREFUIASyIaAl+tnQqYRnMqFQCbmgNAgBISAEhIAQaMwIbFAJL9eqdSs3YLsB6aQ026BZ+jx6Ej5L2nSsRZsW7tR7v+/2OHUP165rO7dy2Uq3YPKH/rd21Zp0kObfwrRj2kHqxO6Z2/CZnUMW//CJc9zWe/f35C3xQeauXLrKO+m2eTeRtwaWjkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAI5I1Asy9TkrdrORQCQkAICAEhIASEgBAQAkKgXhAYM2aMj6dv3771Ep8iEQJCQAgIASEgBISAEKhMBCpCA7cyoVGqhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAg2LgAjchsVfsQsBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIAQSERCBmwiNHggBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIAQaFoHmDRu9YhcCQkAICAEhIASEgBAQAkKgGATat29fjDf5EQJCQAgIASFQLwgsXbq0XuJRJEKgKSAgDdymkMt6RyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEqhIBEbhVmW1KtBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACTQEBEbhNIZf1jkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIVCUCInCrMtuUaCEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEmgICInCbQi7rHYWAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQqEoEROBWZbYp0UJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAINAUEROA2hVzWOwoBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhUJUIiMCtymxTooWAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQaAoINGkC965T7nS/7HeJe+u+t6our6/Z548+7dNfnl6RaZ/939nuvVfec59/9Hk6fWtXr/VpBvOPp3+Uvl8NJ4s/WJxO+8qlK6shyUqjEBACQkAICAEhIASEgBAQAkJACAgBISAEhEAjQKB5I3iHol9h9YrV3i/EYrXJqi9W+SSvq8C0L5j8obvt+Ft9+n7wyFmuQ7cO/vzLL79Mw7xu7frz9M0KPvkySO+X66or7RUMq5ImBISAEBACQkAI1DECy5Ytc5MmTco7lv79+7uOHTu6WbNmuYULF7pu3bq5Xr16ef/z5893c+fOdW3atHGDBw/OO0w5FAJCQAgIASEgBIRAY0Hg2Wefdc8995x/nX333dftt99+9fJqTZrArReEm2AkL9/6in/rfnv2c90HdW+CCOiVhYAQEAJCQAgIASFQGQh89NFH7r777ss7MT/4wQ88gfv888974nevvfZKE7jTpk1zjz76qOvevXsGgbtkyRLHM2T48OF5xyWHQkAICAEhIATqA4E1a9a4s88+Ox3Vqaee6nbeeef0tU6KQ+DGG2907777bi3PrVq1ctddd12t+7pRGgIicEvDT74jCGBqYMzDNR/wnmfsFXmqSyEgBISAEBACQkAICIGGQmDTTTd1bdu2zRp969atsz6Pe/jhhx+mSeJhw4a5Zs2axTnTPSEgBISAEBACFYHA2rXVtwq7IoCLJGL16ppV7ZHbLul+1J2uC0OgSRG4s6fPdq3btHabbrFpLZTWrFzj5o6b6+akbLdu0GJD13OHnq7XjjXLxWo5Tt1gGf288fPcR1MXOEjLzj27uC2Gbu669a8dNv4xH7Bg8gI3f8I8t+TDz3yQ3fpt4t1v3Gdjfx33b+2atW7OW3Pc3LFzXbMNmrlew3q5Htv2iHPqxr05zvUd2Ne1bZ+9Yx7rOcfNZUuXuZmTZ7ohw4dkdfnaHa/551tsu4XbatetsrpdvmS5e//t1LuNm+fab9Le9d29r+uyZZdEP6uXr3YfjP0ghflH7ovFX6Sw6+bzqeOmHWP9YBpjTir8he8tTNni/cy16tDagflmA7unzTrEeSRdc96ancqr+a5DKuwth2/pNtiwtrnoL5Z94WZPne22HrK1a96iSX1KcbDpnhAQAkJACAgBIVDhCHz96193/fr1yyuV++yzj9em3WSTTfJyL0dCQAgIASEgBIRA00KAPsWqVTXmPZnM/fzz9XsgNS0k6udtGz3rtOzzZW7CWxPcrKmzHGrzA3cYWIvAXfH5Cnfbt271JGkI+z4/2sft86N9w1v+nI25HrrwQTf9pdobiI04fU+33/n7uQ1TJLDJquWr3DUj/+iWLVpmtzKOu39vD3fAzw5wGzZf7wcHEIl//+G9bsZrMzLc7/zteFX/8f8d70ncjbpu5AbtMMhtufWWJWlAQDrPnjbbTXxnovt00ac+rGwELu/3+p01BO5eZ2bXvoX4vvWbt7iVyzI3BDvxlhNd/322yXhfLj4Y84H7x3n3ucXvL6717Jirj3Hbfn27jPsQt4SfJEen/GwX8YNb7Pfe/f273Wdfkezmf+Q5+9hp+rjss2Xundfece++/q7r3qu7GzJsiNt4s2QyPu1RJ0JACAgBISAEhIAQqHAEevfuXeEpVPKEgBAQAkJACAiBhkTg0EMPdfyQf/3rX97MUkOmp7HH3SgJXIjHmVNnuknvTHJLPlmSkYftO7TPuObimT887e/tecaebu2qte6t+97yxOLz1z3vtjtye9el13qtUDYPu+Fr13sytlW7Vm6Xk3dNad929pq1o/862r1880uevIXENVm3Zp13365rOzf0sKGua0rjtkWrFikN3rkOP6/e/opbs3K1O/xXXzMv/nj/BfenydsRp41wnbbYyE16cqL3k+Hwq4uWrVu6lctXerL11WdedW88/4br3b+3G7zjYNe+U+33jguDe0uXLHUT3q4hvcOlBYSfTXgXpOtWG7tt9huQzan7x/n/8O5GHDnCLZiywI1/fLx3/9jlj7l+e22dofGK1vLNR9/kn4P1Tt/aybVq39pNeX6Km5r63f/j+13bFLb9RqzXKFmZIuWRTQds5vqP7O/zEI3caS9Mc1Oem+weSPnZsPkGbkgqP0zI21uPu9XnPXm123d3cxukSPU3/zba/edPz5uz9LFlq5ZeK9prY8+e5+alfmh49x/a322z7TauRcsWabc6EQJCQAgIASEgBIRANSHw4osvug8++MANGDDA7bjjjrFJnz59uhs9erTDBq7J3/72Nz/pv8MOO7iBAwfabbd8+XL38ssv+83R5syZ4zdHQ3Nn0KCU0sGWW6bdcfL666+7GTNmuKFDh7ohQ4a4d955x02dOtX/zj33XNepU6cM97oQAkJACAgBIVAoAp9++qkbO3as35yzR48e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HTt2zKHeblyzCDuBA2Yf2uHGjYo9kwAJkAAJkIBnCVDAdYGnf4G0UMGFDG8GbXhMR5s1rfN4JgESIAESIAESIAESIAESIIEbQWDevHkSGxtrdt20aVNB/FtftqJFi/ry9Dg3EiABEiCBfEyAMXDz8eJz6iRAAiRAAiRAAiRAAt5LIDsxcL13VhxZbhFYuXKl2sQuKChIqlWrpo7c6pv9kAAJkAAJkAAJeJYABVzP8mRrJEACJEACJEACJEACJOARAhRwPYKRjZAACZAACZAACZBAnieQFhsgz0+FEyABEiABEiABEiABEiABEiABEiABEiABEiABEiAB3yJAAde31pOzIQESIAESIAESIAESIAESIAESIAESIAESIAES8CECFHB9aDE5FRIgARIgARIgARIgARIgARIgARIgARIgARIgAd8iQAHXt9aTsyEBEiABEiABEiABEiABEiABEiABEiABEiABEvAhAhRwfWgxORUSIAESIAESIAESIAESIAESIAESIAESIAESIAHfIkAB17fWk7MhARIgARIgARIgARIgARIgARIgARIgARIgARLwIQIUcH1oMTkVEiABEiABEiABEiABEiABEiABEiABEiABEiAB3yJQ0Lemw9mQAAmQAAmQAAmQAAmQQP4ksH//frl8+bKUKFFCHQUL8l/9/PlO4KxJgARIgARIgAR8jQD/q/O1FeV8SIAESIAESIAESIAE8iWBSZMmyZEjR8y533TTTdKnTx/zmgkSIAESIAESIAESIIG8SYAhFPLmunHUJEACJEACJEACJEACJGBDoEWLFtK4cWMpVaqUyl++fLls3brVpgwvSIAESIAESIAESIAE8h4BeuDmvTXjiEmABEiABEiABEiABEggHYFWrVqpvGvXrsnrr78uSUlJkpCQILVr105XlhkkQAIkQAIkQAIkQAJ5hwA9cPPOWnGkJEACJEACJEACJEACJJApAT8/P6lYsaIqd/LkyUzLswAJkAAJkAAJkAAJkIB3E6CA693rw9GRAAmQAAmQAAmQAAmQgNsEAgICVB1sakYjARIgARIgARIgARLI2wQo4Obt9ePoSYAESIAESIAESIAESIAESIAESIAESIAESIAEfJgABVwfXlxOjQRIgARIgARIgARIIH8TSE5Ozt8AOHsSIAESIAESIAES8AECFHB9YBE5BRIgARIg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xpBRflZ+ntydU0b9299jCAV7IrwmARIgARIgARIgARIgARLIEQJWIQHx7LD5CB4JhYcYjQRIgAR8kQAEWO1F6cr84P2I34lZ+b0IcQ+Htxkee3fkBelsnBBttditzyg7ffp0VQV/NzIK7YMwDe7052wc3pKfW+sKkRghOGAdO3bMkLEn2Li7Tgj/oD1xPdF/Zm1khbu7c8psDNb7FHCtNJgmARIgARIgARIgARIgARLIMQKIR4gP3vAQw4YvOHCNx4JpJEACJEACJICHxF944QW1WRvimsLbFI/9L1iwQBISEhSggQMHEpSHCMDLdMeOHSokAbxv4QEOr1Yd6sND3bAZDxCggOsBiGyCBEiABEiABEiABEiABEggcwJ4zBFxDbds2SKIw4vHQR1tLpJ5SyxBAiRAAiTgiwQQJgEhF9atW6cO6xzhnYxNtXLTC9Pavy+mN27caLNxKbzFR4wYYXpA++Kc8+qcGAM3r64cx00CJEACJEACJEACJODTBHwxBq5PLxgnRwIkQAIkkG0CiHOKL/ni4+NVHOCUlBS1mRk27WratKlXxPTN9iS9qAGwxoEQR/hCtWbNmoJQBTTvI0AB1/vWhCMiARIgARIgARIgARIgAaGAyzcBCZAACZAACZAACZAACPgTAwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgHcSoIDrnevCUZEACZAACZAACZAACZAACZAACZAACZAACZAACZAAPXD5HiABEiABEiABEiABEiABEiABEiABEiABEiABEiABbyVAD1xvXRmOiwRIgARIgARIgARIgARIgARIgARIgARIgARIIN8TKJjvCXgRgKtXrgoOq/n5+0mBggWsWUyTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAnkEwIUcL1ooRd+slAWfrzAZkRlosvKyFkjbfJ4QQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkD8IUMD1onUOqRQiVVtUVSM6fShJju865kWj41BIgARIgARIgARIgARIgARIgARIgARIgARIgARymwAF3NwmnkF/MX1jBAds04xNMvX/pmRQmrdIgARIgARIgARIgARIgARIgARIgARIgARIgAR8nQAFXF9fYc6PBEiABEiABEiABEiABEjAYwSuXrwoVy5eSNdeoeCSIn5+6fJ9PePcufNy+cpl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CZAACZAACZAACZAACZAACZAACZAACZDAZU+AAu5l/xYgABIgARIgARIgARIgARIgARIgARIgARIgARIggcJKgAJuYV0ZjosESIAESIAESIAESIAESIAESIAESIAESIAESOCyJ1CMu9te9u8BAiABEiABEiABEiABEiABEiABEiABEiABEiABEiikBOiBW0gXhsMiARIgARIgARIgARIgARIgARIgARIgARIgARIggSLnDSMGEiAB1wROnDjhOqOAU0uXLl3AI2D3JEACJEACJEACeU1APykXExOTp12dPXtWUlJSsvSB/28UK1YsSzoTSIAESIAESIAESEATwP8jTp48qW/Nc8mSJSUgIMC850XuCPB/ZLnjx9okQAIkQAIkQAIkQAIkcFETmDVrlgwdOjTLHD799FPp0qVLlnR/Jpw5c0Z+//132bRpk/rwl5GRIb169ZKOHTv6sxu2RQIkQAIkQAIkkEcEVq9eLZMmTcrS+u233y5NmjTJkp7fCWlpafLyyy+rbh999FGpVq1afg/BL/1RwPULRjZCAiRAAiRAAiRAAiRAAhcvgSuvvFIN/uDBg6I9fxs0aJDnE/r2229l27Ztqh94+4aGhkqNGjXyvF92QAIkQAIkQAL+JPD111/LqVOn1JeQtWvX9mfTuW7r2LFj8v3336t27r33XgkKCsp1m/YGatasqZLwRM/Ro0fVdUREhL1Ygdzv2bPH7LdixYrmdWG7yGmdKOAWthXjeEiABEiABEiABEiABEggHwn06NFDcMD+/PNPgXdK+fLlJTw8PE9HsXfvXlO8veOOOyQ/BOM8nRAbJwESIAESuCwJIPTixo0b1dwDAwMLHYMdO3ZIQkKCFC1aVIoXL+738bVo0UJwwJYtWyaTJ09WIZjCwsL83pcvDe7evVtVK1OmTJ7M35cxuaqT0zpxEzNX1JhGAiRAAiRAAiRAAiRAApchgfXr16tZN2/ePM9nrz19IRZTvM1z3OyABEiABEggjwhogRDNV6lSJY968b3ZXbt2qcqVKlWSIkWK+N6QBzUhQsIKU5gCPf/CNCYFyfaix+luneiBawPGWxIgARIgARIgARIgARK42AkcP35cEJMOHkEhISFSt25dad26dY7TWrVqlSrTuHHjHMvmtsCWLVtUExgbjQRIgAQuRQJ4lHz//v0SHBwstWrVcpoiNn2CVyQE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"/><use stroke="#979797" xlink:href="#rect-1"/></g><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#D60000" d="M150.703 66.786a230.9 230.9 0 012.035 3.992l.273.553c.743 1.514 1.326 2.773 1.702 3.694.138.339.08.706-.104 1.1-.094.203-.221.41-.373.619a5.679 5.679 0 01-.503.605l-.147.151h-2.273l-4.2-8.574-5.613 5.727V50.775l15.69 16.01h-6.487z"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="696" height="379" viewBox="0 0 696 379"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><path id="rect-1" d="M0 0h696v379H0z"/><path id="path-2" d="M142 52v21.429l5.25-5.358L151.625 77h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H156L142 52z"/><filter id="filter-3" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0.0941176471 0 0 0 0 0.0901960784 0 0 0 0 0.0901960784 0 0 0 1 0"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="inspect.svg"><g id="Bitmap"><image width="696" height="379" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXAAAAL2CAYAAADowb7lAAAMSWlDQ1BJQ0MgUHJvZmlsZQAASImVVwdUU8kanltSSWiBCEgJvYlSpEsJoUUQkCrYCEkgocSYEETsyqKCaxcRsKGrIoquBRA79rIodtfyUBaVlXWxYEPlTQro6nnvnfefM3e+/PPP95fMnTsDgE41TyrNRXUByJPky+IjQljjUtNYpA5AACZAG7gCLx5fLmXHxUUDKAP9P+XtLYAo++suSq4fx/+r6AmEcj4ASBzEGQI5Pw/iAwDgxXypLB8Aog/UW0/LlyrxBIgNZDBAiKVKnKXGxUqcocYVKpvEeA7EuwAg03g8WRYA2k1QzyrgZ0Ee7TsQu0oEYgkAOmSIA/kingDiSIiH5eVNUWJoBxwyvuHJ+gdnxiAnj5c1iNW5qIQcKpZLc3nT/89y/G/Jy1UM+LCDjSaSRcYrc4Z1u5MzJUqJaRB3SzJiYiHWh/i9WKCyhxilihSRSWp71JQv58CaASbErgJeaBTEphCHS3JjojX6jExxOBdiuELQQnE+N1Ezd5FQHpag4ayWTYmPHcCZMg5bM7eeJ1P5VdqfVuQksTX8d0RC7gD/myJRYoo6ZoxaIE6OgVgbYqY8JyFKbYPZFIk4MQM2MkW8Mn4biP2EkogQNT82KVMWHq+xl+XJB/LFFonE3BgNrswXJUZqeHbxear4jSBuEkrYSQM8Qvm46IFcBMLQMHXu2FWhJEmTL9YuzQ+J18x9Jc2N09jjVGFuhFJvBbGpvCBBMxcPzIcLUs2Px0jz4xLVceIZ2bzRcep48EIQDTggFLCAArYMMAVkA3Frd2M3/KUeCQc8IANZQAhcNJqBGSmqEQl8JoAi8BdEQiAfnBeiGhWCAqj/PKhVP11Apmq0QDUjBzyBOA9EgVz4W6GaJRn0lgz+gBrxD975MNZc2JRjP+rYUBOt0SgGeFk6A5bEMGIoMZIYTnTETfBA3B+Phs9g2NxxH9x3INqv9oQnhDbCY8JNQjvh7mTxfNl3+bDAGNAOPYRrcs74NmfcDrJ64iF4AOSH3DgTNwEu+EjoiY0HQd+eUMvRRK7M/nvuf+TwTdU1dhRXCkoZQgmmOHw/U9tJ23OQRVnTbyukjjVjsK6cwZHv/XO+qbQA9lHfW2KLsP3YOewkdgE7gjUCFnYca8IuY0eVeHAV/aFaRQPe4lXx5EAe8Q/+eBqfykrKXetcu1w/qcfyhYXK/RFwpkiny8RZonwWG+78QhZXwh8+jOXu6uYLgPI7ot6mXjNV3weEefGrbsEGAAIO9Pf3H/6qi2oGYH8ZANTbX3X2s+B2cBKA81V8haxArcOVDwKgAh34RhkDc2ANHGA+7sAL+INgEAZGg1iQCFLBJFhlEVzPMjANzATzQAkoA8vBGlAJNoItYAfYDfaBRnAEnARnwSVwFdwE9+Dq6QTPQQ94C/oQBCEhdISBGCMWiC3ijLgjPkggEoZEI/FIKpKOZCESRIHMRBYgZchKpBLZjNQivyKHkJPIBaQNuYs8QrqQV8hHFENpqAFqhtqhI1AflI1GoYnoRDQLnYoWocXoUrQCrUF3oQ3oSfQSehNtR5+jvRjAtDAmZom5YD4YB4vF0rBMTIbNxkqxcqwGq8ea4f98HWvHurEPOBFn4CzcBa7gSDwJ5+NT8dn4ErwS34E34Kfx6/gjvAf/QqATTAnOBD8ClzCOkEWYRighlBO2EQ4SzsC3qZPwlkgkMon2RG/4NqYSs4kziEuI64l7iCeIbcQOYi+JRDImOZMCSLEkHimfVEJaR9pFOk66RuokvSdrkS3I7uRwchpZQp5PLifvJB8jXyM/JfdRdCm2FD9KLEVAmU5ZRtlKaaZcoXRS+qh6VHtqADWRmk2dR62g1lPPUO9TX2tpaVlp+WqN1RJrzdWq0NqrdV7rkdYHmj7NicahTaApaEtp22knaHdpr+l0uh09mJ5Gz6cvpdfST9Ef0t9rM7SHa3O1BdpztKu0G7Svab/QoejY6rB1JukU6ZTr7Ne5otOtS9G10+Xo8nRn61bpHtK9rdurx9Bz04vVy9NbordT74LeM32Svp1+mL5Av1h/i/4p/Q4GxrBmcBh8xgLGVsYZRqcB0cDegGuQbVBmsNug1aDHUN9wpGGyYaFhleFRw3YmxrRjcpm5zGXMfcxbzI9DzIawhwiHLB5SP+TakHdGQ42CjYRGpUZ7jG4afTRmGYcZ5xivMG40fmCCmziZjDWZZrLB5IxJ91CDof5D+UNLh+4b+rspaupkGm86w3SL6WXTXjNzswgzqdk6s1Nm3eZM82DzbPPV5sfMuywYFoEWYovVFsct/mQZstisXFYF6zSrx9LUMtJSYbnZstWyz8reKslqvtUeqwfWVGsf60zr1dYt1j02FjZjbGba1Nn8bkux9bEV2a61PWf7zs7eLsVuoV2j3TN7I3uufZF9nf19B7pDkMNUhxqHG45ERx/HHMf1jledUCdPJ5FTldMVZ9TZy1nsvN65bRhhmO8wybCaYbddaC5slwKXOpdHw5nDo4fPH944/MUImxFpI1aMODfii6una67rVtd7bvpuo93muzW7vXJ3cue7V7nf8KB7hHvM8WjyeDnSeaRw5IaRdzwZnmM8F3q2eH728vaSedV7dXnbeKd7V3vf9jHwifNZ4nPel+Ab4jvH94jvBz8vv3y/fX5/+7v45/jv9H82yn6UcNTWUR0BVgG8gM0B7YGswPTATYHtQZZBvKCaoMfB1sGC4G3BT9mO7Gz2LvaLENcQWcjBkHccP84szolQLDQitDS0NUw/LCmsMuxhuFV4VnhdeE+EZ8SMiBORhMioyBWRt7lmXD63ltsz2nv0rNGno2hRCVGVUY+jnaJl0c1j0DGjx6wacz/GNkYS0xgLYrmxq2IfxNnHTY07PJY4Nm5s1dgn8W7xM+PPJTASJifsTHibGJK4LPFekkOSIqklWSd5QnJt8ruU0JSVKe3jRoybNe5SqkmqOLUpjZSWnLYtrXd82Pg14zsneE4omXBrov3EwokXJplMyp10dLLOZN7k/emE9JT0nemfeLG8Gl5vBjejOqOHz+Gv5T8XBAtWC7qEAcKVwqeZAZkrM59lBWStyuoSBYnKRd1ijrhS/DI7Mntj9ruc2JztOf25Kbl78sh56XmHJPqSHMnpKeZTCqe0SZ2lJdL2qX5T10ztkUXJtskR+UR5U74BPLBfVjgoflI8KggsqCp4Py152v5CvUJJ4eXpTtMXT39aFF70ywx8Bn9Gy0zLmfNmPprFnrV5NjI7Y3bLHOs5xXM650bM3TGPOi9n3m/zXeevnP9mQcqC5mKz4rnFHT9F/FRXol0iK7m90H/hxkX4IvGi1sUei9ct/lIqKL1Y5lpWXvZpCX/JxZ/dfq74uX9p5tLWZV7LNiwnLpcsv7UiaMWOlXori1Z2rBqzqmE1a3Xp6jdrJq+5UD6yfONa6lrF2vaK6IqmdTbrlq/7VCmqvFkVUrWn2rR6cfW79YL11zYEb6jfaLaxbOPHTeJNdzZHbG6osasp30LcUrDlydbkred+8fmldpvJtrJtn7dLtrfviN9xuta7tnan6c5ldWidoq5r14RdV3eH7m6qd6nfvIe5p2wv2KvY++ev6b/e2he1r2W/z/76A7YHqg8yDpY2IA3TG3oaRY3tTalNbYdGH2pp9m8+eHj44e1HLI9UHTU8uuwY9Vjxsf7jRcd7T0hPdJ/MOtnRMrnl3qlxp26cHnu69UzUmfNnw8+eOsc+d/x8wPkjF/wuHLroc7Hxktelhsuelw/+5vnbwVav1oYr3learvpebW4b1XbsWtC1k9dDr5+9wb1x6WbMzbZbSbfu3J5wu/2O4M6zu7l3X/5e8Hvfvbn3CfdLH+g+KH9o+rDmX47/2tPu1X70Ueijy48THt/r4Hc8/0P+x6fO4if0J+VPLZ7WPnN/dqQrvOvqn+P/7Hwufd7XXfKX3l/VLxxeHPg7+O/LPeN6Ol/KXva/WvLa+PX2NyPftPTG9T58m/e2713pe+P3Oz74fDj3MeXj075pn0ifKj47fm7+EvXlfn9ef7+UJ+OpjgIYbGhmJgCvtgNATwWAcRWeH8ar73kqQdR3UxUC/wmr74Iq8QKgHnbK4zrnBAB7YbMLhtywVx7VE4MB6uEx2DQiz/RwV3PR4I2H8L6//7UZACR4nvks6+/vW9/f/3krDPYuACemqu+XSiHCu8GmYCW6aTSpGnwn/wZ3TIEEcU5bKwAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAFcKADAAQAAAABAAAC9gAAAABq3vZVAABAAElEQVR4AezdBbwtVdk44HXh0kiIdEldFBAQpLtEBKSkRJH+wEAx6LpKp0pJKCANKiXSDR8gISFIg5T0pRv3f975O/PNPrlP3HvOvvOs3++wJ9asWetZcy/wnrXfGdHISlIIECBAgAABAgQIECBAgAABAgQIECBAYNgJTDDseqRDBAgQIECAAAECBAgQIECAAAECBAgQIJALCOB6EAgQIECAAAECBAgQIECAAAECBAgQIDBMBQRwh+nE6BYBAgQIECBAgAABAgQIECBAgAABAgQEcD0DBAgQIECAAAECBAgQIECAAAECBAgQGKYCArjDdGJ0iwABAgQIECBAgAABAgQIECBAgAABAgK4ngECBAgQIECAAAECBAgQIECAAAECBAgMUwEB3GE6MbpFgAABAgQIECBAgAABAgQIECBAgAABAVzPAAECBAgQIECAAAECBAgQIECAAAECBIapgADuMJ0Y3SJAgAABAgQIECBAgAABAgQIECBAgIAArmeAAAECBAgQIECAAAECBAgQIECAAAECw1RAAHeYToxuESBAgAABAgQIECBAgAABAgQIECBAQADXM0CAAAECBAgQIECAAAECBAgQIECAAIFhKiCAO0wnRrcIECBAgAABAgQIECBAgAABAgQIECAggOsZIECAAAECBAgQIECAAAECBAgQIECAwDAVEMAdphOjWwQIECBAgAABAgQIECBAgAABAgQIEBDA9QwQIECAAAECBAgQIECAAAECBAgQIEBgmAoI4A7TidEtAgQIECBAgAABAgQIECBAgAABAgQICOB6BggQIECAAAECBAgQIECAAAECBAgQIDBMBYZVAPeTTz5JL7744jClaq9uvfPOO+nNN98cdp3+8MMP0yuvvDLs+tUuHXrsscfS008/3WN3+fbI4yQBAgQIECBAgAABAgQIECBAoK0ERva1t1dccUW67bbb+npZp/pTTTVV+ulPf5reeOONdP3116fLLrssnX/++WmzzTZLJ510Uqf6DvQu8Oyzz6arrroqXXrppeniiy9OZ555Ztpiiy16v3As13jttdfSddddl+LZueCCC9IPfvCDdNBBB43lu44fzX/88cfpjjvuSFdeeWX+5+PRRx9Nhx56aNp1113LAb777rvppptuSpdffnm68MIL0wwzzJDuvvvu8rwNAgQIECBAgAABAgQIECBAgACB9hXocwA3AoRHH330gEf8mc98Jn3pS19Ka6655oDb0kBK+++/fxo9evSwozjiiCPSz3/+82HXr3bo0JgxY9Kcc86Z3n777W67e/jhhzcFc6NiBHAVAgQIECBAgAABAgQIECBAgACB8UOgzykU3n///XLkW221VbrkkkvS7bffnmJl4A033FCei4399tsvxVe+77nnnnT11Vengw8+uAwuRVBqtdVWS0888UTaeOONm66z03eB3XbbLd17771p1KhRfb94LF7x/e9/Pz344INpueWWG4t3GT+bnnbaadPrr7+eHn/88bTwwgt3OchddtklrzMcg/dddthBAgQIECBAgAABAgQIECBAgACBPgn0OYAbX9eOctxxx6VTTz01rbvuummppZZK8803X5p33nmbbj7LLLPkx7785S+n1VdfPe2+++7p1ltvLetMOOGEae65504bbrhheWw4bkRe3q9+9avDpmvxFfpIRVAtk002WVpkkUXSqquuWj085NvRrwUWWCCttdZaQ96XwehA/JIiUn+MqzJy5Mg0zzzzpJVXXrnLW8b5CPRusMEGXZ53kAABAgQIECBAgAABAgQIECBAoL0F+hzA/eCDD/JVtDvuuGO/Rh5B3siBGiVeWhYl0ikM1/Lpp5+mLbfcMt13333DoouRLzgC4d19rT5yCw/HMlz71RerCORvuummQ/IStmmmmabHrk488cQ9nneSAAECBAgQIECAAAECBAgQIECgPQX6HMB977330kYbbZQmmKDPl5ZCsWo3ykcffVQeG64bv/jFL/L0D8Ohf88//3xab731hkNXateH+GXD5ptvnl5++eXajd2ACRAgQIAAAQIECBAgQIAAAQIEhk6gzy8xixeYTTHFFAPqcXwdPFIpTD755L22E4Gz+Jl00kl7rTvYFX7961+nCOC2WmJVbHU1cQS7I4XAiBEjWm2i23ovvPBCnsahu5W33V5YORGrp+Mr9/EzGKXRaOSrUd966630+c9/vt/tDqRfsUI6UnGMzRK/aPjud7/bKcfzYNwzDAfj+RiMvmiDAAECBAgQIECAAAECBAgQIEBg+An0eRlt5LqN3LYDKfF172WXXbbbJv7zn/+k8847Ly255JJpookmyoOgyy+/fJ5zt9uLshPxsqd4mVfUja/sx0/krj333HN7uqzLc/vvv3/68Y9/XJ6LlZcrrrhi/rPKKqukCM5GiQDiddddl7bYYov8fvGStwceeCBPuxCB7i984Qvpe9/7XlpwwQWbfq644oqy7QgSdzwf1xQlxhV5hh966KHiUP6CuKI/J598cnm848Y777yTDjvssDyPagSTw/Mb3/hGUy7ijtf0tv/II4/kqQRiFfaMM86Y5z+OdpdZZpl0zTXX9HZ5fj78DjjggKZ+xVxdeOGFPV4fwd6jjjoqffOb30yzzz57HjSef/75c//TTjstxbNTLZdddlkn2wMPPLCs0tX5xRdfvGwn+rn++us3PUMXXXRR+SzstNNOZVutbkQajLguchaHYYxjk002SXfddVerTbRcL375Ef1fZ511Ov388Ic/bLkdFQkQIECAAAECBAgQIECAAAECBIZGoM8B3LHdzY8//jhFft3NNtss3XnnneXtYsXuNttsk/785z+Xx6obERBdbLHF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AgQIECAwlgWGXQ7cvoy3upo0cqb2FtzrS9sd63a3ArhjvfF9/5xzzklLLbVUHryNXLaxCjeCt4NVqjmLF1hggbzZGWecsWz+mWeeKbe72qimdphtttm6qjLgY30NnldzIEdu5rFdFltssTxtQnGfeNneQAPrRVs+CRAgQIAAAQIECBAgQIAAAQIExq1AWwdwI6haBPmC7YILLuhR76OPPkpHHXXUgL/q3+NNxtHJvq4CHYxuxcvjvvWtb+VNRcqEeIHcRBNNNBhNl238+9//LreLua3msb377rvL811tvPnmm+Xh4vrywBBtVPP2xmrl3lYGR5D6xBNPHFBvI1XDxhtvXLax/vrrp+eee67ct0GAAAECBAgQIECAAAECBAgQINAeAoMawI1cm+O6VF9cFl8T/+CDD7rsQvRtp512SkcffXSqrojssnIXB4uv83dxql+HqoHG/jQw2P1ppQ8nn3xyWS1eODY2gsjx4rEokQ83gsRRqgHcSI/wz3/+Mz/e1T+efvrp8nBxfXngvxtvvPFGx0N92u+r/fTTT9/0orh999232/u99dZbad1110233nprt3VaORFzE/NVpKSI/MQbbrhheu+991q5XB0CBAgQIECAAAECBAgQIECAAIFhIjCoAdx33nmnaVjvv/9+0353O9WAWHW7Wr96/NNPPy1P7bDDDuV2rDCMFaJdBUcPOeSQfMXo3nvvnSaeeOLymp42pphiivJ0pGiI/KUDKdNOO215efHyteJABJivuuqqYrfL1ZIR1CzK888/X2w2fX788cflfnW7ONgxyF51Lep091kNjr744otN1SJw/o9//KM81l0gvazQxUa8rKwIXB577LFpyimnzGtFsLgIRMaBP/zhD11cndIrr7ySp3aIk2uttVZacskly3pTTTVVud3VKt5rrrmmPB8b0Va1VJ+Fak7eap2etn/yk5+Up88+++x04IEHpupzHCdjvuL5DYddd921rN/fjamnnjr9+c9/Li+/884707bbbpu/1Kw82GEj/gzFKvXwGOjz3qFpuwQIECBAgAABAgQIECBAgAABAv0QGNQAbsevaPeWr7To75gxY4rNFC8j66pUA2qvv/56WWW11VZLyy23XLl/4YUXpsgBesABB6RLLrkkD/ZFncgDuvbaa+cBrLJyLxuzzjprU40rr7wy3z/vvPPSFltskW9HQPTll18u63UMbJYnso0vfOEL5e5vf/vb9Kc//SkPNkfgNoKUsTq4KI8++miKF1BVV0zON998xekU44zga9its846KV4sFqVqU3UtLowVntXSVZ3q+ep2BASLcsIJJ6TjjjsuXw0bHquvvnqTwxVXXJEi5ULkyO1YugqAxgrR+Np/lJjPb3/72+Vlk002Wb6atDgQwfhbbrml2C0/f/e735XbVcs4OGrUqPJcBONjFWxYRTB3t912y1enlhWyjZNOOim9+uqr5aFqGoSbbropvfDCC3kANgKt4dBb2XnnnZuqxC8SVllllXTMMcfk8xwB63g+Ys5jfNWV5XFh9fnv6hcU1V+exPNYBF8XWWSRJrtzzz03/ehHP+oyiBs5pBdffPH005/+NK2xxhq9piRpGpAdAgQIECBAgAABAgQIECBAgACBsSOQBSAHXN59993G7bff3sgCb5FDofzJVow2LrrookYWfOr2HllAsbHqqquW18T1d9xxR1P92267ren8mmuu2Yh7FuXhhx9uZCs0m+pU+xHbSyyxRCMLfBWXtPwZ11XbmmGGGfL9LJjbyAJejSwQ23Q+W0HZiP5kAbRO98iCu40wqbZXbMfx888/v9O57EVhZTuXX3550/mirSww3chWOzey3KpN7WdBy0a2Ure8Plvx2chWVza1sd9++3XZ1/KiykbH+xd9j8/11luvscsuuzS1HcePOOKIvIXwqtbP0lnkz0YWeG6ceuqpjSzonp8PvyyoXLnr/21mQdmyjRj71Vdfnc9BtnK1ceaZZ5bnwrFjyYLdnZ6zan+yIGynZyh7CVojzKJkv1go2y+uiz7Ec/fUU0/ldXr7R/YLhU5tFG0VnzvuuGOn+XjwwQeb5jXL7dt46aWXytvFc9jR/vTTTy/Px8YGG2zQdO8sP24j+4VLU50sfUVTneiLQoAAAQIECBAgQIAAAQIECBAgMLQCsRJvQCVbZdsU9CkCUR0/sxWxne5z6aWXdntttgIwr7/yyit3WycCTkWJgFYEdjveN/azFY2N7AVmRdU+fcY9ikBptBUB3AhWZ1/17/Jexf0322yzLu8TwekIwBX14jPGGPeJgFrsL7300o3jjz++8a9//atTG9tss03TtRFki7Fl+X+bjlfbD/tsNWnTOKrnY0xFoLLTDTscyFaKNt0ngpynnHJKHnTMVrbmgfJoO9qM+1bbjTF+97vf7RQojfoRwI1Abm/lrrvuakRgutr/Yn6ynLeNLD9ut01kq2YbWX7ZpmsjAJulGcivie0Yz+jRoxv33ntvp0Bq9tK2pmvjFxYRlO9LydIYdOp/4XXxxRc3NRWB6ehPdazV7XhuslQM3Z4Pl4ceeqjxi1/8ots68dwUJeaq+mxmaRSKUz4JECBAgAABAgQIECBAgAABAgSGSGBE3DcLCo03JVIOZMG3/Ov88bX5SDsw0UQTDWh8kZs0XpwVuXPnn3/+Ab+8K1IfPPbYYynSGcw888xpjjnmyPsX94m0E9Wv63fV8fj6fuTAja/cZ0G6rqqM1WNh/Pjjj6fIKxt9n2CC5kwc2YrU/PiEE07YbT8idUOkMihMW81LXDQYaRiygHCKvLzhteiii+aWxfmePsM4DCMncVw7cuTIvHqkfIjnpeN4qm3FnEW9SK8xyyyzVE/1aTvSM8QL2bKgafriF7+Y5pxzzgE/V33qQDeVs18GpP/93//Ncw4Xz2U3VR0mQIAAAQIECBAgQIAAAQIECBAYBwLjXQB3HJi5BQECBAgQIECAAAECBAgQIECAAAECBMaJQPPSyXFySzchQIAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAggDsE6G5JgAABAgQIECBAgAABAgQIECBAgACBVgQEcFtRUocAAQIECBAgQIAAAQIECBAgQIAAAQJDICCAOwTobkmAAAECBAgQIECAAAECBAgQIECAAIFWBARwW1FShwABAgQIECBAgAABAgQIECBAgAABAkMgIIA7BOhuSYAAAQIECBAgQIAAAQIECBAgQIAAgVYEBHBbUVKHAAECBAgQIECAAAECBAgQIECAAAECQyAwcgju6ZYECAxQ4IknnhhgC+Pn5fPMM8/4OTCjIkCAAAECBAgQIECAAAECBGorYAVubafewAkQIECAAAECBAgQIECAAAECBAgQGO4CArjDfYb0jwABAgQIECBAgAABAgQIECBAgACB2goI4NZ26g2cAAECBAgQIECAAAECBAgQIECAAIHhLiCAO9xnSP8IECBAgAABAgQIECBAgAABAgQIEKitgABubad+6Ab+6aefprvuuiu99dZb3Xbi448/Tm+88Ua35wd64umnnx5oE64nQIAAAQIECBAgQIAAAQIECBAgMNYFBHArxGPGjEmjR49OO++8c+Xo0GzefvvtacYZZ0wvvPDC0HRgkO8awdpLL7007bTTTmmWWWZJSyyxRHrooYea7vLSSy+ls846K22xxRZpuummSwcffHDT+cHY+eSTT9KSSy6Z5pprrvwz9hUCBAgQIECAAAECBAgQIECAAAECw1Vg5HDt2Ljs15tvvpmOPfbYdOihh6a33347rb322uPy9l3e65hjjkkvv/xyOvHEE/OgcpeV2uTgNddck9ZYY40ee/uNb3wjD/D2WGkQTt57773pzjvvzFuKzwiUL7/88oPQsiYIECBAgAABAgQIECBAgAABAgQIDL5ArVfgvvPOO+mwww5Ls88+e9p7773z4O3gE/e9xVh1e/bZZ+cXHn300em9997reyPD6IrVVlstxUrXG2+8sdteXXDBBem5555L6667brd1BuPEvPPO29TMl770paZ9OwQIECBAgAABAgQIECBAgAABAgSGk0CtA7i/+c1vUnxt/5xzzklrrrnmsJmXU045pexLrAg+99xzy/123BgxYkSacMIJ04orrphGjRrV5RAmmWSSNOuss6a11lqry/ODdXCaaaZJzz77bDr11FPzz6mnnnqwmtbOOBaIXMrf+9738sD/OL612xEgQIAAAQIECBAgQIAAAQIExplArQO4e+65ZzryyCPzlAmbbrrpOEPv6UYffvhhOu6445qqRGqHRqPRdKxdd6affvoeux6B3LFdZptttrTVVlul+FTaV+CEE05IV111Vfroo4/adxB6ToAAAQIECBAgQIAAAQIECBDoRaDWAdyqzeSTT17dHbLtCy+8MM99+5nPfKbsw6OPPpquvfbact8GgboL3HLLLelXv/pV3RmMnwABAgQIECBAgAABAgQIEKiBgADuMJvkX//613mP4gVb1SDuUUcd1eeeRt7Z+KmWWOH78ccfVw8NynY7rhDuyqcjxpgxY9Lrr7/e8fCA9uOleY888sig5jYO/3jp3fvvvz+gvg32xZHm4N///nf+0+ozEtdUxxHXVffvuuuu9P3vf3+wu6o9AgQIECBAgAABAgQIECBAgMCwFBDAHUbTEoGp22+/PW2wwQZp/vnnT7vsskvZu8svvzz985//LPe724gA7RVXXJH+53/+J332s59Nl1xySR7EPfPMM9M3v/nNNOmkk6bpppsuTyEQLw3rb4mg2mmnnZa22GKL/CVwE0wwQVpwwQXznKQRsBvs8tBDD6V11lmny59qzuBW7vv3v/897brrrrlPrOTsWMIwXm4344wz5nXCK7Y333zzFC9k649bBIL32GOPNNVUU6XIw/uFL3whTTHFFLnZQFaSvvbaa3m78803X1p22WVTvJRtlVVWSXvttVfadtttOw4tD4TGsxTnfvjDH+bn//Wvf6XDDz88fz7iJW9f+9rXUjwvRcA1At0XX3xxijQjiyyySFpqqaXSz372sxRz0l259dZb8/biOV5hhRXyn0UXXTRtv/326fnnn+/ysghAR27i1VdfPZ188skpArl/+MMf0le/+tV8XAceeGC6/vrr02abbZbefffdso2dd945n5uYn7/97W/lcRsECBAgQIAAAQIECBAgQIAAgfFBYOT4MIjxZQxF7tt4MVOUCLL94he/KId37LHHdsqPW57MNiKfbwTWquWVV17JX9B23XXXlYfjxWinn356vgr0xhtvTBNPPHF5rpWNuD76dsEFF6RVV101rb/++um+++5LN998cx7Ui+DfeeedN6gvJIsAZYxviSWWSHH/GWaYIX3rW9/KA4PxcrTeSlxzxBFH5IHJJ598stvqEbT8zne+k49tk002SbvvvnuKF51FIHH06NH5ddXgYbcNVU688MILedAzAr/hFaus44VtF110Udpmm23yQH0EYn/5y19Wrup986233sqDpPFSth/96Edpww03THEs2g//CBAXJeocf/zx6a9//WsZ/IxAaczV/vvvX1TLPx9//PH82H/+85+07rrrph133DHdfffdZZ0Yf/Q95jsCuzPNNFN5LjZ++9vf5taxHeYrr7xyvoo5AtgRgL3//vtz3znmmCOq5MfCN9orStz7gAMOSGeccUZxKA/uRjA5+n3NNdeUxz/3uc/lv5iIAxNNNFF53AYBAgQIECBAgAABAgQIECBAYLwQyAJWSiZw7rnnxlvC8p+11157nJu89NJL+b3nnnvuRrbysLz/RhttVPYr+vfqq6+W5zpuPPbYY41sJWUjS73QdE0W7GxkL0Jr3HPPPY1zzjmn6VwWwOvYTI/7WQCtsfTSS+dtnHjiiU11s2Bn2Xb0IQtcNp2PneWWW66sc9ttt3U6/7vf/a48n62SLc+HSeyHQbZCuZEFPMtzrWxkaQsa0d8sSFq2H21lAcWmy2+44YbyfEfrvffe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gEBbCAjgtsU06SQBAgQIECBAgAABAgQIECBAgAABAnUUEMCt46wbMwECBAgQIECAAAECBAgQIECAAAECbSEggNsW06STBAgQIECAAAECBAgQIECAAAECBAjUUUAAt46zbswECBAgQIAAAQIECBAgQIAAAQIECLSFgABuW0yTThIgQIAAAQIECBAgQIAAAQIECBAgUEeBEY2s1HHgxkyAAAECBAgQIECAAAECBAgQIECAAIHhLmAF7nCfIf0jQIAAAQIECBAgQIAAAQIECBAgQKC2AgK4tZ16AydAgAABAgQIECBAgAABAgQIECBAYLgLCOAO9xnSPwIECBAgQIAAAQIECBAgQIAAAQIEaisggFvbqTdwAgQIECBAgAABAgQIECBAgAABAgSGu4AA7nCfofG4f48//vh4PLqxM7QXXnghffTRR2On8fG81fHB7rHHHktPP/30eD5ThkeAAAECBAgQIECAAAECBAhUBWofwH322WfTbrvtllZZZZU044wzpsUXXzxtt9126fLLL6862R4EgQg83nLLLWm//fZL888/f5pvvvkGodX6NPHTn/40zTrrrGn22WdPgt99m/d2tfv444/zPzP77LNP/mdm1KhR6fzzz+928O+++25abbXV0ogRI9K+++7bbT0nCBAgQIAAAQIECBAgQIAAgfYRGNHISvt0d3B7ethhh+XB2+5a/c53vpNOOOGENMUUU3RXxfEWBR566KG04IILdqpd48evk0VPBz799NM0cuTIssqBBx6Y9txzz3LfRvcC7Wo3ZsyYNOecc6a33367aXCHHnpo2nXXXZuOFTvxi6evf/3rxW567bXX0mc/+9ly3wYBAgQIECBAgAABAgQIECDQfgK1XYF7xhlnNAVvY2VbxxJ19thjj46H7fdDYIEFFkjvvPNOOv3008urP/OZz5TbNnoWmHDCCdNyyy1XVlpmmWXKbRs9C7Sr3bTTTptef/31fLX1wgsv3PMg/3v23nvvbar38ssvN+3bIUCAAAECBAgQIECAAAECBNpPoJYB3Pj6+ZZbbpnP1tlnn50+/PDD9Mgjj6T4uvLJJ5/cNIvHHHNMuvPOO5uO2emfQKxkXmuttfp3savytB5nnnlmuvvuu/OUH0haF4iVqe1oF6uu55lnnrTyyiu3NNgIVldL/N2mECBAgAABAgQIECBAgAABAu0t8H/fyW7vcfSp9+ecc05e//77709f+tKXymsjWBL5b6effvq0/vrrl8dvuOGGtMQSS5T7NvovMOmkk5YXTzbZZOW2jd4FYsXyFlts0XtFNToJtLvdNNNM02lMXR2YYYYZmg533G86aYcAAQIECBAgQIAAAQIECBBoC4FarsA97bTTUuQQrQZvq7O13nrrpRVWWKE8FIFehQABAsNdIHLmVku8mFEhQIAAAQIECBAgQIAAAQIE2lugdgHcZ555Js/FuuOOO/Y4c8suu2yP59vp5CeffJKeffbZ/KcvLw374IMPmoYZL4N67733mo61shO5b99///1WqvarTqS+eOutt/p1bX8u6mosHV801VO7A70+2u7tq/GDNXfvvvtuv+a8p/HHuXgOIz9rpDOJ57PVMi7sWu3LQOr1d/y93XOOOeYoq8w999xpgglq91d8OX4bBAgQIECAAAECBAgQIEBgfBGo3f/dR4DjpZde6vXN7FNNNVU5x92t1C0rDNONa665JsXLriaaaKIU446fqaeeOq2zzjrpX//6V6deR1DprrvuSvvss0+ed3O33XbL60QKiZ122inNMsssKfLYxlvub7nllk7XVw889thjeTqKyN8ZX1+ffPLJ04orrpguuuiiarV+b7/44ovpZz/7WVp++eXTxBNPnI8r5myTTTZJ99xzT9nuZZddlhZccMGmn1h9XZSuzi+++OLpP//5T1El/3zyySfTr371q9xz0UUXzY9F3uS99torzT///CnuHdedeuqpTdcVOwO9PtqJXz4ceeSR+f0OPfTQoun8czDnLmy33nrr/BmYcsop8zmPse28884pXuz3wAMPpAjsRtA8gud9KWG26aab5oHFWB0633zz5c9nPKfxvHZVxrZd3DPm+6abbsqf2WLV6ptvvpkOO+yw/HkfMWJEmn322dOPfvSjfOxFP2+88cY83UpcE8/AN77xjfTHP/6xON3psz/j79RIDweij0UJW4UAAQIECBAgQIAAAQIECBAYDwSywI/ShcC3vvWtRja9+c+VV17ZRY3hfejggw8u+/+HP/yh8dprrzUefvjhxnLLLZcfz3JjNrLVj+Ugrr322kYcK8Ycn1nQtvHzn/+86VhxPgvKNp5++uny+urG1Vdf3YjzUTcLAjeuu+66RrS/5pprNrU122yzVS9refv6668v+3rAAQc04n6/+93v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iLQQJ510Uoqvd4+tEsG4aomA+GCW6urR+Lp95CpWBlcgVsOeeOKJZaOxIveWW25JMbennHJKOv/88/PA4FlnndUpP2x5UQ8b55xzTp439uabb05bbbVVvgp3pZVW6uGK8evUuBp/BHDnm2++8QvPaAgQIECAAAECBAgQIECAQI0Fah/A/eijj9LGG2+c7r///nTFFVekyK/a7iVeJnbMMcfkw4gXsv3P//zPWB9S8eKk4kbVnKbFsYF8zjHHHE2Xx9fueyrxsrMiX2tP9ZxrFthhhx1SrECPEiuqV1hhhRQv+IrnaNttt01PPfVUv4KD8dKzb33rW3m78Wfs97//fYo0H3Up43L8M800U/4yv7rYGicBAgQIECBAgAABAgQIEBjfBWodwI0clVtvvXUesIqVt8suu2y38x31YjViO5Sjjz667GakhRgXJb5evsACC5S3GuwXwMWL0qrB9b333ju999575f2qG6+//npaY4010m233VY9XG53XC1cnrCR4uVlkQc6Uho88MAD+Qu5/v3vf+cvOItVuNNNN12/lE4++eTyuo022qill4qVF4wHG+Ny/JGapE4rm8eDx8MQCBAgQIAAAQIECBAgQIBAjwK1DuDusssu6eyzz07xwqbVV1+9S6j4qn6sZj3ttNNSxxc3xbnIFfrrX/869Scva2/X9/d8rJIsyksvvVRs5p//+Mc/yv1IHdFoNMr92Oi433Qy2+kpt218Lb4ot956a/rjH/9Y7JafERQsSqyS7am9ol7xGbl8ixLXRs7W1157rTiUf0awcf31189f4Fbtz1RTTVXWu/vuu8vtYuOaa64pNvPPV155pWm/N5eo3NNYBnp9tB/PQ1G6ekFWb/foqX/R7jvvvJNWWWWVPGgbc7fQQgvlq21jRedAy9NPP1020fHPygcffJCqz2XsV0tv44q6vY2tN7vq/brbjhQrRfn444+LzZY+BzL+lm5QqRR/NiJdQ+SlVggQIECAAAECBAgQIECAAIH2FxjZ/kPo3wj22WefMs3AL37xixQ/HcuHH36Yf2U8Ap3f+9730pRTTtlUJfLKfv/738+PHX/88flLwqq5Wpsqd7HT2/X9PT/ZZJPleX3jlpELd4oppkhzzjlnvoJ4//33b+rJ9ddfnwe/Iv9pvPDszTffLM8/99xz5Xax0TFgGnWi7Sg/+MEP0m9+85s8727sR2qKM844I2244Yb5C5XuuuuufHVnnCtKBL+/8pWvpGWWWabXvKoxlvjqfZEaIYLEsep3zTXXzPseweqYhygRKI5Vu0UZNWpUsZkiwLXvvvumH//4x/n8Rm7Xww47rDwfG2Efc/65z30uP/7WW281nX/11VfTjDPO2HQsVq8WJV66tvzyyxe7+QrWcifb6Ov1cW01IBfXdywDmbtoK4J+jz76aN5szGWseI58qpNMMkn+E0HwWWaZJc0111z5M9Xx/j3tTz311OXpE044IS244IL5Kt9IXRK/IKm+AC9SmUT9eLZWW221cWIXAfFqHyLIXMx90fGqebyMrKtSXd0dv0woykDGH21Uf6FQneei/eIzXjy32GKL5bvxIrP4MxF/HygECBAgQIAAAQIECBAgQIBAGwtkq9tqVw455JBYdtqnn2zVZien7KvgTW08++yzner0dKC36/t7fo899mjqV3Ws++23XyPLa9rpfJZuoJG9eKyRfXW+6VwWJC2HkAWnGrvuumvT+dGjRzeyQHdZJ+pngaOmOnH/4ljxWe3TEkss0ciCY2UbPW3cd999jdlmm61T+9X2soBspyayFZidxla9Jkv50Jh77rmb2o37ZIG9RhbAb/z85z9vOnf44Yc3slWY+X3i89xzz206v/baazeyVA75+YFeH41kKzibxh19qz5vgzF3WSC1aQxVn47bBx54YCPLH52Pr5V/XH755d22vd566zWy1fCdzh9xxBEDtm/FLupkOZWb7p8F9JuGFc9+xz8b99xzT1OdBx98sKmNGFfxDPR3/HGDaLf65yb7pUUjC8w23bvY6fh32w033FCc8kmAAAECBAgQIECAAAECBAi0qUB8Zb5WJVu92RRk6RiY6mo/W9HWpVH2NfOyrQiK9rX0dn1/z2df9W5sv/32Zd9iTMstt1wjW22bdzF7SVUZDIxg0J///OdGlgO4qX7VIcsn28jyzXZ7foYZZmgaegQbOwa7IgCVpTRoPP7443k7ESyNIOBjjz3WdG0rO9lK1Lytah+LMUawq7uSrZBtZDmBm8YR/YjxR4ntCIxGUPree+9tZF/LzwNwHe9T7MeYstWQjWwFcFObxfn4vP3227s918r1ESTsKWAdz91gzV08NxtssEG3/a2OK7a32Wab7qi7PH7sscc2tR3jyvLq5s7ZquhGBPKj3XieDjjggDyo3/Gexf5g2UXguzvfeB6yl/E1slXlTf0u+hCf0ecoSy+9dLd1Tj311LxOX8cfvxjprm9x75VXXjlvt/qPLBVF2Y+4NuZUIUCAAAECBAgQIECAAAECBNpbYER0PwsGKP0UyAKSKb4q3UoKgK5u0dv1AzkfL/OKr/LPOuusKQuKNd0+cnjGV/6L9AdNJwdpJ3KGxlfy4wVnX/ziF9MEE0yQ4qvqWVAyLb744vn+QG4VeU0ffvjhFGOJFAmRKqKV8swzz+Rjn3baadM888xTpm545JFH8pyv0c86lkghsNZaa+VpE4488siUBTfztALxsriYy/iJVBKRwuLiiy9OWRA1xTMW89tqibbimY50DHPMMUenZyDyN8fxavqLVttuh3rjYvwxj9kvRvLUJJH+QiFAgAABAgQIECBAgAABAgTaW0AAt73nT+8JDIpA5HddaaWV8uBs5AiOPLc9lSzlQNpkk01Sttp6rP4SoKc+OEeAAAECBAgQIECAAAECBAgQqINAPZca1mFmjZFAHwS+/e1v58HbLCVAr8HbaDZWKWdf0Re87YOxqgQIECBAgAABAgQIECBAgACB/ggI4PZHzTUExiOB7CVrKcuLnI8oUm689tprPY7ulltuSVtvvXXacsste6znJAECBAgQIECAAAECBAgQIECAwMAFpFAYuKEWCLS9wPzzz5/nK46BRG7bCNBGXuH55psvTTfddHlQ94knnkjnnHNOuvnmm9Nuu+2WDjrooE45bNsewgAIECBAgAABAgQIECBAgAABAsNMQAB3mE2I7hAYCoEHH3wwrbrqqvlLy3q6fwR1999//7T55pv3VM05AgQIECBAgAABAgQIECBAgACBQRIQwB0kSM0QaHeB999/P5177rkpXlAWq20fffTRNPfcc+ercGOFbry0bNlll00jRoxo96HqPwECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CXiJWd1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom4AAbt1m3HgJECBAgAABAgQIECBAgAABAgQIEGgbAQHctpkqHSVAgAABAgQIECBAgAABAgQIECBAoG4CArh1m3HjJUCAAAECBAgQIECAAAECBAgQIECgbQQEcNtmqnSUAAECBAgQIECAAAECBAgQIECAAIG6CQjg1m3GjZcAAQIECBAgQIAAAQIECBAgQIAAgbYREMBtm6nSUQIECBAgQIAAAQIECBAgQIAAAQIE6iYggFu3GTdeAgQIECBAgAABAgQIECBAgAABAgTaRkAAt22mSkcJECBAgAABAgQIECBAgAABAgQIEKibgABu3WbceAkQIECAAAECBAgQIECAAAECBAgQaBsBAdy2mSodJUCAAAECBAgQIECAAAECBAgQIECgbgICuHWbceMlQIAAAQIECBAgQIAAAQIECBAgQKBtBARw22aqdJQAAQIECBAgQIAAAQIECBAgQIAAgboJCODWbcaNlwABAgQIECBAgAABAgQIECBAgACBthEQwG2bqdJRAgQIECBAgAABAgQIECBAgAABAgTqJiCAW7cZN14CBAgQIECAAAECBAgQIECAAAECBNpGQAC3baZKRwkQIECAAAECBAgQIECAAAECBAgQqJuAAG7dZtx4CRAgQIAAAQIECBAgQIAAAQIECBBoGwEB3LaZKh0lQIAAAQIECBAgQIAAAQIECBAgQKBuAgK4dZtx4yVAgAABAgQIECBAgAABAgQIECBAoG0EBHDbZqp0lAABAgQIECBAgAABAgQIECBAgACBugkI4NZtxo2XAAECBAgQIECAAAECBAgQIECAAIG2ERDAbZup0lECBAgQIECAAAECBAgQIECAAAECBOomIIBbtxk3XgIECBAgQIAAAQIECBAgQIAAAQIE2kZAALdtpkpHCRAgQIAAAQIECBAgQIAAAQIECBCom8DI++67r25jNl4CBAgQIECAAAECBAgQIECAAAECBAi0hYAVuG0xTTpJgAABAgQIECBAgAABAgQIECBAgEAdBUa8/fbbjToO3JgJECBAgAABAgQIECBAgAABAgQIECAw3AWswB3uM6R/BAgQIECAAAECBAgQIECAAAECBAjUVkAAt7ZTb+AECBAgQIAAAQIECBAgQIAAAQIECAx3AQHc4T5D+keAAAECBAgQIECAAAECBAgQIECAQG0FBHBrO/UGToAAAQIECBAgQIAAAQIECBAgQIDAcBcQwB3uM6R/BAgQIECAAAECBAgQIECAAAECBAjUVkAAt7ZTb+AECBAgQIAAAQIECBAgQIAAAQIECAx3AQHc4T5D+keAAAECBAgQIECAAAECBAgQIECAQG0FBHBrO/UGToAAAQIECBAgQIAAAQIECBAgQIDAcBcQwB3uM6R/BAgQIECAAAECBAgQIECAAAECBAjUVmBkbUfex4E/9dRT6cknn0zXXXddH6/sufpcc82VVltttRSfY6M88sgjebPzzz//2GhemwQIECBAgAABAgQIECBAgAABAkMkIO4zRPDj+LZW4LYIfu211w568DZuXQSGW+yGagQIECBAgAABAgQIECBAgAABAgQI1EjACtwWJzsCrVEOPPDAFq9ordpee+2VB4ZjFa5CgAABAgQIECBAgAABAgQIECBAgACBqoAVuFUN2wQIECBAgAABAgQIECBAgAABAgQIEBhGAoOyAnew0wsU+WC32267YUSlKwQIECBAgAABAgQIECBAgAABAgQI9CRQxAkjvle8+6mn+s71LjDgAO4pp5yS53Ht/Vat1yjSFcSESy3QupuaBAgQIECAAAECBAgQIECAAAECBIZKoAjexv0jvlfE+MT3BjYjAw7gFhMhN+zAJqKOV1911VXp008/bXno8Yd94oknTn//+9/Tiy++mOacc860wAILtHy9iuO/wIcffpieeOKJ9OSTT+afL7/8cppuuunSzDPPnL785S+nL3zhC+M/wn9HeMMNN6RPPvkkLbzwwmmGGWaozbi7G+iYMWPS9ddfn55//vkUz8XIkSNzl/h7ZOWVV06TTz55d5c6Pp4K/Oc//ylfTjr11FOnJZZYoseRPvvssyne8DvppJOm5Zdfvse64/PJp59+Oj3++ONpyimnTEsvvfT4PNRybPF3R3f/vTJixIj02c9+Ns0444z5v2tif1yV+++/P38m33777TTvvPOmFVdccVzd2n3GQ4Hqcz733HOn+OmtxH933XzzzWW1BRdcMP9zUB6wMd4KFP9OjAHGyrp55pln2Iz1zTffTHfeeWfen/h7Mf7/Mcott9ySPvjgg2H338bd9TfvtH8QaFOB6667rlPP41i7BXBjwWr0ucgS0GlQ3RyIOGkEsQc7q8CAA7jd9NdhAj0KxP8IHXTQQT3W6Xhy2WWXzf8FfN5556Xbb789bbrpprUN4EZg7pprrsmJllpqqTTttNN25Krd/jPPPJN+9atfpXfffbdp7K+++mr+P7gR0Jx11lnTNttsk2abbbamOuPjzjnnnJMPa6qppqp1ALfRaKSzzjqr6X8wi/l+4YUX0r333psuvfTStMkmm6RVVlmlOOWzBgIff/xxuuCCC8qRTjHFFD3+OyX+xy/+HplkkkkGHMCNv5fuu+++/N7t9h+y0e+//vWvKYLedQjgRqD/3HPPLZ+TnjY+97nPpW233balwFdP7bRy7o9//GO6+uqry6oRTBHALTls9EOg+pzPNNNMafTo0b22EkGy6t+j8fdj/NJcGf8F4r+t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hIAQqHgEIGwxA4B5IsxrsFlbaL+54l+gnhPIBpdsVFboxn9sdIgpKpn/qecMU3RCoAwImNJmGJQI3BCN4s7LQuAWGjUEbS77U0biEnZ4Xmhcci8EhIAQEAJCQAgIASEgBISAEBACQqAcCLAZFz9JfgiwcVkxsttuuzl+EiEgBKoPAePwTCkTQtfuVd/bVE6Km6V2mv6ycpLT8CkJd5qrr9QwE5GkjVxqGipxN8JS30n+hYAQEAJCQAgIASEgBISAEBACQkAICAEhIAScE+/TNErBBk3jNfN/S2YF6lO1m7g0E5F//silEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQaEoISAO3KeW23lUICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgapCQBq4VZVdSqwQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAk0JARG4TSm39a5CQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACFQVAiJwqyq7lFghIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBJoSAiJwm1Ju612FgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEKgqBETgVlV2KbFCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACDQlBETgNqXc1rsKASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBIVBVCIjArarsUmKFgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEGhKCIjAbUq5rXcVAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQqCqEGheValVYusNgf1/taje4lJEjReBZy7t2nhfTm8mBISAEBACQkAICAEhIASEgBAQAkJACAiBekCg+ZQpU+ohGkVRfQhsXH1JVoorDgHVLxWXJUqQEBACQkAICAEhIASEgBAQAkJACAgBIVBlCMiEQpVlmJIrBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhEDTQaDZlylpOq+rNxUCQkAICAEhIASEgBAQAtWBwJgxY3xC+/btWx0JViqFgBAQAkJACAgBISAE6gQBaeDWCawKVAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBIVA6AiJwS8dQIQgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIATqBAERuHUCqwIVAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIlI6ACNzSMVQIQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgTpBQARuncCqQIWAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAKlIyACt3QMFYIQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkKgThAQgVsnsCpQISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEQOkINC89CIUgBBonAmvXrq31YhtuuGGte7ohBISAEBACQkAICAEhIASEgBAQAkJACAgBISAE6gqBqiJwP/jgA/fll1+6zp07u/bt2xeMybRp09y8efMcJNyIESMK9i8P5UNg7NixbvHixa5169Zul112KV/AZQrp/fffdzNmzKgV2k477eTatm1b675uCAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgbpAoGoIXIjb9957z2Ow2WabuW222aZgPNatW+f9EFZDyyeffOKmTp3qmjVrVpEEZl3jY3lgx0LjGzNmjFu+fLnr3r2723LLLQv1ntN9q1atXPPmNZ8HaYzTxs0ZiBwIASEgBISAEBACQkAICAEhIASEgBAQAkJACAiBEhGoGgK3xPesOO8rVqxwK1eurLh0VUuCli5d6tasWeM41oV069bN8UM+//xz9/bbb9dFNApTCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIZEVAm5hlhUcPhYAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAg2HQEVp4GKftkWLFm6TTTYpGZHPPvvMLViwwC1btsx16NDBL7XPFShL5T/88EP36aefulWrVnlbp126dHFdu3bN5dURH2YR0NbEVAN2UrfYYosMe6k8W7JkiQ/Ljlxg2zeUTp06+TRzz/xgtxdzAXHCO2JPFnMMxIlgXmDRokXe3i8mJ8Bi4cKF/hk2hAlrgw2S+fsvvvjCffzxx/698ESaCKdly5Y+jHL+A3fS+tFHH7nVq1f7uHr16lUrfXPnzvU2kInbzGGQzhA/3mnzzTdPJ48yhVvSj11bzsEIDGbPnu3zmrzq27dvrfjSgeRxMmfOHJ9nhCsRAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBAC5UKgwQlcCLiZM2d6Ag8ib9NNNy2Z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tQg5sXDhQoEncmJiYo6J4JgbjQRIgARIgARuFAEKuDeKPPslARIgARIgARIgARIgARIggRwisHfvXiVorlmzRoW4QDcdO3bMod5uXLMIO4EDZh/a4caNij2TAAmQAAmQgGcJUMB1gad/gbRQwYUMbwZteExHmzWt83gmARIgARIgARIgARIgARIggRtBYN68eRIbG2t23bRpU0H8W1+2okWL+vL0ODcSIAESIIF8TIAxcPPx4nPqJEACJEACJEACJEAC3ksgOzFwvXdWHFluEVi5cqXaxC4oKEiqVaumjtzqm/2QAAmQAAmQAAl4lgAFXM/yZGskQAIkQAIkQAIkQAIk4BECFHA9gpGNkAAJkAAJkAAJkECeJ5AWGyDPT4UTIAESIAESIAESIAESIAESIAESIAESIAESIAESIAHfIkAB17fWk7MhARIgARIgARIgARIgARIgARIgARIgARIgARLwIQIUcH1oMTkVEiABEiABEiABEiABEiABEiABEiABEiABEiAB3yJAAde31pOzIQESIAESIAESIAESIAESIAESIAESIAESIAES8CECFHB9aDE5FRIgARIgARIgARIgARIgARIgARIgARIgARIgAd8iQAHXt9aTsyEBEiABEiABEiABEiABEiABEiABEiABEiABEvAhAhRwfWgxORUSIAESIAESIAESIAESIAESIAESIAESIAESIAHfIlDQt6bD2ZAACZAACZAACZAACZBA/iSwf/9+uXz5spQoUUIdBQvyX/38+U7grEmABEiABEiABHyNAP+r87UV5XxIgARIgARIgARIgATyJYFJkybJkSNHzLnfdNNN0qdPH/OaCRIgARIgARIgARIggbxJgCEU8ua6cdQkQAIkQAIkQAIkQAIkYEOgRYsW0rhxYylVqpTKX758uWzdutWmDC9IgARIgARIgARIgATyHgF64Oa9NeOISYAESIAESIAESIAESCAdgVatWqm8a9euyeuvvy5JSUmSkJAgtWvXTleWGSRAAiRAAiRAAiRAAnmHAD1w885acaQkQAIkQAIkQAIkQAIkkCkBPz8/qVixoip38uTJTMuzAAmQAAmQAAmQAAmQgHcToIDr3evD0ZEACZAACZAACZAACZCA2wQCAgJUHWxqRiMBEiABEiABEiABEsjbBCjg5u314+hJgARIgARIgARIgARIgARIgARIgARIgARIgAR8mAAFXB9eXE6NBEiABEiABEiABEggfxNITk7O3wA4exIgARIgARIgARLwAQIUcH1gETkFEiABEiABEiABEiABErASCAoKUpd79uyRq1evWm8xTQIkQAIkQAIkQAIkkMcIUMDNYwvG4ZIACZAACZAACZAACZBAZgQqVaqkikC83bRpU2bFeZ8ESIAESIAESIAESMCLCfhdM8yLx8ehkQAJkAAJkAAJkAAJkEC+JLBhwwY17wYNGrg9f/yLP2nSJFm3bp2qGxoaKiEhIRIdHS0dO3Z0uz1WIAESIAESIAESIAESuHEE6IF749izZxIgAS8lgB27L6Wk2BxXrlzx0tFyWCRAAiRAAiSQnoCfn5/cfPPNUq9ePXXzxIkTkpCQoI70pZlDAiRAAiRAAiRAAiTgzQQKevPg8tPYUlIuy9r1qV4Wrs67WnSUhIaUlHUbNskDwx9V6Tl//OJqdZbLBoHvxk+UT774Wnp26yyvvvhMNlrKmapDH35c1qxdLy8/9x/p1bNbznTiw62C34aNm21meNcd/eTxR0bY5FkvPv7sKxn7w4/So2tnGf2S6jMAVAAAQABJREFU970nrGNlmgRIgARIwPcJHD16VN5//301UXjf9u7dW8qWLStFihTx/clzhiRAAiRAAiRAAiTgYwQo4HrJgp48dUpGPPqkW6N567WXpFOHdqI9Ay8mX3Krfm4XxqN8z7w4WnB+ZMRQqVihfG4PIcP+9uzdJ5+N+VYKFiwor7/8XIZl4aEJS77kncwvXX8v6PdGhpO5gTcX/L1EZs2ZJ7VqVpd7Bw28gSOx7bpWjWoSUKiQytwSu03Onz+v3re2pWyvUi6nqAzu9m3LhVckQAIkQAI3hoAOnYDe77//filTpsyNGQh7JQESIAESIAESIAESyDYBCrjZRuiZBgoHBEiD+nVtGrtsPMIN8QgGsbN06VI290uWDLa59vYLRFueM2+hGibEOm8TcE+dOi1z5/+txpeZgOvtrPPK+Hbv2auYX/IyIfzJx0aaCN985wP5adrv5jUTJEACJEACJJAXCBw/flwNs2TJkhRv88KCcYwkQAIkQAIkQAIkkAEBCrgZwMnNW8HBJeTbL/5n02VS0hm5udttKu+xkcPl5natbe7zggRIgARIgARIgARIgAQcEbh69arKLleunKPbzCMBEiABEiABEiABEshDBCjg5qHFcnWohw4fkXXrN8qeffslIryitG55k5QoXtxp9RMnT8nW2DiJT9gl4idSLSpKYhrUlcDAQKd1XL1x/sIF2bI1ThXXHyRwsWnLVjl77pzZTIjhTRwdVdW81onDxlz27j8gELirGzF/L1y4aMT83WjUjzXmFCTNmjSSqKpVVHGEZti4aYt61L1mjepGjLfCuhl13h6fIOfPnTeYVJLQ0BCVd/jIUdlrcIJt35GgznhZtSZ1x2adERkRLmXLlNaXNuerV69Jws5dsn7jJjl9OkkQm7h1y+ZSoEABm3LZucCarjdisoIHHuePMMZTpXKE1KgWnWk/8Cxea7wfMH+8HxrUq5uh9zPa37h5q/F+2CmIzYx+6tSuJWXsPMAxn7Nnz6lyBQoWkHp1attMEeuN9YDVrlVDAgwvcxjaPWmMCYb3KOz48RPpmNc1+ixa1DNx+rBGsdu2q3U6cDBRKhke7RiTfu+oQeTgC/o8mHhI9VDLeG8GBRXLwd7YNAmQAAmQAAmQAAmQAAmQAAmQAAmQgC8RoIDrS6tpzOWvufPl2Rdfs5lVWNkyMubTD6RSxQo2+bj4Y9YcefHVN9PlI7zB26+/LDWNWKDZsb1798uwkU+ka+Kt92y9jeFd/O6br6YrN9sIufDhJ19Ii+ZN5e47/+UwTvC3X35siJJ1JMWISzt42COqjcnff51OEH7l9bclbtsOecnY2OvW6xt7zV+4SN798NN0/dqP+T+PPyID+vVOVw4Zb73/kfz0y28295o3aywfvvOGGUfV5qabF/959mWZZ4zTkTVtHCNvvPqC2sDO0f0dhlj63v8+V6Kv9T422cJmW/YWG7ddnnj6BYGwbW+vv/K8dOvcwSY7bvsOedDY8Ati/+K5M2zuQaC/39hcDzZt8nglnCP9+ZjvZOHipUiahlAh9swnjv1SalTP3vsPHRwzHiF9+bW3ZdmKVWZ/OvHvQXfI8CGDpVChnPtViC8whj0ySq0B3udYLxoJkAAJkAAJ5DSBC8aX6DA/P7+c7ortkwAJkAAJkAAJkAAJ5DCBnFMtcnjgbD49AXhOQryFqHdTsyayaOky2QCvTUOM+3bcBHnx2SdtKk35+VfRQioEx/ZtWsmlSykyfcafsnPXHhny0GMyfcr3preqTWUXL+C1OnL4EFUaHrKffPG1Svfrc6uUDwszW4FXbEa2c9duGfXMS6pI547tpWL58rLP8MyFsJmd+KmIO6zHh/Z+/f1P1YfO02OqX9fWu1Tn65i5t93SXcqXC5Npv/2heK9YuUbF++3ZLb1Iquu6ej6QmKiKoi14KcNbOfHQYfn+x6nKa/WB4Y/ITxPHir+/f7omJ02dpvIG//suKV2qlMz8a67yfn7hlTelgvFIZcMG9cw62Ehv0OBh6jo0pKQM6N9HihQuLLONLwUgsD730mtS0vCExnsrO9aje2epd53n8pWr1RzwhUGf226xadYTm63AA3zgPUMEXuYQme/of7vx3ikncdvjZeov02XcD5OkUMGCMnzoYJu+PXWxfsMmU8SGYP7y8//J1GPaU32zHRIgARIggfxLAP8b7d69WwEoW7Zs/gXBmZMACZAACZAACZCAjxCggOsjC6mn0bVTB3nt5ecMMc9P7r17oHw99gfD4/FbQ5SdKS88M8r0woBY9/HnqWIqNhR7ePgD5r1+t98q/xo0WPDY95ffjJVnnnxMN+/2GaEKMA4YHmPXAm7vW3pIrZrVXW4PInRkRCX5+P2vbB7/37N3nxQrlvVQD7Vr1hAcMIjdWsDVY3ZlgODT7/Zequj99w6Shx9/SiDgzp2/UDwh4A4fcp/UNzyM7cNgQHwe8eiTssfwckaIhCaNGjoc7leffSiNGtZX93r36i5DRvyfEmS/HT9B/vfef806Eyb9pNIQOr//9gspF5b6ga+/IbYPN/oBny++GpttAbdj+7ZmnxD1Ea4iqmpl831i3vRAYvyEyaZ4O2m87XsHIRTglY2fkVsNAd7Tm+qtXL1Whhuet7Dbb+0pz/7nMYciuwemySZIgARIgARIQBH49ddfZefOnXLkyBHj/67UGLi1azv+EprISIAESIAESIAESIAE8g6B9C57eWfsHKkDAvfdc6cSb/WtDu3a6KScOXPWTP81Z4F6pBuelsOH3meKtyiA2LGDBvZXZecvXGzWudGJp554NJ3Ihti08Cy9UQaxE6KoNnjBdrq5nbqEl6wnzFkMYwi26B+GGLmODHFptXiL+4UNj9q7rq/t0mUrbUIr/GmE04BBjNbiLa5RByI/DLGLHYVXUDe97AXi8FffjlejemzksHTvnW5dOpr8Vq9d79HRL/lnuSne3jmgryHePk7x1qOE2RgJkAAJkIAjAvHx8XLo0CEl3gYHB0vfvn2lSpUqjooyjwRIgARIgARIgARIIA8RoAduHlosV4YaGRluUwwCrbakM2ekRInUzcx27dmjsvFouX5sXpfDOSnpjHkfZaztWMvlVhpCZfOmjXOrO5f7qVEtSgoaj+BbTW+Qho25PGXYgGzGn3+psBEQhq9cuaKaRtgMGDYTc2SNGzVIl43NwbRBjK1SOVK1p4XZhvXTwiroctYQEkeOHhXEVfZ2O3rsuDlEeKEjZIi9aX7YWM1ThrAeOmYxOD02crjNlyqe6oftkAAJkAAJkIA9gYceekhlFS1a1P4Wr0mABEiABEiABEiABPIwAVvlKQ9PhEMX5U0YUKiQDQr/AmlO1vpROhTYs2efWW5HfMbildoEwyIEmxVzMRERXjEXe3O9q1KlQtMVLligQLq87GS899GnMnHyzzZNaM9bnXkx+aJO2pxDQ0JsrnERXKKEmXfk6DEl4B4/cdLMCw1NE/11ZglLncOHj4oR0cHrDSFAtOFLCBzOLDtxlJ21iXyI4j9O+UXuuqNfRsV4jwRIgARIgAQ8QoDCrUcwshESIAESIAESIAES8DoCFHC9bklyZ0B4LB52S4+u8srzT+VOp9noJdjYPCu7pr1Ws9tObtZHmAMt3t5z1wDp3+c2Fd5Ab1g2eNgjKjatszFdvnw53S2rkI9NymCFCqX9Krh8OdW711rx6tW0vEJ2XxJYy1nT14yYxzfSAgICzO5/NTbjC6+Ue18CvPD0E4a39EEZ+8OP8v7/PlNhLNyJ+WwOnAkSIAESIAESIAESIAESIAESIAESIIF8TyBNtcn3KPIXgKpVIgVxOo8eO3ZDJn5N3BP3/P3SPImdDbiAEX9WW/KlFJ00zwcOHlJpxEbNK7Z46TI11FYtmsmjDz2Ybtim97STKR07nhZGQFc+ZgntUPZ6KISSRpw8bUcNr1x7s3rolgtLC59Q6Hr4CIQiAFc/Pz+zqrXOjWAeXqmCORZ432ZZwL0+p/PnL5jtZZRo36aV9DY2LbuUkiLLV62WuG075KnnX5Efx33ldMO93/+YJTssYRxuMzZVi6paJaNueI8ESIAESIAESIAESIAESIAESIAESCCfEEhTvPLJhDnNVALRUVVVYsXKNU43wPI0K39/P3PTKB1j15N9FDBCF+jQAonGBh5W27N3n82GXdZ7Oq3r4vr8BdfEOl03p87nzqXGuHX0SCQ23tIxXJ31P2/BImMjE1t1d9mKVWZxvQEchNdq0anviYWLlpr3dWLx0uU6aXgAh5npkiXThN/jJ2xj/m7cvMUs5ywRFFRM3fJkvGDdV4nixc3YzX/Nmaez3T6XLV1a1Vm1Zp1LdfE+hCGcyRuvPK/SCOfw1nsfqbSjlyXLVsiEST+Zx/4DiY6KMY8ESIAESIAESIAESIAESIAESIAESCAfEqCAmw8XHVPu3LG9REZUUrN/+bW3DE9cW0/N06eTlJg0aeo0jxLSsWx/mvabHD58xKNtozEtQiLsgN6U68KFi4I4splZmMWzFPWdbQyWWTuevK/XaO78v+VgYpoovW//AXnj7fcz7QoMfvhxillu/wHjsf7vJ6prxGW1hk4Y0O92lf/X3PmC0A3a0NeXX3+nLrt16SjWcBZlyqSKm7j53fgfTeEbguWYb8bpJpyey5dLFYO3xG5THuEpKelDPjit7MKNxx4ZrkpN/ulX+fOvOTY14BW8dv1Gee7l1wUb/Dkz/WUH5jR9xkxxZ4yREeHywjOjVNN/zJojOGgkQAIkQAIkQAIkQAIkQAIkQAIkQAIk4A4BhlBwh5YPlYV34HP/eVyGPvy4wLOw2639pXGjhlLS2KzqQGKieuwb0x3Qr7dHZ93ntlsM4fEDWfD3EnVUrFDe8JotKs2bNpbHRqaKbdnpsG/vXiom7IaNm6VH7wFqTrt27ZaLyZcybRYemxC258xbKJ+P+VYdCDUBj8r77rlTunbqkGkbni7QtXMH+fyrVPG0V9871XyKFA4wBVZ4DWfmhfvRp18KRNlSoSGybsNmVR717hxgu7FWz+5d5PuJk2XP3v3yyBNPS4P6daVIkcICL21tQ+67WyfVOdDY5RqP+0PYnDT1F/nNCAWAWK9rDO/gUBc2vmvSKEbCjDAOEJofHfWs8qCuWKGcavut114yvmQIt+nP3YtunTvJX3MWKHH4hVfelK+/+16qVqks2LQsNm67ubHZYyOHOW26Taub1BcDCFfx6hvvqANzQ4iDLz5+z2k9faN3rx7yjyGIz1u4SF589U1jA7haEhGe+uWJLsMzCZAACZAACZAACZAACZAACZAACZAACTgjQA9cZ2S8Id8vbRB+RvgBZ2aNO2pfxho71r4cBNvpU3+Q5s0aq2oQ3SAyIWYnDHFX2xnxPD1pELMgzEEchMGrEcJYYuJhh93oMSP8givWzRA87+jfxyyKOcE+evcNqVmjmkr7W+K0qgzLy/NPPSFPPPqQ6Z28c9ceNT54JFtNj0ufbe957scKcVs//fBtJXKiD8wH3rEQPb/5/CO1ORby9aZmSMP8C6SOAXNp0bypWlPUg9gLr94J332hNkNLLZ36ClF//NefC7xsYRDBtXgLdr9MGieVIyNSC1teHx4+RGIa1FM5aB9jrFOrhoz59AOzlP349A0IxF999qEMGvgvJfiiPt4POC45iGOs67l6xvvmg7dfl6dHParEYYjT+PIALBAXFxzRd1CxIKdNYuyYC967KA9D3VOnT9vU8bsep9nRz+rzxqZmWtB+5sXRNvVwYf8+cvX9nq4hZpAACZAACZAACZAACZAACZAACZAACfgcAT/jMWLbAJk+N0VOyBUCycnJsnffATlz9qxgQ6ty5coKvCvzqkFgw6P/8DqtVDFtM6u8Oh88tr//wAFDNEwyNuOqIDp2ravzOXnqlOzZs08qGB7PZS1hD5zVv3gxWXbv2Sspl1MkMjxcSpQo7qyoykecXcQdxgZoEHmtsXEzrJjLNxEq5KDxpQEEbsS2xSZu9uJpLg+J3ZEACZAACZCAUwIbNmxQ9xo0aOC0DG+QAAmQAAmQAAmQAAn4PgEKuL6/xpwhCZAACZAACZAACZBAHiRAATcPLhqHTAIkQAIkQAIkQAI5QMBzz3rnwODYJAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAnkZwIUcPPz6nPuJEACJEACJEACJEACJEACJEACJEACJEACJEACXk2goFePjoMjARIgARIgARIgARIggXxOQIdSyOcYOH0SIAESIAESIAESyLcE6IGbb5eeEycBEiABEiABEiABEiABEiABEiABEiABEiABEvB2AvTA9fYV4vhIgARIgARIgARIgATyNYHatWvn6/lz8iRAAiRAAiRAAiSQ3wnQAze/vwM4fxIgARIgARIgARIgARIgARIgARIgARIgARIgAa8lQAHXa5eGAyMBEiABEiABEiABEiABEiABEiABEiABEiABEsjvBCjg5vd3AOdPAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiTgtQQo4Hrt0nBgJEACJEACJEACJEACJEACJEACJEACJEACJEAC+Z0ANzHzsnfA12N/kN9mzFSjmjrhWylcuLBKDxv5hBxMPCQN6tWV0S8942Wj5nBIgARIgARIgARIgARIgARIgARIgARIgARIgARyggAF3Jygmo02T548KQcOJqoWrl69ZrYE8Rb5ZcuUNvOYIAESIAESIAESIAESIAErgYsXLwoOewsODhY/Pz/7bF6TAAmQAAmQAAmQQLYIXLlyRS5cuJCujaJFi0qBAgXS5TMjawQo4GaNG2uRAAmQAAmQAAmQAAmQgNcR+PDDD2Xs2LHpxrVy5UopUaJEunxHGYmJiXLzzTerW4sWLZKyZcs6KuaRvEuXLsmff/4pcXFx6sPf5cuXpVu3btKmTRuPtM9GSIAESIAESIAEcpbA+vXrZfLkyek6ueuuu6RBgwbp8nM74/z58/Lyyy+rbh999FGpWLFibg/BI/1RwPUIRjZCAiRAAiRAAiRAAiRAAjeeAETazp07q4FAFN23b5+Eh4e7LN6i4rZt21T9YsWKSZkyZVQ6p15++OEHSUhIUM0XLFhQ4CmM8dJIgARIgARIIC8R+O6779QTMPgSskqVKl41dDzpPWnSJDWmwYMHm6E6PTnIyMhI1dyZM2fkxIkTKh0REeHJLrLc1v79+826Of1/jdlRFhKZrRMF3CxAZRUSIAESIAESIAESIAES8EYCI0aMMIc1evRomTBhgjRq1MjMcyUBTxXUqVWrVo6GXThw4IAp3g4aNEj158r4WIYESIAESIAEvInA2bNnJTY2Vg2pUKFC3jQ0NZbdu3fLrl27xN/fXwICAjw+vsaNGwsO2KpVq2Tq1KmCL2VDQkI83ldWGsSX2TB8yZ0T88/KmBzVyWydKOA6osY8EiABEiABEiABEiABEsjjBNatW6dmUL9+fbdm0qNHD8GR07ZhwwbVRalSpSje5jRstk8CJEACJJBjBLRAiA7Kly+fY/1kteG9e/eqqgiJlNPx8CFCwrwpTIGevzeNSUGye9HjdLZOFHDtgN3oyyKFi5hDsP5gBQYWVfl4lI1GAiRAAiRAAiRAAiRAAhkRwEZmW7duVUVq166dUVHB5iPwmLG3unXrSlBQkH22x663b9+u2qpevbrH2mRDJEACJOBNBPAo+aFDhyQwMFAqV65sMzRs+gSvSHzuxxMPjuzw4cPqSYXjx49LSkqKCjODR9WrVq2qvCkd1Tl37pyqYxXSEIcUHpHODN6j165dU4/+FylSRI0Z4XROnTol5cqVU96VnvAsxTzi4+PVI/Z42gNhc/CYfWZ/B/Bo+ebNm+X06dNSo0YNNX+MDUfx4sUdxmpHTPWdO3cKOOCxfgirderUUX3ac0A8dowLVrNmTUlKSlLhhMAfdcDbqs+g3J49ewSsYfoLUzDWYYjUDeMlOjraY16f+HuNv+1HjhxRc8da4UtQ/J23xrnHWmqPYIwDIZVgWEP9v4G+rlatmroHXvrvMhg72nwMa6bfVwgTgU3K7E3ft3+/25fT1+6sk66DM8Iv4UkevKcw1pIlSwrm4khA1wI73mv4uduxY4f62cPPEtY3o/d2Vn6eXJ2Tu+vkZ1S4ZoXANAmQAAmQAAmQAAmQAAmQwI0noD1UMxNgHY1048aN8q9//UvdwgdLRx+ydD18aL3lllv0pXnG5mL40JoTdvXqVXnhhRdU03fccYfUq1cvJ7phmyRAAiRwQwn89NNPgk0kEdt75MiRNmNZs2aN2vgJj7W/+eabNgJhcnKyIEa4vRioG8DvzLvvvltfmme0icfX8TvWavgybujQoUqMteYjDXEU/cOGDBmixgQB02oQNRE7NTv2xhtvKNHRURsQicHHXkjDPL7//nvZsmWLTTWIorgHgRaP7g8YMMDmPmKefvvtt4LQBlYDa/zNadiwoTVbiZ2IYQu77bbbZPr06Tb3IZSOGjXKRiTF3zCsU2b2/PPP29TLrLyz+5s2bZIpU6Y47fOZZ54xQxZA1HzrrbecNWXm433x4osvqmvrRl9YC0fx6BGWCf+bQKjG/O3/t4DAjHHA/v3vfytxVF04eXF3ndAMvhAZN26cEm4dNduvXz9p1qyZeQviPNYA1qVLF5k/f75AYLUa3tt4j9tbVn6e3JmTu+vk/CsY+5HzmgRIgARIgARIgARIgARIIE8Q0B428KKx/4BlPwF8MH388cdVNjycZs+erdJ6QxL78p64xgcwbY4+JOp7PJMACZBAXiagH4l2tJmT9goMCwuzEW8x32+++cb0dIQnIzwLIZqhPYiZeMTa3vCl28KFC1U2+oNXLzx84VUJIROC5tNPP53Oc1ePAxUnT56svE/hxVihQgXluYr6pUuXVu1m9UV7yxYuXFiNC+PXHp8QvPA3YdasWdKrVy+zCwi0EFW1iI35YBx4YkR7y6KwPVt4m2KuMHilNm3aVHnurl+/XvWJzbzAFB6b2qwMIN7iy0u0i74TExPV5mSLFy+Wnj17qirwg2zRooXyWkbG33//rfKjoqKkUqVKKo0XrJnVM9a84WYC44OQDYPoir/tCAcA8R2CKgR3eDNrg1Ddrl07dQn2+gvh5s2bC/7ma4Nwrg1e4riHJ3jwPrP/23zw4EGzHXBw9L8FWGmzXxedr89ZWScI5v/73//UOoItfi7AHF61eJ+Ck/17Fe8vbfj/Bh7LeMII3tXaM3nmzJnpBNys/Dy5Oyd314kCrl5JnkmABEiABEiABEiABEjARwjoD2sxMTGZzggfNuGZBfvqq6+UgItNzBw9PplpYy4W0AIzPixaP0S7WJ3FSIAESMDrCUDkw6PuMEdiljNxF155+jH0Bx54IF14AYQDgKej1fAouRZvu3btKh07djRvQ+wcM2aM8n6FoAvBy2pW8RIC2YMPPmhTBiIhRL3sGDxr4eUI4dEaiqBbt27y0UcfqUfhraIs+lq2bJkp3t55552m1yxitD/33HOml7FVaIS35cSJE9VQ4aV7//33m3/LevfurTwxIQz/888/NrHe9VqgYt++fQVCJ6x79+7y0ksvqfkfO3ZM5eEFc9Cx4uG5qgVczCcnvvxcvny56hvC+qOPPmojwuMJGoiUEAO1YfMwLTbjiRz9P0GfPn1s+Ovy+gyWCC+A8BCtWrXS2eoMb3IY/ma3bNlSpe1fUA+Gv+0IbeHMsrpOeKIIwj/m+uyzz9qEecL7HgJymTJlbLq1CrgIJTJw4ECT1fjx41VoDoQ6sVpWfp6yMid31yltha2jZZoESIAESIAESIAESIAESCDPEtDx+OBl4o7px1Td3fjMnT4QwxCeTLCc7MedMbEsCZAACXiaAEQhiIUwq1em7gcejTB7cRcek9oc7YEDYcz6xRf60N6Z8C7s0KGDrq7OEGzh+QqzPv2gMowXq3gJwdhe4IXI5CiuqK7vyhnzwCPqVvFW19N/pzQr5EP8njdvnioCD1pryAN8uajjtqKAdWy///67Elsh8CFUgvWLyICAADPWsD0HLfJB9NXiLdrGeHX7Vs9V3NOm6+IaXss5YdqzFV6vVqEWfWGMVhHbvn+9vs42xrKW1+9FXUffw/8Gep4Iz+RoHVFWf/GQ0XhQLqvrpIVWMMB62hvWCp65VtOiMn4G+vfvb8NP/1zqnw/Uy+rPU1bnpMeqmWe0TrYz0zV5JgESIAESIAESIAESIAESyJME8Cil/hDlbvxcPGIKc7ahTlaBwGPsjz/+UI+x6g8pECE6d+6c1SZZjwRIgAS8moD2bIXYZP9YN7xatWBpL3bBgxN1cP/TTz9V3o4QFe09C/Xk4bmqhS14uOrf4/o+zhCo4F3ryJNWC8nwTswJ71E9DoiQ8KqFVzLGq+OQwoMVFhoaqouqjbZ0/FodCsC8aSS0dyeEbC3Sor0VK1aoYhBSscmVvWnPZSsHPH6vx2DvdYr6R48eVc1Yww1Y29V/0xDCwD6Gr7VcdtL4mwwBFTF/P/nkE2nTpo3auMyV/rSAqcXZjMahy2B9wAps8T6cNm2aqobN5iByOzP9vwdCVDizrK4T2sOGY/A0RxvvvPOOtG3bVvDEkKMvOnT/+ucQTyTZi74IowCzhiTJys9Tduakx+nKOlHA1bR4JgESIAESIAESIAESIAEfIKBjumEqGX3Qsp8qPGO1VxJEAE8aPuBiAxZt8JAZMWKE2pld5/FMAiRAAr5EQAtHjjzqtOiH+VrFI1zj9yMez58xY4YSqhYtWiQ4IBDeeuut6TZ9tLaF0AA4nJkWPvV9iKR6Iy4IYTlhEALxqHpsbGy65rVQjRuI6apNs8Oc7fmgDMJMwKyCsxaikQ+x88cff0TSoVnjxWrPUhSEQGk1sNFCsvbWtN5HWvO3F+Lty2XnGgL+2rVr1bzRHzYTgzVp0kSFebBfV2tfCAcA0+Ks9Z592joH8MT10qVLVYxdlEUIBmeGEAL4PwJmXRf78lldJ90uvphGGCb0Ba9XHBCMsfmc9T2E8hBWtUe7oy+0Ha2dzkN9V3+esjMn9ANzZZ0o4Kay4isJkAAJkAAJkAAJkAAJ+AQBHQYB3lT23iYZTRAbgGizf4RW52f1XKVKFRk0aJDaUAcfBvGhCjtBIyYhjQRIgAR8kYAWghyJWdrbDl61EDHtDZ6FCBsA4RYxTCFCQbBCqARrjFbU0/1AvIKHYkZmDT2AclooRdr+HvI8Ydg0TIu3iNeqPSbxGD48X19++WXVjVU81LGDEb7B3uARqsdtFSV1HkIdgF9Ghk3KtGl+jjxoreKuMwFXl7GORbftqTM2QnvqqafUe2H16tVqwy5wQBqbj77yyisOwxrgiRz8vYW5Mj5skKa9tcEF709s8AUDU6uXtMq0vGgOyLKupaWISmZ1nXQ79957rxLoEYoJQi5Ednj+IpYyGCGMiDYdegLX9mMCP/1FgJWNfj+48/OU3Tm5uk4UcPXK8kwCJEACJEACJEACJEACPkAAH+Zg1piBrkxL7/QNLxVXHst0pU1dBrtb4xFQHHgcFWIxNkqhkQAJkICvEtBPNDgS/vQTCVbhyJ4DRDsInjiw+Rg2mYQYhw2trHFatdiJJyc6depk30yG11p4QigC+9ihGVZ08ea5c+fMDbQQfxTxbK1mDfdgFdj0hmGI+WpvEIO1KGmtox+HR7gKdzhowc7alu5T89HCps7XZ6uHbkZrqctn94y48TgQ9gGepxBwEQ4CoRUcffGqx49+nYWAsB8ThEu0hy8ZsA5gDVG3S5cu9kVtrjVHsHK0brpwVtdJ18cZP1PYjAwi7KpVq+Tnn39Wt1euXKk8knVZPSaI+vZhFvTPJ8pa1z4rP0/ZnZOr65T+qx49U55JgARIgARIgARIgARIgATyHAF80Ic5i5fobEJWz11nZTyRrx9dhahLIwESIAFfJIBNuHRoAgixVkOYG/2ouauiH55iqFevnmoGj6pbTW9oZn2M23o/o7QWuKwCVkbl3b2nPY1RD5uYWQ0i5KxZs1QWBEIIf9q02AYh0WoIx6DrIN+6aZj21sWXhBD2XDUtnjlaC83HkQiP9rVwh7SrAinKZtcgkHbv3t1sxv49oW9oD1T83XXk6a3LWc+aA74MxhMzMITuyOyJHi18ZhTOAW1ldZ1Q194wJ3yZod879hz0+tmHVkA7et3xxYX1ZzQrP0/ZnZOr60QB1/4dwGsSIAESIAESIAESIAESyMME9IYu8M7RH15cmc66detUMU9vYGbftxYZ9M7e9vd5TQIkQAJ5nQAEXG36dyuu8TtZxy/Ftb1wCsEMj4ZbhSi0hY2VNmzYgCqmkKsujBfdBoRhbOJlrQvBE/W+/PJLtSmVrqPP+rF3R2EedJnsnPXfI7ShvY6RRkiIzz//3NxUzV5g09cQwRFuB3PCZpiIpatFU4huVlFRi6yog023UN5qeMwe7K2iMtrVMW41R2sdLfJpUdN6D2nrZmj6y1P7Mtm5xvgQNkOvk24LoSd+/fVXdQkR05H3LW7q8eELA3seui37s34vaC9nfBmMWLuZmV5riJF4vzoT0bOyTuj7l19+UeEirD9bGCN+XvQa6i859Fj1/0CO1lbf0+81XUeXdefnKatz0n26uk4MoaCJ8UwCJEACJEACJEACJEACPkAAO3bjgzJCIuCRR+3JNGTIEBk2bJiaIT7U33fffeZjqMjEh1sYHtPVHwxxjQ/Z2msW19k17WmiP/Bktz3WJwESIAFvIwBRDfFCT5w4IQgTgMf+8Ri39rzV47X/ImvNmjVKrPvjjz/UUxT4/Q2hSYtpaLN9+/a6ujp36NBBeUqiDB4lx4HfrxAyEeMTQhr61gKbrgwPWAiBMC1a6XueOkP4hIcjxoa/KxDbMBZs2GT1CLUXSDHHJUuWqLHD49bqdavHZv83BDF80Q54QcjGAfERIi9CAWiPaKvnqlUYtW8PY9br5YyP1QN43Lhxaq766ZL/+7//Mz1D9ZjdPWN8+HuOA16m2NANY9KxW9EeNhazCtnWPrC5F+Iow0aPHq3Yoyw8Rh966CFrUTNtP1eEvkC84swMHtZgDhszZow6Y43DwsLkscceU9d4yco64T2M0CE48H7SPzdaYEe7iPtvjW2MOpqTFqVRTpsWcO3fe1n5ecrKnPQ4cHZ1neiBa6XGNAmQAAmQAAmQAAmQAAnkcQIQaZ955hnROy4jBiEOq5cJvGARKw67WutDTxsfiHQeRGDro4W6TFbP+OCpvXKs48lqe6xHAiRAAt5K4K677jIfq4d4iN9/2MBLx2eFGGsvqiJ+K0Qv/J6EpylCCEBIRB42kXr00UeVCGedMx6nf+SRR2x+x0P406EEIKAhjq69aU9W5OfU72OMDV8WIkQCDIIaxFs8po4xa7MX0SBWPvzwwzYbUiFEAZhqgTQ6OlpXN8+DBw+WmJgY8xoM0B/4o83WrVvbbMSlv1BEm3qMurKVj724q8ugTcwP/LBGWCtsSAWPUP3lqS6b1bN+pB9t4v2gRUnwGDp0qDRr1sxp03Xr1pUePXqYX8LC0xPjw1idGUIg6Pt4IgfioiuGDfQGDBhg817C+1iHF7C24e46Ydz6PQrG+D9Fi7dYO4jYd955p7ULJdrrDEfrh/cGzP69l9WfJ3fnpMeGs6vr5Ge4H6f59ltbYJoESIAESIAESIAESIAESOCGEdCPy2oh9oYNxIMd49FV7ZnzxBNP2HyQ9mA3bIoESIAEvIYAwgXggGejvWDraJAQvSAuQfCF5yMEPEdir6O6EPkQixSP3kOIQz0IUjfaILph0yh4/EKIc0fcxBMjMLCDqPree++p6+eee84UJlWG5QWCH7xuETYAAh9ERE9+GWnpKleSWFcIt+AH0Rjr6g5DdwaJTcGmTp2qqmTE2J02nZV1d53wvsbPBtYVm63iCw+sqysews7GkFF+Vn6e3J1TRv3b32MIBXsivCYBEiABEiABEiABEiABEsgRAlYhAfHssPkIHgmFhxiNBEiABHyRAARY7UXpyvzg/YjfiVn5vQhxD4e3GR57d+QF6WycEG212K3PKDt9+nRVBX83MgrtgzAN7vTnbBzekp9b6wqRGCE4YB07dsyQsSfYuLtOCP+gPXE90X9mbWSFu7tzymwM1vsUcK00mCYBEiABEiABEiABEiABEsgxAohHiA/e8BDDhi84cI3HgmkkQAIkQAIkgIfEX3jhBbVZG+KawtsUj/0vWLBAEhISFKCBAwcSlIcIwMt0x44dKiQBvG/hAQ6vVh3qw0PdsBkPEKCA6wGIbIIESIAESIAESIAESIAESCBzAnjMEXENt2zZIojDi8dBHW0uknlLLEECJEACJOCLBBAmASEX1q1bpw7rHOGdjE21ctML09q/L6Y3btxos3EpvMVHjBhhekD74pzz6pwYAzevrhzHTQIkQAIkQAIkQAIk4NMEfDEGrk8vGCdHAiRAAiSQbQKIc4ov+eLj41Uc4JSUFLWZGTbtatq0qVfE9M32JL2oAbDGgRBH+EK1Zs2aglAFNO8jQAHX+9aEIyIBEiABEiABEiABEiABoYDLNwEJkAAJkAAJkAAJkAAI+BMDCZAACZAACZAACZAACZAACZAACZAACZAACZAACZCAdxKggOud68JRkQAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAA9cPkeIAESIAESIAESIAESIAESIAESIAESIAESIAESIAFvJUAPXG9dGY6LBEiABEiABEiABEiABEiABEiABEiABEiABEgg3xMomO8JeBGAq1euCg6r+fn7SYGCBaxZTJMACZAACZAACZAACZAACZAACZAACZAACZAACeQTAhRwvWihF36yUBZ+vMBmRGWiy8rIWSNt8nhBAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQPwhQwPWidQ6pFCJVW1RVIzp9KEmO7zrmRaPjUEiABEiABEiABEiABEiABEiABEiABEiABEiABHKbAAXc3CaeQX8xfWMEB2zTjE0y9f+mZFCat0iABEiABEiABEiABEiA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"/><use stroke="#7E7C7B" xlink:href="#rect-1"/></g><g id="Default"><use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/><path fill="#FFF" stroke="#A7333A" d="M141.5 50.775l15.69 16.01h-6.488c.886 1.695 3.06 5.91 4.01 8.24.318.776-.979 2.324-.979 2.324h0l-2.42.151-4.2-8.574-5.613 5.727V50.775z"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/03-dom-navigation/1-dom-children/solution.md b/2-ui/1-document/03-dom-navigation/1-dom-children/solution.md index decfa62c7d..4352655b5f 100644 --- a/2-ui/1-document/03-dom-navigation/1-dom-children/solution.md +++ b/2-ui/1-document/03-dom-navigation/1-dom-children/solution.md @@ -1,27 +1,27 @@ -There are many ways, for instance: +๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. -The `<div>` DOM node: +`<div>` DOM ๋…ธ๋“œ: ```js document.body.firstElementChild -// or +// ๋˜๋Š” document.body.children[0] -// or (the first node is space, so we take 2nd) +// ๋˜๋Š” (์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋Š” ๊ณต๋ฐฑ์ด๋ฏ€๋กœ ๋‘ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ด) document.body.childNodes[1] ``` -The `<ul>` DOM node: +`<ul>` DOM ๋…ธ๋“œ: ```js document.body.lastElementChild -// or +// ๋˜๋Š” document.body.children[1] ``` -The second `<li>` (with Pete): +๋‘ ๋ฒˆ์งธ `<li>` (Pete): ```js -// get <ul>, and then get its last element child +// <ul>์„ ๊ฐ€์ ธ์˜ค๊ณ , <ul>์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด document.body.lastElementChild.lastElementChild ``` diff --git a/2-ui/1-document/03-dom-navigation/1-dom-children/task.md b/2-ui/1-document/03-dom-navigation/1-dom-children/task.md index d97f2748a7..325d46772f 100644 --- a/2-ui/1-document/03-dom-navigation/1-dom-children/task.md +++ b/2-ui/1-document/03-dom-navigation/1-dom-children/task.md @@ -2,14 +2,14 @@ importance: 5 --- -# DOM children +# ์ž์‹ DOM -Look at this page: +์•„๋ž˜ ํŽ˜์ด์ง€๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html <html> <body> - <div>Users:</div> + <div>์‚ฌ์šฉ์ž:</div> <ul> <li>John</li> <li>Pete</li> @@ -18,7 +18,7 @@ Look at this page: </html> ``` -For each of the following, give at least one way of how to access them: -- The `<div>` DOM node? -- The `<ul>` DOM node? -- The second `<li>` (with Pete)? +์•„๋ž˜ DOM ๋…ธ๋“œ์— ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์„ ์ตœ์†Œ ํ•œ ๊ฐ€์ง€ ์ด์ƒ์”ฉ ์ƒ๊ฐํ•ด๋ณด์„ธ์š”. +- `<div>` DOM ๋…ธ๋“œ +- `<ul>` DOM ๋…ธ๋“œ +- ๋‘ ๋ฒˆ์งธ `<li>` (Pete) diff --git a/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/solution.md b/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/solution.md index d76936320c..8e3adf0456 100644 --- a/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/solution.md +++ b/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/solution.md @@ -1,6 +1,6 @@ -1. Yes, true. The element `elem.lastChild` is always the last one, it has no `nextSibling`. -2. No, wrong, because `elem.children[0]` is the first child *among elements*. But there may exist non-element nodes before it. So `previousSibling` may be a text node. +1. ๋„ค ๋งž์Šต๋‹ˆ๋‹ค. `elem.lastChild`๋Š” ํ•ญ์ƒ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— `nextSibling`์ด ์—†์Šต๋‹ˆ๋‹ค. +2. ์•„๋‹™๋‹ˆ๋‹ค. `elem.children[0]`์€ *์š”์†Œ ๋…ธ๋“œ ์ค‘* ์ฒซ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ์•ž์— ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊ฐ€ ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `previousSibling`์€ ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -Please note: for both cases if there are no children, then there will be an error. +์ฃผ์˜ ์‚ฌํ•ญ: ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -If there are no children, `elem.lastChild` is `null`, so we can't access `elem.lastChild.nextSibling`. And the collection `elem.children` is empty (like an empty array `[]`). +์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด `elem.lastChild`์€ `null`์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— `elem.lastChild.nextSibling`์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ปฌ๋ ‰์…˜ `elem.children`์€ ๋นˆ ๋ฐฐ์—ด `[]`๊ฐ™์ด ๋นˆ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/task.md b/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/task.md index 235e83a0ca..2c7463b4f1 100644 --- a/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/task.md +++ b/2-ui/1-document/03-dom-navigation/3-navigation-links-which-null/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# The sibling question +# ํ˜•์ œ ๋…ธ๋“œ์— ๊ด€ํ•œ ์งˆ๋ฌธ -If `elem` -- is an arbitrary DOM element node... +์ž„์˜์˜ DOM ์š”์†Œ ๋…ธ๋“œ `elem`์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. -- Is it true that `elem.lastChild.nextSibling` is always `null`? -- Is it true that `elem.children[0].previousSibling` is always `null` ? +- `elem.lastChild.nextSibling`์€ ํ•ญ์ƒ `null`์ผ๊นŒ์š”? +- `elem.children[0].previousSibling`์€ ํ•ญ์ƒ `null`์ผ๊นŒ์š”? diff --git a/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/solution.md b/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/solution.md index f2aa86302a..187e7e1581 100644 --- a/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/solution.md +++ b/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/solution.md @@ -1 +1 @@ -We'll be using `rows` and `cells` properties to access diagonal table cells. +`rows`์™€ `cells` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•ด ํ…Œ์ด๋ธ”์˜ ๋Œ€๊ฐ์„  ์…€์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/task.md b/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/task.md index 23be59fc19..eccfd3d822 100644 --- a/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/task.md +++ b/2-ui/1-document/03-dom-navigation/4-select-diagonal-cells/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Select all diagonal cells +# ๋ชจ๋“  ๋Œ€๊ฐ์„  ์…€ ์„ ํƒํ•˜๊ธฐ -Write the code to paint all diagonal table cells in red. +ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋Œ€๊ฐ์„  ์…€์„ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ์น ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”. -You'll need to get all diagonal `<td>` from the `<table>` and paint them using the code: +`<table>`์—์„œ ๋ชจ๋“  ๋Œ€๊ฐ์„  `<td>`๋ฅผ ๊ฐ€์ ธ์™€ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์น ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js -// td should be the reference to the table cell +// td๋Š” ํ…Œ์ด๋ธ” ์…€์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. td.style.backgroundColor = 'red'; ``` -The result should be: +๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. [iframe src="solution" height=180] diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md index 090a81e4be..8b759337f3 100644 --- a/2-ui/1-document/03-dom-navigation/article.md +++ b/2-ui/1-document/03-dom-navigation/article.md @@ -7,35 +7,35 @@ libs: # DOM ํƒ์ƒ‰ํ•˜๊ธฐ -DOM(๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ)์„ ์ด์šฉํ•˜๋ฉด ์š”์†Œ์™€ ์š”์†Œ์˜ ์ปจํ…์ธ ์— ๋ฌด์—‡์ด๋“  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ธฐ ์ „์— DOM ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์„ ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +DOM์„ ์ด์šฉํ•˜๋ฉด ์š”์†Œ์™€ ์š”์†Œ์˜ ์ฝ˜ํ…์ธ ์— ๋ฌด์—‡์ด๋“  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ธฐ ์ „์—”, ๋‹น์—ฐํžˆ ์กฐ์ž‘ํ•˜๊ณ ์ž ํ•˜๋Š” DOM ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์„ ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -DOM์— ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์—ฐ์‚ฐ์€ `document` ๊ฐ์ฒด์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `document` ๊ฐ์ฒด๋Š” DOM์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ "์ง„์ž…์ (entry point)"์ด์ฃ . ์—ฌ๊ธฐ๋ฅผ ํ†ตํ•˜๋ฉด ์–ด๋–ค ๋…ธ๋“œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +DOM์— ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์—ฐ์‚ฐ์€ `document` ๊ฐ์ฒด์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `document` ๊ฐ์ฒด๋Š” DOM์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ '์ง„์ž…์ '์ด์ฃ . ์ง„์ž…์ ์„ ํ†ต๊ณผํ•˜๋ฉด ์–ด๋–ค ๋…ธ๋“œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์€ DOM ๋…ธ๋“œ ํƒ์ƒ‰์ด ์–ด๋–ค ๊ด€๊ณ„๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง€๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ![](dom-links.svg) -์ด ๊ด€๊ณ„์— ๋Œ€ํ•˜์—ฌ ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. +ํ™”์‚ดํ‘œ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ด€๊ณ„์— ๋Œ€ํ•˜์—ฌ ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค. -## ๊ผญ๋Œ€๊ธฐ์˜ documentElement ์™€ body +## ํŠธ๋ฆฌ ์ƒ๋‹จ์˜ documentElement์™€ body -DOM ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์˜ ๋…ธ๋“œ๋Š” `document` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +DOM ํŠธ๋ฆฌ ์ƒ๋‹จ์˜ ๋…ธ๋“œ๋“ค์€ `document`๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `<html>` = `document.documentElement` -์ตœ์ƒ๋‹จ์˜ ๋ฌธ์„œ ๋…ธ๋“œ๋Š” `document.documentElement` ์ž…๋‹ˆ๋‹ค. ์ด ๋…ธ๋“œ๋Š” `<html>` ํƒœ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” DOM ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +: `document`๋ฅผ ์ œ์™ธํ•˜๊ณ  DOM ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์— ์žˆ๋Š” ๋ฌธ์„œ ๋…ธ๋“œ๋Š” `<html>` ํƒœ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” `document.documentElement`์ž…๋‹ˆ๋‹ค. `<body>` = `document.body` -`document.body`๋Š” `<body>` ์š”์†Œ์— ํ•ด๋‹นํ•˜๋Š” DOM ๋…ธ๋“œ๋กœ, ์ž์ฃผ ์“ฐ์ด๋Š” ๋…ธ๋“œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. +: `document.body`๋Š” `<body>` ์š”์†Œ์— ํ•ด๋‹นํ•˜๋Š” DOM ๋…ธ๋“œ๋กœ, ์ž์ฃผ ์“ฐ์ด๋Š” ๋…ธ๋“œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. `<head>` = `document.head` -`<head>` ํƒœ๊ทธ๋Š” `document.head`๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +: `<head>` ํƒœ๊ทธ๋Š” `document.head`๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -````warn header="`document.body`๊ฐ€ `null`์ผ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ, ์ฃผ์˜ํ•˜์„ธ์š”." -์‹คํ–‰ ์‹œ์ ์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์š”์†Œ๋Š” ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +````warn header="`document.body`๊ฐ€ `null`์ผ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•˜์„ธ์š”." +์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฝ๋Š” ๋„์ค‘์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์š”์†Œ๋Š” ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -ํŠนํžˆ, ์Šคํฌ๋ฆฝํŠธ๊ฐ€ `<head>` ์•ˆ์— ์žˆ์„ ๋•Œ, `document.body`๋Š” ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„์ง `document.body`๋ฅผ ์ฝ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . +๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„์ง `document.body`๋ฅผ ์ฝ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— `<head>` ์•ˆ์— ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ์—์„  `document.body`์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜์ฃ . -์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์—, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ์ฒซ ๋ฒˆ์งธ `alert`๋Š” `null`์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ์ฒซ ๋ฒˆ์งธ `alert` ์ฐฝ์—” `null`์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html run <html> @@ -43,7 +43,7 @@ DOM ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์˜ ๋…ธ๋“œ๋Š” `document` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ <head> <script> *!* - alert( "From HEAD: " + document.body ); // null, there's no <body> yet + alert( "HEAD: " + document.body ); // null, ์•„์ง <body>์— ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜์Œ */!* </script> </head> @@ -51,7 +51,7 @@ DOM ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์˜ ๋…ธ๋“œ๋Š” `document` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ <body> <script> - alert( "From BODY: " + document.body ); // HTMLBodyElement, now it exists + alert( "BODY: " + document.body ); // HTMLBodyElement, ์ง€๊ธˆ์€ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์Œ </script> </body> @@ -59,103 +59,103 @@ DOM ํŠธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์˜ ๋…ธ๋“œ๋Š” `document` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ ``` ```` -```smart header="DOM ์„ธ๊ณ„์—์„œ `null`์€ \"์กด์žฌํ•˜์ง€ ์•Š์Œ\"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค" -DOM์—์„œ `null`๊ฐ’์€ "์กด์žฌํ•˜์ง€ ์•Š์Œ"์ด๋‚˜ "ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ์—†์Œ"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +```smart header="DOM์˜ ๋‚˜๋ผ์—์„œ `null`์€ \'์กด์žฌํ•˜์ง€ ์•Š์Œ\'์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค." +DOM์—์„œ `null` ๊ฐ’์€ '์กด์žฌํ•˜์ง€ ์•Š์Œ'์ด๋‚˜ 'ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ์—†์Œ'์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ``` ## childNodes, firstChild, lastChild๋กœ ์ž์‹ ๋…ธ๋“œ ํƒ์ƒ‰ํ•˜๊ธฐ ์•ž์œผ๋กœ ์‚ฌ์šฉํ•  ๋‘ ๊ฐ€์ง€ ์šฉ์–ด๋ฅผ ๋จผ์ € ์ •์˜ํ•˜๊ณ  ์„ค๋ช…์„ ์ด์–ด๋‚˜๊ฐ€๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -- **์ž์‹ ๋…ธ๋“œ(child node, children)**๋Š” ๋ฐ”๋กœ ์•„๋ž˜์˜ ์ž์‹ ์š”์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ๋ฐ”๋กœ ์•„๋ž˜์—์„œ ์ค‘์ฒฉ ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. `<head>`์™€ `<body>`๋Š” `<html>`์š”์†Œ์˜ ์ž์‹ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. -- **ํ›„์† ๋…ธ๋“œ(descendants)**๋Š” ์ค‘์ฒฉ ๊ด€๊ณ„์— ์žˆ๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ, ์ž์‹ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ ๋“ฑ์ด ํ›„์† ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +- **์ž์‹ ๋…ธ๋“œ(child node, children)** ๋Š” ๋ฐ”๋กœ ์•„๋ž˜์˜ ์ž์‹ ์š”์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ๋ฐ”๋กœ ์•„๋ž˜์—์„œ ์ค‘์ฒฉ ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. `<head>`์™€ `<body>`๋Š” `<html>`์š”์†Œ์˜ ์ž์‹ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +- **ํ›„์† ๋…ธ๋“œ(descendants)** ๋Š” ์ค‘์ฒฉ ๊ด€๊ณ„์— ์žˆ๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ, ์ž์‹ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ ๋“ฑ์ด ํ›„์† ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -์•„๋ž˜์—์„œ `<body>`๋Š” `<div>`์™€ `<ul>` (๊ทธ๋ฆฌ๊ณ  ๋ช‡ ๊ฐœ์˜ ๋นˆ ํ…์ŠคํŠธ ๋…ธ๋“œ)์„ ์ž์‹ ๋…ธ๋“œ๋กœ ๊ฐ–์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `<body>`๋Š” `<div>`์™€ `<ul>`, ๋ช‡ ๊ฐœ์˜ ๋นˆ ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์ž์‹ ๋…ธ๋“œ๋กœ ๊ฐ–์Šต๋‹ˆ๋‹ค. ```html run <html> <body> - <div>Begin</div> + <div>์‹œ์ž‘</div> <ul> <li> - <b>Information</b> + <b>ํ•ญ๋ชฉ</b> </li> </ul> </body> </html> ``` -`<div>`๋‚˜ `<ul>`๊ฐ™์€ `<body>`์˜ ์ž์‹ ์š”์†Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `<li>`(`<ul>`์˜ ์ž์‹ ๋…ธ๋“œ)๋‚˜ `<b>`(`<li>`์˜ ์ž์‹ ๋…ธ๋“œ)๊ฐ™์ด ๋” ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์ค‘์ฒฉ ์š”์†Œ๋„ `<body>`์˜ ํ›„์† ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +`<div>`๋‚˜ `<ul>`๊ฐ™์€ `<body>`์˜ ์ž์‹ ์š”์†Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `<ul>`์˜ ์ž์‹ ๋…ธ๋“œ์ธ `<li>`์™€ `<b>`๊ฐ™์ด ๋” ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์ค‘์ฒฉ ์š”์†Œ๋„ `<body>`์˜ ํ›„์† ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. **`childNodes` ์ปฌ๋ ‰์…˜์€ ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.** -์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด `document.body`์˜ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด `document.body`์˜ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html run <html> <body> - <div>Begin</div> + <div>์‹œ์ž‘</div> <ul> - <li>Information</li> + <li>ํ•ญ๋ชฉ</li> </ul> - <div>End</div> + <div>๋</div> <script> *!* for (let i = 0; i < document.body.childNodes.length; i++) { - alert( document.body.childNodes[i] ); // Text, DIV, Text, UL, ..., SCRIPT + alert( document.body.childNodes[i] ); // Text, DIV, Text, UL, ... , SCRIPT } */!* </script> - ...more stuff... + ...์ถ”๊ฐ€ ๋‚ด์šฉ... </body> </html> ``` -ํฅ๋ฏธ๋กœ์šด ์ ์ด ํ•˜๋‚˜ ๋ฐœ๊ฒฌ๋˜์—ˆ๋„ค์š”. ๋งˆ์ง€๋ง‰ ์š”์†Œ๋กœ `<script>`๊ฐ€ ์ถœ๋ ฅ๋œ ๊ฒƒ์„ ํ™•์ธํ•˜์…จ์„ ๊ฒ๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋‚ด `<script>` ์•„๋ž˜ ๋” ๋งŽ์€ ์š”์†Œ(...more stuff...)๊ฐ€ ์žˆ์ง€๋งŒ, ์Šคํฌ๋ฆฝํŠธ๋Š” ์ด ์š”์†Œ๋ฅผ ๋ณด์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์—” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์Šคํฌ๋ฆฝํŠธ ์•„๋ž˜์˜ ์š”์†Œ๋ฅผ ์ฝ์ง€ ์•Š์€ ์ƒํƒœ์ด๊ธฐ ๋•Œ์ด์ฃ . +์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํฅ๋ฏธ๋กœ์šด ์ ์ด ํ•˜๋‚˜ ๋ฐœ๊ฒฌ๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์— `<script>`๊ฐ€ ์ถœ๋ ฅ๋˜์ฃ . `<script>` ์•„๋ž˜ ๋” ๋งŽ์€ ๋‚ด์šฉ(...์ถ”๊ฐ€ ๋‚ด์šฉ...)์ด ์žˆ์ง€๋งŒ, ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์‹œ์ ์—” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ถ”๊ฐ€ ๋‚ด์šฉ์€ ์ฝ์ง€ ๋ชปํ•œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธ ์—ญ์‹œ ์ถ”๊ฐ€ ๋‚ด์šฉ์„ ๋ณด์ง€ ๋ชปํ•ด์„œ ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. **`firstChild`์™€ `lastChild` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ, ๋งˆ์ง€๋ง‰ ์ž์‹ ๋…ธ๋“œ์— ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** -์ด ํ”„๋กœํผํ‹ฐ๋“ค์€ ๋น ๋ฅธ ์ ‘๊ทผ์„ ๋„์™€์ฃผ๋Š” ์—ญํ• ๋งŒ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ, ์•„๋ž˜ ๋น„๊ต๋ฌธ์€ ํ•ญ์ƒ ์ฐธ์ด ๋ฉ๋‹ˆ๋‹ค. +์ด ํ”„๋กœํผํ‹ฐ๋“ค์€ ๋‹จ์ถ•ํ‚ค ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ์•„๋ž˜ ๋น„๊ต๋ฌธ์€ ํ•ญ์ƒ ์ฐธ์ด ๋ฉ๋‹ˆ๋‹ค. ```js elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild ``` -์ด ์™ธ์—, ์ž์‹ ๋…ธ๋“œ์˜ ์œ ๋ฌด๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ํŠน๋ณ„ํ•œ ํ•จ์ˆ˜, `elem.hasChildNodes()`๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ ์ž์‹ ๋…ธ๋“œ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•  ๋• ํ•จ์ˆ˜ `elem.hasChildNodes()`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ### DOM ์ปฌ๋ ‰์…˜ -์œ„์—์„œ ์‚ดํŽด๋ณธ `childNodes`๋Š” ๋งˆ์น˜ ๋ฐฐ์—ด ๊ฐ™์•„ ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `childNodes`๋Š” ๋ฐฐ์—ด์ด ์•„๋‹Œ *์ปฌ๋ ‰์…˜(collection)*์ž…๋‹ˆ๋‹ค. iterable(๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ) ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ด์ฃ . +์œ„์—์„œ ์‚ดํŽด๋ณธ `childNodes`๋Š” ๋งˆ์น˜ ๋ฐฐ์—ด ๊ฐ™์•„ ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `childNodes`๋Š” ๋ฐฐ์—ด์ด ์•„๋‹Œ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ(iterable, ์ดํ„ฐ๋Ÿฌ๋ธ”) ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ธ *์ปฌ๋ ‰์…˜(collection)* ์ž…๋‹ˆ๋‹ค. `childNodes`๋Š” ์ปฌ๋ ‰์…˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. 1. `for..of`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js for (let node of document.body.childNodes) { - alert(node); // ์ปฌ๋ ‰์…˜ ๋‚ด์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค + alert(node); // ์ปฌ๋ ‰์…˜ ๋‚ด์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. } ``` - That's because it's iterable (provides the `Symbol.iterator` property, as required). + ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๊ธฐ ๋•Œ๋ฌธ์— `Symbol.iterator` ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์–ด์„œ `for..of`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜์ฃ . 2. ๋ฐฐ์—ด์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ```js run - alert(document.body.childNodes.filter); // undefined (filter ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค) + alert(document.body.childNodes.filter); // undefined (filter ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.) ``` -์ฒซ ๋ฒˆ์งธ ํŠน์ง•์€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ํŠน์ง•๋„ ์ฉ ์ข‹์ง€๋Š” ์•Š์ง€๋งŒ ์ฐธ์„ ๋งŒํ•ฉ๋‹ˆ๋‹ค. `Array.from`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปฌ๋ ‰์…˜์„ ๊ฐ€์ง€๊ณ  "์ง„์งœ" ๋ฐฐ์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด, ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +์ฒซ ๋ฒˆ์งธ ํŠน์ง•์€ ์žฅ์ ์œผ๋กœ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ํŠน์ง•์€ ์ฉ ์ข‹์ง€๋Š” ์•Š์ง€๋งŒ `Array.from`์„ ์‚ฌ์šฉํ•˜๋ฉด '์ง„์งœ' ๋ฐฐ์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์„ ๋งŒํ•ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์— ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `Array.from`์„ ์ ์šฉํ•ฉ์‹œ๋‹ค. ```js run - alert( Array.from(document.body.childNodes).filter ); // ์ด์ œ filter๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + alert( Array.from(document.body.childNodes).filter ); // function ``` ```warn header="DOM ์ปฌ๋ ‰์…˜์€ ์ฝ๋Š” ๊ฒƒ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค." DOM ์ปฌ๋ ‰์…˜์„ ๋น„๋กฏํ•ด ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ ์„ค๋ช…ํ•˜๋Š” *๋ชจ๋“ * ํƒ์ƒ‰์šฉ ํ”„๋กœํผํ‹ฐ๋Š” ์ฝ๊ธฐ ์ „์šฉ์ž…๋‹ˆ๋‹ค. -childNodes[i] = ...`๋ฅผ ์ด์šฉํ•ด ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ต์ฒดํ•˜ ๋Š”๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +`childNodes[i] = ...`๋ฅผ ์ด์šฉํ•ด ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•˜์ฃ . DOM์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ด ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ``` @@ -163,18 +163,18 @@ DOM์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ```warn header="DOM ์ปฌ๋ ‰์…˜์€ ์‚ด์•„์žˆ์Šต๋‹ˆ๋‹ค." ๋ช‡๋ช‡ ์˜ˆ์™ธ์‚ฌํ•ญ์„ ์ œ์™ธํ•˜๊ณ  ๊ฑฐ์˜ ๋ชจ๋“  DOM ์ปฌ๋ ‰์…˜์€ *์‚ด์•„์žˆ์Šต๋‹ˆ๋‹ค*. DOM์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋ฐ˜์˜ํ•œ๋‹ค๋Š” ๋ง์ด์ฃ . -`elem.childNodes`๋ฅผ ์ด์šฉํ•ด ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋„์ค‘์— DOM์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๊ฐ€ ๋”ํ•ด์ง€๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜๋ฉด, ์ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ปฌ๋ ‰์…˜์—๋„ ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. +`elem.childNodes`๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋„์ค‘์— DOM์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜๋ฉด, ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ปฌ๋ ‰์…˜์—๋„ ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ``` -````warn header="์ปฌ๋ ‰์…˜์— `for..in` ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”" -์ปฌ๋ ‰์…˜์€ `for..of`๋ฅผ ์ด์šฉํ•ด ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ฐ€๋” `for..in`์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. +````warn header="์ปฌ๋ ‰์…˜์— `for..in` ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”," +์ปฌ๋ ‰์…˜์€ `for..of`๋ฅผ ์ด์šฉํ•ด ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ฐ€๋” `for..in`์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์ฃ . -`for..in`์€ ์ ˆ๋Œ€ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. `for..in`๋ฐ˜๋ณต๋ฌธ์€ ๊ฐ์ฒด์˜ ๋ชจ๋“  ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์— ๋ฐ˜๋ณต์„ ์‹œํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์—” ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” "์ถ”๊ฐ€" ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด ํ”„๋กœํผํ‹ฐ์— ๊นŒ์ง€ ๋ฐ˜๋ณต๋ฌธ์ด ๋Œ๊ธธ ์›ํ•˜์ง€ ์•Š์œผ์‹ค ๊ฑฐ๋‹ˆ๊นŒ์š”. +`for..in`์€ ์ ˆ๋Œ€ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. `for..in` ๋ฐ˜๋ณต๋ฌธ์€ ๊ฐ์ฒด์˜ ๋ชจ๋“  ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์—” ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” '์ถ”๊ฐ€' ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด ํ”„๋กœํผํ‹ฐ๊นŒ์ง€ ์ˆœํšŒ ๋Œ€์ƒ์— ํฌํ•จํ•˜๊ธธ ์›ํ•˜์ง€ ์•Š์œผ์‹ค ๊ฑฐ๋‹ˆ๊นŒ์š”. ```html run <body> <script> - // shows 0, 1, length, item, values and more. + // 0, 1, length, item, values ๋“ฑ ๋ถˆํ•„์š”ํ•œ ํ”„๋กœํผํ‹ฐ๊นŒ์ง€๋„ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. for (let prop in document.body.childNodes) alert(prop); </script> </body> @@ -184,7 +184,7 @@ DOM์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ๊ฐ™์€ ๋ถ€๋ชจ๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ๋Š” *ํ˜•์ œ(sibling) ๋…ธ๋“œ* ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -`<head>`์™€ `<body>`๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +`<head>`์™€ `<body>`๋Š” ๋Œ€ํ‘œ์ ์ธ ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ```html <html> @@ -192,75 +192,75 @@ DOM์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ </html> ``` -- `<body>`๋Š” `<head>`์˜ "๋‹ค์Œ(next)" ๋˜๋Š” "์šฐ์ธก(right)"์— ์žˆ๋Š” ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. -- `<head>`๋Š” `<body>`์˜ "์ด์ „(previous)" ๋˜๋Š” "์ขŒ์ธก(left)"์— ์žˆ๋Š” ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +- `<body>`๋Š” `<head>`์˜ '๋‹ค์Œ(next)' ํ˜น์€ '์šฐ์ธก(right)'์— ์žˆ๋Š” ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. +- `<head>`๋Š” `<body>`์˜ '์ด์ „(previous)' ํ˜น์€ '์ขŒ์ธก(left)'์— ์žˆ๋Š” ํ˜•์ œ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. -The next sibling is is `nextSibling`, and the previous one is `previousSibling`. +๋‹ค์Œ ํ˜•์ œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” `nextSibling`, ์ด์ „ ํ˜•์ œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” `previousSibling` ํ”„๋กœํผํ‹ฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`parentNode`๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ถ€๋ชจ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” `parentNode` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•ด ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For example: +์˜ˆ์‹œ: -```js +```js run // <body>์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋Š” <html>์ž…๋‹ˆ๋‹ค alert( document.body.parentNode === document.documentElement ); // true -// <head> ๋‹ค์Œ ๋…ธ๋“œ๋Š” <body>์ž…๋‹ˆ๋‹ค. +// <head>์˜ ๋‹ค์Œ ํ˜•์ œ ๋…ธ๋“œ๋Š” <body>์ž…๋‹ˆ๋‹ค. alert( document.head.nextSibling ); // HTMLBodyElement -// <body> ์ด์ „ ๋…ธ๋“œ๋Š” <head>์ž…๋‹ˆ๋‹ค. +// <body>์˜ ์ด์ „ ํ˜•์ œ ๋…ธ๋“œ๋Š” <head>์ž…๋‹ˆ๋‹ค. alert( document.body.previousSibling ); // HTMLHeadElement ``` ## ์š”์†Œ ๊ฐ„ ์ด๋™ -์œ„์—์„œ ์–ธ๊ธ‰๋œ ํƒ์ƒ‰์— ๊ด€ํ•œ ํ”„๋กœํผํ‹ฐ๋Š” *๋ชจ๋“ * ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. `childNodes`๋ฅผ ์ด์šฉํ•˜๋ฉด ํ…์ŠคํŠธ ๋…ธ๋“œ, ์š”์†Œ ๋…ธ๋“œ, ์‹ฌ์ง€์–ด ์ฃผ์„ ๋…ธ๋“œ๊นŒ์ง€ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ๋ง์ด์ฃ . +์ง€๊ธˆ๊นŒ์ง€ ์–ธ๊ธ‰ํ•œ ํƒ์ƒ‰ ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ๋Š” *๋ชจ๋“ * ์ข…๋ฅ˜์˜ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. `childNodes`๋ฅผ ์ด์šฉํ•˜๋ฉด ํ…์ŠคํŠธ ๋…ธ๋“œ, ์š”์†Œ ๋…ธ๋“œ, ์‹ฌ์ง€์–ด ์ฃผ์„ ๋…ธ๋“œ๊นŒ์ง€ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์ฃ . -ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ ํ…์ŠคํŠธ ๋…ธ๋“œ๋‚˜ ์ฃผ์„ ๋…ธ๋“œ๋Š” ์ž˜ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›น ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํƒœ๊ทธ์˜ ๋ถ„์‹ ์ธ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ์กฐ์ž‘ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์ด ๋Œ€๋‹ค์ˆ˜์ด์ฃ . +ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ ํ…์ŠคํŠธ ๋…ธ๋“œ๋‚˜ ์ฃผ์„ ๋…ธ๋“œ๋Š” ์ž˜ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›น ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํƒœ๊ทธ์˜ ๋ถ„์‹ ์ธ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์ž‘์—…์ด ๋Œ€๋‹ค์ˆ˜์ด์ฃ . -์ด๋Ÿฐ ์ ์„ ๋ฐ˜์˜ํ•˜์—ฌ, ์ง€๊ธˆ๋ถ€ํ„ด *์š”์†Œ ๋…ธ๋“œ*๋งŒ์„ ๊ณ ๋ คํ•˜๋Š” ํƒ์ƒ‰ ๊ด€๊ณ„๋ฅผ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์‹ค์ œ ์ƒํ™ฉ์„ ํ† ๋Œ€๋กœ DOM *์š”์†Œ ๋…ธ๋“œ* ํƒ์ƒ‰์ด ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. ![](dom-links-elements.svg) -๊ทธ๋ฆผ ์† ๊ด€๊ณ„๋Š” ์œ„์ชฝ์—์„œ ๋‹ค๋ค˜๋˜ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋…ธ๋“œ ๊ฐ„ ๊ด€๊ณ„์™€ ์œ ์‚ฌํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. `์š”์†Œ(Element)`๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์ถ”๊ฐ€๋œ ์ ๋งŒ ๋‹ค๋ฅด๋„ค์š”. +์œ„ ๊ทธ๋ฆผ ์† ๊ด€๊ณ„๋Š” ์ฑ•ํ„ฐ ์•ž์ชฝ์—์„œ ๋‹ค๋ค˜๋˜ ๊ด€๊ณ„์™€ ์œ ์‚ฌํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. `Element`๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์ถ”๊ฐ€๋œ ์ ๋งŒ ๋‹ค๋ฅด๋„ค์š”. -- `children` ํ”„๋กœํผํ‹ฐ๋Š” ํ•ด๋‹น ์š”์†Œ์˜ ์ž์‹ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `firstElementChild`์™€ `lastElementChild` ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ๊ฐ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ์š”์†Œ์™€ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `previousElementSibling`์™€ `nextElementSibling`๋Š” ํ˜•์ œ ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `parentElement` ๋Š” ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `children` ํ”„๋กœํผํ‹ฐ๋Š” ํ•ด๋‹น ์š”์†Œ์˜ ์ž์‹ ๋…ธ๋“œ ์ค‘ ์š”์†Œ ๋…ธ๋“œ๋งŒ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `firstElementChild`์™€ `lastElementChild` ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ๊ฐ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ์š”์†Œ ๋…ธ๋“œ์™€ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `previousElementSibling`๊ณผ `nextElementSibling`์€ ํ˜•์ œ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `parentElement` ๋Š” ๋ถ€๋ชจ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -````smart header="๋ถ€๋ชจ๊ฐ€ ์š”์†Œ๋ผ๋Š” ๋ณด์žฅ์ด *์—†๋Š”๋ฐ* ์™œ `parentElement`๋ฅผ ์“ฐ๋‚˜์š”?" -`parentElement` ํ”„๋กœํผํ‹ฐ๋Š” ๋ถ€๋ชจ "์š”์†Œ(๋…ธ๋“œ)"๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, `parentNode` ํ”„๋กœํผํ‹ฐ๋Š” "๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋ถ€๋ชจ ๋…ธ๋“œ"๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ฃ . ๋Œ€๋‹ค์ˆ˜์˜ ๊ฒฝ์šฐ์— ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ™์€ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +````smart header="๋ถ€๋ชจ๊ฐ€ ์š”์†Œ๊ฐ€ *์•„๋‹ˆ๋ผ๋ฉด* `parentElement`๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?" +`parentElement` ํ”„๋กœํผํ‹ฐ๋Š” ๋ถ€๋ชจ '์š”์†Œ ๋…ธ๋“œ'๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ˜๋ฉด `parentNode` ํ”„๋กœํผํ‹ฐ๋Š” '์ข…๋ฅ˜์— ์ƒ๊ด€์—†์ด ๋ถ€๋ชจ ๋…ธ๋“œ'๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๊ฐœ ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ™์€ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -`document.documentElement`๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ๋นผ๊ณ  ๋ง์ด์ฃ . +๊ทธ๋Ÿฐ๋ฐ `document.documentElement`์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ```js run alert( document.documentElement.parentNode ); // document alert( document.documentElement.parentElement ); // null ``` -์ด๋ ‡๊ฒŒ ๋ฐ˜ํ™˜ ๊ฐ’์ด ๋‹ค๋ฅธ ์ด์œ ๋Š” `document.documentElement` (`<html>`)์˜ ๋ถ€๋ชจ๊ฐ€ `document`์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `document` ๋…ธ๋“œ๋Š” ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์‹œ์—์„œ `parentNode`๋Š” ์˜๋„ํ•œ ๋Œ€๋กœ `document` ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, `parentElement`๋Š” `document` ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋ฐ˜ํ™˜ ๊ฐ’์ด ๋‹ค๋ฅธ ์ด์œ ๋Š” `<html>`์— ํ•ด๋‹นํ•˜๋Š” `document.documentElement`์˜ ๋ถ€๋ชจ๋Š” `document`์ธ๋ฐ, `document` ๋…ธ๋“œ๋Š” ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์‹œ์—์„œ `parentNode`๋Š” ์˜๋„ํ•œ ๋Œ€๋กœ `document` ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, `parentElement`๋Š” `null`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์‚ฌ์†Œํ•œ ์ฐจ์ด๋Š” ์ž„์˜์˜ ์š”์†Œ ๋…ธ๋“œ `elem`์—์„œ ์‹œ์ž‘ํ•ด `<html>`๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ณ  ์‹ถ์€๋ฐ, `document`๊นŒ์ง€๋Š” ๊ฐ€๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์‚ฌ์†Œํ•œ ์ฐจ์ด๋Š” ์ž„์˜์˜ ์š”์†Œ ๋…ธ๋“œ `elem`์—์„œ ์‹œ์ž‘ํ•ด `<html>`๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ณ  ์‹ถ์€๋ฐ, `document`๊นŒ์ง€๋Š” ๊ฐ€๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js -while(elem = elem.parentElement) { // <html>๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค. +while(elem = elem.parentElement) { // <html>๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค. alert( elem ); } ``` ```` -`childNodes`๋ฅผ `children`์œผ๋กœ ๋Œ€์ฒดํ•ด, ์œ„์—์„œ ์“ฐ์˜€๋˜ ์˜ˆ์ œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์   ์˜ค์ง ์š”์†Œ ๋…ธ๋“œ๋งŒ ์ถœ๋ ฅ๋˜๋„ค์š”. +์•ž์„œ ๋ณด์•˜๋˜ ์˜ˆ์‹œ์—์„œ `childNodes`๋ฅผ `children`์œผ๋กœ ๋Œ€์ฒดํ•ด๋ด…์‹œ๋‹ค. ์š”์†Œ ๋…ธ๋“œ๋งŒ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run <html> <body> - <div>Begin</div> + <div>์‹œ์ž‘</div> <ul> - <li>Information</li> + <li>ํ•ญ๋ชฉ</li> </ul> - <div>End</div> + <div>๋</div> <script> *!* @@ -276,29 +276,29 @@ while(elem = elem.parentElement) { // <html>๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค. ## ํ…Œ์ด๋ธ” ํƒ์ƒ‰ํ•˜๊ธฐ [#dom-navigation-tables] -์ง€๊ธˆ๊นŒ์ง„ ํƒ์ƒ‰์— ์“ฐ์ด๋Š” ๊ธฐ๋ณธ์ ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ DOM ํƒ์ƒ‰ ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. -ํŠน์ • ํƒ€์ž…์˜ DOM ์š”์†Œ๋Š” ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ ์™ธ์— ์ถ”๊ฐ€์ ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํŽธ์˜๋ฅผ ์œ„ํ•ด์„œ์ด์ฃ . +๊ทธ๋Ÿฐ๋ฐ ์ผ๋ถ€ DOM ์š”์†Œ ๋…ธ๋“œ๋Š” ํŽธ์˜๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ ์™ธ์— ์ถ”๊ฐ€์ ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -Tables are a great example of that, and a particularly important case. +ํ…Œ์ด๋ธ”์ด ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ž…๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค. -**`<table>`** ์š”์†Œ๋Š” ์œ„์—์„œ ๋ฐฐ์šด ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ ์ด์™ธ์— ์•„๋ž˜์˜ ํ”„๋กœํผํ‹ฐ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- `table.rows`๋Š” ํ…Œ์ด๋ธ” ๋‚ด `<tr>`์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `table.caption/tHead/tFoot`์€ ๊ฐ๊ฐ `<caption>`, `<thead>`, `<tfoot>` ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -- `table.tBodies`๋Š” ํ…Œ์ด๋ธ” ๋‚ด `<tbody>` ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค(ํ‘œ์ค€์— ๋”ฐ๋ฅด๋ฉด, table ๋‚ด์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ tbody๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค). +**`<table>`** ์š”์†Œ๋Š” ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ ์ด์™ธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +- `table.rows`๋Š” `<tr>`์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. +- `table.caption/tHead/tFoot`์€ ๊ฐ๊ฐ `<caption>`, `<thead>`, `<tfoot>` ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. +- `table.tBodies`๋Š” `<tbody>` ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์ค€์— ๋”ฐ๋ฅด๋ฉด, ํ…Œ์ด๋ธ” ๋‚ด์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ `<tbody>`๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•œ๋ฐ, ์ตœ์†Œํ•œ ํ•˜๋‚˜๋Š” ๋ฌด์กฐ๊ฑด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. HTML ๋ฌธ์„œ์—๋Š” `<tbody>`๊ฐ€ ์—†๋”๋ผ๋„ ๋ธŒ๋ผ์šฐ์ €๋Š” `<tbody>` ๋…ธ๋“œ๋ฅผ DOM์— ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. **`<thead>`, `<tfoot>`, `<tbody>`** ์š”์†Œ๋Š” `rows` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- `tbody.rows`๋Š” tbody ๋‚ด `<tr>` ์š”์†Œ ์ปฌ๋ ‰์…˜์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `tbody.rows`๋Š” tbody ๋‚ด `<tr>` ์š”์†Œ ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. -**`<tr>`:** -- `tr.cells`์€ ์ฃผ์–ด์ง„ `<tr>` ์•ˆ์˜ ๋ชจ๋“  `<td>`, `<th>`์„ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- `tr.sectionRowIndex`๋Š” ์ฃผ์–ด์ง„ `<tr>`์ด `<thead>/<tbody>/<tfoot>`์•ˆ์ชฝ์—์„œ ๋ช‡ ๋ฒˆ์งธ ์ค„์— ์œ„์น˜ํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธ๋ฑ์Šค(index)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- `tr.rowIndex`๋Š” `<table>`๋‚ด์—์„œ ํ•ด๋‹น `<tr>`์ด ๋ช‡ ๋ฒˆ์งธ ์ค„์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +**`<tr>` ์š”์†Œ๋Š” ๋‹ค์Œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.** +- `tr.cells`๋Š” ์ฃผ์–ด์ง„ `<tr>` ์•ˆ์˜ ๋ชจ๋“  `<td>`, `<th>`์„ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- `tr.sectionRowIndex`๋Š” ์ฃผ์–ด์ง„ `<tr>`์ด `<thead>/<tbody>/<tfoot>`์•ˆ์ชฝ์—์„œ ๋ช‡ ๋ฒˆ์งธ ์ค„์— ์œ„์น˜ํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- `tr.rowIndex`๋Š” `<table>`๋‚ด์—์„œ ํ•ด๋‹น `<tr>`์ด ๋ช‡ ๋ฒˆ์งธ ์ค„์ธ ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -**`<td>`๊ณผ `<th>`:** -- `td.cellIndex`๋Š” ์ฃผ์–ด์ง„ `<td>`๊ฐ€ `<tr>`๋‚ด ๋ช‡ ๋ฒˆ์งธ ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +**`<td>`์™€ `<th>` ์š”์†Œ๋Š” ๋‹ค์Œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.** +- `td.cellIndex`๋Š” `<td>`๋‚˜ `<th>`๊ฐ€ ์†ํ•œ `<tr>`์—์„œ ํ•ด๋‹น ์…€์ด ๋ช‡ ๋ฒˆ์งธ์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -์‚ฌ์šฉ ์˜ˆ์‹œ: +์šฉ๋ก€: ```html run height=100 <table id="table"> @@ -317,17 +317,17 @@ Tables are a great example of that, and a particularly important case. </script> ``` -ํ‘œ์— ๊ด€๋ จํ•œ ๊ณต์‹ ์ŠคํŽ™์€ [tabular data](https://html.spec.whatwg.org/multipage/tables.html)์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ‘œ์— ๊ด€๋ จํ•œ ๊ณต์‹ ๋ช…์„ธ์„œ๋Š” [tabular data](https://html.spec.whatwg.org/multipage/tables.html)์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -ํ…Œ์ด๋ธ”๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, HTML ํผ(form)์—๋งŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ํƒ์ƒ‰ ํ”„๋กœํผํ‹ฐ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ํผ์„ ๋ฐฐ์šฐ๋ฉด์„œ ์ด ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +ํ…Œ์ด๋ธ”๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, HTML ํผ(form)์—๋งŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ํƒ์ƒ‰ ํ”„๋กœํผํ‹ฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํผ์„ ๋ฐฐ์šฐ๋ฉด์„œ ์ด ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ## ์š”์•ฝ -ํƒ์ƒ‰ ํ”„๋กœํผํ‹ฐ(navigation property)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํŠน์ • DOM ๋…ธ๋“œ์—์„œ ์ด์›ƒํ•ด์žˆ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๋ฐ”๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํƒ์ƒ‰ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์›ƒ ๋…ธ๋“œ๋กœ ๋ฐ”๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํƒ์ƒ‰ ํ”„๋กœํผํ‹ฐ๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐœ์˜ ์ง‘ํ•ฉ์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. -- ๋ชจ๋“  ๋…ธ๋“œ์— ์ ์šฉ ๊ฐ€๋Šฅํ•œ `parentNode`, `childNodes`, `firstChild`, `lastChild`, `previousSibling`, `nextSibling`. -- ์š”์†Œ ๋…ธ๋“œ์—๋งŒ ์ ์šฉ ๊ฐ€๋Šฅํ•œ `parentElement`, `children`, `firstElementChild`, `lastElementChild`, `previousElementSibling`, `nextElementSibling`. +- ๋ชจ๋“  ๋…ธ๋“œ์— ์ ์šฉ ๊ฐ€๋Šฅํ•œ `parentNode`, `childNodes`, `firstChild`, `lastChild`, `previousSibling`, `nextSibling` +- ์š”์†Œ ๋…ธ๋“œ์—๋งŒ ์ ์šฉ ๊ฐ€๋Šฅํ•œ `parentElement`, `children`, `firstElementChild`, `lastElementChild`, `previousElementSibling`, `nextElementSibling` -ํ…Œ์ด๋ธ”๊ณผ ๊ฐ™์€ ๋ช‡๋ช‡ ํŠน์ • ํƒ€์ž…์˜ DOM ์š”์†Œ๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ์™€ ์ปฌ๋ ‰์…˜์„ ์ œ๊ณตํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. +ํ…Œ์ด๋ธ”๊ณผ ๊ฐ™์€ ๋ช‡๋ช‡ DOM ์š”์†Œ๋Š” ์ถ”๊ฐ€ ํ”„๋กœํผํ‹ฐ์™€ ์ฝ˜ํ…์ธ ์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ปฌ๋ ‰์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/03-dom-navigation/dom-links-elements.svg b/2-ui/1-document/03-dom-navigation/dom-links-elements.svg index 190285533f..fd0b2826a4 100644 --- a/2-ui/1-document/03-dom-navigation/dom-links-elements.svg +++ b/2-ui/1-document/03-dom-navigation/dom-links-elements.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="440" height="316" viewBox="0 0 440 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-links-elements.svg"><path id="Rectangle-8" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M129 10h198v28H129z"/><text id="document.documentEle" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="142.6" y="29">document.documentElement </tspan></text><text id="Type-something" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="336.9" y="29"><HTML></tspan></text><path id="Rectangle-7" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M163 78h117v28H163z"/><text id="document.body--" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="174.2" y="95">document.body </tspan></text><text id="(if-inside-body)" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="300.9" y="95">(if inside body)</tspan></text><path id="Line-5" stroke="#8A704D" stroke-linecap="square" stroke-width="2" d="M14.5 115H427"/><text id="parentElement" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="175" y="172" fill="#8A704D">parent</tspan> <tspan x="218.2" y="172" fill="#EE6B47">Element</tspan></text><path id="Rectangle-6" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M180 213h80v28h-80z"/><text id="<DIV>" fill="#8A704D" font-family="OpenSans-Regular, Open Sans" font-size="12" font-weight="normal"><tspan x="204.192" y="232"><DIV></tspan></text><path id="Line-6" fill="#EE6B47" fill-rule="nonzero" d="M220.5 178.71l8.112 14.421-1.743.98-5.369-9.543V208.5h-2v-23.935l-5.369 9.547-1.743-.98 8.112-14.422z"/><path id="Line-7" fill="#EE6B47" fill-rule="nonzero" d="M415.369 218.388l14.42 8.112-14.42 8.112-.98-1.743 9.542-5.369H266.5v-2h157.434l-9.546-5.369.98-1.743z"/><text id="nextElementSibling" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="276" y="212" fill="#8A704D">next</tspan> <tspan x="304.8" y="212" fill="#EE6B47">Element</tspan> <tspan x="355.2" y="212" fill="#8A704D">Sibling</tspan></text><path id="Line-8" fill="#EE6B47" fill-rule="nonzero" d="M23.631 218.388l.98 1.743-9.544 5.369H169v2H15.067l9.545 5.369-.98 1.743L9.21 226.5l14.421-8.112z"/><text id="previousElementSibli" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="6" y="212" fill="#8A704D">previous</tspan> <tspan x="63.6" y="212" fill="#EE6B47">Element</tspan> <tspan x="114" y="212" fill="#8A704D">Sibling</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M174.822 248.123l1.055 1.7-56.244 34.908 10.941-.47.086 1.997-16.53.713 7.975-14.497 1.752.964-5.279 9.595 56.244-34.91z"/><path id="Line-3" fill="#EE6B47" fill-rule="nonzero" d="M269.214 248.115l53.772 35.364-5.024-9.73 1.777-.918 7.592 14.702-16.506-1.147.138-1.995 10.924.759-53.772-35.364 1.099-1.671z"/><text id="children" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="188" y="273">children</tspan></text><text id="firstElementChild--" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="43" y="307" fill="#8A704D">first</tspan> <tspan x="79" y="307" fill="#EE6B47">Element</tspan> <tspan x="129.4" y="307" fill="#8A704D">Child </tspan></text><text id="lastElementChild" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="273" y="307" fill="#8A704D">last</tspan> <tspan x="301.8" y="307" fill="#EE6B47">Element</tspan> <tspan x="352.2" y="307" fill="#8A704D">Child</tspan></text><path id="Line-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M222.5 151.5v4h-2v-4h2zm0-6v4h-2v-4h2zm0-6v4h-2v-4h2zm-1-14.29l8.112 14.421-1.743.98-5.37-9.544.001.433h-2l-.001-.433-5.368 9.545-1.743-.98 8.112-14.422zm1 8.29v4h-2v-4h2z"/><path id="Line-2-Copy" fill="#EE6B47" fill-rule="nonzero" d="M221.5 44.71l8.112 14.421-1.743.98-5.369-9.544v21.528h-2V50.567l-5.369 9.545-1.743-.98L221.5 44.71z"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="440" height="316" viewBox="0 0 440 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-links-elements.svg"><path id="Rectangle-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M129 10h198v28H129z"/><text id="document.documentEle" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="142.6" y="29">document.documentElement </tspan></text><text id="Type-something" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="336.9" y="29"><HTML></tspan></text><path id="Rectangle-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M163 78h117v28H163z"/><text id="document.body--" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="174.2" y="95">document.body </tspan></text><text id="(if-inside-body)" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="300.9" y="95">(if inside body)</tspan></text><path id="Line-5" stroke="#AF6E24" stroke-linecap="square" stroke-width="2" d="M14.5 115H427"/><text id="parentElement" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="175" y="172" fill="#AF6E24">parent</tspan> <tspan x="218.2" y="172" fill="#C06334">Element</tspan></text><path id="Rectangle-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M180 213h80v28h-80z"/><text id="<DIV>" fill="#AF6E24" font-family="OpenSans-Regular, Open Sans" font-size="12" font-weight="normal"><tspan x="204.192" y="232"><DIV></tspan></text><path id="Line-6" fill="#C06334" fill-rule="nonzero" d="M220.5 178.71l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.879-8.674V208.5h-2v-23.933l-4.878 8.673-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55z"/><path id="Line-7" fill="#C06334" fill-rule="nonzero" d="M415.369 218.388l.871.49 12 6.75 1.55.872-1.55.872-12 6.75-.871.49-.98-1.743.87-.49 8.673-4.879H266.5v-2h157.432l-8.672-4.878-.872-.49.98-1.744z"/><text id="nextElementSibling" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="276" y="212" fill="#AF6E24">next</tspan> <tspan x="304.8" y="212" fill="#C06334">Element</tspan> <tspan x="355.2" y="212" fill="#AF6E24">Sibling</tspan></text><path id="Line-8" fill="#C06334" fill-rule="nonzero" d="M23.631 218.388l.98 1.743-.87.49-8.674 4.879H169v2H15.067l8.673 4.878.872.49-.98 1.744-.872-.49-12-6.75-1.55-.872 1.55-.872 12-6.75.871-.49z"/><text id="previousElementSibli" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="6" y="212" fill="#AF6E24">previous</tspan> <tspan x="63.6" y="212" fill="#C06334">Element</tspan> <tspan x="114" y="212" fill="#AF6E24">Sibling</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M174.822 248.123l1.055 1.7-.85.527-48.476 30.089-6.917 4.292 9.941-.428 1-.043.085 1.998-.999.043-13.755.594-1.776.076.857-1.557 6.636-12.064.482-.876 1.752.964-.482.876-4.797 8.718 6.918-4.293 48.477-30.089.85-.527z"/><path id="Line-3" fill="#C06334" fill-rule="nonzero" d="M269.214 248.115l.835.55 46.157 30.354 6.78 4.46-4.565-8.841-.459-.889 1.777-.918.459.889 6.317 12.233.816 1.58-1.774-.123-13.735-.954-.997-.07.138-1.995.998.07 9.926.689-6.78-4.46-46.156-30.354-.836-.55 1.099-1.671z"/><text id="children" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="188" y="273">children</tspan></text><text id="firstElementChild--" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="43" y="307" fill="#AF6E24">first</tspan> <tspan x="79" y="307" fill="#C06334">Element</tspan> <tspan x="129.4" y="307" fill="#AF6E24">Child </tspan></text><text id="lastElementChild" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="273" y="307" fill="#AF6E24">last</tspan> <tspan x="301.8" y="307" fill="#C06334">Element</tspan> <tspan x="352.2" y="307" fill="#AF6E24">Child</tspan></text><path id="Line-Copy-2" fill="#C06334" fill-rule="nonzero" d="M222.5 151.5v4h-2v-4h2zm0-6v4h-2v-4h2zm0-6v4h-2v-4h2zm-1-14.29l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.88-8.676.001.435h-2l-.001-.432-4.877 8.672-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55zm1 8.29v4h-2v-4h2z"/><path id="Line-2-Copy" fill="#C06334" fill-rule="nonzero" d="M221.5 44.71l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.879-8.674v21.528h-2V50.567l-4.878 8.673-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55z"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/03-dom-navigation/dom-links.svg b/2-ui/1-document/03-dom-navigation/dom-links.svg index df252deb91..6c34bca4a4 100644 --- a/2-ui/1-document/03-dom-navigation/dom-links.svg +++ b/2-ui/1-document/03-dom-navigation/dom-links.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="420" height="388" viewBox="0 0 420 388"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-links.svg"><path id="Rectangle-9" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M150 20h117v28H150z"/><path id="Rectangle-7" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M151 154h117v28H151z"/><path id="Rectangle-8" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M117 87h198v28H117z"/><text id="document" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="179.7" y="38">document</tspan></text><text id="document.documentEle" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="129.6" y="105">document.documentElement </tspan></text><text id="Type-something" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="324.9" y="105"><HTML></tspan></text><text id="document.body--" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="164.2" y="173">document.body </tspan></text><text id="(if-inside-body)" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="283.9" y="173">(if inside body)</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M209.5 119.71l8.112 14.421-1.743.98-5.369-9.544v23.785h-2v-23.785l-5.369 9.545-1.743-.98 8.112-14.422z"/><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M209.5 52.71l8.112 14.421-1.743.98-5.369-9.543v21.527h-2v-21.53l-5.369 9.547-1.743-.98L209.5 52.71z"/><path id="Line" stroke="#8A704D" stroke-linecap="square" stroke-width="2" d="M2.5 191H415"/><text id="parentNode" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="172" y="248">parentNode</tspan></text><path id="Rectangle-6" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M169 289h80v28h-80z"/><text id="<DIV>" fill="#8A704D" font-family="OpenSans-Regular, Open Sans" font-size="12" font-weight="normal"><tspan x="192.192" y="308"><DIV></tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M208.5 254.21l8.112 14.421-1.743.98-5.37-9.546.001 24.435h-2l-.001-24.432-5.368 9.544-1.743-.98 8.112-14.422z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M209.5 226.5v4h-2v-4h2zm0-6v4h-2v-4h2zm0-6v4h-2v-4h2zm-1-14.29l8.112 14.421-1.743.98-5.37-9.544.001.433h-2l-.001-.433-5.368 9.545-1.743-.98 8.112-14.422zm1 8.29v4h-2v-4h2z"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M356.369 294.388l14.42 8.112-14.42 8.112-.98-1.743 9.543-5.369H254.5v-2h110.432l-9.544-5.369.98-1.743z"/><text id="nextSibling" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="264" y="288">nextSibling</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M61.631 294.388l.98 1.743-9.544 5.369H165.5v2H53.067l9.545 5.369-.98 1.743L47.21 302.5l14.421-8.112z"/><text id="previousSibling" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="50" y="288">previousSibling</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M162.822 324.123l1.055 1.7-56.244 34.908 10.941-.47.086 1.997-16.53.713 7.975-14.497 1.752.964-5.279 9.595 56.244-34.91z"/><path id="Line-3" fill="#EE6B47" fill-rule="nonzero" d="M257.214 324.115l53.772 35.364-5.024-9.73 1.777-.918 7.592 14.702-16.506-1.147.138-1.995 10.924.759-53.772-35.364 1.099-1.671z"/><text id="childNodes" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="170" y="343">childNodes</tspan></text><text id="firstChild--" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="64" y="379">firstChild </tspan></text><text id="Type-something" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="279" y="379">lastChild</tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="420" height="388" viewBox="0 0 420 388"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-links.svg"><path id="Rectangle-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M150 20h117v28H150z"/><path id="Rectangle-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M151 154h117v28H151z"/><path id="Rectangle-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M117 87h198v28H117z"/><text id="document" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="179.7" y="38">document</tspan></text><text id="document.documentEle" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="129.6" y="105">document.documentElement </tspan></text><text id="Type-something" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="324.9" y="105"><HTML></tspan></text><text id="document.body--" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="164.2" y="173">document.body </tspan></text><text id="(if-inside-body)" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="283.9" y="173">(if inside body)</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M209.5 119.71l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.879-8.674v23.785h-2v-23.785l-4.878 8.673-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55z"/><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M209.5 52.71l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.879-8.674v21.528h-2V58.567l-4.878 8.673-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55z"/><path id="Line" stroke="#AF6E24" stroke-linecap="square" stroke-width="2" d="M2.5 191H415"/><text id="parentNode" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="172" y="248">parentNode</tspan></text><path id="Rectangle-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M169 289h80v28h-80z"/><text id="<DIV>" fill="#AF6E24" font-family="OpenSans-Regular, Open Sans" font-size="12" font-weight="normal"><tspan x="192.192" y="308"><DIV></tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M208.5 254.21l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.88-8.676.001 8.185v16.25h-2v-16.25l-.001-8.182-4.877 8.672-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55z"/><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M209.5 226.5v4h-2v-4h2zm0-6v4h-2v-4h2zm0-6v4h-2v-4h2zm-1-14.29l.872 1.55 6.75 12 .49.871-1.743.98-.49-.87-4.88-8.676.001.435h-2l-.001-.432-4.877 8.672-.49.872-1.744-.98.49-.872 6.75-12 .872-1.55zm1 8.29v4h-2v-4h2z"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M356.369 294.388l.871.49 12 6.75 1.55.872-1.55.872-12 6.75-.871.49-.98-1.743.87-.49 8.673-4.879H254.5v-2h110.432l-8.672-4.878-.872-.49.98-1.744z"/><text id="nextSibling" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="264" y="288">nextSibling</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M61.631 294.388l.98 1.743-.87.49-8.674 4.879H165.5v2H53.067l8.673 4.878.872.49-.98 1.744-.872-.49-12-6.75-1.55-.872 1.55-.872 12-6.75.871-.49z"/><text id="previousSibling" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="50" y="288">previousSibling</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M162.822 324.123l1.055 1.7-.85.527-48.476 30.089-6.917 4.292 9.941-.428 1-.043.085 1.998-.999.043-13.755.594-1.776.076.857-1.557 6.636-12.064.482-.876 1.752.964-.482.876-4.797 8.718 6.918-4.293 48.477-30.089.85-.527z"/><path id="Line-3" fill="#C06334" fill-rule="nonzero" d="M257.214 324.115l.835.55 46.157 30.354 6.78 4.46-4.565-8.841-.459-.889 1.777-.918.459.889 6.317 12.233.816 1.58-1.774-.123-13.735-.954-.997-.07.138-1.995.998.07 9.926.689-6.78-4.46-46.156-30.354-.836-.55 1.099-1.671z"/><text id="childNodes" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="170" y="343">childNodes</tspan></text><text id="firstChild--" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="64" y="379">firstChild </tspan></text><text id="Type-something" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="279" y="379">lastChild</tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md index a7cc212aa0..9db17890b3 100644 --- a/2-ui/1-document/04-searching-elements-dom/article.md +++ b/2-ui/1-document/04-searching-elements-dom/article.md @@ -6,7 +6,7 @@ ## document.getElementById ํ˜น์€ id๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ ๊ฒ€์ƒ‰ํ•˜๊ธฐ -์š”์†Œ์— `id` ์†์„ฑ์ด ์žˆ์œผ๋ฉด ์š”์†Œ์˜ ์œ„์น˜์— ์ƒ๊ด€์—†์ด `document.getElementById(id)`๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์š”์†Œ์— `id` ์†์„ฑ์ด ์žˆ์œผ๋ฉด ์œ„์น˜์— ์ƒ๊ด€์—†์ด ๋ฉ”์„œ๋“œ `document.getElementById(id)`๋ฅผ ์ด์šฉํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -26,7 +26,7 @@ </script> ``` -์š”์†Œ์— `id` ์†์„ฑ์ด ์žˆ์œผ๋ฉด `id` ์†์„ฑ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋”ด ์ „์—ญ ๋ณ€์ˆ˜ ํ•˜๋‚˜๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š”๋ฐ, ์ด๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด์— ๋”ํ•˜์—ฌ `id` ์†์„ฑ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋”ด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด ์ ‘๊ทผํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run <div id="*!*elem*/!*"> @@ -34,15 +34,15 @@ </div> <script> - // ๋ณ€์ˆ˜ elem์€ id๊ฐ€ "elem"์ธ DOM ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. + // ๋ณ€์ˆ˜ elem์€ id๊ฐ€ 'elem'์ธ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. elem.style.background = 'red'; // id๊ฐ€ elem-content์ธ ์š”์†Œ๋Š” ์ค‘๊ฐ„์— ํ•˜์ดํ”ˆ(-)์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜ ์ด๋ฆ„์œผ๋กœ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - // ์ด๋Ÿด ๋• window['elem-content']๊ฐ™์ด ๋Œ€๊ด„ํ˜ธ(`[...]`)๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + // ์ด๋Ÿด ๋• ๋Œ€๊ด„ํ˜ธ(`[...]`)๋ฅผ ์‚ฌ์šฉํ•ด์„œ window['elem-content']๋กœ ์ ‘๊ทผํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. </script> ``` -๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ์ž๋™์œผ๋กœ ์„ ์–ธ๋œ ์ „์—ญ๋ณ€์ˆ˜๋Š” ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋˜๋ฉด ๋ฌด์šฉ์ง€๋ฌผ์ด ๋ฉ๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ์š”์†Œ id๋ฅผ ๋”ฐ์„œ ์ž๋™์œผ๋กœ ์„ ์–ธ๋œ ์ „์—ญ๋ณ€์ˆ˜๋Š” ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋˜๋ฉด ๋ฌด์šฉ์ง€๋ฌผ์ด ๋ฉ๋‹ˆ๋‹ค. ```html run untrusted height=0 <div id="elem"></div> @@ -55,11 +55,11 @@ ``` ```warn header="id๋ฅผ ๋”ฐ์„œ ๋งŒ๋“ค์–ด์ง„ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์š”์†Œ ์ ‘๊ทผ ์‹œ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”." -`id`์— ๋Œ€์‘ํ•˜๋Š” ์ „์—ญ๋ณ€์ˆ˜๋Š” [๋ช…์„ธ](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem)์˜ ๋‚ด์šฉ์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์ค€์ด๊ธด ํ•˜์ง€๋งŒ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๋‚จ๊ฒจ๋‘” ๋™์ž‘์ž…๋‹ˆ๋‹ค. +`id`์— ๋Œ€์‘ํ•˜๋Š” ์ „์—ญ๋ณ€์ˆ˜๋Š” [๋ช…์„ธ์„œ](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem)์˜ ๋‚ด์šฉ์„ ๊ตฌํ˜„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์œผ๋กœ ํ‘œ์ค€์ด๊ธด ํ•˜์ง€๋งŒ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๋‚จ๊ฒจ๋‘” ๋™์ž‘์ž…๋‹ˆ๋‹ค. -๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ DOM์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์„œ ๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜๋ฅผ ๋„๋ชจํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ๋ฐฉ์‹์€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ฐ„๋‹จํ•  ๋• ๊ดœ์ฐฎ์ง€๋งŒ, ์ด๋ฆ„์ด ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ์‹์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ทฐ ์˜์—ญ์„ ๊ด€์žฅํ•˜๋Š” HTML์„ ๋ณด์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋งŒ ๋ณด๊ณ  ๋ณ€์ˆ˜์˜ ์ถœ์ฒ˜๋ฅผ ์•Œ๊ธฐ ํž˜๋“ค๋‹ค๋Š” ๋‹จ์ ๋„ ์žˆ์ฃ . +๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ DOM์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์„œ ๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜๋ฅผ ๋„๋ชจํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ๋ฐฉ์‹์€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ฐ„๋‹จํ•  ๋• ๊ดœ์ฐฎ์ง€๋งŒ, ์ด๋ฆ„์ด ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ์‹์€ ์•„๋‹™๋‹ˆ๋‹ค. HTML์„ ๋ณด์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ ์ฝ”๋“œ๋งŒ ๋ณด๊ณ  ๋ณ€์ˆ˜์˜ ์ถœ์ฒ˜๋ฅผ ์•Œ๊ธฐ ํž˜๋“ค๋‹ค๋Š” ๋‹จ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„  ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์š”์†Œ์˜ ์ถœ์ฒ˜๊ฐ€ ๋ช…ํ™•ํ•œ ๊ฒฝ์šฐ, `id`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„  ๊ฐ„๊ฒฐ์„ฑ์„ ์œ„ํ•ด ์š”์†Œ์˜ ์ถœ์ฒ˜๊ฐ€ ๋ช…ํ™•ํ•œ ๊ฒฝ์šฐ, `id`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์‹ค๋ฌด์—์„  `document.getElementById`๋ฅผ ์‚ฌ์šฉํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ``` @@ -78,16 +78,16 @@ `elem.querySelectorAll(css)`์€ ๋‹ค์žฌ๋‹ค๋Šฅํ•œ ์š”์†Œ ๊ฒ€์ƒ‰ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” `elem`์˜ ์ž์‹ ์š”์†Œ ์ค‘ ์ฃผ์–ด์ง„ CSS ์„ ํƒ์ž์— ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ ๋ชจ๋‘๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ๋Š” `document` ๋‚ด ๋งˆ์ง€๋ง‰ `<li>`์š”์†Œ ๋ชจ๋‘๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ๋Š” ๋งˆ์ง€๋ง‰ `<li>`์š”์†Œ ๋ชจ๋‘๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ```html run <ul> - <li>The</li> - <li>test</li> + <li>1-1</li> + <li>1-2</li> </ul> <ul> - <li>has</li> - <li>passed</li> + <li>2-1</li> + <li>2-2</li> </ul> <script> *!* @@ -95,7 +95,7 @@ */!* for (let elem of elements) { - alert(elem.innerHTML); // "test", "passed" + alert(elem.innerHTML); // "1-2", "2-2" } </script> ``` @@ -103,7 +103,7 @@ `querySelectorAll`์€ CSS ์„ ํƒ์ž๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์•„์ฃผ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ```smart header="๊ฐ€์ƒ ํด๋ž˜์Šค๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." -querySelectorAll์—๋Š” `:hover`๋‚˜ `:active` ๊ฐ™์€ CSS ์„ ํƒ์ž์˜ ๊ฐ€์ƒ ํด๋ž˜์Šค(pseudo-class)๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `document.querySelectorAll(':hover')`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๊ฐ€ ์œ„์— ์žˆ๋Š”(hover ์ƒํƒœ์ธ) ์š”์†Œ ๋ชจ๋‘๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ : ์ปฌ๋ ‰์…˜์€ DOM ํŠธ๋ฆฌ ์ตœ์ƒ๋‹จ์— ์œ„์น˜ํ•œ `<html>`๋ถ€ํ„ฐ ๊ฐ€์žฅ ํ•˜๋‹จ์˜ ์š”์†Œ ์ˆœ์œผ๋กœ ์ฑ„์›Œ์ง‘๋‹ˆ๋‹ค. +querySelectorAll์—๋Š” `:hover`๋‚˜ `:active` ๊ฐ™์€ CSS ์„ ํƒ์ž์˜ ๊ฐ€์ƒ ํด๋ž˜์Šค(pseudo-class)๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `document.querySelectorAll(':hover')`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๊ฐ€ ์œ„์— ์žˆ๋Š”(hover ์ƒํƒœ์ธ) ์š”์†Œ ๋ชจ๋‘๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ปฌ๋ ‰์…˜์€ DOM ํŠธ๋ฆฌ ์ตœ์ƒ๋‹จ์— ์œ„์น˜ํ•œ `<html>`๋ถ€ํ„ฐ ๊ฐ€์žฅ ํ•˜๋‹จ์˜ ์š”์†Œ ์ˆœ์œผ๋กœ ์ฑ„์›Œ์ง‘๋‹ˆ๋‹ค. ``` ## querySelector [#querySelector] @@ -118,7 +118,7 @@ querySelectorAll์—๋Š” `:hover`๋‚˜ `:active` ๊ฐ™์€ CSS ์„ ํƒ์ž์˜ ๊ฐ€์ƒ ํด [elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches)๋Š” DOM์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์ผ์ด ์•„๋‹Œ ์กฐ๊ธˆ ๋‹ค๋ฅธ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์š”์†Œ `elem`์ด ์ฃผ์–ด์ง„ CSS ์„ ํƒ์ž์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ด์ค๋‹ˆ๋‹ค. ์ผ์น˜ํ•œ๋‹ค๋ฉด `true`, ์•„๋‹ˆ๋ผ๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ฃ . -์š”์†Œ๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” ๋ฐฐ์—ด ๋“ฑ์—์„œ ์›ํ•˜๋Š” ์š”์†Œ๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๊ณ ์ž ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +์š”์†Œ๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” ๋ฐฐ์—ด ๋“ฑ์„ ์ˆœํšŒํ•ด ์›ํ•˜๋Š” ์š”์†Œ๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๊ณ ์ž ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -140,9 +140,9 @@ querySelectorAll์—๋Š” `:hover`๋‚˜ `:active` ๊ฐ™์€ CSS ์„ ํƒ์ž์˜ ๊ฐ€์ƒ ํด ## closest -๋ถ€๋ชจ ์š”์†Œ, ๋ถ€๋ชจ ์š”์†Œ์˜ ๋ถ€๋ชจ ์š”์†Œ ๋“ฑ DOM ํŠธ๋ฆฌ์—์„œ ํŠน์ • ์š”์†Œ์˜ ์ƒ์œ„์— ์žˆ๋Š” ์š”์†Œ๋“ค์„ ํ•œ๋ฐ ๋ฌถ์–ด ํ•ด๋‹น ์š”์†Œ์˜ *์กฐ์ƒ* ์š”์†Œ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. +๋ถ€๋ชจ ์š”์†Œ, ๋ถ€๋ชจ ์š”์†Œ์˜ ๋ถ€๋ชจ ์š”์†Œ ๋“ฑ DOM ํŠธ๋ฆฌ์—์„œ ํŠน์ • ์š”์†Œ์˜ ์ƒ์œ„์— ์žˆ๋Š” ์š”์†Œ๋“ค์€ *์กฐ์ƒ(ancestor)* ์š”์†Œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. -`elem.closest(css)`๋ฉ”์„œ๋“œ๋Š” `elem` ์ž๊ธฐ ์ž์‹ ์„ ํฌํ•จํ•˜์—ฌ CSS ์„ ํƒ์ž์™€ ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค. +๋ฉ”์„œ๋“œ `elem.closest(css)`๋Š” `elem` ์ž๊ธฐ ์ž์‹ ์„ ํฌํ•จํ•˜์—ฌ CSS ์„ ํƒ์ž์™€ ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค. `closest`๋ฉ”์„œ๋“œ๋Š” ํ•ด๋‹น ์š”์†Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด DOM ํŠธ๋ฆฌ๋ฅผ ํ•œ ๋‹จ๊ณ„์”ฉ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ์›ํ•˜๋Š” ์š”์†Œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. CSS ์„ ํƒ์ž์™€ ์ผ์น˜ํ•˜๋Š” ์š”์†Œ๋ฅผ ์ฐพ์œผ๋ฉด, ๊ฒ€์ƒ‰์„ ์ค‘๋‹จํ•˜๊ณ  ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. @@ -176,7 +176,7 @@ querySelectorAll์—๋Š” `:hover`๋‚˜ `:active` ๊ฐ™์€ CSS ์„ ํƒ์ž์˜ ๊ฐ€์ƒ ํด ํŠœํ† ๋ฆฌ์–ผ์˜ ์™„์„ฑ๋„๋ฅผ ๋†’์ด๊ณ  ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋“ค์„ ๋งŒ๋‚  ๋•Œ ๋‹นํ™ฉํ•˜์ง€ ์•Š์œผ์‹œ๊ธธ ๋ฐ”๋ผ๋ฉด์„œ ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ์ž ์‹œ ์–ธ๊ธ‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -- `elem.getElementsByTagName(tag)` -- ์ฃผ์–ด์ง„ ํƒœ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ์š”์†Œ๋ฅผ ์ฐพ๊ณ , ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ `tag`์— `"*"`์ด ๋“ค์–ด๊ฐ€๋ฉด, "๋ชจ๋“  ํƒœ๊ทธ"๊ฐ€ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค. +- `elem.getElementsByTagName(tag)` -- ์ฃผ์–ด์ง„ ํƒœ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ์š”์†Œ๋ฅผ ์ฐพ๊ณ , ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ `tag`์— `"*"`์ด ๋“ค์–ด๊ฐ€๋ฉด, '๋ชจ๋“  ํƒœ๊ทธ'๊ฐ€ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค. - `elem.getElementsByClassName(className)` -- class ์†์„ฑ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์š”์†Œ๋ฅผ ์ฐพ๊ณ , ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - `document.getElementsByName(name)` -- ์•„์ฃผ ๋“œ๋ฌผ๊ฒŒ ์“ฐ์ด๋Š” ๋ฉ”์„œ๋“œ๋กœ, ๋ฌธ์„œ ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰ ๊ธฐ์ค€์€ `name` ์†์„ฑ๊ฐ’์ด๊ณ , ์ด ๋ฉ”์„œ๋“œ ์—ญ์‹œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. @@ -218,10 +218,10 @@ let divs = document.getElementsByTagName('div'); </script> ``` -```warn header="`\"s\"`๋ฅผ ์ ˆ๋Œ€ ๋น ํŠธ๋ฆฌ์ง€ ๋งˆ์„ธ์š”!" -์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๋“ค์€ ๊ฐ€๋” `"s"`๋ฅผ ๋นผ๋จน๋Š” ์‹ค์ˆ˜๋ฅผ ํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. <code>getElement<b>s</b>ByTagName</code>๋ฅผ ์จ์•ผ ํ•˜๋Š”๋ฐ `"s"`๋ฅผ ๋น ํŠธ๋ฆฌ๊ณ  `getElementByTagName`์„ ์ž…๋ ฅํ•˜๊ณค ํ•˜์ฃ . +```warn header="`'s'`๋ฅผ ์ ˆ๋Œ€ ๋น ํŠธ๋ฆฌ์ง€ ๋งˆ์„ธ์š”!" +์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๋“ค์€ ๊ฐ€๋” `'s'`๋ฅผ ๋นผ๋จน๋Š” ์‹ค์ˆ˜๋ฅผ ํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. <code>getElement<b>s</b>ByTagName</code>๋ฅผ ์จ์•ผ ํ•˜๋Š”๋ฐ `getElementByTagName`์„ ์ž…๋ ฅํ•˜๊ณค ํ•˜์ฃ . -`getElementById`๋Š” ์š”์†Œ ํ•˜๋‚˜๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— `"s"`๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. `getElementsByTagName`๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋Š” ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ ์ค‘๊ฐ„์— `"s"`๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. +`getElementById`๋Š” ์š”์†Œ ํ•˜๋‚˜๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— `s`๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. `getElementsByTagName` ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋Š” ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ ์ค‘๊ฐ„์— `"s"`๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ``` ````warn header="์š”์†Œ ํ•˜๋‚˜๊ฐ€ ์•„๋‹Œ, ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค!" @@ -232,9 +232,9 @@ let divs = document.getElementsByTagName('div'); document.getElementsByTagName('input').value = 5; ``` -์œ„ ์ฝ”๋“œ๋Š” input ์š”์†Œ ์ „์ฒด๋ฅผ ๋‹ด์€ *์ปฌ๋ ‰์…˜*์— 5๋ฅผ ํ• ๋‹นํ•˜๋ ค ํ•˜๋ฏ€๋กœ, ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณธ๋ž˜ ์˜๋„๋Š” ์ปฌ๋ ‰์…˜์ด ์•„๋‹Œ ์š”์†Œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด์—ˆ์ฃ . +input ์š”์†Œ ์ „์ฒด๋ฅผ ๋‹ด์€ *์ปฌ๋ ‰์…˜*์— 5๋ฅผ ํ• ๋‹นํ•˜๋Š” ์œ„ ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋ณธ๋ž˜ ์˜๋„๋Š” ์ปฌ๋ ‰์…˜ ๋‚ด ์š”์†Œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด์—ˆ์„ ๊ฒ๋‹ˆ๋‹ค. -์ปฌ๋ ‰์…˜์„ ์ˆœํšŒํ•˜๊ฑฐ๋‚˜ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์ปฌ๋ ‰์…˜์ด ์•„๋‹Œ ์š”์†Œ๋ฅผ ์–ป๊ณ , ๊ทธ ์š”์†Œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฉด ๊ธฐ์กด ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . +์ปฌ๋ ‰์…˜์„ ์ˆœํšŒํ•˜๊ฑฐ๋‚˜ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ๋ฅผ ์–ป๊ณ  ๊ทธ ์š”์†Œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฉด ๊ธฐ์กด ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . ```js // (๋ฌธ์„œ์— input ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด) ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. @@ -251,22 +251,22 @@ document.getElementsByTagName('input')[0].value = 5; </form> <script> - // name ์†์„ฑ์„ ์ด์šฉํ•ด ๋ด…์‹œ๋‹ค. + // name ์†์„ฑ์„ ์ด์šฉํ•ด ๊ฒ€์ƒ‰ let form = document.getElementsByName('my-form')[0]; - // ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ด์šฉํ•ด ๋ด…์‹œ๋‹ค. + // form ๋‚ด์—์„œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ด์šฉํ•ด ๊ฒ€์ƒ‰ let articles = form.getElementsByClassName('article'); - alert(articles.length); // ํด๋ž˜์Šค ์†์„ฑ๊ฐ’์ด "article"์ธ ์š”์†Œ๋Š” 2๊ฐœ์ž…๋‹ˆ๋‹ค. + alert(articles.length); // 2. ํด๋ž˜์Šค ์†์„ฑ๊ฐ’์ด 'article'์ธ ์š”์†Œ๋Š” 2๊ฐœ์ž…๋‹ˆ๋‹ค. </script> ``` ## ์‚ด์•„์žˆ๋Š” ์ปฌ๋ ‰์…˜ -`"getElementsBy"`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” *์‚ด์•„์žˆ๋Š”* ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ์— ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์ปฌ๋ ‰์…˜์„ "์ž๋™ ๊ฐฑ์‹ "ํ•ด์ค˜ ์ตœ์‹  ์ƒํƒœ๋ฅผ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ฃ . +`'getElementsBy'`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” *์‚ด์•„์žˆ๋Š”* ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ์— ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์ปฌ๋ ‰์…˜์ด '์ž๋™ ๊ฐฑ์‹ '๋˜์–ด ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์ œ์—” ์Šคํฌ๋ฆฝํŠธ ๋‘ ๊ฐœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜ˆ์‹œ ๋‚ด์—” ์Šคํฌ๋ฆฝํŠธ ๋‘ ๊ฐœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -1. ์ฒซ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋Š” `<div>`์— ์ƒ์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์— ์ด ์ปฌ๋ ‰์…˜์˜ ๊ธธ์ด๋Š” `1`์ž…๋‹ˆ๋‹ค. +1. ์ฒซ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋Š” `<div>`์— ์ƒ์‘ํ•˜๋Š” ์š”์†Œ๋ฅผ ๋‹ด์€ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์— ์ด ์ปฌ๋ ‰์…˜์˜ ๊ธธ์ด๋Š” `1`์ž…๋‹ˆ๋‹ค. 2. ๋‘ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฌธ์„œ์— `<div>`๊ฐ€ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€๋œ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ปฌ๋ ‰์…˜์˜ ๊ธธ์ด๋Š” `2`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ```html run @@ -286,9 +286,9 @@ document.getElementsByTagName('input')[0].value = 5; </script> ``` -๋ฐ˜๋ฉด, `querySelectorAll`์€ *์ •์ ์ธ* ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์š”์†Œ๋ฅผ ๋‹ด์€ ๊ณต๊ฐ„์ธ ์ปฌ๋ ‰์…˜์ด ํ•œ ๋ฒˆ ํ™•์ •๋˜๋ฉด ๋”๋Š” ๋Š˜์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋ฐ˜๋ฉด, `querySelectorAll`์€ *์ •์ ์ธ* ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์ด ํ•œ ๋ฒˆ ํ™•์ •๋˜๋ฉด ๋”๋Š” ๋Š˜์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ž˜์—์„œ ๋ณด์‹œ๋Š” ๋ฐ”์™€ ๊ฐ™์ด ๋‘ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋™์ผํ•˜๊ฒŒ `1`์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. +`querySelectorAll`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‘ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋™์ผํ•˜๊ฒŒ `1`์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ```html run @@ -312,7 +312,7 @@ document.getElementsByTagName('input')[0].value = 5; ## ์š”์•ฝ -์•„๋ž˜ 6๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋Š” DOM์—์„œ ์›ํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค. +DOM์—์„œ ์›ํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์ฃผ์š” ๋ฉ”์„œ๋“œ 6๊ฐ€์ง€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. <table> <thead> @@ -320,7 +320,7 @@ document.getElementsByTagName('input')[0].value = 5; <td>๋ฉ”์„œ๋“œ</td> <td>๊ฒ€์ƒ‰ ๊ธฐ์ค€</td> <td>ํ˜ธ์ถœ ๋Œ€์ƒ์ด ์š”์†Œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€</td> -<td>์ปฌ๋ ‰์…˜ ๊ฐฑ์‹  ๊ฐ€๋Šฅ ์—ฌ๋ถ€</td> +<td>์ปฌ๋ ‰์…˜ ๊ฐฑ์‹  ์—ฌ๋ถ€</td> </tr> </thead> <tbody> @@ -363,7 +363,7 @@ document.getElementsByTagName('input')[0].value = 5; </tbody> </table> -์•„๋งˆ ์‹ค๋ฌด์—์„  `querySelector`๋‚˜ `querySelectorAll`์„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜์‹ค ๊ฒ๋‹ˆ๋‹ค. `getElementBy`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋Œ€๊ฒŒ ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ผ๋ถ€ ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๊ผญ ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋งˆ ์‹ค๋ฌด์—์„  `querySelector`๋‚˜ `querySelectorAll`์„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜์‹ค ๊ฒ๋‹ˆ๋‹ค. `getElementBy`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋Œ€๊ฐœ ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ผ๋ถ€ ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๊ผญ ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์— ์•Œ์•„๋‘๋ฉด ์ข‹์„ ๋งŒํ•œ ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/solution.md b/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/solution.md index 52c34640aa..bd0252b4dc 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/solution.md +++ b/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/solution.md @@ -1,8 +1,8 @@ -There's a catch here. +ํ•จ์ •์ด ์žˆ๋Š” ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค. -At the time of `<script>` execution the last DOM node is exactly `<script>`, because the browser did not process the rest of the page yet. +`<script>`๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์—” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ `<script>` ์•„๋ž˜์— ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ DOM ๋…ธ๋“œ๋Š” `<script>` ์ž๊ธฐ ์ž์‹ ์ž…๋‹ˆ๋‹ค. -So the result is `1` (element node). +๋”ฐ๋ผ์„œ ์–ผ๋Ÿฟ์ฐฝ์—” `1`(์š”์†Œ ๋…ธ๋“œ)์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html run height=60 <html> diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/task.md b/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/task.md index 0ed407cae5..4258e2070d 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/task.md +++ b/2-ui/1-document/05-basic-dom-node-properties/2-lastchild-nodetype-inline/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# What's in the nodeType? +# ๋…ธ๋“œ ํƒ€์ž… ๋งž์ถ”๊ธฐ -What does the script show? +์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์˜ˆ์ธกํ•ด๋ณด์„ธ์š”. ```html <html> diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.md b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.md index 0088882c2a..51db3a3828 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.md +++ b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.md @@ -1,4 +1,4 @@ -Let's make a loop over `<li>`: +`<li>`๋ฅผ ์ด์šฉํ•œ ๋ฐ˜๋ณต๋ฌธ์„ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. ```js for (let li of document.querySelectorAll('li')) { @@ -6,16 +6,16 @@ for (let li of document.querySelectorAll('li')) { } ``` -In the loop we need to get the text inside every `li`. +๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ ๊ฐ๊ฐ์˜ `li` ์•ˆ์— ์žˆ๋Š” ํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. -We can read the text from the first child node of `li`, that is the text node: +`li`์˜ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ์ธ ํ…์ŠคํŠธ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ํ…์ŠคํŠธ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js for (let li of document.querySelectorAll('li')) { let title = li.firstChild.data; - // title is the text in <li> before any other nodes + // title์€ <li> ์•ˆ์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋“ค๋ณด๋‹ค ์•ž์— ์œ„์น˜ํ•œ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค. } ``` -Then we can get the number of descendants as `li.getElementsByTagName('li').length`. +๊ทธ๋ฆฌ๊ณ  `li.getElementsByTagName('li').length`๋ฅผ ์ด์šฉํ•ด `li` ๋…ธ๋“œ ์•„๋ž˜์— ์žˆ๋Š” ๋ชจ๋“  `<li>` ํƒœ๊ทธ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.view/index.html b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.view/index.html index 5947ec0977..76a289623d 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.view/index.html +++ b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.view/index.html @@ -3,36 +3,36 @@ <body> <ul> - <li>Animals + <li>์œก์ƒ ๋™๋ฌผ <ul> - <li>Mammals + <li>ํฌ์œ ๋ฅ˜ <ul> - <li>Cows</li> - <li>Donkeys</li> - <li>Dogs</li> - <li>Tigers</li> + <li>์†Œ</li> + <li>๋‹น๋‚˜๊ท€</li> + <li>๊ฐœ</li> + <li>ํ˜ธ๋ž‘์ด</li> </ul> </li> - <li>Other + <li>๋น„ ํฌ์œ ๋ฅ˜ <ul> - <li>Snakes</li> - <li>Birds</li> - <li>Lizards</li> + <li>๋ฑ€</li> + <li>์ƒˆ</li> + <li>๋„๋งˆ๋ฑ€</li> </ul> </li> </ul> </li> - <li>Fishes + <li>์ˆ˜์ƒ ๋™๋ฌผ <ul> - <li>Aquarium + <li>๋‹ด์ˆ˜ ๋™๋ฌผ <ul> - <li>Guppy</li> - <li>Angelfish</li> + <li>๋ถ•์–ด</li> + <li>๋ฉ”๊ธฐ</li> </ul> </li> - <li>Sea + <li>ํ•ด์–‘ ๋™๋ฌผ <ul> - <li>Sea trout</li> + <li>ํ•ด๋งˆ</li> </ul> </li> </ul> @@ -41,12 +41,12 @@ <script> for (let li of document.querySelectorAll('li')) { - // get the title from the text node + // ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์›ํ•˜๋Š” ๊ธ€์ž๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. let title = li.firstChild.data; - title = title.trim(); // remove extra spaces from ends + title = title.trim(); // ํ…์ŠคํŠธ ๋์— ์žˆ๋Š” ๊ณต๋ฐฑ์„ ์ง€์›๋‹ˆ๋‹ค. - // get the descendants count + // ํ›„์† ๋…ธ๋“œ์˜ ๊ฐฏ์ˆ˜๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. let count = li.getElementsByTagName('li').length; alert(title + ': ' + count); diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/source.view/index.html b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/source.view/index.html index fbfacaa88f..89a293bf38 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/source.view/index.html +++ b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/source.view/index.html @@ -1,38 +1,38 @@ -<!DOCTYPE HTML> +๏ปฟ<!DOCTYPE HTML> <html> <body> <ul> - <li>Animals + <li>์œก์ƒ ๋™๋ฌผ <ul> - <li>Mammals + <li>ํฌ์œ ๋ฅ˜ <ul> - <li>Cows</li> - <li>Donkeys</li> - <li>Dogs</li> - <li>Tigers</li> + <li>์†Œ</li> + <li>๋‹น๋‚˜๊ท€</li> + <li>๊ฐœ</li> + <li>ํ˜ธ๋ž‘์ด</li> </ul> </li> - <li>Other + <li>๋น„ ํฌ์œ ๋ฅ˜ <ul> - <li>Snakes</li> - <li>Birds</li> - <li>Lizards</li> + <li>๋ฑ€</li> + <li>์ƒˆ</li> + <li>๋„๋งˆ๋ฑ€</li> </ul> </li> </ul> </li> - <li>Fishes + <li>์ˆ˜์ƒ ๋™๋ฌผ <ul> - <li>Aquarium + <li>๋‹ด์ˆ˜ ๋™๋ฌผ <ul> - <li>Guppy</li> - <li>Angelfish</li> + <li>๋ถ•์–ด</li> + <li>๋ฉ”๊ธฐ</li> </ul> </li> - <li>Sea + <li>ํ•ด์–‘ ๋™๋ฌผ <ul> - <li>Sea trout</li> + <li>ํ•ด๋งˆ</li> </ul> </li> </ul> @@ -40,8 +40,8 @@ </ul> <script> - // ... your code... + // ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. </script> </body> -</html> +</html> \ No newline at end of file diff --git a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/task.md b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/task.md index f2d9edc674..13a73f63a4 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/task.md +++ b/2-ui/1-document/05-basic-dom-node-properties/2-tree-info/task.md @@ -2,13 +2,13 @@ importance: 5 --- -# Count descendants +# ํ›„์† ๋…ธ๋“œ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ -There's a tree structured as nested `ul/li`. +`ul`๊ณผ `li` ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ ํŠธ๋ฆฌ ๊ตฌ์กฐ ๋ฌธ์„œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. -Write the code that for each `<li>` shows: +`li` ๋…ธ๋“œ ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. -1. What's the text inside it (without the subtree) -2. The number of nested `<li>` -- all descendants, including the deeply nested ones. +1. `li` ๋…ธ๋“œ ์•ˆ์— ์žˆ๋Š” ํ…์ŠคํŠธ๋ฅผ ์ถœ๋ ฅ +2. `li` ๋…ธ๋“œ ์•„๋ž˜์— ์žˆ๋Š” ๋ชจ๋“  `<li>` ํƒœ๊ทธ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ถœ๋ ฅ [demo src="solution"] diff --git a/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/solution.md b/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/solution.md index 32900a7896..cd02148217 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/solution.md +++ b/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/solution.md @@ -1,4 +1,4 @@ -The answer: **`BODY`**. +**`BODY`**๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html run <script> @@ -10,8 +10,8 @@ The answer: **`BODY`**. </script> ``` -What's going on step by step: +์ฐจ๊ทผ์ฐจ๊ทผ ์„ค๋ช…ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -1. The content of `<body>` is replaced with the comment. The comment is `<!--BODY-->`, because `body.tagName == "BODY"`. As we remember, `tagName` is always uppercase in HTML. -2. The comment is now the only child node, so we get it in `body.firstChild`. -3. The `data` property of the comment is its contents (inside `<!--...-->`): `"BODY"`. +1. `<body>`์˜ ์ฝ˜ํ…์ธ ๊ฐ€ `<!--BODY-->`๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. `body.tagName`์€ `"BODY"`์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `tagName`์€ ํ•ญ์ƒ ๋Œ€๋ฌธ์ž๋ผ๋Š” ์ ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. +2. `<body>`์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ๊ต์ฒด๋˜๋ฉด์„œ ์ฃผ์„์ด ์œ ์ผํ•œ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `body.firstChild`์„ ์‚ฌ์šฉํ•ด ์ฃผ์„์„ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +3. ์ฃผ์„ ๋…ธ๋“œ์˜ `data` ํ”„๋กœํผํ‹ฐ์—” ์ฃผ์„ ๋‚ด์šฉ(`<!--...-->` ์•ˆ์ชฝ์˜ ๋‚ด์šฉ)์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `data` ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์€ `"BODY"`์ž…๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/task.md b/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/task.md index efe50b48f2..33aa22bbe1 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/task.md +++ b/2-ui/1-document/05-basic-dom-node-properties/3-tag-in-comment/task.md @@ -2,9 +2,9 @@ importance: 3 --- -# Tag in comment +# ์ฃผ์„ ์•ˆ์˜ ํƒœ๊ทธ -What does this code show? +์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์˜ˆ์ธกํ•ด๋ณด์„ธ์š”. ```html <script> @@ -12,6 +12,6 @@ What does this code show? body.innerHTML = "<!--" + body.tagName + "-->"; - alert( body.firstChild.data ); // what's here? + alert( body.firstChild.data ); // ์–ผ๋Ÿฟ ์ฐฝ์—” ์–ด๋–ค ๋‚ด์šฉ์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? </script> ``` diff --git a/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/solution.md b/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/solution.md index cb9456717b..099a64fffc 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/solution.md +++ b/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/solution.md @@ -1,33 +1,33 @@ -We can see which class it belongs by outputting it, like: +`document` ๋…ธ๋“œ๊ฐ€ ์–ด๋–ค ํด๋ž˜์Šค์— ์†ํ•ด์žˆ๋Š”์ง€๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run alert(document); // [object HTMLDocument] ``` -Or: +์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋กœ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run alert(document.constructor.name); // HTMLDocument ``` -So, `document` is an instance of `HTMLDocument` class. +์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด `document`๋Š” `HTMLDocument` ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. -What's its place in the hierarchy? +๊ทธ๋ ‡๋‹ค๋ฉด `HTMLDocument` ํด๋ž˜์Šค๋Š” DOM ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ์–ด๋””์— ์žˆ์„๊นŒ์š”? -Yeah, we could browse the specification, but it would be faster to figure out manually. +๋ช…์„ธ์„œ๋ฅผ ํ™•์ธํ•˜๋ฉด ์•Œ ์ˆ˜ ์žˆ๊ธด ํ•˜์ง€๋งŒ, ์ง์ ‘ ๋งŒ๋“  ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์น˜๋ฅผ ๋” ๋นจ๋ฆฌ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Let's traverse the prototype chain via `__proto__`. +`__proto__`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€ ๋ด…์‹œ๋‹ค. -As we know, methods of a class are in the `prototype` of the constructor. For instance, `HTMLDocument.prototype` has methods for documents. +์•„์‹œ๋‹ค์‹œํ”ผ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋Š” ์ƒ์„ฑ์ž์˜ `prototype`์— ๊ตฌํ˜„๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. `document`์˜ ๋ฉ”์„œ๋“œ๋Š” `HTMLDocument.prototype`์— ๊ตฌํ˜„๋˜์–ด ์žˆ์ฃ . -Also, there's a reference to the constructor function inside the `prototype`: +์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ `prototype` ์•ˆ์—๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ฐธ์กฐ ์—ญ์‹œ ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. ```js run alert(HTMLDocument.prototype.constructor === HTMLDocument); // true ``` -To get a name of the class as a string, we can use `constructor.name`. Let's do it for the whole `document` prototype chain, till class `Node`: +ํด๋ž˜์Šค ์ด๋ฆ„์„ ์–ป์œผ๋ ค๋ฉด `constructor.name`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. `Node` ํด๋ž˜์Šค๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ `document`์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ „์ฒด๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run alert(HTMLDocument.prototype.constructor.name); // HTMLDocument @@ -35,6 +35,6 @@ alert(HTMLDocument.prototype.__proto__.constructor.name); // Document alert(HTMLDocument.prototype.__proto__.__proto__.constructor.name); // Node ``` -That's the hierarchy. +์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We also could examine the object using `console.dir(document)` and see these names by opening `__proto__`. The console takes them from `constructor` internally. +์ด ์™ธ์—๋„ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ `console.dir(document)`๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ , `__proto__`์— ์ €์žฅ๋œ ์ •๋ณด๋ฅผ ํ†ตํ•ด ์ด๋ฆ„์„ ์•Œ์•„๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†” ๋‚ด๋ถ€์—์„œ ์ž๋™์œผ๋กœ `constructor`์˜ ์ด๋ฆ„์„ ์ถ”์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/task.md b/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/task.md index de266c6ae9..0aecfc59c1 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/task.md +++ b/2-ui/1-document/05-basic-dom-node-properties/4-where-document-in-hierarchy/task.md @@ -2,10 +2,10 @@ importance: 4 --- -# Where's the "document" in the hierarchy? +# DOM ๊ณ„์ธต ๊ตฌ์กฐ์™€ 'document' -Which class does the `document` belong to? +`document`๋Š” ์–ด๋–ค ํด๋ž˜์Šค์— ์†ํ• ๊นŒ์š”? -What's its place in the DOM hierarchy? +DOM ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ `document`์ด ์†ํ•œ ํด๋ž˜์Šค๋Š” ์–ด๋””์— ์œ„์น˜ํ•ด ์žˆ์„๊นŒ์š”? -Does it inherit from `Node` or `Element`, or maybe `HTMLElement`? +์ด ํด๋ž˜์Šค๋Š” `Node`, `Element`, `HTMLElement` ์ค‘ ์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์„๊นŒ์š”? diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md index f815bf2253..e850e97838 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/article.md +++ b/2-ui/1-document/05-basic-dom-node-properties/article.md @@ -1,58 +1,58 @@ -# ๋…ธ๋“œ ํ”„๋กœํผํ‹ฐ: ํƒ€์ž…, ํƒœ๊ทธ ๊ทธ๋ฆฌ๊ณ  ๋‚ด์šฉ(type, tag and contents) +# ์ฃผ์š” ๋…ธ๋“œ ํ”„๋กœํผํ‹ฐ -DOM ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ ์ข€ ๋” ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. +DOM ๋…ธ๋“œ์— ๋Œ€ํ•ด ์ข€ ๋” ์•Œ์•„๋ด…์‹œ๋‹ค. -In this chapter we'll see more into what they are and learn their most used properties. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  DOM ๋…ธ๋“œ๋ž€ ๋ฌด์—‡์ธ์ง€, DOM ๋…ธ๋“œ์˜ ์ฃผ์š” ํ”„๋กœํผํ‹ฐ๋Š” ๋ฌด์—‡์ด ์žˆ๋Š”์ง€ ํ•™์Šตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ## DOM ๋…ธ๋“œ ํด๋ž˜์Šค -Different DOM nodes may have different properties. For instance, an element node corresponding to tag `<a>` has link-related properties, and the one corresponding to `<input>` has input-related properties and so on. Text nodes are not the same as element nodes. But there are also common properties and methods between all of them, because all classes of DOM nodes form a single hierarchy. +DOM ๋…ธ๋“œ๋Š” ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๊ฐ๊ฐ ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํƒœ๊ทธ `<a>`์— ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ ๋…ธ๋“œ์—” ๋งํฌ ๊ด€๋ จ๋œ ํ”„๋กœํผํ‹ฐ๋ฅผ, `<input>`์— ๋Œ€์‘ํ•˜๋Š” ์š”์†Œ ๋…ธ๋“œ์—” ์ž…๋ ฅ ๊ด€๋ จํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•˜์ฃ . ํ…์ŠคํŠธ ๋…ธ๋“œ๋Š” ์š”์†Œ ๋…ธ๋“œ์™€ ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์€ ๋งํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ชจ๋“  DOM ๋…ธ๋“œ๋Š” ๊ณตํ†ต ์กฐ์ƒ์œผ๋กœ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋…ธ๋“œ ์ข…๋ฅ˜๋Š” ๋‹ค๋ฅด์ง€๋งŒ, ๋ชจ๋“  DOM ๋…ธ๋“œ๋Š” ๊ณตํ†ต๋œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -๊ฐ๊ฐ์˜ DOM ๋…ธ๋“œ๋Š” ๊ทธ์— ๋Œ€์‘ํ•˜๋Š” ๋‚ด์žฅ ํด๋ž˜์Šค์— ์†ํ•ฉ๋‹ˆ๋‹ค. +DOM ๋…ธ๋“œ๋Š” ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋Œ€์‘ํ•˜๋Š” ๋‚ด์žฅ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -๊ณ„์ธต๊ตฌ์กฐ์˜ ๊ผญ๋Œ€๊ธฐ์—” [EventTarget](https://dom.spec.whatwg.org/#eventtarget)์ด ์žˆ๊ณ , [Node](http://dom.spec.whatwg.org/#interface-node)๋Š” ์ด EventTarget์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ DOM ๋…ธ๋“œ๋“ค์€ Node๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. +๊ณ„์ธต ๊ตฌ์กฐ ๊ผญ๋Œ€๊ธฐ์—” [EventTarget](https://dom.spec.whatwg.org/#eventtarget)์ด ์žˆ๋Š”๋ฐ, [Node](http://dom.spec.whatwg.org/#interface-node)๋Š” EventTarget์„, ๋‹ค๋ฅธ DOM ๋…ธ๋“œ๋“ค์€ Node ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. -์•„๋ž˜ ๊ทธ๋ฆผ์€ ์ด๋Ÿฐ ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ์ž˜ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ๊ด€๊ณ„๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](dom-class-hierarchy.svg) -๋…ธ๋“œ ํด๋ž˜์Šค: +๊ฐ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ์ง€๋‹™๋‹ˆ๋‹ค. -- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class. Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later. -- [Node](http://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base for DOM nodes. It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are concrete node classes that inherit from it, namely: `Text` for text nodes, `Element` for element nodes and more exotic ones like `Comment` for comment nodes. -- [Element](http://dom.spec.whatwg.org/#interface-element) -- is a base class for DOM elements. It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`. A browser supports not only HTML, but also XML and SVG. The `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` and `HTMLElement`. -- [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) -- is finally the basic class for all HTML elements. It is inherited by concrete HTML elements: - - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `<input>` elements, - - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `<body>` elements, - - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `<a>` elements, - - ...and so on, each tag has its own class that may provide specific properties and methods. +- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- ๋ฃจํŠธ์— ์žˆ๋Š” '์ถ”์ƒ(abstract)' ํด๋ž˜์Šค๋กœ, ์ด ํด๋ž˜์Šค์— ๋Œ€์‘ํ•˜๋Š” ๊ฐ์ฒด๋Š” ์‹ค์ œ๋กœ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. EventTarget๊ฐ€ ๋ชจ๋“  DOM ๋…ธ๋“œ์˜ ๋ฒ ์ด์Šค์— ์žˆ๊ธฐ๋•Œ๋ฌธ์— DOM ๋…ธ๋“œ์—์„œ '์ด๋ฒคํŠธ'๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณง ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +- [Node](http://dom.spec.whatwg.org/#interface-node) -- ์—ญ์‹œ '์ถ”์ƒ' ํด๋ž˜์Šค๋กœ, DOM ๋…ธ๋“œ์˜ ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. getter ์—ญํ• ์„ ํ•˜๋Š” `parentNode`, `nextSibling`, `childNodes` ๋“ฑ์˜ ์ฃผ์š” ํŠธ๋ฆฌ ํƒ์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. `Node` ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋Š” ์ ˆ๋Œ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๋Š” ์—ฌ๋Ÿฟ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์œ„ํ•œ `Text` ํด๋ž˜์Šค์™€ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ์œ„ํ•œ `Element` ํด๋ž˜์Šค, ์ฃผ์„ ๋…ธ๋“œ๋ฅผ ์œ„ํ•œ `Comment`ํด๋ž˜์Šค๋Š” `Node`ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. +- [Element](http://dom.spec.whatwg.org/#interface-element) -- DOM ์š”์†Œ๋ฅผ ์œ„ํ•œ ๋ฒ ์ด์Šค ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. `nextElementSibling`, `children` ์ด๋‚˜ `getElementsByTagName`, `querySelector` ๊ฐ™์ด ์š”์†Œ ์ „์šฉ ํƒ์ƒ‰์„ ๋„์™€์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” HTML๋ฟ๋งŒ ์•„๋‹ˆ๋ผ XML, SVG๋„ ์ง€์›ํ•˜๋Š”๋ฐ `Element` ํด๋ž˜์Šค๋Š” ์ด์™€ ๊ด€๋ จ๋œ `SVGElement`, `XMLElement`, `HTMLElement` ํด๋ž˜์Šค์˜ ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +- [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) -- HTML ์š”์†Œ ๋…ธ๋“œ์˜ ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ๋‚˜์—ดํ•œ ํด๋ž˜์Šค๋“ค์€ ์‹ค์ œ HTML ์š”์†Œ์— ๋Œ€์‘ํ•˜๊ณ  `HTMLElement`๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. + - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- `<input>` ์š”์†Œ์— ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค + - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- `<body>` ์š”์†Œ์— ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค + - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- `<a>` ์š”์†Œ์— ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค + - ์ด์™ธ์—๋„ ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ๋งŽ์€๋ฐ, ๊ฐ ํƒœ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋Š” ๊ณ ์œ ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -๊ฐ ๋…ธ๋“œ์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ƒ์†์œผ๋กœ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ํŠน์ • ๋…ธ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ƒ์†์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. -For example, let's consider the DOM object for an `<input>` element. It belongs to [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) class. +`<input>` ์š”์†Œ์— ๋Œ€์‘ํ•˜๋Š” DOM ๊ฐ์ฒด๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ด…์‹œ๋‹ค. ์ด ๊ฐ์ฒด๋Š” [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. -It gets properties and methods as a superposition of (listed in inheritance order): +๊ฐ์ฒด์—” ์•„๋ž˜์— ๋‚˜์—ดํ•œ ํด๋ž˜์Šค์—์„œ ์ƒ์†๋ฐ›์€ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -- `HTMLInputElement` -- this class provides input-specific properties, -- `HTMLElement` -- it provides common HTML element methods (and getters/setters), -- `Element` -- provides generic element methods, -- `Node` -- provides common DOM node properties,. -- `EventTarget` -- gives the support for events (to be covered), -- ...and finally it inherits from `Object`, so "plain object" methods like `hasOwnProperty` are also available. +- `HTMLInputElement` -- ์ž…๋ ฅ ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค +- `HTMLElement` -- HTML ์š”์†Œ ๋ฉ”์„œ๋“œ์™€ getter, setter๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค +- `Element` -- ์š”์†Œ ๋…ธ๋“œ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค +- `Node` -- ๊ณตํ†ต DOM ๋…ธ๋“œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค +- `EventTarget` -- ์ด๋ฒคํŠธ ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค +- `Object` -- `hasOwnProperty`๊ฐ™์ด '์ผ๋ฐ˜ ๊ฐ์ฒด' ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค -DOM ๋…ธ๋“œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ํ™•์ธํ•˜๋ ค๋ฉด ๊ฐ์ฒด๊ฐ€ `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„๋‹ค๋Š” ์ ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `constructor` ํ”„๋กœํผํ‹ฐ๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ์ฐธ์กฐํ•˜๊ณ , `constructor.name`์„ ํ†ตํ•ด ์ด๋ฆ„์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” ์•ž์„œ ๊ฐ์ฒด๋Š” `constructor` ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„๋‹ค๋Š” ๊ฑธ ๋ฐฐ์šด ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•˜๋ฉด DOM ๋…ธ๋“œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `constructor` ํ”„๋กœํผํ‹ฐ๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์ด๋ฆ„์€ `constructor.name`์— ์ €์žฅ๋˜์–ด์žˆ๋‹ค๋Š” ์ ์„ ์ด์šฉํ•˜๋ฉด ๋˜์ฃ . ```js run alert( document.body.constructor.name ); // HTMLBodyElement ``` -...`toString`์„ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค: +`toString`์„ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. ```js run alert( document.body ); // [object HTMLBodyElement] ``` -`instanceof` ๋ฅผ ์‚ฌ์šฉํ•ด ์ƒ์† ๊ด€๊ณ„๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์ƒ์† ์—ฌ๋ถ€๋Š” `instanceof`๋ฅผ ์‚ฌ์šฉํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run alert( document.body instanceof HTMLBodyElement ); // true @@ -62,38 +62,38 @@ alert( document.body instanceof Node ); // true alert( document.body instanceof EventTarget ); // true ``` -์œ„์—์„œ ํ™•์ธํ•œ ๋ฐ”์™€ ๊ฐ™์ด DOM ๋…ธ๋“œ๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ด๋ฏ€๋กœ, ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜์˜ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด DOM ๋…ธ๋“œ๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ฐ–๋Š” ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. -๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์— `console.dir(elem)`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ด๋Ÿฐ ๊ด€๊ณ„๋ฅผ ๋ˆˆ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `HTMLElement.prototype`, `Element.prototype`๋“ฑ์ด ์ฝ˜์†”์— ์ถœ๋ ฅ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์— `console.dir(elem)`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ด๋Ÿฐ ๊ด€๊ณ„๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `HTMLElement.prototype`, `Element.prototype`๋“ฑ์ด ์ฝ˜์†”์— ์ถœ๋ ฅ๋  ๊ฒ๋‹ˆ๋‹ค. -```smart header="`console.dir(elem)` ์™€ `console.log(elem)`" -๋ธŒ๋ผ์šฐ์ € ๋Œ€๋ถ€๋ถ„์€ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ `console.log` ์™€ `console.dir` ๋ช…๋ น์–ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋“ค์€ ์ฝ˜์†”์— ์ธ์ˆ˜(argument)๋ฅผ ์ถœ๋ ฅํ•ด์ค๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์—์„  ์ด ๋‘ ๋ช…๋ น์–ด๊ฐ€ ๊ฐ์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +```smart header="`console.dir(elem)`๊ณผ `console.log(elem)`์˜ ์ฐจ์ด" +๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๋Œ€๋ถ€๋ถ„์€ `console.log`์™€ `console.dir` ๋ช…๋ น์–ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋“ค์€ ์ฝ˜์†”์— ์ธ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ด์ค๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋ผ๋ฉด ๋‘ ๋ช…๋ น์–ด๋Š” ๋Œ€๊ฐœ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ DOM ์š”์†Œ์—์„  ๋‹ค๋ฅธ ์ถœ๋ ฅ๊ฐ’์„ ๋ณด์ž…๋‹ˆ๋‹ค: +ํ•˜์ง€๋งŒ ์ธ์ˆ˜๊ฐ€ DOM ์š”์†Œ์ผ ๋•Œ๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -- `console.log(elem)` ๋Š” ์š”์†Œ(elem)์˜ DOM ํŠธ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , -- `console.dir(elem)` ๋Š” ์š”์†Œ(elem)๋ฅผ DOM ๊ฐ์ฒด์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•˜์—ฌ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +- `console.log(elem)`๋Š” ์š”์†Œ์˜ DOM ํŠธ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. +- `console.dir(elem)`๋Š” ์š”์†Œ๋ฅผ DOM ๊ฐ์ฒด์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•˜์—ฌ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -`document.body`๋ฅผ ํ†ตํ•ด ๊ทธ ์ฐจ์ด๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด์„ธ์š”. +`document.body`๋ฅผ ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์„œ ๊ทธ ์ฐจ์ด๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด๋ณด์„ธ์š”. ``` -````smart header="์ŠคํŽ™ ๋ฌธ์„œ์—์„œ ์“ฐ์ด๋Š” IDL" -์ŠคํŽ™ ๋ฌธ์„œ์—์„  DOM ํด๋ž˜์Šค๋ฅผ JavaScript๊ฐ€ ์•„๋‹Œ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ํ‘œ๊ธฐ๋ฒ•์ธ [Interface description language](https://en.wikipedia.org/wiki/Interface_description_language) (IDL)์„ ์ด์šฉํ•˜์—ฌ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. +````smart header="๋ช…์„ธ์„œ์—์„œ ์“ฐ์ด๋Š” IDL" +๋ช…์„ธ์„œ์—์„  DOM ํด๋ž˜์Šค๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  [Interface Description Language(IDL)](https://en.wikipedia.org/wiki/Interface_description_language)๋ฅผ ์ด์šฉํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. -IDL์€ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์˜ ์•ž์— ํƒ€์ž…์„ ๋ถ™์—ฌ์„œ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. `DOMString`๊ณผ `boolean` ๊ณผ ๊ฐ™์€ ํƒ€์ž…์ด ํ”„๋กœํผํ‹ฐ ์•ž์— ๋ถ™๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +IDL์—์„  ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ ์•ž์— ํƒ€์ž…์„ ๋ถ™์ž…๋‹ˆ๋‹ค. `DOMString`๊ณผ `boolean` ๊ฐ™์€ ํƒ€์ž…์ด ํ”„๋กœํผํ‹ฐ ์•ž์— ๋ถ™์ฃ . -์•„๋ž˜๋Š” ์ŠคํŽ™ ๋ฌธ์„œ์˜ ์ผ๋ถ€๋ฅผ ๋ฐœ์ทŒํ•˜์—ฌ ์ฃผ์„์„ ๋‹ฌ์•„๋†“์€ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค: +๋ช…์„ธ์„œ ์ผ๋ถ€์— ์ฃผ์„์„ ๋‹ฌ์•„๋†“์•˜์œผ๋‹ˆ ํ•จ๊ป˜ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js -// HTMLInputElement๋ฅผ ์ •์˜ +// HTMLInputElement ์ •์˜ ์‹œ์ž‘ *!* -// ์ฝœ๋ก  ":" ์€ HTMLInputElement๊ฐ€ HTMLElement๋กœ ๋ถ€ํ„ฐ ์ƒ์†๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ +// ์ฝœ๋ก (:)์€ HTMLInputElement๊ฐ€ HTMLElement๋กœ ๋ถ€ํ„ฐ ์ƒ์†๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. */!* interface HTMLInputElement: HTMLElement { - // <input> elements ์™€ ๊ด€๋ จ๋œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ + // <input> ์š”์†Œ์™€ ๊ด€๋ จ๋œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‚˜์—ด๋˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. *!* - // "DOMString"์€ ์•„๋ž˜ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด ๋ฌธ์ž์—ด์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ + // 'DOMString'์€ ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋ฌธ์ž์—ด์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. */!* attribute DOMString accept; attribute DOMString alt; @@ -101,12 +101,12 @@ interface HTMLInputElement: HTMLElement { attribute DOMString value; *!* - // ๋ถˆ๋ฆฐ๊ฐ’์„ ๊ฐ€์ง€๋Š” ํ”„๋กœํผํ‹ฐ (true/false) + // ๋ถˆ๋ฆฐ ๊ฐ’(true/false)์„ ๊ฐ€์ง€๋Š” ํ”„๋กœํผํ‹ฐ attribute boolean autofocus; */!* ... *!* - // "void"๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด๊ฐ’์ด ์—†์Œ์„ ์˜๋ฏธํ•จ + // 'void'๋Š” ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด๊ฐ’์ด ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. */!* void select(); ... @@ -114,15 +114,15 @@ interface HTMLInputElement: HTMLElement { ``` ```` -## nodeType ํ”„๋กœํผํ‹ฐ +## 'nodeType' ํ”„๋กœํผํ‹ฐ -`nodeType` ํ”„๋กœํผํ‹ฐ๋Š” DOM ๋…ธ๋“œ์˜ "ํƒ€์ž…"์„ ์•Œ์•„๋‚ด๊ณ ์ž ํ•  ๋•Œ ์“ฐ์ด๋Š” ์˜›๋‚ ์‹์˜ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. +`nodeType` ํ”„๋กœํผํ‹ฐ๋Š” DOM ๋…ธ๋“œ์˜ 'ํƒ€์ž…'์„ ์•Œ์•„๋‚ด๊ณ ์ž ํ•  ๋•Œ ์“ฐ์ด๋Š” ๊ตฌ์‹ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. -๋…ธ๋“œ ํƒ€์ž…์€ ์ƒ์ˆซ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค: -- `elem.nodeType == 1` ์€ ์š”์†Œ ๋…ธ๋“œ, -- `elem.nodeType == 3` ์€ ํ…์ŠคํŠธ(Text) ๋…ธ๋“œ, -- `elem.nodeType == 9` ์€ DOCUMENT ๊ฐ์ฒด(document object)๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , -- [์ŠคํŽ™ ๋ฌธ์„œ](https://dom.spec.whatwg.org/#node)๋กœ ๊ฐ€๋ฉด ๋‹ค์–‘ํ•œ ๋…ธ๋“œ ํƒ€์ž…์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฐ ๋…ธ๋“œ ํƒ€์ž…์€ ์ƒ์ˆซ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. +- `elem.nodeType == 1` -- ์š”์†Œ ๋…ธ๋“œ +- `elem.nodeType == 3` -- ํ…์ŠคํŠธ ๋…ธ๋“œ +- `elem.nodeType == 9` -- ๋ฌธ์„œ ๊ฐ์ฒด +- ๊ธฐํƒ€ ๋…ธ๋“œ ํƒ€์ž…์— ๋Œ€ํ•œ ๊ฐ’์€ [๋ช…์„ธ์„œ](https://dom.spec.whatwg.org/#node)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: @@ -131,150 +131,150 @@ interface HTMLInputElement: HTMLElement { <script> let elem = document.body; - // ์–ด๋–ค ํƒ€์ž…์ผ๊นŒ์š”? - alert(elem.nodeType); // 1 => ์š”์†Œ + // ํƒ€์ž…์„ ์•Œ์•„๋ด…์‹œ๋‹ค. + alert(elem.nodeType); // 1 => ์š”์†Œ ๋…ธ๋“œ - // ์ฒซ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ๋Š”... - alert(elem.firstChild.nodeType); // 3 => ํ…์ŠคํŠธ + // ์ฒซ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ + alert(elem.firstChild.nodeType); // 3 => ํ…์ŠคํŠธ ๋…ธ๋“œ - // ๋ฌธ์„œ๊ฐ์ฒด๋Š” ํƒ€์ž…์ด 9 - alert( document.nodeType ); // 9 + // ๋ฌธ์„œ ๊ฐ์ฒด์˜ ํƒ€์ž… ํ™•์ธ + alert( document.nodeType ); // 9 => ๋ฌธ์„œ ๊ฐ์ฒด </script> </body> ``` -๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ๋…ธ๋“œ ํƒ€์ž…์„ `instanceof`๋‚˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ€๋”์€ `nodeType`๋ฅผ ์“ฐ๋Š” ๊ฒŒ ๊ฐ„๋‹จํ•  ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `nodeType`์„ ์“ฐ๋ฉด ์˜ค์ง ํƒ€์ž…์„ ์ฝ๊ธฐ๋งŒ ํ•˜๊ณ  ๋ฐ”๊พธ์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. +๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ๋…ธ๋“œ์˜ ํƒ€์ž…์„ `instanceof`๋‚˜ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด ํ™•์ธํ•˜๋Š”๋ฐ, ๊ฐ€๋”์€ `nodeType`๋ฅผ ์“ฐ๋Š” ๊ฒŒ ๊ฐ„๋‹จํ•  ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `nodeType`์€ ํƒ€์ž… ํ™•์ธ ํ•˜๋Š” ๋ฐ๋งŒ ์“ธ ์ˆ˜ ์žˆ๊ณ  ๋ฐ”๊พธ์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. -## ํƒœ๊ทธ: nodeName ๊ณผ tagName +## nodeName๊ณผ tagName์œผ๋กœ ํƒœ๊ทธ ์ด๋ฆ„ ํ™•์ธํ•˜๊ธฐ -`nodeName` ์ด๋‚˜ `tagName` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DOM ๋…ธ๋“œ์˜ ํƒœ๊ทธ ์ด๋ฆ„์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`nodeName`์ด๋‚˜ `tagName` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DOM ๋…ธ๋“œ์˜ ํƒœ๊ทธ ์ด๋ฆ„์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜ˆ: +์˜ˆ์‹œ: ```js run alert( document.body.nodeName ); // BODY alert( document.body.tagName ); // BODY ``` -๊ทธ๋Ÿผ `tagName` ๊ณผ `nodeName` ์ฐจ์ด๋Š” ์—†๋Š”๊ฑธ๊นŒ์š”? +๊ทธ๋Ÿผ `tagName`๊ณผ `nodeName`์˜ ์ฐจ์ด๋Š” ์—†๋Š” ๊ฑธ๊นŒ์š”? -๋ฌผ๋ก  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ๋ฌ˜ํ•˜์ง€๋งŒ ์ด๋ฆ„์—์„œ ๊ทธ ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ฌผ๋ก  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ๋ฌ˜ํ•˜์ง€๋งŒ ์ด๋ฆ„์—์„œ ๊ทธ ์ฐจ์ด๋ฅผ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ์ฃ . -- `tagName` ํ”„๋กœํผํ‹ฐ๋Š” `์š”์†Œ(Element)` ๋…ธ๋“œ์—๋งŒ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -- `nodeName`์€ ๋ชจ๋“  `Node`์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: - - ์š”์†Œ๋…ธ๋“œ์—์„  `tagName`๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. - - text, comment ๋“ฑ์˜ ๋…ธ๋“œ ํƒ€์ž…์—์„  ๋…ธ๋“œ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. +- `tagName` ํ”„๋กœํผํ‹ฐ๋Š” `์š”์†Œ` ๋…ธ๋“œ์—๋งŒ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. +- `nodeName`์€ ๋ชจ๋“  `Node`์— ์žˆ์Šต๋‹ˆ๋‹ค. + - ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉด `tagName`๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. + - ํ…์ŠคํŠธ ๋…ธ๋“œ, ์ฃผ์„ ๋…ธ๋“œ ๋“ฑ์—์„  ๋…ธ๋“œ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. `nodeName`์€ ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ์ง€์›๋˜์ง€๋งŒ, `tagName`์€ `Element` ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์œ ๋ž˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์š”์†Œ ๋…ธ๋“œ์—์„œ๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค. -`document`์™€ comment ๋…ธ๋“œ๋กœ `tagName` ๊ณผ `nodeName`์˜ ์ฐจ์ด์ ์„ ํ™•์ธ ํ•ด ๋ด…์‹œ๋‹ค: +`document`์™€ ์ฃผ์„ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด `tagName`๊ณผ `nodeName`์˜ ์ฐจ์ด์ ์„ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. ```html run -<body><!-- comment --> +<body><!-- ์ฃผ์„ --> <script> - // for comment + // ์ฃผ์„ ๋…ธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋‘ ํ”„๋กœํผํ‹ฐ ๋น„๊ต alert( document.body.firstChild.tagName ); // undefined (์š”์†Œ๊ฐ€ ์•„๋‹˜) alert( document.body.firstChild.nodeName ); // #comment - // for document + // ๋ฌธ์„œ ๋…ธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋‘ ํ”„๋กœํผํ‹ฐ ๋น„๊ต alert( document.tagName ); // undefined (์š”์†Œ๊ฐ€ ์•„๋‹˜) alert( document.nodeName ); // #document </script> </body> ``` -์š”์†Œ๋งŒ ๋‹ค๋ฃจ๊ณ  ์žˆ๋‹ค๋ฉด `tagName`๊ณผ `nodeName`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‘˜์—๋Š” ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +์š”์†Œ ๋…ธ๋“œ๋งŒ ๋‹ค๋ฃจ๊ณ  ์žˆ๋‹ค๋ฉด `tagName`๊ณผ `nodeName`์—๋Š” ์ฐจ์ด๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋‘˜ ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```smart header="ํƒœ๊ทธ ์ด๋ฆ„์€ XHTML์„ ์ œ์™ธํ•˜๊ณ  ํ•ญ์ƒ ๋Œ€๋ฌธ์ž์ž…๋‹ˆ๋‹ค" -๋ธŒ๋ผ์šฐ์ €๋Š” HTML๊ณผ XML์œ ํ˜•์˜ ๋ฌธ์„œ๋ฅผ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์›นํŽ˜์ด์ง€๋Š” ๋Œ€๊ฒŒ HTML ๋ชจ๋“œ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ํ—ค๋”๊ฐ€ `Content-Type: application/xml+xhtml`์ธ XML-๋ฌธ์„œ์˜ ๊ฒฝ์šฐ๋Š” XML ๋ชจ๋“œ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. +```smart header="ํƒœ๊ทธ ์ด๋ฆ„์€ XML ๋ชจ๋“œ๋ฅผ ์ œ์™ธํ•˜๊ณ  ํ•ญ์ƒ ๋Œ€๋ฌธ์ž์ž…๋‹ˆ๋‹ค." +๋ธŒ๋ผ์šฐ์ €์—์„œ HTML๊ณผ XML์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ชจ๋“œ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์›นํŽ˜์ด์ง€๋Š” ๋Œ€๊ฐœ HTML ๋ชจ๋“œ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ํ—ค๋”๊ฐ€ `Content-Type: application/xml+xhtml`์ธ XML ๋ฌธ์„œ๋ฅผ ๋ฐ›์œผ๋ฉด XML ๋ชจ๋“œ๋กœ ๋ฌธ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -HTML ๋ชจ๋“œ์—์„  `tagName/nodeName`์ด ๋ชจ๋‘ ๋Œ€๋ฌธ์ž๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. `<body>` ์ด๋“  `<BoDy>` ์ƒ๊ด€์—†์ด `BODY`๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. +HTML ๋ชจ๋“œ์—์„  `tagName`๊ณผ `nodeName`์ด ๋ชจ๋‘ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. `<body>` ์ด๋“  `<BoDy>`์ด๋“  `BODY`๊ฐ€ ๋˜์ฃ . -XML ๋ชจ๋“œ์—์„  ๋ฌธ์ž๊ฐ€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๋Š”๋ฐ, ์ตœ๊ทผ์—” ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +XML ๋ชจ๋“œ์—์„  ์ผ€์ด์Šค๊ฐ€ '๊ทธ๋Œ€๋กœ' ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. XML ๋ชจ๋“œ๋Š” ์š”์ฆ˜์—” ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` -## innerHTML: ๋‚ด์šฉ ๋“ค์—ฌ๋‹ค๋ณด๊ธฐ +## innerHTML๋กœ ๋‚ด์šฉ ์กฐ์ž‘ํ•˜๊ธฐ -[innerHTML](https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML) ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ ์•ˆ์˜ HTML์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[innerHTML](https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML) ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ ์•ˆ์˜ HTML์„ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์š”์†Œ ์•ˆ์˜ HTML์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. innerHTML์€ ํŽ˜์ด์ง€๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์“ฐ์ด๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. +์š”์†Œ ์•ˆ HTML์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. innerHTML์€ ํŽ˜์ด์ง€๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์“ฐ์ด๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” `document.body`์•ˆ์˜ ๋‚ด์šฉ(contents)์„ ์ถœ๋ ฅํ•˜๊ณ  ์™„์ „ํžˆ ๋ฐ”๊พธ๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค: +`document.body` ์•ˆ์˜ ๋‚ด์šฉ์„ ์ถœ๋ ฅํ•˜๊ณ  ์™„์ „ํžˆ ๋ฐ”๊พธ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run <body> - <p>A paragraph</p> - <div>A div</div> + <p>p ํƒœ๊ทธ</p> + <div>div ํƒœ๊ทธ</div> <script> - alert( document.body.innerHTML ); // read the current contents - document.body.innerHTML = 'The new BODY!'; // replace it + alert( document.body.innerHTML ); // ๋‚ด์šฉ ์ฝ๊ธฐ + document.body.innerHTML = '์ƒˆ๋กœ์šด BODY!'; // ๊ต์ฒด </script> </body> ``` -๋ฌธ๋ฒ•์ด ํ‹€๋ฆฐ HTML์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ ์ด๋ฅผ ๊ณ ์ณ ์ค„ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค: +๋ฌธ๋ฒ•์ด ํ‹€๋ฆฐ HTML์„ ๋„ฃ์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ ๊ณ ์ณ ์ค๋‹ˆ๋‹ค. ```html run <body> <script> - document.body.innerHTML = '<b>test'; // forgot to close the tag - alert( document.body.innerHTML ); // <b>test</b> (fixed) + document.body.innerHTML = '<b>test'; // ๋‹ซ๋Š” ํƒœ๊ทธ๋ฅผ ์žŠ์Œ + alert( document.body.innerHTML ); // <b>test</b> (์ž๋™์œผ๋กœ ์ˆ˜์ •๋จ) </script> </body> ``` -```smart header="Scripts don't execute" -If `innerHTML` inserts a `<script>` tag into the document -- it becomes a part of HTML, but doesn't execute. +```smart header="์Šคํฌ๋ฆฝํŠธ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค." +`innerHTML`์„ ์‚ฌ์šฉํ•ด ๋ฌธ์„œ์— `<script>` ํƒœ๊ทธ๋ฅผ ์‚ฝ์ž…ํ•˜๋ฉด ํ•ด๋‹น ํƒœ๊ทธ๋Š” HTML์˜ ์ผ๋ถ€๊ฐ€ ๋˜๊ธด ํ•˜์ง€๋งŒ ์‹คํ–‰์€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` -### Beware: "innerHTML+=" does a full overwrite +### 'innerHTML+=' ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์  -We can append HTML to an element by using `elem.innerHTML+="more html"`. +`elem.innerHTML+="์ถ”๊ฐ€ html"`์„ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ์— HTML์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Like this: +์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . ```js -chatDiv.innerHTML += "<div>Hello<img src='smile.gif'/> !</div>"; -chatDiv.innerHTML += "How goes?"; +chatDiv.innerHTML += "<div>์•ˆ๋…•ํ•˜์„ธ์š”<img src='smile.gif'/> !</div>"; +chatDiv.innerHTML += "์ž˜ ์ง€๋‚ด์ฃ ?"; ``` -But we should be very careful about doing it, because what's going on is *not* an addition, but a full overwrite. +๊ทธ๋Ÿฐ๋ฐ 'innerHTML+='์€ ์ถ”๊ฐ€๊ฐ€ *์•„๋‹ˆ๋ผ* ๋‚ด์šฉ์„ ๋ฎ์–ด์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Technically, these two lines do the same: +๊ธฐ์ˆ ์ ์œผ๋กœ ์•„๋ž˜ ๋‘ ์ค„์˜ ์ฝ”๋“œ๋Š” ๋™์ผํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ```js elem.innerHTML += "..."; -// is a shorter way to write: +// ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜ ์ฝ”๋“œ์˜ ์ถ•์•ฝ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. *!* elem.innerHTML = elem.innerHTML + "..." */!* ``` -In other words, `innerHTML+=` does this: +์ฆ‰, `innerHTML+=`๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. -1. The old contents is removed. -2. The new `innerHTML` is written instead (a concatenation of the old and the new one). +1. ๊ธฐ์กด ๋‚ด์šฉ ์‚ญ์ œ +2. ๊ธฐ์กด ๋‚ด์šฉ๊ณผ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์„ ํ•ฉ์นœ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์„ ์”€ -**As the content is "zeroed-out" and rewritten from the scratch, all images and other resources will be reloaded**. +**๊ธฐ์กด ๋‚ด์šฉ์ด '์™„์ „ํžˆ ์‚ญ์ œ'๋œ ํ›„ ๋ฐ‘๋ฐ”๋‹ฅ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋‚ด์šฉ์ด ์“ฐ์—ฌ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€ ๋“ฑ์˜ ๋ฆฌ์†Œ์Šค ์ „๋ถ€๊ฐ€ ๋‹ค์‹œ ๋กœ๋”ฉ๋ฉ๋‹ˆ๋‹ค**. -In the `chatDiv` example above the line `chatDiv.innerHTML+="How goes?"` re-creates the HTML content and reloads `smile.gif` (hope it's cached). If `chatDiv` has a lot of other text and images, then the reload becomes clearly visible. +`chatDiv` ์˜ˆ์‹œ์˜ `chatDiv.innerHTML+="์ž˜ ์ง€๋‚ด์ฃ ?"` ์œ—์ค„์˜ HTML ๋‚ด์šฉ์ด ์žฌ์ƒ์„ฑ๋˜๊ณ  `smile.gif` ์—ญ์‹œ ๋‹ค์‹œ ๋กœ๋”ฉ๋˜๋Š” ๊ฒƒ์ด์ฃ . ์–ด๋”˜๊ฐ€์— ์ด๋Ÿฐ ๋ฆฌ์†Œ์Šค๋“ค์„ ์บ์‹ฑํ•ด ๋†“์•˜๋‹ค๋ฉด ์ข‹์•˜์„ ๊ฑฐ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“œ๋Š” ์ˆœ๊ฐ„์ด๋„ค์š”. `chatDiv`์— ํ…์ŠคํŠธ์™€ ์ด๋ฏธ์ง€๊ฐ€ ๋งŽ์ด ์žˆ์—ˆ๋‹ค๋ฉด ๋‚ด์šฉ์„ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ๋ฒ„๋ฒ…์ž„์ด ์ƒ๊ธฐ๋Š”๊ฑธ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -There are other side-effects as well. For instance, if the existing text was selected with the mouse, then most browsers will remove the selection upon rewriting `innerHTML`. And if there was an `<input>` with a text entered by the visitor, then the text will be removed. And so on. +์ด ์™ธ์—๋„ `innerHTML+=`์€ ์—ฌ๋Ÿฌ ๋ถ€์ž‘์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์— ์žˆ๋˜ ํ…์ŠคํŠธ๋ฅผ ๋งˆ์šฐ์Šค๋กœ ๋“œ๋ž˜๊ทธํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ๋‚ด์šฉ์„ ๋‹ค์‹œ ์จ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋“œ๋ž˜๊ทธ๊ฐ€ ํ•ด์ œ๋  ๊ฒ๋‹ˆ๋‹ค. `<input>` ํƒœ๊ทธ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์ด ์‚ฌ๋ผ์ง€๊ธฐ๋„ ํ•˜์ฃ . ๋ถ€์ž‘์šฉ ์‚ฌ๋ก€๋Š” ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. -Luckily, there are other ways to add HTML besides `innerHTML`, and we'll study them soon. +`innerHTML` ๋ง๊ณ  HTML์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ๋ถ€์ž‘์šฉ ์—†์ด ์›ํ•˜๋Š” HTML์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๋ฐฉ๋ฒ•์€ ๊ณง ๋ฐฐ์šฐ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -## outerHTML: full HTML of the element +## outerHTML๋กœ ์š”์†Œ์˜ ์ „์ฒด HTML ๋ณด๊ธฐ -The `outerHTML` property contains the full HTML of the element. That's like `innerHTML` plus the element itself. +`outerHTML` ํ”„๋กœํผํ‹ฐ์—” ์š”์†Œ ์ „์ฒด HTML์ด ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค. `outerHTML`์€ `innerHTML`์— ์š”์†Œ ์ž์ฒด๋ฅผ ๋”ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -Here's an example: +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run <div id="elem">Hello <b>World</b></div> @@ -284,11 +284,11 @@ Here's an example: </script> ``` -**Beware: unlike `innerHTML`, writing to `outerHTML` does not change the element. Instead, it replaces it as a whole in the outer context.** +**`innerHTML`๊ณผ ๋‹ฌ๋ฆฌ `outerHTML`์„ ์‚ฌ์šฉํ•ด์„œ HTML์„ ์“ธ๋• ์š”์†Œ ์ž์ฒด๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  `outerHTML`์€ DOM ์•ˆ์˜ ์š”์†Œ๋ฅผ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.** -Yeah, sounds strange, and strange it is, that's why we make a separate note about it here. Take a look. +๋„ค, ๋ญ”๊ฐ€ ์ด์ƒํ•˜๊ฒŒ ๋“ค๋ฆฌ์‹ค ๊ฒ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋„ ์ด์ƒํ•˜๊ณ ์š”. ๊ทธ๋Ÿด ๊ฒƒ์„ ์˜ˆ์ƒํ•˜๊ณ  ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ๋ฅผ ์ค€๋น„ํ•ด ๋†“์•˜์Šต๋‹ˆ๋‹ค. -Consider the example: +์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ ์ดํ•ดํ•ด ๋ด…์‹œ๋‹ค. ```html run <div>Hello, world!</div> @@ -297,159 +297,159 @@ Consider the example: let div = document.querySelector('div'); *!* - // replace div.outerHTML with <p>...</p> + // div.outerHTML๋ฅผ ์‚ฌ์šฉํ•ด <p>...</p>๋กœ ๊ต์ฒด */!* - div.outerHTML = '<p>A new element</p>'; // (*) + div.outerHTML = '<p>์ƒˆ๋กœ์šด ์š”์†Œ</p>'; // (*) *!* - // Wow! The div is still the same! + // ์–ด! div๊ฐ€ ๊ทธ๋Œ€๋กœ๋„ค์š”! */!* alert(div.outerHTML); // <div>Hello, world!</div> (**) </script> ``` -Looks really odd, right? +๋ญ”๊ฐ€ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. -In the line `(*)` we replaced `div` with `<p>A new element</p>`. In the outer document we can see the new content instead of the `<div>`. But, as we can see in line `(**)`, the old `div` variable is still the same! +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `div`๋ฅผ `<p>์ƒˆ๋กœ์šด ์š”์†Œ</p>`๋กœ ๊ต์ฒดํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜๋„ํ•œ ๋Œ€๋กœ ๋ฌธ์„œ(DOM)์— `<div>`๊ฐ€ ์•„๋‹Œ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์ด ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `(**)`์—์„œ ๊ธฐ์กด์˜ `div`๋ฅผ ์ถœ๋ ฅํ•˜๋„ค์š”! -The `outerHTML` assignment does not modify the DOM element, but removes it from the outer context and inserts a new piece of HTML instead of it. +์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚œ ์ด์œ ๋Š” `outerHTML`์— ํ•˜๋Š” ํ• ๋‹น ์—ฐ์‚ฐ์ด DOM ์š”์†Œ(outerHTML ์—ฐ์‚ฐ์˜ ๋Œ€์ƒ์œผ๋กœ, ์œ„ ์˜ˆ์‹œ์—์„  ๋ณ€์ˆ˜ `div`)๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ• ๋‹น ์—ฐ์‚ฐ์€ ์š”์†Œ๋ฅผ DOM์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ๋กœ์šด HTML ์กฐ๊ฐ์„ ๋„ฃ์Šต๋‹ˆ๋‹ค. -So what happened in `div.outerHTML=...` is: -- `div` was removed from the document. -- Another HTML `<p>A new element</p>` was inserted instead. -- `div` still has the old value. The new HTML wasn't saved to any variable. +์ฆ‰, `div.outerHTML=...`๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. +- '๋ฌธ์„œ'์—์„œ `div`๋ฅผ ์‚ญ์ œ +- ์ƒˆ๋กœ์šด HTML ์กฐ๊ฐ์ธ `<p>A new element</p>`์„ ์‚ญ์ œ ํ›„ ์ƒ๊ธด ๊ณต๊ฐ„์— ์‚ฝ์ž… +- `div`์—” ์—ฌ์ „ํžˆ ๊ธฐ์กด ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๊ณ  ์ƒˆ๋กœ์šด HTML ์กฐ๊ฐ์€ ์–ด๋””์—๋„ ์ €์žฅ๋˜์–ด์žˆ์ง€ ์•Š์Œ -It's so easy to make an error here: modify `div.outerHTML` and then continue to work with `div` as if it had the new content in it. But it doesn't. Such thing is correct for `innerHTML`, but not for `outerHTML`. +`outerHTML`์˜ ์ด๋Ÿฐ ๋™์ž‘ ๋ฐฉ์‹ ๋•Œ๋ฌธ์— `outerHTML`์„ ์‚ฌ์šฉํ•  ๋• ์‹ค์ˆ˜ ํ•  ์—ฌ์ง€๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. `div.outerHTML`์„ ์ˆ˜์ •ํ•œ ํ›„ `div`์— ์ƒˆ๋กœ์šด ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ”๋‹ค๊ณ  ์ฐฉ๊ฐํ•˜๋ฉฐ ์ž‘์—…ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์ฃ . ์ •๋ฆฌํ•˜์ž๋ฉด ์ด๋ ‡์Šต๋‹ˆ๋‹ค. `innerHTML`์€ `div`๋ฅผ ์ˆ˜์ •ํ•˜์ง€๋งŒ `outerHTML`์€ `div`๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -We can write to `elem.outerHTML`, but should keep in mind that it doesn't change the element we're writing to. It creates the new HTML on its place instead. We can get references to new elements by querying DOM. +๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— `elem.outerHTML`์— ๋ฌด์–ธ๊ฐ€๋ฅผ ์“ธ ๋•Œ๋Š” `elem`์ด ์ˆ˜์ •๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ผญ ๋ช…์‹ฌํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ• ๋‹น๋ฐ›์€ HTML์€ `elem`์ด ์žˆ๋˜ ๊ณต๊ฐ„์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•˜๋ ค๋ฉด DOM ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค. -## nodeValue/data: text node content +## nodeValue/data๋กœ ํ…์ŠคํŠธ ๋…ธ๋“œ ๋‚ด์šฉ ์กฐ์ž‘ํ•˜๊ธฐ -The `innerHTML` property is only valid for element nodes. +`innerHTML` ํ”„๋กœํผํ‹ฐ๋Š” ์š”์†Œ ๋…ธ๋“œ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Other node types, such as text nodes, have their counterpart: `nodeValue` and `data` properties. These two are almost the same for practical use, there are only minor specification differences. So we'll use `data`, because it's shorter. +ํ…์ŠคํŠธ ๋…ธ๋“œ ๊ฐ™์€ ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๋…ธ๋“œ์—๋Š” `innerHTML`๊ณผ ์œ ์‚ฌํ•œ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ์ธ `nodeValue`์™€ `data`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ์•„์ฃผ ์œ ์‚ฌํ•˜๊ณ , ์‹ค๋ฌด์—์„œ๋„ ๊ตฌ๋ถ„ ์—†์ด ์“ฐ๊ธด ํ•˜์ง€๋งŒ ๋ช…์„ธ์„œ์ƒ์— ์ž‘์€ ์ฐจ์ด๊ฐ€ ์žˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค๋งŒ `data`๊ฐ€ ์ข€ ๋” ์งง๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„  `data`๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -An example of reading the content of a text node and a comment: +ํ…์ŠคํŠธ ๋…ธ๋“œ์™€ ์ฃผ์„ ๋…ธ๋“œ์˜ ๋‚ด์šฉ์„ ์ฝ๋Š” ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•ด ๋ด…์‹œ๋‹ค. ```html run height="50" <body> - Hello - <!-- Comment --> + ์•ˆ๋…•ํ•˜์„ธ์š”. + <!-- ์ฃผ์„ --> <script> let text = document.body.firstChild; *!* - alert(text.data); // Hello + alert(text.data); // ์•ˆ๋…•ํ•˜์„ธ์š”. */!* let comment = text.nextSibling; *!* - alert(comment.data); // Comment + alert(comment.data); // ์ฃผ์„ */!* </script> </body> ``` -For text nodes we can imagine a reason to read or modify them, but why comments? +๊ทธ๋Ÿฐ๋ฐ ์ด์ฏค๋˜๋ฉด ์ด๋Ÿฐ ์˜๋ฌธ์ด ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ๋…ธ๋“œ์˜ ๋‚ด์šฉ์„ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ์ผ์€ ์ผ์–ด๋‚  ๋ฒ• ํ•œ๋ฐ ์ฃผ์„ ๋…ธ๋“œ๋Š” ์™œ ์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ๊ฑด์ง€ ๋ผ๋Š” ์˜๋ฌธ์ด์ฃ . -Sometimes developers embed information or template instructions into HTML in them, like this: +๊ฐœ๋ฐœ์ž๋“ค์€ ์ข…์ข… ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ •๋ณด๋‚˜ ์ง€์‹œ์‚ฌํ•ญ์„ HTML์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ```html <!-- if isAdmin --> - <div>Welcome, Admin!</div> + <div>๊ด€๋ฆฌ์ž๋กœ ๋กœ๊ทธ์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค!</div> <!-- /if --> ``` -...Then JavaScript can read it from `data` property and process embedded instructions. +์ด๋Ÿด ๋•Œ `data` ํ”„๋กœํผํ‹ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ์ฃผ์„ ๋…ธ๋“œ์˜ ๋‚ด์šฉ์„ ์ฝ๊ณ  ์‚ฝ์ž…๋œ ์ง€์‹œ์‚ฌํ•ญ์„ ์ฒ˜๋ฆฌํ•˜๋ฉด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -## textContent: pure text +## textContent๋กœ ์ˆœ์ˆ˜ํ•œ ํ…์ŠคํŠธ๋งŒ -The `textContent` provides access to the *text* inside the element: only text, minus all `<tags>`. +`textContent`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ ๋‚ด์˜ *ํ…์ŠคํŠธ*์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `<ํƒœ๊ทธ>`๋Š” ์ œ์™ธํ•˜๊ณ  ์˜ค๋กœ์ง€ ํ…์ŠคํŠธ๋งŒ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์ฃ . -For instance: +์˜ˆ์‹œ: ```html run <div id="news"> - <h1>Headline!</h1> - <p>Martians attack people!</p> + <h1>์ฃผ์š” ๋‰ด์Šค!</h1> + <p>ํ™”์„ฑ์ธ์ด ์ง€๊ตฌ๋ฅผ ์นจ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค!</p> </div> <script> - // Headline! Martians attack people! + // ์ฃผ์š” ๋‰ด์Šค! ํ™”์„ฑ์ธ์ด ์ง€๊ตฌ๋ฅผ ์นจ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค! alert(news.textContent); </script> ``` -As we can see, only text is returned, as if all `<tags>` were cut out, but the text in them remained. +์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์›๋ž˜๋ถ€ํ„ฐ `<ํƒœ๊ทธ>`๊ฐ€ ์—†์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ํ…์ŠคํŠธ๋งŒ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In practice, reading such text is rarely needed. +๊ทธ๋Ÿฐ๋ฐ ์‹ค๋ฌด์—์„  ํ…์ŠคํŠธ ์ฝ๊ธฐ๋ฅผ ๋‹จ๋…์œผ๋กœ ์“ฐ๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š์Šต๋‹ˆ๋‹ค. -**Writing to `textContent` is much more useful, because it allows to write text the "safe way".** +**`textContent`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ…์ŠคํŠธ๋ฅผ '์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•'์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค๋ฌด์—์„  `textContent`๋ฅผ ์“ฐ๊ธฐ ์šฉ์œผ๋กœ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.** -Let's say we have an arbitrary string, for instance entered by a user, and want to show it. +์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ž„์˜์˜ ๋ฌธ์ž์—ด์„ ๋‹ค์‹œ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค. -- With `innerHTML` we'll have it inserted "as HTML", with all HTML tags. -- With `textContent` we'll have it inserted "as text", all symbols are treated literally. +- `innerHTML`์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด์ด 'HTML ํ˜•ํƒœ๋กœ' ํƒœ๊ทธ์™€ ํ•จ๊ป˜ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. +- `textContent`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด์ด '์ˆœ์ˆ˜ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ' ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํƒœ๊ทธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํŠน์ˆ˜๋ฌธ์ž๋“ค์ด ๋ฌธ์ž์—ด๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. -Compare the two: +๋‘ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋น„๊ตํ•ด๋ด…์‹œ๋‹ค. ```html run <div id="elem1"></div> <div id="elem2"></div> <script> - let name = prompt("What's your name?", "<b>Winnie-the-pooh!</b>"); + let name = prompt("์ด๋ฆ„์„ ์•Œ๋ ค์ฃผ์„ธ์š”.", "<b>์ด๋ณด๋ผ</b>"); elem1.innerHTML = name; elem2.textContent = name; </script> ``` -1. The first `<div>` gets the name "as HTML": all tags become tags, so we see the bold name. -2. The second `<div>` gets the name "as text", so we literally see `<b>Winnie-the-pooh!</b>`. +1. ์ฒซ ๋ฒˆ์งธ `<div>`์—” ์ด๋ฆ„์ด 'HTML ํ˜•ํƒœ'๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅํ•œ ํƒœ๊ทธ๋Š” ํƒœ๊ทธ๋กœ ํ•ด์„๋˜์–ด ๊ตต์€ ๊ธ€์”จ๊ฐ€ ์ถœ๋ ฅ๋˜๋„ค์š”. +2. ๋‘ ๋ฒˆ์งธ `<div>`์—” ์ด๋ฆ„์ด 'ํ…์ŠคํŠธ ํ˜•ํƒœ'๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž…๋ ฅํ•œ ๊ฐ’ ๊ทธ๋Œ€๋กœ `<b>์ด๋ณด๋ผ</b>`๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In most cases, we expect the text from a user, and want to treat it as text. We don't want unexpected HTML in our site. An assignment to `textContent` does exactly that. +๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์€ ํ…์ŠคํŠธ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ HTML์ด ์‚ฌ์ดํŠธ์— ์นจํˆฌํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์œผ๋ ค๋ฉด `textContent`๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค. -## The "hidden" property +## hidden ํ”„๋กœํผํ‹ฐ -The "hidden" attribute and the DOM property specifies whether the element is visible or not. +hidden ์†์„ฑ๊ณผ hidden ํ”„๋กœํผํ‹ฐ๋Š” ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ค„์ง€ ๋ง์ง€ ์ง€์ •ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We can use it in HTML or assign using JavaScript, like this: +`hidden`์€ HTML ์•ˆ์—์„œ ์“ธ ์ˆ˜๋„ ์žˆ๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run height="80" -<div>Both divs below are hidden</div> +<div>์•„๋ž˜ ๋‘ div๋ฅผ ์ˆจ๊ฒจ๋ด…์‹œ๋‹ค.</div> -<div hidden>With the attribute "hidden"</div> +<div hidden>HTML์˜ hidden ์†์„ฑ ์‚ฌ์šฉํ•˜๊ธฐ</div> -<div id="elem">JavaScript assigned the property "hidden"</div> +<div id="elem">์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ hidden ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉํ•˜๊ธฐ</div> <script> elem.hidden = true; </script> ``` -Technically, `hidden` works the same as `style="display:none"`. But it's shorter to write. +`hidden`์€ ๊ธฐ์ˆ ์ ์œผ๋กœ `style="display:none"`์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์งง๋‹ค๋Š” ์ ๋งŒ ๋‹ค๋ฅด์ฃ . -Here's a blinking element: +`hidden`์„ ์‚ฌ์šฉํ•ด ์š”์†Œ๋ฅผ ๊นœ๋นก์ด๊ฒŒ ํ•ด๋ด…์‹œ๋‹ค. ```html run height=50 -<div id="elem">A blinking element</div> +<div id="elem">๊นœ๋นก์ด๋Š” ์š”์†Œ</div> <script> setInterval(() => elem.hidden = !elem.hidden, 1000); </script> ``` -## More properties +## ๊ธฐํƒ€ ํ”„๋กœํผํ‹ฐ -DOM elements also have additional properties, in particular those that depend on the class: +์ง€๊ธˆ๊นŒ์ง€ ์†Œ๊ฐœํ•œ ํ”„๋กœํผํ‹ฐ ์™ธ์—๋„ DOM ์š”์†Œ์—” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ํด๋ž˜์Šค๋งˆ๋‹ค ํŠน์ง•์ ์ธ ํ”„๋กœํผํ‹ฐ ๋ช‡ ๊ฐ€์ง€๋ฅผ ์†Œ๊ฐœํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. -- `value` -- the value for `<input>`, `<select>` and `<textarea>` (`HTMLInputElement`, `HTMLSelectElement`...). -- `href` -- the "href" for `<a href="...">` (`HTMLAnchorElement`). -- `id` -- the value of "id" attribute, for all elements (`HTMLElement`). -- ...and much more... +- `value` -- `<input>`๊ณผ `<select>`, `<textarea>`์˜ ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค๋Š” `HTMLInputElement`, `HTMLSelectElement` ๋“ฑ์ž…๋‹ˆ๋‹ค. +- `href` -- `<a href="...">`์˜ href ์†์„ฑ ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค๋Š” `HTMLAnchorElement`์ž…๋‹ˆ๋‹ค. +- `id` -- id ์†์„ฑ ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์š”์†Œ ๋…ธ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋Œ€์‘ํ•˜๋Š” ํด๋ž˜์Šค๋Š” `HTMLElement`์ž…๋‹ˆ๋‹ค. +- ๊ธฐํƒ€ ๋“ฑ๋“ฑ -For instance: +์˜ˆ์‹œ: ```html run height="80" <input type="text" id="elem" value="value"> @@ -461,39 +461,39 @@ For instance: </script> ``` -Most standard HTML attributes have the corresponding DOM property, and we can access it like that. +๋Œ€๋ถ€๋ถ„์˜ ํ‘œ์ค€ HTML ์†์„ฑ์€ ๊ทธ์— ๋Œ€์‘ํ•˜๋Š” DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์œ„ ์˜ˆ์‹œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -If we want to know the full list of supported properties for a given class, we can find them in the specification. For instance, `HTMLInputElement` is documented at <https://html.spec.whatwg.org/#htmlinputelement>. +ํŠน์ • ํด๋ž˜์Šค์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ์ „์ฒด๋ฅผ ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ๋ช…์„ธ์„œ๋ฅผ ์ฝ์–ด๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `HTMLInputElement`์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์€ <https://html.spec.whatwg.org/#htmlinputelement>์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Or if we'd like to get them fast or are interested in a concrete browser specification -- we can always output the element using `console.dir(elem)` and read the properties. Or explore "DOM properties" in the Elements tab of the browser developer tools. +๋ช…์„ธ์„œ๋ฅผ ์ฝ์ง€ ์•Š๊ณ ๋„ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ์ฝ˜์†” ์ฐฝ์— `console.dir(elem)`๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ•ด๋‹น ์š”์†Œ์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์„ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Elements ํŒจ๋„์˜ ํ•˜์œ„ ํŒจ๋„ ์ค‘ 'Properties'๋ฅผ ์„ ํƒํ•ด๋„ ๋™์ผํ•œ ๋ชฉ๋ก์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -Each DOM node belongs to a certain class. The classes form a hierarchy. The full set of properties and methods come as the result of inheritance. +๊ฐ DOM ๋…ธ๋“œ๋Š” ๊ณ ์œ ํ•œ ํด๋ž˜์Šค์— ์†ํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋“ค์€ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. DOM ๋…ธ๋“œ์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋А๋ƒ์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. -Main DOM node properties are: +์ฃผ์š” DOM ๋…ธ๋“œ ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `nodeType` -: We can use it to see if a node is a text or an element node. It has a numeric value: `1` -- for elements,`3` -- for text nodes, and few other for other node types. Read-only. +: ์š”์†Œ ํƒ€์ž…์„ ์•Œ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์š”์†Œ ๋…ธ๋“œ๋ผ๋ฉด `1`์„, ํ…์ŠคํŠธ ๋…ธ๋“œ๋ผ๋ฉด `3`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํƒ€์ž… ์™ธ์—๋„ ๊ฐ ๋…ธ๋“œ ํƒ€์ž…์—” ๋Œ€์‘ํ•˜๋Š” ์ƒ์ˆซ๊ฐ’์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ๊ธฐ ์ „์šฉ์ž…๋‹ˆ๋‹ค. `nodeName/tagName` -: For elements, tag name (uppercased unless XML-mode). For non-element nodes `nodeName` describes what it is. Read-only. +: ์š”์†Œ ๋…ธ๋“œ์˜ ํƒœ๊ทธ ์ด๋ฆ„์„ ์•Œ์•„๋‚ผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. XML ๋ชจ๋“œ์ผ ๋•Œ๋ฅผ ์ œ์™ธํ•˜๊ณ  ํƒœ๊ทธ ์ด๋ฆ„์€ ํ•ญ์ƒ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๋…ธ๋“œ์—๋Š” `nodeName`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ฝ๊ธฐ ์ „์šฉ์ž…๋‹ˆ๋‹ค. `innerHTML` -: The HTML content of the element. Can be modified. +: ์š”์†Œ ์•ˆ์˜ HTML์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ ์•ˆ์˜ HTML์„ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `outerHTML` -: The full HTML of the element. A write operation into `elem.outerHTML` does not touch `elem` itself. Instead it gets replaced with the new HTML in the outer context. +: ์š”์†Œ์˜ ์ „์ฒด HTML์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `elem.outerHTML`์— ๋ฌด์–ธ๊ฐ€๋ฅผ ํ• ๋‹นํ•ด๋„ `elem` ์ž์ฒด๋Š” ๋ฐ”๋€Œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ์ƒˆ๋กœ์šด HTML์ด ์™ธ๋ถ€ ์ปจํ…์ŠคํŠธ์—์„œ ๋งŒ๋“ค์–ด์ง€๊ณ , `elem`์ด ์‚ญ์ œ๋œ ์ž๋ฆฌ๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค. `nodeValue/data` -: The content of a non-element node (text, comment). These two are almost the same, usually we use `data`. Can be modified. +: ์š”์†Œ๊ฐ€ ์•„๋‹Œ ๋…ธ๋“œ(ํ…์ŠคํŠธ, ์ฃผ์„ ๋…ธ๋“œ ๋“ฑ)์˜ ๋‚ด์šฉ์„ ์ฝ์„ ๋•Œ ์“ฐ์ž…๋‹ˆ๋‹ค. ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ `data`๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด๋ฉฐ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•  ๋•Œ๋„ ์ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `textContent` -: The text inside the element: HTML minus all `<tags>`. Writing into it puts the text inside the element, with all special characters and tags treated exactly as text. Can safely insert user-generated text and protect from unwanted HTML insertions. +: HTML์—์„œ ๋ชจ๋“  `<ํƒœ๊ทธ>`๋ฅผ ์ œ์™ธํ•œ ํ…์ŠคํŠธ๋งŒ ์ฝ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ• ๋‹น ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์“ธ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ์ด๋•Œ ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํŠน์ˆ˜๋ฌธ์ž๋Š” ๋ฌธ์ž์—ด๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž๋ฅผ ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›์น˜ ์•Š๋Š” HTML์ด ์‚ฌ์ดํŠธ์— ์‚ฝ์ž…๋˜๋Š” ๊ฒƒ์„ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `hidden` -: When set to `true`, does the same as CSS `display:none`. +: `true`๋กœ ์„ค์ •ํ•˜๋ฉด CSS์—์„œ `display:none`์„ ์„ค์ •ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -์ •๋ฆฌํ•˜์ž๋ฉด `innerHTML+=` ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค: +DOM ๋…ธ๋“œ๋Š” ํด๋ž˜์Šค์— ๋”ฐ๋ผ ์ด ์™ธ์—๋„ ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. `<input>` ์š”์†Œ(`HTMLInputElement`)๋Š” `value`, `type` ํ”„๋กœํผํ‹ฐ๋ฅผ, `<a>` ์š”์†Œ(`HTMLAnchorElement`)๋Š” `href` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ ๊ฐ™์ด ๋ง์ด์ฃ . ๋Œ€๋ถ€๋ถ„์˜ ํ‘œ์ค€ HTML ์†์„ฑ์€ ๋Œ€์‘ํ•˜๋Š” DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. -Although, HTML attributes and DOM properties are not always the same, as we'll see in the next chapter. +๊ทธ๋Ÿฐ๋ฐ HTML ์š”์†Œ์™€ DOM ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•ญ์ƒ ๊ฐ™์€ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ด€๋ จ ๋‚ด์šฉ์€ ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/05-basic-dom-node-properties/dom-class-hierarchy.svg b/2-ui/1-document/05-basic-dom-node-properties/dom-class-hierarchy.svg index f8a9f8ffcc..39f7d8f8c3 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/dom-class-hierarchy.svg +++ b/2-ui/1-document/05-basic-dom-node-properties/dom-class-hierarchy.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="478" height="364" viewBox="0 0 478 364"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-class-hierarchy.svg"><path id="Rectangle-9" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M181 6h118v28H181z"/><path id="Rectangle-8" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M181 74h118v28H181z"/><text id="EventTarget" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="200.9" y="24">EventTarget</tspan></text><text id="Node" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="225.6" y="91">Node </tspan></text><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M240.5 39.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M181 144h118v28H181z"/><text id="Element" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="214.8" y="161">Element </tspan></text><path id="Line-2-Copy" fill="#EE6B47" fill-rule="nonzero" d="M240.5 109.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-4" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M181 230h118v28H181z"/><text id="HTMLElement" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="200.4" y="247">HTMLElement </tspan></text><path id="Line-2-Copy-4" fill="#EE6B47" fill-rule="nonzero" d="M240.5 195.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-6" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M171 300h138v28H171z"/><text id="HTMLBodyElement" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="186" y="317">HTMLBodyElement </tspan></text><path id="Line-2-Copy-6" fill="#EE6B47" fill-rule="nonzero" d="M240.5 265.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-7" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M12 300h138v28H12z"/><text id="HTMLInputElement" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="24.4" y="317">HTMLInputElement </tspan></text><path id="Line-2-Copy-7" fill="#EE6B47" fill-rule="nonzero" d="M170 261l-6.753 14.12-3.684-4.736-30.238 23.52-1.228-1.58 30.238-23.519-3.684-4.735L170 261z"/><path id="Rectangle-8-Copy-8" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M332 300h138v28H332z"/><text id="HTMLAnchorElement" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="341.3" y="317">HTMLAnchorElement </tspan></text><path id="Line-2-Copy-8" fill="#EE6B47" fill-rule="nonzero" d="M307 259l14.554 5.76-4.47 4.002 21.328 23.816-1.49 1.334-21.327-23.816-4.47 4.003L307 259z"/><path id="Rectangle-8-Copy-2" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M45 126h118v28H45z"/><text id="Text" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="89.6" y="144">Text </tspan></text><path id="Line-2-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M171 96l-6.589 14.198-3.738-4.693-19.332 15.4-1.246-1.564 19.331-15.401-3.738-4.692L171 96z"/><path id="Rectangle-8-Copy-3" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M315 126h118v28H315z"/><text id="Comment" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="348.8" y="144">Comment </tspan></text><path id="Line-2-Copy-3" fill="#EE6B47" fill-rule="nonzero" d="M307 96l15.338 3.123-3.701 4.722 19.767 15.484-1.233 1.575-19.767-15.485-3.7 4.725L307 96z"/><path id="Line-2-Copy-9" fill="#EE6B47" fill-rule="nonzero" d="M307 174l15.338 3.123-3.701 4.722 19.767 15.484-1.233 1.575-19.767-15.485-3.7 4.725L307 174z"/><path id="Rectangle-8-Copy-5" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M315 205h118v28H315z"/><text id="SVGElement" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="338" y="223">SVGElement </tspan></text><text id="<div>Text</div>" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="48" y="171" fill="#8A704D"><div></tspan> <tspan x="84" y="171" fill="#F5A623">Text</tspan> <tspan x="112.8" y="171" fill="#8A704D"></div></tspan></text><text id="<input-type="โ€ฆ">" fill="#F5A623" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="24.4" y="341"><input type="โ€ฆ"></tspan></text><text id="<body>" fill="#F5A623" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="220.4" y="341"><body></tspan></text><text id="<a-href="โ€ฆ">" fill="#F5A623" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="358.8" y="341"><a href="โ€ฆ"></tspan></text><text id="<div>Text</div>" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="189" y="188" fill="#8A704D"><</tspan> <tspan x="196.2" y="188" fill="#F5A623">div</tspan> <tspan x="217.8" y="188" fill="#8A704D">></tspan> <tspan x="225" y="188" fill="#998364">Text</tspan> <tspan x="253.8" y="188" fill="#8A704D"></</tspan> <tspan x="268.2" y="188" fill="#F5A623">div</tspan> <tspan x="289.8" y="188" fill="#8A704D">></tspan></text><text id="<!--comment-->" fill="#F5A623" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="327.6" y="171"><!--comment--></tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="478" height="364" viewBox="0 0 478 364"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="dom-class-hierarchy.svg"><path id="Rectangle-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M181 6h118v28H181z"/><path id="Rectangle-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M181 74h118v28H181z"/><text id="EventTarget" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="200.9" y="24">EventTarget</tspan></text><text id="Node" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="225.6" y="91">Node </tspan></text><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M240.5 39.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M181 144h118v28H181z"/><text id="Element" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="214.8" y="161">Element </tspan></text><path id="Line-2-Copy" fill="#C06334" fill-rule="nonzero" d="M240.5 109.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M181 230h118v28H181z"/><text id="HTMLElement" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="200.4" y="247">HTMLElement </tspan></text><path id="Line-2-Copy-4" fill="#C06334" fill-rule="nonzero" d="M240.5 195.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M171 300h138v28H171z"/><text id="HTMLBodyElement" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="186" y="317">HTMLBodyElement </tspan></text><path id="Line-2-Copy-6" fill="#C06334" fill-rule="nonzero" d="M240.5 265.5l7 14h-6v17h-2v-17h-6l7-14z"/><path id="Rectangle-8-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M12 300h138v28H12z"/><text id="HTMLInputElement" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="24.4" y="317">HTMLInputElement </tspan></text><path id="Line-2-Copy-7" fill="#C06334" fill-rule="nonzero" d="M170 261l-6.753 14.12-3.685-4.736-29.448 22.905-.79.614-1.227-1.578.79-.614 29.448-22.906-3.684-4.735L170 261z"/><path id="Rectangle-8-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M332 300h138v28H332z"/><text id="HTMLAnchorElement" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="341.3" y="317">HTMLAnchorElement </tspan></text><path id="Line-2-Copy-8" fill="#C06334" fill-rule="nonzero" d="M307 259l14.554 5.76-4.47 4.002 20.661 23.07.667.746-1.49 1.334-.667-.745-20.66-23.071-4.47 4.003L307 259z"/><path id="Rectangle-8-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M45 126h118v28H45z"/><text id="Text" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="89.6" y="144">Text </tspan></text><path id="Line-2-Copy-2" fill="#C06334" fill-rule="nonzero" d="M171 96l-6.589 14.198-3.738-4.693-18.55 14.777-.782.623-1.246-1.564.782-.623 18.549-14.778-3.738-4.692L171 96z"/><path id="Rectangle-8-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M315 126h118v28H315z"/><text id="Comment" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="348.8" y="144">Comment </tspan></text><path id="Line-2-Copy-3" fill="#C06334" fill-rule="nonzero" d="M307 96l15.338 3.123-3.701 4.723 18.98 14.867.787.616-1.233 1.575-.788-.617-18.979-14.867-3.7 4.724L307 96z"/><path id="Line-2-Copy-9" fill="#C06334" fill-rule="nonzero" d="M307 174l15.338 3.123-3.701 4.723 18.98 14.867.787.616-1.233 1.575-.788-.617-18.979-14.867-3.7 4.724L307 174z"/><path id="Rectangle-8-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M315 205h118v28H315z"/><text id="SVGElement" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="338" y="223">SVGElement </tspan></text><text id="<div>Text</div>" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="48" y="171" fill="#AF6E24"><div></tspan> <tspan x="84" y="171" fill="#C06334">Text</tspan> <tspan x="112.8" y="171" fill="#AF6E24"></div></tspan></text><text id="<input-type="โ€ฆ">" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="24.4" y="341"><input type="โ€ฆ"></tspan></text><text id="<body>" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="220.4" y="341"><body></tspan></text><text id="<a-href="โ€ฆ">" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="358.8" y="341"><a href="โ€ฆ"></tspan></text><text id="<div>Text</div>" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="189" y="188" fill="#AF6E24"><</tspan> <tspan x="196.2" y="188" fill="#C06334">div</tspan> <tspan x="217.8" y="188" fill="#AF6E24">></tspan> <tspan x="225" y="188" fill="#DBAF88">Text</tspan> <tspan x="253.8" y="188" fill="#AF6E24"></</tspan> <tspan x="268.2" y="188" fill="#C06334">div</tspan> <tspan x="289.8" y="188" fill="#AF6E24">></tspan></text><text id="<!--comment-->" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="327.6" y="171"><!--comment--></tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md index 4cdf231b0a..3b5bd36d87 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Get the attribute +# ์†์„ฑ ๊ฐ€์ ธ์˜ค๊ธฐ -Write the code to select the element with `data-widget-name` attribute from the document and to read its value. +๋ฌธ์„œ์—์„œ `data-widget-name`์ด๋ผ๋Š” ์†์„ฑ์„ ๊ฐ€์ง„ ์š”์†Œ๋ฅผ ์ฐพ๊ณ , ํ•ด๋‹น ์š”์†Œ์˜ ๊ฐ’์„ ์ฝ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. ```html run <!DOCTYPE html> diff --git a/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/solution.md b/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/solution.md index 726be4c8fa..d8361c9b4a 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/solution.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/solution.md @@ -1,9 +1,9 @@ -First, we need to find all external references. +๋จผ์ € ์™ธ๋ถ€ ์ฐธ์กฐ๋ฅผ ๋ชจ๋‘ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -There are two ways. +๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์™ธ๋ถ€ ์ฐธ์กฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The first is to find all links using `document.querySelectorAll('a')` and then filter out what we need: +์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ `document.querySelectorAll('a')`๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋“  ๋งํฌ๋ฅผ ์ฐพ์€ ํ›„ ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ```js let links = document.querySelectorAll('a'); @@ -12,23 +12,23 @@ for (let link of links) { *!* let href = link.getAttribute('href'); */!* - if (!href) continue; // no attribute + if (!href) continue; // ์†์„ฑ์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ - if (!href.includes('://')) continue; // no protocol + if (!href.includes('://')) continue; // ํ”„๋กœํ† ์ฝœ์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ - if (href.startsWith('http://internal.com')) continue; // internal + if (href.startsWith('http://internal.com')) continue; // ๋‚ด๋ถ€ ๋งํฌ link.style.color = 'orange'; } ``` -Please note: we use `link.getAttribute('href')`. Not `link.href`, because we need the value from HTML. +์ฐธ๊ณ : HTML์˜ ๊ฐ’์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— `link.href`๊ฐ€ ์•„๋‹ˆ๋ผ `link.getAttribute('href')`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -...Another, simpler way would be to add the checks to CSS selector: +๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ CSS ์„ ํƒ์ž์— ์กฐ๊ฑด์„ ๋ช…์‹œํ•ด ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ```js -// look for all links that have :// in href -// but href doesn't start with http://internal.com +// href์— :// ๊ฐ€ ํฌํ•จ๋œ ๋ชจ๋“  ๋งํฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. +// ๊ทธ ์ค‘ http://internal.com์œผ๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š” ๋งํฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. let selector = 'a[href*="://"]:not([href^="http://internal.com"])'; let links = document.querySelectorAll(selector); diff --git a/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/task.md b/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/task.md index b0a8ab7b17..dc5f36769e 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/task.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/2-yellow-links/task.md @@ -2,15 +2,15 @@ importance: 3 --- -# Make external links orange +# ์™ธ๋ถ€ ๋งํฌ๋ฅผ ์ฃผํ™ฉ์ƒ‰์œผ๋กœ ๋งŒ๋“ค๊ธฐ -Make all external links orange by altering their `style` property. +`style` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด ๋ชจ๋“  ์™ธ๋ถ€ ๋งํฌ๋ฅผ ์ฃผํ™ฉ์ƒ‰์œผ๋กœ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. -A link is external if: -- Its `href` has `://` in it -- But doesn't start with `http://internal.com`. +์™ธ๋ถ€ ๋งํฌ๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. +- `href`์— `://`๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- ํ•˜์ง€๋งŒ `http://internal.com`์œผ๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Example: +์˜ˆ์‹œ: ```html run <a name="list">the list</a> @@ -30,6 +30,6 @@ Example: </script> ``` -The result should be: +๊ฒฐ๊ณผ: [iframe border=1 height=180 src="solution"] diff --git a/2-ui/1-document/06-dom-attributes-and-properties/article.md b/2-ui/1-document/06-dom-attributes-and-properties/article.md index 87d04bbe04..c683859cf0 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/article.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/article.md @@ -1,18 +1,18 @@ # ์†์„ฑ๊ณผ ํ”„๋กœํผํ‹ฐ -๋ธŒ๋ผ์šฐ์ €๋Š” ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋‚˜๋ฉด HTML์„ ์ฝ์–ด(์ด ๊ณผ์ •์„ ํŒŒ์‹ฑ(parsing, ๊ตฌ๋ฌธ๋ถ„์„)์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค) DOM ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์š”์†Œ ๋…ธ๋“œ(Element node)์—์„œ ํ‘œ์ค€ HTML ์†์„ฑ(HTML attribute)์€ ํŒŒ์‹ฑ์„ ๊ฑฐ์ณ DOM ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ(property)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ €๋Š” ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋‚˜๋ฉด HTML์„ ์ฝ์–ด(ํŒŒ์‹ฑ(parsing)) DOM ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์š”์†Œ ๋…ธ๋“œ(element node)์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ํ‘œ์ค€ HTML ์†์„ฑ(attribute)์€ DOM ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ(property)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด `<body id="page">`ํƒœ๊ทธ๊ฐ€ ์žˆ๋‹ค๋ฉด id ์†์„ฑ์€ DOM ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋กœ ์ „ํ™˜ ๋ผ `body.id="page"`๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํƒœ๊ทธ `<body id="page">`๊ฐ€ ์žˆ์„ ๋•Œ, DOM ๊ฐ์ฒด์—์„œ `body.id="page"`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์ด ๋ง์ด์ฃ . -ํ•˜์ง€๋งŒ ์†์„ฑ-ํ”„๋กœํผํ‹ฐ๋Š” ์ผ๋Œ€์ผ์˜ ๊ด€๊ณ„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ์ œ์—์„  ์†์„ฑ๊ณผ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š”์ง€, ์–ธ์ œ ๊ฐ™์€์ง€, ์–ธ์ œ ๋‹ค๋ฅธ์ง€ ์ฃผ์˜ํ•˜์—ฌ ๋‘ ๊ฐœ๋…์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ์†์„ฑ-ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•ญ์ƒ ์ผ๋Œ€์ผ๋กœ ๋งคํ•‘๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค! ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์†์„ฑ๊ณผ ํ”„๋กœํผํ‹ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š”์ง€, ๋‘ ๊ฐ€์ง€๊ฐ€ ์–ธ์ œ ์ผ๋Œ€์ผ๋กœ ๋งคํ•‘๋˜๋Š”์ง€, ์–ธ์ œ๋Š” ๋งคํ•‘๋˜์ง€ ์•Š๋Š”์ง€์— ์ฃผ์˜ํ•˜๋ฉด์„œ ๋‘ ๊ฐœ๋…์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ## DOM ํ”„๋กœํผํ‹ฐ -์ด๋ฏธ ๋‚ด์žฅ(built-in) DOM ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. DOM ํ”„๋กœํผํ‹ฐ๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋‚ด์žฅ ํ”„๋กœํผํ‹ฐ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ž์‹ ๋งŒ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์•ž์„œ ๋‚ด์žฅ DOM ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. DOM ํ”„๋กœํผํ‹ฐ์˜ ์ข…๋ฅ˜๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋‚ด์žฅ ํ”„๋กœํผํ‹ฐ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ž์‹ ๋งŒ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -DOM ๋…ธ๋“œ(DOM node)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด๊ฑธ ํ•œ๋ฒˆ ๋ฐ”๊ฟ”๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +DOM ๋…ธ๋“œ(DOM node)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ๋ฐ”๊ฟ”๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ `document.body`์— ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค: +`document.body`์— ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ```js run document.body.myData = { @@ -23,17 +23,17 @@ document.body.myData = { alert(document.body.myData.title); // Imperator ``` -์—ฌ๊ธฐ์— ๋ฉ”์„œ๋“œ๋„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋ฉ”์„œ๋“œ๋„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run document.body.sayTagName = function() { alert(this.tagName); }; -document.body.sayTagName(); // BODY (๋ฉ”์„œ๋“œ์—์„œ ์‚ฌ์šฉ๋œ "this" ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š”๊ฑด document.body์ž…๋‹ˆ๋‹ค) +document.body.sayTagName(); // BODY (sayTagName์˜ 'this'์—” document.body๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.) ``` -`Element.prototype`์™€ ๊ฐ™์€ ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์„ ์ˆ˜์ •ํ•ด ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค: +`Element.prototype` ๊ฐ™์€ ๋‚ด์žฅ ํ”„๋กœํ† ํƒ€์ž…์„ ์ˆ˜์ •ํ•ด ๋ชจ๋“  ์š”์†Œ ๋…ธ๋“œ์—์„œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run Element.prototype.sayHi = function() { @@ -44,76 +44,76 @@ document.documentElement.sayHi(); // Hello, I'm HTML document.body.sayHi(); // Hello, I'm BODY ``` -DOM ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ฒ˜๋Ÿผ ํ–‰๋™ํ•ฉ๋‹ˆ๋‹ค: +์˜ˆ์‹œ์—์„œ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด DOM ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ฒ˜๋Ÿผ ํ–‰๋™ํ•˜๋ฏ€๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง•์„ ๋ณด์ž…๋‹ˆ๋‹ค. - ์–ด๋–ค ๊ฐ’์ด๋“  ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ฐ€๋ฆฝ๋‹ˆ๋‹ค(์ด๋ ‡๊ฒŒ ์จ์•ผ ์ž‘๋™ํ•˜๊ณ  `elem.nodeType`, ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค `elem.NoDeTyPe`). +- ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ฐ€๋ฆฝ๋‹ˆ๋‹ค. `elem.nodeType`๋Š” ๋™์ž‘ํ•˜์ง€๋งŒ `elem.NoDeTyPe`๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ## HTML ์†์„ฑ -HTML์—์„œ ํƒœ๊ทธ(tag)๋Š” ๋ณต์ˆ˜์˜ ์†์„ฑ(attribute)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” HTML์„ ํŒŒ์‹ฑํ•ด DOM ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ HTML *ํ‘œ์ค€* ์†์„ฑ์„ ์ธ์‹ํ•˜๊ณ , ์ด ํ‘œ์ค€ ์†์„ฑ์„ ์ด์šฉํ•ด DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +HTML์—์„œ ํƒœ๊ทธ๋Š” ๋ณต์ˆ˜์˜ ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” HTML์„ ํŒŒ์‹ฑํ•ด DOM ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ HTML *ํ‘œ์ค€* ์†์„ฑ์„ ์ธ์‹ํ•˜๊ณ , ์ด ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. -HTML ์š”์†Œ๊ฐ€ `id`์™€ ๊ฐ™์€ *ํ‘œ์ค€* ์†์„ฑ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ด์— ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ž์—ฐ์Šค๋ ˆ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ‘œ์ค€์ด ์•„๋‹Œ ์†์„ฑ์ด ์‚ฌ์šฉ๋œ ๊ฒฝ์šฐ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ ์š”์†Œ๊ฐ€ `id` ๊ฐ™์€ *ํ‘œ์ค€* ์†์„ฑ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ด์— ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ž์—ฐ์Šค๋ ˆ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ‘œ์ค€์ด ์•„๋‹Œ ์†์„ฑ์ผ ๋•Œ๋Š” ์ƒํ™ฉ์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ html์ด ์žˆ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค: +์˜ˆ์‹œ: ```html run <body id="test" something="non-standard"> <script> alert(document.body.id); // test *!* - // ํ‘œ์ค€์ด ์•„๋‹Œ ์†์„ฑ์€ ํ”„๋กœํผํ‹ฐ๋กœ ํŒŒ์‹ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค + // ๋น„ํ‘œ์ค€ ์†์„ฑ์€ ํ”„๋กœํผํ‹ฐ๋กœ ์ „ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. alert(document.body.something); // undefined */!* </script> </body> ``` -ํ•œ ์š”์†Œ์—์„  ํ‘œ์ค€์ธ ์†์„ฑ์ด ๋‹ค๋ฅธ ์š”์†Œ์—์„  ํ‘œ์ค€์ด ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `<input>`์š”์†Œ์—์„œ `"type"`์€ ํ‘œ์ค€์ด์ง€๋งŒ([HTMLInputElement](https://html.spec.whatwg.org/#htmlinputelement)), `<body>`์—์„  ์•„๋‹™๋‹ˆ๋‹ค([HTMLBodyElement](https://html.spec.whatwg.org/#htmlbodyelement)). ํ‘œ์ค€ ์†์„ฑ(standard attribute)์€ ํ•ด๋‹น ์š”์†Œ(HTML element)์˜ ๋ช…์„ธ์„œ์— ๊ฐ€๋ฉด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•œ ์š”์†Œ์—์„  ํ‘œ์ค€์ธ ์†์„ฑ์ด ๋‹ค๋ฅธ ์š”์†Œ์—์„  ํ‘œ์ค€์ด ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—๋„ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `"type"`์€ `<input>` ์š”์†Œ([HTMLInputElement](https://html.spec.whatwg.org/#htmlinputelement))์—์„  ํ‘œ์ค€์ด์ง€๋งŒ, `<body>`([HTMLBodyElement](https://html.spec.whatwg.org/#htmlbodyelement))์—์„  ์•„๋‹™๋‹ˆ๋‹ค. ์š”์†Œ์— ์–ด๋–ค ํ‘œ์ค€ ์†์„ฑ์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋ ค๋ฉด ํ•ด๋‹น ์š”์†Œ์˜ ๋ช…์„ธ์„œ์— ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”: +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•ด๋ด…์‹œ๋‹ค. ```html run <body id="body" type="..."> <input id="input" type="text"> <script> alert(input.type); // text *!* - alert(body.type); // undefined: type์€ body์˜ ํ‘œ์ค€ ์†์„ฑ์ด ์•„๋‹ˆ๋ฏ€๋กœ DOM ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค + alert(body.type); // type์€ body์˜ ํ‘œ์ค€ ์†์„ฑ์ด ์•„๋‹ˆ๋ฏ€๋กœ DOM ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•„ undefined๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. */!* </script> </body> ``` -์œ„์—์„œ ํ™•์ธํ•œ ๋ฐ”์™€ ๊ฐ™์ด ํ‘œ์ค€์†์„ฑ์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์ด์— ์—ฐ๊ฒฐ๋˜๋Š” DOM-ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋น„ํ‘œ์ค€ ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†๋Š” ๊ฑธ๊นŒ์š”? +์ด์ฒ˜๋Ÿผ ํ‘œ์ค€ ์†์„ฑ์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ด์— ๋งคํ•‘ํ•˜๋Š” DOM ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋น„ํ‘œ์ค€ ์†์„ฑ์€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” ๊ฑธ๊นŒ์š”? -๋ฌผ๋ก  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์†์„ฑ์€ ์•„๋ž˜์˜ ๋ฉ”์„œ๋“œ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +๋ฌผ๋ก  ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์†์„ฑ์€ ์•„๋ž˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- `elem.hasAttribute(name)` -- ์†์„ฑ์˜ ์กด์žฌ ํ™•์ธ. -- `elem.getAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ๊ฐ€์ ธ์˜ด. -- `elem.setAttribute(name, value)` -- ์†์„ฑ๊ฐ’์„ ๋ณ€๊ฒฝํ•จ. -- `elem.removeAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ์ œ๊ฑฐํ•จ. +- `elem.hasAttribute(name)` -- ์†์„ฑ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ +- `elem.getAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ๊ฐ€์ ธ์˜ด +- `elem.setAttribute(name, value)` -- ์†์„ฑ๊ฐ’์„ ๋ณ€๊ฒฝํ•จ +- `elem.removeAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ์ง€์›€ -์œ„ ๋ฉ”์„œ๋“œ๋Š” HTML์— ๋ช…์‹œ๋œ ์†์„ฑ์„ ๋ณ€ํ™”์‹œํ‚ต๋‹ˆ๋‹ค. +์œ„ ๋ฉ”์„œ๋“œ๋“ค์€ HTML์—์„œ ๋ช…์‹œํ•œ ์†์„ฑ์„ ๋Œ€์ƒ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ `elem.attributes`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์†์„ฑ๊ฐ’์„ ์ฝ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `elem.attributes`์€ ๋‚ด์žฅ ํด๋ž˜์Šค [Attr](https://dom.spec.whatwg.org/#attr)๋ฅผ ๊ตฌํ˜„ํ•œ `name` and `value` ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ `elem.attributes`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์†์„ฑ๊ฐ’์„ ์ฝ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `elem.attributes`์„ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด์žฅ ํด๋ž˜์Šค [Attr](https://dom.spec.whatwg.org/#attr)๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋“ค์„ ๋‹ด์€ ์ปฌ๋ ‰์…˜์ด ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ, ๊ฐ์ฒด์—” `name`๊ณผ `value` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๋Š” ๋ฐ๋ชจ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค: +๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run <body something="non-standard"> <script> *!* - alert(document.body.getAttribute('something')); // ๋น„ํ‘œ์ค€(non-standard) ์†์„ฑ์— ์ ‘๊ทผ + alert(document.body.getAttribute('something')); // ๋น„ํ‘œ์ค€ ์†์„ฑ์— ์ ‘๊ทผ */!* </script> </body> ``` -HTML ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค: +HTML ์†์„ฑ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง•์„ ๋ณด์ž…๋‹ˆ๋‹ค. -- ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(`id`์™€ `ID`๊ฐ€ ๊ฐ™์Šต๋‹ˆ๋‹ค). +- ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ฐ€๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `id`์™€ `ID`๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค. - ๊ฐ’์€ ํ•ญ์ƒ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. -HTML ์†์„ฑ์— ๊ด€ํ•œ ๋˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”: +HTML ์†์„ฑ์„ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃจ๋Š”์ง€์— ๋Œ€ํ•œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run <body> @@ -126,25 +126,25 @@ HTML ์†์„ฑ์— ๊ด€ํ•œ ๋˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”: alert( elem.outerHTML ); // (3) ์ถ”๊ฐ€๋œ ์†์„ฑ ํ™•์ธํ•˜๊ธฐ - for (let attr of elem.attributes) { // (4) ์†์„ฑ์— ์ ‘๊ทผํ•˜๊ธฐ + for (let attr of elem.attributes) { // (4) ์†์„ฑ ์ „์ฒด ๋‚˜์—ดํ•˜๊ธฐ alert( `${attr.name} = ${attr.value}` ); } </script> </body> ``` -์ฃผ์˜ํ•ด์„œ ๋ณผ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: +์ฃผ์˜ํ•ด์„œ ๋ณผ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. `getAttribute('About')` -- ์ฒซ ๋ฒˆ์งธ ๊ธ€์ž๊ฐ€ ๋Œ€๋ฌธ์ž A์ด์ง€๋งŒ, HTML ์•ˆ์—๋Š” ๋ชจ๋‘ ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋Œ€/์†Œ๋ฌธ์ž๊ฐ€ ๋‹ค๋ฆ„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ •์ƒ์ ์œผ๋กœ ๊ฐ’์ด ์ถœ๋ ฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์†์„ฑ์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -2. ์–ด๋–ค ๊ฐ’์ด๋“  ์†์„ฑ์— ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ตœ์ข…์ ์œผ๋ก  ๋ฌธ์ž์—ด๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค. ์ˆซ์ž 123์ด ๋ฌธ์ž์—ด `"123"` ์œผ๋กœ ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค. -3. `outerHTML`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์†์„ฑ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -4. `attributes` ์ปฌ๋ ‰์…˜์€ iterable ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ‘œ์ค€, ๋น„ํ‘œ์ค€ ์š”์†Œ์˜ ์†์„ฑ์„ `name` ๊ณผ `value` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. +1. `getAttribute('About')` -- ์ฒซ ๋ฒˆ์งธ ๊ธ€์ž๊ฐ€ ๋Œ€๋ฌธ์ž A์ด์ง€๋งŒ, HTML ์•ˆ์—์„œ๋Š” ๋ชจ๋‘ ์†Œ๋ฌธ์ž๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์†์„ฑ์€ ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. +2. ์–ด๋–ค ๊ฐ’์ด๋“  ์†์„ฑ์— ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ตœ์ข…์ ์œผ๋ก  ๋ฌธ์ž์—ด๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค. ์ˆซ์ž 123์ด ๋ฌธ์ž์—ด `"123"` ์œผ๋กœ ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค. +3. `outerHTML`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง์ ‘ ์ถ”๊ฐ€ํ•œ ์†์„ฑ์„ ๋น„๋กฏํ•œ ๋ชจ๋“  ์†์„ฑ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +4. `attributes`๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ปฌ๋ ‰์…˜์€ ์—ด๊ฑฐ ๊ฐ€๋Šฅ(iterable)ํ•ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์— ๋‹ด๊ธด ๊ฐ ๊ฐ์ฒด์˜ `name`, `value` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†์„ฑ ์ „์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ํ”„๋กœํผํ‹ฐ-์†์„ฑ ๋™๊ธฐํ™” -ํ‘œ์ค€ ์†์„ฑ์ด ๋ณ€ํ™”ํ•˜๋ฉด ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๊ณ , ๋ช‡๋ช‡ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด ์†์„ฑ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. +ํ‘œ์ค€ ์†์„ฑ์ด ๋ณ€ํ•˜๋ฉด ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋ฉ๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€ํ•˜๋ฉด ์†์„ฑ ์—ญ์‹œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐฑ์‹ ๋ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ์†์„ฑ์œผ๋กœ์จ์˜ `id`๊ฐ€ ์ˆ˜์ •๋˜์—ˆ๊ณ , ์ด์— ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ฐ˜๋Œ€๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ์†์„ฑ `id`๊ฐ€ ์ˆ˜์ •๋˜๋ฉด ์ด์— ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐฑ์‹ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ฐ˜๋Œ€๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ```html run <input> @@ -152,17 +152,17 @@ HTML ์†์„ฑ์— ๊ด€ํ•œ ๋˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”: <script> let input = document.querySelector('input'); - // attribute => property + // ์†์„ฑ ์ถ”๊ฐ€ => ํ”„๋กœํผํ‹ฐ ๊ฐฑ์‹  input.setAttribute('id', 'id'); - alert(input.id); // id (updated) + alert(input.id); // id (๊ฐฑ์‹ ) - // property => attribute + // ํ”„๋กœํผํ‹ฐ ๋ณ€๊ฒฝ => ์†์„ฑ ๊ฐฑ์‹  input.id = 'newId'; - alert(input.getAttribute('id')); // newId (updated) + alert(input.getAttribute('id')); // newId (๊ฐฑ์‹ ) </script> ``` -ํ•˜์ง€๋งŒ `input.value`์™€ ๊ฐ™์ด ๋™๊ธฐํ™”๊ฐ€ ์†์„ฑ์—์„œ ํ”„๋กœํผํ‹ฐ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ผ์–ด๋‚˜๋Š” ์˜ˆ์™ธ์ƒํ™ฉ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค: +๊ทธ๋Ÿฐ๋ฐ ์•„๋ž˜ ์˜ˆ์‹œ์˜ `input.value`์ฒ˜๋Ÿผ ๋™๊ธฐํ™”๊ฐ€ ์†์„ฑ์—์„œ ํ”„๋กœํผํ‹ฐ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ผ์–ด๋‚˜๋Š” ์˜ˆ์™ธ์ƒํ™ฉ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ```html run <input> @@ -170,27 +170,27 @@ HTML ์†์„ฑ์— ๊ด€ํ•œ ๋˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”: <script> let input = document.querySelector('input'); - // attribute => property + // ์†์„ฑ ์ถ”๊ฐ€ => ํ”„๋กœํผํ‹ฐ ๊ฐฑ์‹  input.setAttribute('value', 'text'); - alert(input.value); // text + alert(input.value); // text (๊ฐฑ์‹ ) *!* - // NOT property => attribute + // ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ์†์„ฑ์ด ๊ฐฑ์‹ ๋˜์ง€ ์•Š์Œ input.value = 'newValue'; - alert(input.getAttribute('value')); // text (์—…๋ฐ์ดํŠธ ์•ˆ๋จ!) + alert(input.getAttribute('value')); // text (๊ฐฑ์‹  ์•ˆ๋จ!) */!* </script> ``` -์œ„์˜ ์˜ˆ์‹œ์—์„œ ๋‹ค์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: -- ์†์„ฑ `value`๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ๋„ ์ˆ˜์ •๋œ๋‹ค. -- ํ•˜์ง€๋งŒ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•ด๋„ ์†์„ฑ์€ ์ˆ˜์ •๋˜์ง€ ์•Š๋Š”๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„  ๋‹ค์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ์†์„ฑ `value`๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ๋„ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค. +- ํ•˜์ง€๋งŒ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•ด๋„ ์†์„ฑ์€ ์ˆ˜์ •๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฐ ํŠน์ง•์€ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ์ €์˜ ์–ด๋–ค ํ–‰๋™ ๋•Œ๋ฌธ์— `value`์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”๋ฐ, ์ˆ˜์ • ์ „์˜ "์›๋ž˜" ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์˜ค๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์†์„ฑ์—์„œ ์ด ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์˜ค๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ '๊ธฐ๋Šฅ'์€ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ์ €์˜ ์–ด๋–ค ํ–‰๋™ ๋•Œ๋ฌธ์— `value`๊ฐ€ ์ˆ˜์ •๋˜์—ˆ๋Š”๋ฐ ์ˆ˜์ • ์ „์˜ '์›๋ž˜' ๊ฐ’์œผ๋กœ ๋ณต๊ตฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ, ์†์„ฑ์— ์ €์žฅ๋œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์˜ค๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -## DOM ํ”„๋กœํผํ‹ฐ์˜ ํƒ€์ž… +## DOM ํ”„๋กœํผํ‹ฐ ๊ฐ’์˜ ํƒ€์ž… -DOM ํ”„๋กœํผํ‹ฐ๋Š” ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `input.checked` ํ”„๋กœํผํ‹ฐ(์ฒดํฌ๋ฐ•์Šค์—์„œ ์‚ฌ์šฉ๋จ)์˜ ๊ฒฝ์šฐ ๋ถˆ๋ฆฐ(boolean) ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค: +DOM ํ”„๋กœํผํ‹ฐ๋Š” ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ฒดํฌ ๋ฐ•์Šค์— ์‚ฌ์šฉ๋˜๋Š” `input.checked` ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ๋ถˆ๋ฆฐ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ```html run <input id="input" type="checkbox" checked> checkbox @@ -201,7 +201,7 @@ DOM ํ”„๋กœํผํ‹ฐ๋Š” ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `input.check </script> ``` -๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์˜ˆ๋ฅผ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. `style` ์†์„ฑ์˜ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด์ด์ง€๋งŒ, `style` ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค: +๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์˜ˆ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. `style` ์†์„ฑ์˜ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด์ด์ง€๋งŒ, `style` ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ```html run <div id="div" style="color:red;font-size:120%">Hello</div> @@ -216,62 +216,62 @@ DOM ํ”„๋กœํผํ‹ฐ๋Š” ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `input.check </script> ``` -๊ทธ๋Ÿฐ๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœํผํ‹ฐ๋Š” ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. +๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์€ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. -์•„์ฃผ ๋“œ๋ฌธ ๊ฒฝ์šฐ๊ธด ํ•˜์ง€๋งŒ, DOM ํ”„๋กœํผํ‹ฐ ํƒ€์ž…์ด ๋ฌธ์ž์—ด์ผ์ง€๋ผ๋„ ์†์„ฑ๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. a ํƒœ๊ทธ์˜ href ์†์„ฑ์ด ์ƒ๋Œ€ URL์ด๋‚˜ `#hash`์ด๋”๋ผ๋„, `href` DOM ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ํ•ญ์ƒ *์ „์ฒด* URL ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. +์•„์ฃผ ๋“œ๋ฌผ๊ธด ํ•˜์ง€๋งŒ, DOM ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋ฌธ์ž์—ด์ด๋”๋ผ๋„ ์†์„ฑ๊ฐ’๊ณผ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `href` ์†์„ฑ์ด ์ƒ๋Œ€ URL์ด๋‚˜ `#hash`์ด๋”๋ผ๋„ `href` DOM ํ”„๋กœํผํ‹ฐ์—” ํ•ญ์ƒ URL *์ „์ฒด* ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. -์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค: +์˜ˆ์‹œ: ```html height=30 run <a id="a" href="#hello">link</a> <script> - // attribute + // ์†์„ฑ alert(a.getAttribute('href')); // #hello - // property - alert(a.href ); // form ๋‚ด์˜ ์ „์ฒด URL http://site.com/page#hello + // ํ”„๋กœํผํ‹ฐ + alert(a.href ); // ์‹คํ–‰๋˜๋Š” ์‚ฌ์ดํŠธ ์ฃผ์†Œ์— ๋”ฐ๋ผ http://site.com/page#hello ํ˜•ํƒœ๋กœ ๊ฐ’์ด ์ €์žฅ๋จ </script> ``` -HTML์— ๋‚ด์— ์‚ฌ์šฉ๋œ `href` ๊ฐ’๊ณผ ๊ฐ™์ด ์ •ํ™•ํ•œ ์†์„ฑ๊ฐ’์„ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด `getAttribute`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +HTML์— ๋‚ด์— ๋ช…์‹œ๋œ `href` ์†์„ฑ์˜ ๊ฐ’์„ ์ •ํ™•ํ•˜๊ฒŒ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด `getAttribute`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ## ๋น„ํ‘œ์ค€ ์†์„ฑ, dataset -HTML์„ ์ž‘์„ฑํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ‘œ์ค€์ด ์•„๋‹Œ ์†์„ฑ๋„ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋น„ํ‘œ์ค€(non-standard) ์†์„ฑ์„ ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผ ์œ ์šฉํ•˜๊ณ  ์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•˜์ง€ ์•Š์€ ์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ธ์ œ ์ด ๋น„ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. +HTML์„ ์ž‘์„ฑํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๋Œ€๋ถ€๋ถ„ ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ‘œ์ค€์ด ์•„๋‹Œ ์†์„ฑ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋น„ํ‘œ์ค€์ด ์œ ์šฉํ•œ ์ง€ ์•„๋‹Œ์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ๊ฒฝ์šฐ์— ๋น„ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. -๋น„ํ‘œ์ค€ ์†์„ฑ์€ ์ปค์Šคํ…€ ๋ฐ์ดํ„ฐ๋ฅผ HTML์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋„˜๊ธฐ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋‚˜ HTML-์š”์†Œ๋ฅผ "mark(ํ‘œ์‹œ)" ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋น„ํ‘œ์ค€ ์†์„ฑ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ง€์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ HTML์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋„˜๊ธฐ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋‚˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์กฐ์ž‘ํ•  HTML ์š”์†Œ๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: ```html run -<!-- "name"์ด ๋ณด์—ฌ์ง€๋Š” div๋ผ๊ณ  markํ•จ(show-info์‚ฌ์šฉ) --> +<!-- ์ด๋ฆ„(name) ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” div๋ผ๊ณ  ํ‘œ์‹œ --> <div *!*show-info="name"*/!*></div> -<!-- age๊ฐ€ ๋ณด์—ฌ์ง€๋Š” ์ž๋ฆฌ --> +<!-- ๋‚˜์ด(age) ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” div๋ผ๊ณ  ํ‘œ์‹œ --> <div *!*show-info="age"*/!*></div> <script> - // ๋งˆํฌ๋œ ์š”์†Œ๋ฅผ ์ฐพ์•„ ๊ทธ ์ž๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ณด์—ฌ์คŒ + // ํ‘œ์‹œํ•œ ์š”์†Œ๋ฅผ ์ฐพ๊ณ , ๊ทธ ์ž๋ฆฌ์— ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ฝ”๋“œ let user = { name: "Pete", age: 25 }; for(let div of document.querySelectorAll('[show-info]')) { - // ํ•ด๋‹นํ•˜๋Š” ์ •๋ณด๋ฅผ ํ•„๋“œ ๊ฐ’์— ์ž…๋ ฅํ•ด ์คŒ + // ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ํ•„๋“œ ๊ฐ’์— ์ž…๋ ฅํ•ด ์คŒ let field = div.getAttribute('show-info'); - div.innerHTML = user[field]; // first Pete into "name", then 25 into "age" + div.innerHTML = user[field]; // Pete๊ฐ€ 'name'์—, 25๊ฐ€ 'age'์— ์‚ฝ์ž…๋จ } </script> ``` -์š”์†Œ์— ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +๋น„ํ‘œ์ค€ ์†์„ฑ์€ ์š”์†Œ์— ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. -์ฃผ๋ฌธ(order) ์ƒํƒœ(state)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ปค์Šคํ…€ ์†์„ฑ `order-state`์˜ ์Šคํƒ€์ผ์„ ๊พธ๋ฏธ๋Š” ์˜ˆ์ œ: +์•„๋ž˜ ์˜ˆ์‹œ์—์„  ์ฃผ๋ฌธ ์ƒํƒœ(order state)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ปค์Šคํ…€ ์†์„ฑ `order-state`๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ๋ฌธ ์ƒํƒœ์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ```html run <style> - /* ์Šคํƒ€์ผ์ด ์ปค์Šคํ…€ ์†์„ฑ์ธ "order-state"์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค */ + /* ์Šคํƒ€์ผ์ด ์ปค์Šคํ…€ ์†์„ฑ 'order-state'์— ๋”ฐ๋ผ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค. */ .order[order-state="new"] { color: green; } @@ -298,22 +298,24 @@ HTML์„ ์ž‘์„ฑํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ </div> ``` -์ด๋Š” ์†์„ฑ์ด ๋‹ค๋ฃจ๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์  ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ƒํƒœ(state)๋ฅผ ์ด๋ ‡๊ฒŒ ์‰ฝ๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์ด๋ ‡๊ฒŒ ์ปค์Šคํ…€ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ `.order-state-new`, `.order-state-pending`, `order-state-canceled`๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์™œ ์„ ํ˜ธ๋ ๊นŒ์š”? + +์ด์œ ๋Š” ์†์„ฑ์€ ํด๋ž˜์Šค๋ณด๋‹ค ๋‹ค๋ฃจ๊ธฐ ํŽธ๋ฆฌํ•˜๋‹ค๋Š” ์  ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์†์„ฑ์˜ ์ƒํƒœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js // ์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ง€์šฐ๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ์‰ฝ๊ฒŒ ์ƒํƒœ(state)๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค div.setAttribute('order-state', 'canceled'); ``` -ํ•˜์ง€๋งŒ ์ปค์Šคํ…€ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ ๋‚˜์ค‘์— ๊ทธ ์†์„ฑ์ด ํ‘œ์ค€์œผ๋กœ ๋“ฑ๋ก๋˜๊ฒŒ ๋˜๋ฉด ์–ด๋–จ๊นŒ์š”? HTML์€ ์‚ด์•„์žˆ๋Š” ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋“ค์˜ ์š”๊ตฌ๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ง€์†ํ•ด์„œ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์ฃ . ๊ทธ๋ž˜์„œ ์•ž์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒฝ์šฐ์— ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๋ถ€์ž‘์šฉ์ด ์ƒ๊ธฐ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. +๋ฌผ๋ก  ์ปค์Šคํ…€ ์†์„ฑ์—๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„ํ‘œ์ค€ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ ๋‚˜์ค‘์— ๊ทธ ์†์„ฑ์ด ํ‘œ์ค€์œผ๋กœ ๋“ฑ๋ก๋˜๊ฒŒ ๋˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. HTML์€ ์‚ด์•„์žˆ๋Š” ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋“ค์˜ ์š”๊ตฌ๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ง€์†ํ•ด์„œ ๋ฐœ์ „ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ๊ฒฝ์šฐ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๋ถ€์ž‘์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์ถฉ๋Œ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) ์†์„ฑ์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์ถฉ๋Œ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์†์„ฑ์ธ [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -**"data-"๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ์†์„ฑ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋“ฑ๋กํ•œ ์†์„ฑ์ž…๋‹ˆ๋‹ค. ์ด ์†์„ฑ๋“ค์€ `dataset` ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** +**'data-'๋กœ ์‹œ์ž‘ํ•˜๋Š” ์†์„ฑ ์ „์ฒด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์šฉ๋„์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ„๋„๋กœ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค. `dataset` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** -์˜ˆ๋ฅผ ๋“ค์–ด `elem`์ด `"data-about"`์ด๋ผ๋Š” ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” `elem.dataset.about`์ด๋ผ๋Š” ๋ฌธ๋ฒ•์„ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค +์š”์†Œ `elem`์— ์ด๋ฆ„์ด `"data-about"`์ธ ์†์„ฑ์ด ์žˆ๋‹ค๋ฉด `elem.dataset.about`์„ ์‚ฌ์šฉํ•ด ๊ทธ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์ฃ . -์ด๋ ‡๊ฒŒ ๋ง์ด์ฃ : +์˜ˆ์‹œ: ```html run <body data-about="Elephants"> @@ -322,9 +324,9 @@ div.setAttribute('order-state', 'canceled'); </script> ``` -`data-order-state`์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ๋‹จ์–ด๋กœ ๊ตฌ์„ฑ๋œ ์†์„ฑ์˜ ๊ฒฝ์šฐ๋Š” ์นด๋ฉœ ํ‘œ๊ธฐ๋ฒ•(camel-cased)์„ ์‚ฌ์šฉํ•ด `dataset.orderState`์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. +`data-order-state` ๊ฐ™์ด ์—ฌ๋Ÿฌ ๋‹จ์–ด๋กœ ๊ตฌ์„ฑ๋œ ์†์„ฑ์€ ์นด๋ฉœ ํ‘œ๊ธฐ๋ฒ•(camel-cased)์„ ์‚ฌ์šฉํ•ด `dataset.orderState`์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. -์ฃผ๋ฌธ ์ƒํƒœ(order state)์— ๊ด€ํ•œ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด์ฃ : +์ด๋Ÿฐ ํŠน์ง•์„ ์‚ฌ์šฉํ•ด ์ฃผ๋ฌธ ์ƒํƒœ์— ๊ด€ํ•œ ์˜ˆ์‹œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run <style> @@ -346,39 +348,39 @@ div.setAttribute('order-state', 'canceled'); </div> <script> - // read + // ์ฝ๊ธฐ alert(order.dataset.orderState); // new - // modify + // ์ˆ˜์ •ํ•˜๊ธฐ order.dataset.orderState = "pending"; // (*) </script> ``` -`data-*` ์†์„ฑ์€ ์ปค์Šคํ…€ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์•ˆ์ „ํ•˜๊ณ  ์œ ํšจํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. +`data-*` ์†์„ฑ์€ ์ปค์Šคํ…€ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ณ  ์œ ํšจํ•˜๊ฒŒ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค. -data-์†์„ฑ์„ ์ฝ์„ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ์†์„ฑ์ด ์ˆ˜์ •๋˜๋ฉด CSS๊ฐ€ ํ•ด๋‹น ๋ทฐ๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด ์ค๋‹ˆ๋‹ค. ์œ„์˜ ์ฃผ๋ฌธ์ƒํƒœ ์˜ˆ์‹œ์—์„œ `(*)` ํ‘œ์‹œ๊ฐ€ ๋œ ๋งˆ์ง€๋ง‰ ๋ผ์ธ์€ ์ƒ‰์„ ํŒŒ๋ž€์ƒ‰์œผ๋กœ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค. +`data-*` ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ๊ธฐ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ˆ˜์ •๋„ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด์ฃผ์„ธ์š”. ์†์„ฑ์ด ์ˆ˜์ •๋˜๋ฉด CSS๊ฐ€ ํ•ด๋‹น ๋ทฐ๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด ์ค๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ์ƒ‰์ด ํŒŒ๋ž€์ƒ‰์œผ๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค. ## ์š”์•ฝ -- ์†์„ฑ(Attributes) -- HTML ์•ˆ์— ์“ฐ์ž„. -- ํ”„๋กœํผํ‹ฐ(Properties) -- DOM ๊ฐ์ฒด ์•ˆ์— ์“ฐ์ž„. +- ์†์„ฑ -- HTML ์•ˆ์— ์“ฐ์ž„ +- ํ”„๋กœํผํ‹ฐ -- DOM ๊ฐ์ฒด ์•ˆ์— ์“ฐ์ž„ ๋น„๊ตํ‘œ: | | ํ”„๋กœํผํ‹ฐ | ์†์„ฑ | |------------|------------|------------| -|ํƒ€์ž…|๋ชจ๋“  ํƒ€์ž… ๊ฐ€๋Šฅ, ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ spec์— ํƒ€์ž…์ด ๋ช…์‹œ๋˜์–ด ์žˆ์Œ|๋ฌธ์ž์—ด| -|์ด๋ฆ„|๋Œ€/์†Œ๋ฌธ์ž ๊ตฌ๋ถ„|๋Œ€/์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Œ| +|ํƒ€์ž…|๋ชจ๋“  ํƒ€์ž… ๊ฐ€๋Šฅ, ๊ฐ ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ์˜ ํƒ€์ž…์€ ๋ช…์„ธ์„œ์— ์„ค๋ช…๋˜์–ด ์žˆ์Œ|๋ฌธ์ž์—ด| +|์ด๋ฆ„|๋Œ€ยท์†Œ๋ฌธ์ž ๊ตฌ๋ถ„|๋Œ€ยท์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Œ| ์†์„ฑ๊ณผ ํ•จ๊ป˜ ์“ฐ์ด๋Š” ๋ฉ”์„œ๋“œ: -- `elem.hasAttribute(name)` -- ์†์„ฑ์˜ ์กด์žฌ ํ™•์ธ. -- `elem.getAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ๊ฐ€์ ธ์˜ด. -- `elem.setAttribute(name, value)` -- ์†์„ฑ๊ฐ’์„ ๋ณ€๊ฒฝํ•จ. -- `elem.removeAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ์ œ๊ฑฐํ•จ. -- `elem.attributes` ์€ ์†์„ฑ์˜ ๋ชจ์Œ(collection)์„ ๋ฐ˜ํ™˜ํ•จ. +- `elem.hasAttribute(name)` -- ์†์„ฑ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ +- `elem.getAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ๊ฐ€์ ธ์˜ด +- `elem.setAttribute(name, value)` -- ์†์„ฑ๊ฐ’์„ ๋ณ€๊ฒฝํ•จ +- `elem.removeAttribute(name)` -- ์†์„ฑ๊ฐ’์„ ์ง€์›€ +- `elem.attributes` -- ์†์„ฑ์˜ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•จ -๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ์—์„œ ์†์„ฑ๋ณด๋‹ค๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ๋‚ซ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, HTML ์†์„ฑ์˜ ์ •ํ™•ํ•œ ๊ฐ’์ด ํ•„์š”ํ•œ ๋‹ค์Œ์˜ ์‚ฌ๋ก€๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ์ ˆ์น˜ ์•Š์€ ๊ฒฝ์šฐ์ด๋ฏ€๋กœ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: +๊ฑฐ์˜ ๋ชจ๋“  ์ƒํ™ฉ์—์„œ ์†์„ฑ๋ณด๋‹ค๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ๋‚ซ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์•„๋ž˜ ์‚ฌ๋ก€๊ฐ™์ด ์ •ํ™•ํ•œ HTML ์†์„ฑ ๊ฐ’์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ ์ ˆ์น˜ ์•Š์œผ๋ฏ€๋กœ ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- ๋น„ํ‘œ์ค€ ์†์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ. ๋‹ค๋งŒ ์†์„ฑ์ด `data-`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ, `dataset`์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -- HTML์— ์ ํžŒ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ์˜ ๊ฐ’์„ ์ฝ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ. ์›๋ณธ๊ฐ’๊ณผ DOM ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด ๋‹ค๋ฅธ๋ฐ, ์›๋ณธ๊ฐ’์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. `href` ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ํ•ญ์ƒ ์ „์ฒด URL ๊ฐ’์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +- ๋น„ํ‘œ์ค€ ์†์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ. ๋‹ค๋งŒ ์†์„ฑ์ด `data-`๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ์—” `dataset`์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- HTML์— ์ ํžŒ ๊ฐ’ '๊ทธ๋Œ€๋กœ'๋ฅผ ์ฝ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ. `href` ํ”„๋กœํผํ‹ฐ์— ํ•ญ์ƒ ์ „์ฒด URL์ด ์ €์žฅ๋˜๋Š” ๊ฒƒ ๊ฐ™์ด DOM ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’๊ณผ ์†์„ฑ ๊ฐ’์ด ๋‹ค๋ฅธ๋ฐ, '์›๋ณธ'๊ฐ’์„ ์–ป๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—” ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/solution.md b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/solution.md index a38f016457..b62e67ab61 100644 --- a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/solution.md +++ b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/solution.md @@ -1,8 +1,8 @@ -Answer: **1 and 3**. +์ •๋‹ต: **1 ๊ณผ 3**. -Both commands result in adding the `text` "as text" into the `elem`. +๋‘ ๋ช…๋ น์–ด๋Š” `text`๋ฅผ 'ํ…์ŠคํŠธ๋กœ' `elem` ์•ˆ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. -Here's an example: +์˜ˆ์‹œ: ```html run height=80 <div id="elem1"></div> diff --git a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md index e127bc0efa..eab23709c4 100644 --- a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md +++ b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md @@ -4,9 +4,9 @@ importance: 5 # createTextNode vs innerHTML vs textContent -We have an empty DOM element `elem` and a string `text`. +๋นˆ DOM ์š”์†Œ `elem`๊ณผ `text`๋ผ๋Š” ๋ฌธ์ž์—ด์ด ์žˆ์Šต๋‹ˆ๋‹ค. -Which of these 3 commands do exactly the same? +์…‹ ์ค‘์—์„œ ๊ฐ™์€ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? 1. `elem.append(document.createTextNode(text))` 2. `elem.innerHTML = text` diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md index 15238fcf4f..8ae95c4b28 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md @@ -1,6 +1,6 @@ -First, let's make HTML/CSS. +๋จผ์ € HTMLยทCSS๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค. -Each component of the time would look great in its own `<span>`: +์‹œ๊ฐ„์„ ๊ตฌ์„ฑํ•˜๋Š” ์‹œ, ๋ถ„, ์ดˆ๋Š” ๊ฐ๊ฐ `<span>` ์„ ์‚ฌ์šฉํ•ด ๊พธ๋ฐ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html <div id="clock"> @@ -8,9 +8,9 @@ Each component of the time would look great in its own `<span>`: </div> ``` -Also we'll need CSS to color them. - -The `update` function will refresh the clock, to be called by `setInterval` every second: +์ƒ‰์„ ์ž…ํžˆ๊ธฐ ์œ„ํ•ด์„œ๋Š” CSS๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + +`setInterval`์— ์˜ํ•ด ๋งค ์ดˆ ํ˜ธ์ถœ๋˜๋Š” `update` ํ•จ์ˆ˜๋Š” ์‹œ๊ฐ์„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ```js function update() { @@ -32,9 +32,9 @@ function update() { } ``` -In the line `(*)` we every time check the current date. The calls to `setInterval` are not reliable: they may happen with delays. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ๋Š” ํ˜„์žฌ ๋‚ ์งœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. `setInterval`์„ ์‚ฌ์šฉํ•ด ํ˜ธ์ถœํ•˜๋ฉด ์ง€์—ฐ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ ๋ขฐ์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค. -The clock-managing functions: +์‹œ๊ณ„๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜ ์ฝ”๋“œ: ```js let timerId; @@ -50,4 +50,4 @@ function clockStop() { } ``` -Please note that the call to `update()` is not only scheduled in `clockStart()`, but immediately run in the line `(*)`. Otherwise the visitor would have to wait till the first execution of `setInterval`. And the clock would be empty till then. +`update()`๋Š” `clockStart()` ์—์„œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ๋„ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์–‘์ชฝ ๋ชจ๋‘์—์„œ `update()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด `setInterval`์ด ์‹คํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€ ์‚ฌ์šฉ์ž๋Š” ์•„๋ฌด๋Ÿฐ ๋‚ด์šฉ์ด ์—†๋Š” ์‹œ๊ณ„๋ฅผ ๋ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html index 1bf642b102..e017bb3783 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html @@ -44,7 +44,7 @@ function clockStart() { timerId = setInterval(update, 1000); - update(); // <-- start right now, don't wait 1 second till the first setInterval works + update(); // <-- ์ฒซ ๋ฒˆ์งธ setInterval์ด ์‹คํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์ด ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. } function clockStop() { @@ -54,10 +54,10 @@ clockStart(); </script> - <!-- click on this button calls clockStart() --> + <!-- ์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด clockStart() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. --> <input type="button" onclick="clockStart()" value="Start"> - <!-- click on this button calls clockStop() --> + <!-- ์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด clockStop() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. --> <input type="button" onclick="clockStop()" value="Stop"> </body> diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/source.view/index.html b/2-ui/1-document/07-modifying-document/10-clock-setinterval/source.view/index.html index ecf5df99af..3b95d962dc 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/source.view/index.html +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/source.view/index.html @@ -2,10 +2,10 @@ <html> <body> - <!-- click on this button calls clockStart() --> + <!-- ์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด clockStart() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. --> <input type="button" onclick="clockStart()" value="Start"> - <!-- click on this button calls clockStop() --> + <!-- ์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด clockStop() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. --> <input type="button" onclick="clockStop()" value="Stop"> </body> diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/task.md b/2-ui/1-document/07-modifying-document/10-clock-setinterval/task.md index a1b53e337d..5127b20695 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/task.md +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/task.md @@ -2,10 +2,10 @@ importance: 4 --- -# Colored clock with setInterval +# setInterval์„ ์‚ฌ์šฉํ•œ ์•Œ๋ก๋‹ฌ๋กํ•œ ์‹œ๊ณ„ -Create a colored clock like here: +์•„๋ž˜์ฒ˜๋Ÿผ ์•Œ๋ก๋‹ฌ๋กํ•œ ์‹œ๊ณ„๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. [iframe src="solution" height=60] -Use HTML/CSS for the styling, JavaScript only updates time in elements. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์š”์†Œ ๋‚ด๋ถ€ ์‹œ๊ฐ„์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์Šคํƒ€์ผ์„ ๊พธ๋ฏธ๋ ค๋ฉด HTMLยทCSS๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. diff --git a/2-ui/1-document/07-modifying-document/11-append-to-list/solution.md b/2-ui/1-document/07-modifying-document/11-append-to-list/solution.md index 4e77fb5cbf..875372237d 100644 --- a/2-ui/1-document/07-modifying-document/11-append-to-list/solution.md +++ b/2-ui/1-document/07-modifying-document/11-append-to-list/solution.md @@ -1,7 +1,7 @@ -When we need to insert a piece of HTML somewhere, `insertAdjacentHTML` is the best fit. - -The solution: +๋ฌธ์„œ ์–ด๋”˜๊ฐ€์— HTML์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ๋•Œ๋Š” `insertAdjacentHTML`์ด ์ตœ๊ณ ์˜ ์„ ํƒ์ž…๋‹ˆ๋‹ค. + +์ •๋‹ต: ```js one.insertAdjacentHTML('afterend', '<li>2</li><li>3</li>'); diff --git a/2-ui/1-document/07-modifying-document/11-append-to-list/task.md b/2-ui/1-document/07-modifying-document/11-append-to-list/task.md index 543cd3e466..d36d4b3d18 100644 --- a/2-ui/1-document/07-modifying-document/11-append-to-list/task.md +++ b/2-ui/1-document/07-modifying-document/11-append-to-list/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Insert the HTML in the list +# ๋ฆฌ์ŠคํŠธ์— HTML ์‚ฝ์ž…ํ•˜๊ธฐ -Write the code to insert `<li>2</li><li>3</li>` between two `<li>` here: +๋‘ `<li>` ์‚ฌ์ด์— `<li>2</li><li>3</li>`์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. ```html <ul id="ul"> diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/solution.md b/2-ui/1-document/07-modifying-document/12-sort-table/solution.md index 25dd58b0cf..7f37806eb0 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/solution.md +++ b/2-ui/1-document/07-modifying-document/12-sort-table/solution.md @@ -1,19 +1,18 @@ -The solution is short, yet may look a bit tricky, so here I provide it with extensive comments: - +๊ผผ์ˆ˜์ฒ˜๋Ÿผ ๋ณด์ผ์ง€๋„ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ํ•ด๋‹ต์€ ๊ฐ„๋‹จํ•œ๋ฐ์š”, ์ƒ์„ธํ•œ ์„ค๋ช…์€ ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ```js -let sortedRows = Array.from(table.rows) - .slice(1) - .sort((rowA, rowB) => rowA.cells[0].innerHTML > rowB.cells[0].innerHTML ? 1 : -1); +let sortedRows = Array.from(table.tBodies[0].rows) // 1 + .sort((rowA, rowB) => rowA.cells[0].innerHTML.localeCompare(rowB.cells[0].innerHTML)); -table.tBodies[0].append(...sortedRows); +table.tBodies[0].append(...sortedRows); // (3) ``` -1. Get all `<tr>`, like `table.querySelectorAll('tr')`, then make an array from them, cause we need array methods. -2. The first TR (`table.rows[0]`) is actually a table header, so we take the rest by `.slice(1)`. -3. Then sort them comparing by the content of the first `<td>` (the name field). -4. Now insert nodes in the right order by `.append(...sortedRows)`. +ํ’€์ด ๊ณผ์ •: + +1. `<tbody>`๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  `<tr>`์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. +2. ๊ทธ ํ›„ name ํ•„๋“œ์— ํ•ด๋‹นํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ `<td>`์˜ ๋‚ด์šฉ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค. +3. ์ด์ œ `.append(...sortedRows)`๋ฅผ ์‚ฌ์šฉํ•ด ์ •๋ ฌ๋œ ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. - Tables always have an implicit <tbody> element, so we need to take it and insert into it: a simple `table.append(...)` would fail. +ํ–‰์— ํ•ด๋‹นํ•˜๋Š” ์š”์†Œ๋“ค์„ ์ง€์šธ ํ•„์š” ์—†์ด '์žฌ์‚ฝ์ž…' ํ•˜๋ฉด ๊ธฐ์กด ์œ„์น˜๋ฅผ ์ €์ ˆ๋กœ ๋ฒ—์–ด๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. - Please note: we don't have to remove them, just "re-insert", they leave the old place automatically. +์˜ˆ์‹œ์—์„œ๋Š” `<tbody>` ๊ฐ€ ํ‘œ์— ๋ช…์‹œ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š”๋ฐ์š”, HTML ํ‘œ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ `<tbody>`๋ฅผ ๊ฐ–์ง€ ์•Š๋”๋ผ๋„ DOM ๊ตฌ์กฐ์ƒ์—๋Š” ์–ธ์ œ๋‚˜ ์กด์žฌํ•œ๋‹ค๋Š” ์ ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/solution.view/index.html b/2-ui/1-document/07-modifying-document/12-sort-table/solution.view/index.html index 81e985748f..40692031a1 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/solution.view/index.html +++ b/2-ui/1-document/07-modifying-document/12-sort-table/solution.view/index.html @@ -1,37 +1,30 @@ <!DOCTYPE html> -<html> -<body> - <table id="table"> - <tr> - <th>Name</th> - <th>Surname</th> - <th>Age</th> - </tr> - <tr> - <td>John</td> - <td>Smith</td> - <td>10</td> - </tr> - <tr> - <td>Pete</td> - <td>Brown</td> - <td>15</td> - </tr> - <tr> - <td>Ann</td> - <td>Lee</td> - <td>5</td> - </tr> - </table> +<table id="table"> +<thead> + <tr> + <th>Name</th><th>Surname</th><th>Age</th> + </tr> +</thead> +<tbody> + <tr> + <td>John</td><td>Smith</td><td>10</td> + </tr> + <tr> + <td>Pete</td><td>Brown</td><td>15</td> + </tr> + <tr> + <td>Ann</td><td>Lee</td><td>5</td> + </tr> + <tr> + <td>...</td><td>...</td><td>...</td> + </tr> +</tbody> +</table> - <script> - let sortedRows = Array.from(table.rows) - .slice(1) - .sort((rowA, rowB) => rowA.cells[0].innerHTML > rowB.cells[0].innerHTML ? 1 : -1); +<script> + let sortedRows = Array.from(table.tBodies[0].rows) + .sort((rowA, rowB) => rowA.cells[0].innerHTML.localeCompare(rowB.cells[0].innerHTML)); - table.tBodies[0].append(...sortedRows); - </script> - -</body> -</html> + table.tBodies[0].append(...sortedRows); +</script> diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/source.view/index.html b/2-ui/1-document/07-modifying-document/12-sort-table/source.view/index.html index e41eb229fa..117dc0a296 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/source.view/index.html +++ b/2-ui/1-document/07-modifying-document/12-sort-table/source.view/index.html @@ -1,33 +1,27 @@ <!DOCTYPE html> -<html> -<body> - <table id="table"> - <tr> - <th>Name</th> - <th>Surname</th> - <th>Age</th> - </tr> - <tr> - <td>John</td> - <td>Smith</td> - <td>10</td> - </tr> - <tr> - <td>Pete</td> - <td>Brown</td> - <td>15</td> - </tr> - <tr> - <td>Ann</td> - <td>Lee</td> - <td>5</td> - </tr> - </table> +<table id="table"> +<thead> + <tr> + <th>Name</th><th>Surname</th><th>Age</th> + </tr> +</thead> +<tbody> + <tr> + <td>John</td><td>Smith</td><td>10</td> + </tr> + <tr> + <td>Pete</td><td>Brown</td><td>15</td> + </tr> + <tr> + <td>Ann</td><td>Lee</td><td>5</td> + </tr> + <tr> + <td>...</td><td>...</td><td>...</td> + </tr> +</tbody> +</table> - <script> - // ... your code ... - </script> - -</body> -</html> +<script> + // ... ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ... +</script> diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/task.md b/2-ui/1-document/07-modifying-document/12-sort-table/task.md index 41d6fca29c..2d85f300f7 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/task.md +++ b/2-ui/1-document/07-modifying-document/12-sort-table/task.md @@ -2,38 +2,34 @@ importance: 5 --- -# Sort the table +# ํ‘œ ์ •๋ ฌํ•˜๊ธฐ -There's a table: +์ฃผ์–ด์ง„ ํ‘œ๊ฐ€ ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. +```html run <table> -<tr> - <th>Name</th> - <th>Surname</th> - <th>Age</th> -</tr> -<tr> - <td>John</td> - <td>Smith</td> - <td>10</td> -</tr> -<tr> - <td>Pete</td> - <td>Brown</td> - <td>15</td> -</tr> -<tr> - <td>Ann</td> - <td>Lee</td> - <td>5</td> -</tr> -<tr> - <td>...</td> - <td>...</td> - <td>...</td> -</tr> +<thead> + <tr> + <th>Name</th><th>Surname</th><th>Age</th> + </tr> +</thead> +<tbody> + <tr> + <td>John</td><td>Smith</td><td>10</td> + </tr> + <tr> + <td>Pete</td><td>Brown</td><td>15</td> + </tr> + <tr> + <td>Ann</td><td>Lee</td><td>5</td> + </tr> + <tr> + <td>...</td><td>...</td><td>...</td> + </tr> +</tbody> </table> +``` -There may be more rows in it. +ํ‘œ์—๋Š” ์ด๋ณด๋‹ค ๋” ๋งŽ์€ ํ–‰๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Write the code to sort it by the `"name"` column. +`'name'` ์—ด์„ ๊ธฐ์ค€์œผ๋กœ ํ‘œ๋ฅผ ์ •๋ ฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. diff --git a/2-ui/1-document/07-modifying-document/4-clear-elem/solution.md b/2-ui/1-document/07-modifying-document/4-clear-elem/solution.md index 62c3386d84..a36df85064 100644 --- a/2-ui/1-document/07-modifying-document/4-clear-elem/solution.md +++ b/2-ui/1-document/07-modifying-document/4-clear-elem/solution.md @@ -1,5 +1,5 @@ -First, let's see how *not* to do it: +๋จผ์ € ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js function clear(elem) { @@ -9,11 +9,11 @@ function clear(elem) { } ``` -That won't work, because the call to `remove()` shifts the collection `elem.childNodes`, so elements start from the index `0` every time. But `i` increases, and some elements will be skipped. +`remove()`๋Š” `elem.childNodes`์„ ๋ณ€ํ™”์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต๋ฌธ์„ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค `0` ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ `i` ๋Š” ๊ณ„์†ํ•ด์„œ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ, ๊ฒฐ๊ตญ ์ผ๋ถ€ ์›์†Œ๋“ค์„ ์ง€๋‚˜์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -The `for..of` loop also does the same. +`for..of` ๋ฐ˜๋ณต๋ฌธ์—๋„ ์—ญ์‹œ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -The right variant could be: +์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js function clear(elem) { @@ -23,7 +23,7 @@ function clear(elem) { } ``` -And also there's a simpler way to do the same: +๊ฐ™์€ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋” ์‰ฌ์šด ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js function clear(elem) { diff --git a/2-ui/1-document/07-modifying-document/4-clear-elem/task.md b/2-ui/1-document/07-modifying-document/4-clear-elem/task.md index 938d534703..99febca761 100644 --- a/2-ui/1-document/07-modifying-document/4-clear-elem/task.md +++ b/2-ui/1-document/07-modifying-document/4-clear-elem/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Clear the element +# ์š”์†Œ ์‚ญ์ œํ•˜๊ธฐ -Create a function `clear(elem)` that removes everything from the element. +์š”์†Œ์˜ ๋ชจ๋“  ํ•˜์œ„ ์š”์†Œ๋“ค์„ ์‚ญ์ œํ•˜๋Š” `clear(elem)` ์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. ```html run height=60 <ol id="elem"> @@ -13,8 +13,8 @@ Create a function `clear(elem)` that removes everything from the element. </ol> <script> - function clear(elem) { /* your code */ } + function clear(elem) { /* ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. */ } - clear(elem); // clears the list + clear(elem); // elem ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. </script> ``` diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md index 6b85168b99..6455ac18be 100644 --- a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md +++ b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md @@ -1,9 +1,9 @@ -The HTML in the task is incorrect. That's the reason of the odd thing. +์ด ์ด์ƒํ•œ ๋™์ž‘์˜ ์ด์œ ๋Š” ๋ฐ”๋กœ ์ฃผ์–ด์ง„ HTML์ด ์ž˜๋ชป๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -The browser has to fix it automatically. But there may be no text inside the `<table>`: according to the spec only table-specific tags are allowed. So the browser adds `"aaa"` *before* the `<table>`. +๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฅผ ์ž๋™์œผ๋กœ ๊ณ ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ช…์„ธ์— ๋”ฐ๋ฅด๋ฉด `<table>` ์•ˆ์—๋Š” ํ‘œ์™€ ๊ด€๋ จ๋œ ํŠน์ • ํƒœ๊ทธ๋งŒ์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ…์ŠคํŠธ๊ฐ€ ์žˆ์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” `'aaa'`๋ฅผ `<table>` *์•ž์—* ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. -Now it's obvious that when we remove the table, it remains. +์ด์ œ ํ‘œ๋ฅผ ์‚ญ์ œํ•ด๋„ ํ…์ŠคํŠธ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ์ด์œ ๊ฐ€ ๋ถ„๋ช…ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. -The question can be easily answered by exploring the DOM using the browser tools. It shows `"aaa"` before the `<table>`. +์ด ๋ฌธ์ œ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด DOM์„ ํƒ์ƒ‰ํ•ด๋ณด๋ฉด ์‰ฝ๊ฒŒ ๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ๋„๊ตฌ์—์„œ๋Š” `<table>` ์•ž์— `'aaa'` ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. -The HTML standard specifies in detail how to process bad HTML, and such behavior of the browser is correct. +HTML ํ‘œ์ค€์—๋Š” ์ž˜๋ชป๋œ HTML์„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ตฌ์ฒด์ ์œผ๋กœ ์ •ํ•ด์ ธ ์žˆ์œผ๋ฏ€๋กœ, ์ด๋Ÿฌํ•œ ๋ธŒ๋ผ์šฐ์ €์˜ ๋™์ž‘์€ ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์ž…๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md index 03064ed2c3..07f13070f9 100644 --- a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md +++ b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md @@ -2,9 +2,13 @@ importance: 1 --- -# Why does "aaa" remain? +# ์™œ 'aaa' ๊ฐ€ ๋‚จ์•„ ์žˆ์„๊นŒ์š” -Run the example. Why does `table.remove()` not delete the text `"aaa"`? +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” `table.remove()` ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์œผ๋‹ˆ ๋ฌธ์„œ์—์„œ ํ‘œ๋ฅผ ์‚ญ์ œํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด, ํ…์ŠคํŠธ `'aaa'` ๊ฐ€ ์—ฌ์ „ํžˆ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์™œ ์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜๋Š” ๊ฑธ๊นŒ์š”? ```html height=100 run <table id="table"> @@ -15,9 +19,9 @@ Run the example. Why does `table.remove()` not delete the text `"aaa"`? </table> <script> - alert(table); // the table, as it should be + alert(table); // table ์€ ์‚ญ์ œํ•  ํ‘œ์˜ id ์ž…๋‹ˆ๋‹ค. table.remove(); - // why there's still aaa in the document? + // ์™œ ๋ฌธ์„œ ์•ˆ์— aaa๊ฐ€ ๋‚จ์•„ ์žˆ์„๊นŒ์š”? </script> ``` diff --git a/2-ui/1-document/07-modifying-document/6-create-list/solution.md b/2-ui/1-document/07-modifying-document/6-create-list/solution.md index 1669be18fa..58e78145f0 100644 --- a/2-ui/1-document/07-modifying-document/6-create-list/solution.md +++ b/2-ui/1-document/07-modifying-document/6-create-list/solution.md @@ -1 +1 @@ -Please note the usage of `textContent` to assign the `<li>` content. +`<li>` ์— ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ `textContent` ์‚ฌ์šฉ๋ฒ•์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/6-create-list/task.md b/2-ui/1-document/07-modifying-document/6-create-list/task.md index 43b0a34a78..f66b63584a 100644 --- a/2-ui/1-document/07-modifying-document/6-create-list/task.md +++ b/2-ui/1-document/07-modifying-document/6-create-list/task.md @@ -2,18 +2,18 @@ importance: 4 --- -# Create a list +# ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑํ•˜๊ธฐ -Write an interface to create a list from user input. +์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›์•„ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. -For every list item: +๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์š”์†Œ๋Š” ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. -1. Ask a user about its content using `prompt`. -2. Create the `<li>` with it and add it to `<ul>`. -3. Continue until the user cancels the input (by pressing `key:Esc` or CANCEL in prompt). +1. `prompt`๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฆฌ์ŠคํŠธ์˜ ๋‚ด์šฉ์„ ์ž…๋ ฅ๋ฐ›์Šต๋‹ˆ๋‹ค. +2. 1๋ฒˆ์—์„œ ์ž…๋ ฅ๋ฐ›์€ ๋‚ด์šฉ์„ ๊ฐ–๋Š” `<li>` ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ `<ul>` ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. +3. ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์„ ์ทจ์†Œํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค (`ESC` ํ‚ค๋‚˜ ํ”„๋กฌํ”„ํŠธ ์ฐฝ์˜ ์ทจ์†Œ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๊นŒ์ง€). -All elements should be created dynamically. +๋ชจ๋“  ์š”์†Œ๋Š” ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -If a user types HTML-tags, they should be treated like a text. +์‚ฌ์šฉ์ž๊ฐ€ HTML ํƒœ๊ทธ๋ฅผ ์ž…๋ ฅํ•˜๋”๋ผ๋„ ํ…์ŠคํŠธ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [demo src="solution"] diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/build-tree-dom.view/index.html b/2-ui/1-document/07-modifying-document/7-create-object-tree/build-tree-dom.view/index.html index 06d9c01b12..6b4c92164a 100755 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/build-tree-dom.view/index.html +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/build-tree-dom.view/index.html @@ -28,8 +28,8 @@ } function createTreeDom(obj) { - // if there's no children, then the call returns undefined - // and the <ul> won't be created + // ์ž์‹ ์š”์†Œ๊ฐ€ ์—†๋‹ค๋ฉด ํ•จ์ˆ˜๋Š” undefined๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. + // ๋˜ํ•œ <ul> ์—ญ์‹œ ์ƒ์„ฑ๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. if (!Object.keys(obj).length) return; let ul = document.createElement('ul'); diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/innerhtml.view/index.html b/2-ui/1-document/07-modifying-document/7-create-object-tree/innerhtml.view/index.html index 0f5f6b0376..74b3be9ab7 100644 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/innerhtml.view/index.html +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/innerhtml.view/index.html @@ -27,7 +27,7 @@ container.innerHTML = createTreeText(obj); } - function createTreeText(obj) { // standalone recursive function + function createTreeText(obj) { // ๋…๋ฆฝ ์‹คํ–‰ํ˜• ์žฌ๊ท€ํ•จ์ˆ˜ let li = ''; let ul; for (let key in obj) { diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md b/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md index d29636ee2a..b02b2d1c67 100644 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md @@ -1,4 +1,4 @@ -The easiest way to walk the object is to use recursion. +๊ฐ์ฒด๋ฅผ ์ˆœํšŒํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -1. [The solution with innerHTML](sandbox:innerhtml). -2. [The solution with DOM](sandbox:build-tree-dom). +1. [innerHTML์„ ์‚ฌ์šฉํ•œ ํ’€์ด](sandbox:innerhtml). +2. [DOM์„ ์‚ฌ์šฉํ•œ ํ’€์ด](sandbox:build-tree-dom). diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/source.view/index.html b/2-ui/1-document/07-modifying-document/7-create-object-tree/source.view/index.html index 8586f6b24d..100e3bd817 100755 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/source.view/index.html +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/source.view/index.html @@ -9,7 +9,7 @@ <div id="tree"></div> - <!-- The result should be: + <!-- ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. <div id="tree"> <ul> <li>Fish @@ -58,7 +58,7 @@ }; function createTree(container, data) { - /* your code */ + /* ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. */ } createTree(document.getElementById('tree'), data); diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md b/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md index 5ec1a01bc8..2b4425d0d8 100644 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Create a tree from the object +# ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํŠธ๋ฆฌ(tree) ์ƒ์„ฑํ•˜๊ธฐ -Write a function `createTree` that creates a nested `ul/li` list from the nested object. +์ค‘์ฒฉ๋œ ๊ฐ์ฒด์˜ ๋ฐ์ดํ„ฐ๋กœ `ulยทli` ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” `createTree` ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. -For instance: +์˜ˆ์‹œ: ```js let data = { @@ -28,24 +28,24 @@ let data = { }; ``` -The syntax: +์ฝ”๋“œ ํ˜•์‹: ```js let container = document.getElementById('container'); *!* -createTree(container, data); // creates the tree in the container +createTree(container, data); // container ์š”์†Œ ๋‚ด์— ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. */!* ``` -The result (tree) should look like this: +๊ฒฐ๊ณผ๋ฌผ์ด ๋  ํŠธ๋ฆฌ๋Š” ์ด๋Ÿฐ ๋ชจ์Šต์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [iframe border=1 src="build-tree-dom"] -Choose one of two ways of solving this task: +๋‘ ๋ฐฉ๋ฒ• ์ค‘ ์›ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ณผ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ๋ณด์„ธ์š”. -1. Create the HTML for the tree and then assign to `container.innerHTML`. -2. Create tree nodes and append with DOM methods. +1. ์ „์ฒด ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ `container.innerHTML` ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. +2. ๋…ธ๋“œ๋ฅผ ๊ฐ๊ฐ ์ƒ์„ฑํ•œ ํ›„ DOM ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…Œ์ด๋„ˆ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. -Would be great if you could do both. +๋‘ ๋ฐฉ๋ฒ•์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ๋” ์ข‹์Šต๋‹ˆ๋‹ค. -P.S. The tree should not have "extra" elements like empty `<ul></ul>` for the leaves. +๋‚ด์šฉ์ด ์—†๋Š” `<ul></ul>`์ฒ˜๋Ÿผ '๋ถˆํ•„์š”ํ•œ' ์š”์†Œ๊ฐ€ ํŠธ๋ฆฌ์— ์กด์žฌํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค๋Š” ์ ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/8-tree-count/solution.md b/2-ui/1-document/07-modifying-document/8-tree-count/solution.md index 43b9a362c8..8182930a87 100644 --- a/2-ui/1-document/07-modifying-document/8-tree-count/solution.md +++ b/2-ui/1-document/07-modifying-document/8-tree-count/solution.md @@ -1 +1 @@ -To append text to each `<li>` we can alter the text node `data`. +๊ฐ `<li>` ์— ํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ํ…์ŠคํŠธ ๋…ธ๋“œ์˜ `data` ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/8-tree-count/solution.view/index.html b/2-ui/1-document/07-modifying-document/8-tree-count/solution.view/index.html index ec44bfda18..fb592894c8 100644 --- a/2-ui/1-document/07-modifying-document/8-tree-count/solution.view/index.html +++ b/2-ui/1-document/07-modifying-document/8-tree-count/solution.view/index.html @@ -43,11 +43,11 @@ let lis = document.getElementsByTagName('li'); for (let li of lis) { - // get the count of all <li> below this <li> + // ์ด <li> ์˜ ๋ชจ๋“  ํ•˜์œ„ <li> ์˜ ๊ฐœ์ˆ˜๋ฅผ ์–ป์–ด์˜ต๋‹ˆ๋‹ค. let descendantsCount = li.getElementsByTagName('li').length; if (!descendantsCount) continue; - // add directly to the text node (append to the text) + // ํ…์ŠคํŠธ ๋…ธ๋“œ์— ์œ„์˜ ๋‚ด์šฉ์„ ์ง์ ‘ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. li.firstChild.data += ' [' + descendantsCount + ']'; } </script> diff --git a/2-ui/1-document/07-modifying-document/8-tree-count/source.view/index.html b/2-ui/1-document/07-modifying-document/8-tree-count/source.view/index.html index 542bd9376f..ab97d27626 100644 --- a/2-ui/1-document/07-modifying-document/8-tree-count/source.view/index.html +++ b/2-ui/1-document/07-modifying-document/8-tree-count/source.view/index.html @@ -40,7 +40,7 @@ </ul> <script> - // ... your code ... + // ... ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ... </script> </body> diff --git a/2-ui/1-document/07-modifying-document/8-tree-count/task.md b/2-ui/1-document/07-modifying-document/8-tree-count/task.md index d6343bf3bd..949b650efe 100644 --- a/2-ui/1-document/07-modifying-document/8-tree-count/task.md +++ b/2-ui/1-document/07-modifying-document/8-tree-count/task.md @@ -2,12 +2,12 @@ importance: 5 --- -# Show descendants in a tree +# ํŠธ๋ฆฌ์˜ ์ž์† ์ˆ˜ ๋‚˜ํƒ€๋‚ด๊ธฐ -There's a tree organized as nested `ul/li`. +์ค‘์ฒฉ๋œ `ulยทli` ๋กœ ์ด๋ฃจ์–ด์ง„ ํŠธ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -Write the code that adds to each `<li>` the number of its descendants. Skip leaves (nodes without children). +๊ฐ `<li>` ๊ฐ€ ๊ฐ€์ง„ ์ž์† ์š”์†Œ๋“ค์˜ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. (์ž์‹์ด ์—†๋Š” ๋…ธ๋“œ๋Š” ์ƒ๋žตํ•˜์„ธ์š”.) -The result: +๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. [iframe border=1 src="solution"] diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md index 67bb5e13d1..0b92d3b34b 100644 --- a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md +++ b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md @@ -1,9 +1,9 @@ -We'll create the table as a string: `"<table>...</table>"`, and then assign it to `innerHTML`. +์—ฌ๊ธฐ์„œ๋Š” ํ‘œ๋ฅผ `"<table>...</table>"` ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด์˜ ํ˜•ํƒœ๋กœ ์ƒ์„ฑํ•œ ํ›„ `innerHTML` ์„ ์‚ฌ์šฉํ•ด ๋ฌธ์„œ์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹์„ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -The algorithm: +๋ฐฉ๋ฒ•: -1. Create the table header with `<th>` and weekday names. -1. Create the date object `d = new Date(year, month-1)`. That's the first day of `month` (taking into account that months in JavaScript start from `0`, not `1`). -2. First few cells till the first day of the month `d.getDay()` may be empty. Let's fill them in with `<td></td>`. -3. Increase the day in `d`: `d.setDate(d.getDate()+1)`. If `d.getMonth()` is not yet the next month, then add the new cell `<td>` to the calendar. If that's a Sunday, then add a newline <code>"</tr><tr>"</code>. -4. If the month has finished, but the table row is not yet full, add empty `<td>` into it, to make it square. +1. ๋จผ์ € `<th>`๋ฅผ ์‚ฌ์šฉํ•ด ํ‘œ์˜ ํ—ค๋”(header)๋ฅผ ๋งŒ๋“  ํ›„ ์š”์ผ์„ ์ ์–ด์ค๋‹ˆ๋‹ค. +2. `d = new Date(year, month-1)` ํ˜•์‹์œผ๋กœ ๋‚ ์งœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌ๋ฉด `month` ๋กœ ๋Œ€์ž…ํ•œ ์›”์˜ ์ฒซ ๋ฒˆ์งธ ๋‚ ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์›”์„ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.) +3. ์ฒซ๋ฒˆ์งธ ์—ด๋ถ€ํ„ฐ `d.getDay()` ๋กœ ๊ตฌํ•œ ๊ฐ ๋‹ฌ์˜ ์ฒซ๋ฒˆ์งธ ๋‚ ๊นŒ์ง€์˜ ๋นˆ์นธ์€ `<td></td>` ๋กœ ์ฑ„์›Œ์ฃผ์„ธ์š”. +4. `d.setDate(d.getDate()+1)`์„ ์‚ฌ์šฉํ•ด `d`๊ฐ์ฒด์˜ ๋‚ ์งœ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์„ธ์š”. `d.getMonth()` ๋กœ ๊ตฌํ•œ ๋‹ฌ์ด ๋‹ค์Œ ๋‹ฌ๋กœ ๋ณ€ํ•˜๊ธฐ ์ „๊นŒ์ง€ `<td>`๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ์นธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ƒˆ๋กœ์šด ์นธ์ด ์ผ์š”์ผ์ด๋ผ๋ฉด <code>"</tr><tr>"</code> ๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค์Œ ์ฃผ๋กœ ๋„˜์–ด๊ฐ€์„ธ์š”. +5. ๋‹ฌ๋ ฅ์ด ์™„์„ฑ๋˜์—ˆ์ง€๋งŒ ๋งˆ์ง€๋ง‰ ํ–‰์— ๋นˆ ๊ณต๊ฐ„์ด ๋‚จ์•„์žˆ๋‹ค๋ฉด ๋นˆ `<td>` ๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ฌ๋ ฅ์„ ์‚ฌ๊ฐํ˜•์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.view/index.html b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.view/index.html index 7e211abc6c..be15e4cf4c 100644 --- a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.view/index.html +++ b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.view/index.html @@ -29,30 +29,29 @@ <script> function createCalendar(elem, year, month) { - let mon = month - 1; // months in JS are 0..11, not 1..12 + let mon = month - 1; // ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ์›”์„ 1์›”~12์›”์ด ์•„๋‹Œ 0์›”~11์›”๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. let d = new Date(year, mon); let table = '<table><tr><th>MO</th><th>TU</th><th>WE</th><th>TH</th><th>FR</th><th>SA</th><th>SU</th></tr><tr>'; - // spaces for the first row - // from Monday till the first day of the month + // ์ฒซ๋ฒˆ์งธ ํ–‰์„ ๋งŒ๋“œ๋Š” ๋ถ€๋ถ„ + // ์›”์š”์ผ๋ถ€ํ„ฐ ์›”์˜ ์ฒซ ๋ฒˆ์งธ ๋‚ ๊นŒ์ง€๋Š” ๊ณต๋ฐฑ์œผ๋กœ ์ฑ„์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. // * * * 1 2 3 4 for (let i = 0; i < getDay(d); i++) { table += '<td></td>'; } - // <td> with actual dates + // ์‹ค์ œ ๋‚ ์งœ๊ฐ€ ๋“ค์–ด์žˆ๋Š” <td> while (d.getMonth() == mon) { table += '<td>' + d.getDate() + '</td>'; - if (getDay(d) % 7 == 6) { // sunday, last day of week - newline + if (getDay(d) % 7 == 6) { // ์ฃผ์˜ ๋งˆ์ง€๋ง‰ ์š”์ผ์ธ ์ผ์š”์ผ์„ ๋งŒ๋‚˜๋ฉด ๊ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. table += '</tr><tr>'; } d.setDate(d.getDate() + 1); } - - // add spaces after last days of month for the last row + // ๋‹ฌ๋ ฅ์˜ ๋งˆ์ง€๋ง‰ ํ–‰์— ๋นˆ์นธ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. // 29 30 31 * * * * if (getDay(d) != 0) { for (let i = getDay(d); i < 7; i++) { @@ -60,15 +59,15 @@ } } - // close the table + // table ํƒœ๊ทธ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค. table += '</tr></table>'; elem.innerHTML = table; } - function getDay(date) { // get day number from 0 (monday) to 6 (sunday) + function getDay(date) { // ์›”์š”์ผ๋ถ€ํ„ฐ ์ผ์š”์ผ์„ 0๋ถ€ํ„ฐ 6์˜ ์ˆซ์ž๋กœ ์–ป๋Š” ๋ถ€๋ถ„ let day = date.getDay(); - if (day == 0) day = 7; // make Sunday (0) the last day + if (day == 0) day = 7; // ์ผ์š”์ผ์— ํ•ด๋‹นํ•˜๋Š” ๋ฒˆํ˜ธ(0)๋ฅผ 7๋กœ ๊ณ ์น˜๋Š” ๋ถ€๋ถ„ return day - 1; } diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/source.view/index.html b/2-ui/1-document/07-modifying-document/9-calendar-table/source.view/index.html index e1f4cd6bd4..e1abd4b442 100644 --- a/2-ui/1-document/07-modifying-document/9-calendar-table/source.view/index.html +++ b/2-ui/1-document/07-modifying-document/9-calendar-table/source.view/index.html @@ -28,7 +28,7 @@ <script> function createCalendar(elem, year, month) { - // ...your code that generates the calndar in elem... + // ...elem ์•ˆ์— ๋‹ฌ๋ ฅ์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”... } createCalendar(calendar, 2012, 9); diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/task.md b/2-ui/1-document/07-modifying-document/9-calendar-table/task.md index 37b1a60d23..9b41d09150 100644 --- a/2-ui/1-document/07-modifying-document/9-calendar-table/task.md +++ b/2-ui/1-document/07-modifying-document/9-calendar-table/task.md @@ -2,16 +2,16 @@ importance: 4 --- -# Create a calendar +# ๋‹ฌ๋ ฅ ๋งŒ๋“ค๊ธฐ -Write a function `createCalendar(elem, year, month)`. +`createCalender(elem, year, month)` ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”. -The call should create a calendar for the given year/month and put it inside `elem`. +์ด ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ์—ฐ๋„/์›”์˜ ๋‹ฌ๋ ฅ์„ ์ƒ์„ฑํ•˜๊ณ  `elem` ์•ˆ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -The calendar should be a table, where a week is `<tr>`, and a day is `<td>`. The table top should be `<th>` with weekday names: the first day should be Monday, and so on till Sunday. +๋‹ฌ๋ ฅ์€ ๊ฐ ์ฃผ๋ฅผ `<tr>`, ๋‚ ์งœ๋Š” `<td>`๋กœ ๋‚˜ํƒ€๋‚ด๋Š” ํ‘œ์—ฌ์•ผ ํ•˜๋ฉฐ ํ‘œ์˜ ์ตœ์ƒ๋‹จ์€ ์›”์š”์ผ๋กœ ์‹œ์ž‘ํ•ด์„œ ์ผ์š”์ผ๋กœ ๋๋‚˜๋Š” ์š”์ผ์ด ์ ํžŒ `<th>` ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -For instance, `createCalendar(cal, 2012, 9)` should generate in element `cal` the following calendar: +์˜ˆ๋ฅผ ๋“ค๋ฉด `createCalender(cal, 2012, 9)` ๋Š” `cal` ์š”์†Œ ์•ˆ์— ์•„๋ž˜ ๋‹ฌ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. [iframe height=210 src="solution"] -P.S. For this task it's enough to generate the calendar, should not yet be clickable. +์ฐธ๊ณ ๋กœ ์ด ๊ณผ์ œ๋Š” ๋‹ฌ๋ ฅ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋ฉฐ ํด๋ฆญ์„ ๋น„๋กฏํ•œ ๋™์ž‘์€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ์ข‹์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md index 933f2a16dc..47a059cff0 100644 --- a/2-ui/1-document/07-modifying-document/article.md +++ b/2-ui/1-document/07-modifying-document/article.md @@ -1,14 +1,14 @@ # ๋ฌธ์„œ ์ˆ˜์ •ํ•˜๊ธฐ -"์‚ด์•„์žˆ๋Š”" ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„  DOM ์กฐ์ž‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +'์ƒ๋™๊ฐ ์žˆ๋Š”' ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ•ต์‹ฌ์€ DOM ์กฐ์ž‘์— ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋ฒˆ ์ฃผ์ œ์—์„  ์ƒˆ๋กญ๊ฒŒ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ํŽ˜์ด์ง€ ์ƒ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์ ์‹œ์— ์š”์†Œ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ํŽ˜์ด์ง€์— ์žˆ๋Š” ๊ธฐ์กด ์ฝ˜ํ…์ธ ๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ## ์˜ˆ์ œ: ๋ฉ”์‹œ์ง€ ๋ณด์—ฌ์ฃผ๊ธฐ -Let's see the methods on example. We'll add a message on the page that looks nicer than `alert`. +`alert` ์ฐฝ๋ณด๋‹ค ๋ณด๊ธฐ ์ข‹์€ ๋ฉ”์‹œ์ง€ ์ฐฝ์„ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์€ alert ์ฐฝ์„ ์‚ดํŽด๋ด…์‹œ๋‹ค: +์˜ˆ์‹œ: ```html autorun height="80" <style> @@ -28,45 +28,52 @@ Let's see the methods on example. We'll add a message on the page that looks nic */!* ``` -That was an HTML example. Now let's create the same `div` with JavaScript (assuming that the styles are in the HTML or an external CSS file). +์œ„ ์˜ˆ์‹œ์—์„  HTML์„ ์‚ฌ์šฉํ•ด ๋ฉ”์‹œ์ง€ ์ฐฝ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ์—” ๊ฐ™์€ ์ฐฝ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ์Šคํƒ€์ผ์€ HTML์ด๋‚˜ ์™ธ๋ถ€ CSS ํŒŒ์ผ์— ์ €์žฅ๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ## ์š”์†Œ ์ƒ์„ฑํ•˜๊ธฐ -To create DOM nodes, there are two methods: +DOM ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. `document.createElement(tag)` -: ํƒœ๊ทธ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์ƒˆ๋กœ์šด ์š”์†Œ ๋งŒ๋“ค๊ธฐ: +: ํƒœ๊ทธ ์ด๋ฆ„(`tag`)์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ฆ ```js let div = document.createElement('div'); ``` `document.createTextNode(text)` -: ์›ํ•˜๋Š” ํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์ƒˆ๋กœ์šด *ํ…์ŠคํŠธ ๋…ธ๋“œ* ๋งŒ๋“ค๊ธฐ: +: ์ฃผ์–ด์ง„ ํ…์ŠคํŠธ(`text`)๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด *ํ…์ŠคํŠธ ๋…ธ๋“œ*๋ฅผ ๋งŒ๋“ฆ ```js - let textNode = document.createTextNode('์•ˆ๋…•ํ•˜์„ธ์š”'); + let textNode = document.createTextNode('์•ˆ๋…•ํ•˜์„ธ์š”.'); ``` +๊ฐœ๋ฐœ์„ ํ•  ๋• ์œ„ ์˜ˆ์‹œ(๋ฉ”์‹œ์ง€๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” `div`)์ฒ˜๋Ÿผ ์ฃผ๋กœ ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + ### ๋ฉ”์‹œ์ง€ ์ƒ์„ฑํ•˜๊ธฐ -In our case the message is a `div` with `alert` class and the HTML in it: +๋ฉ”์‹œ์ง€๊ฐ€ ๋“ค์–ด๊ฐˆ `div`๋Š” ์„ธ ๋‹จ๊ณ„๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js +// 1. <div> ์š”์†Œ ๋งŒ๋“ค๊ธฐ let div = document.createElement('div'); + +// 2. ๋งŒ๋“  ์š”์†Œ์˜ ํด๋ž˜์Šค๋ฅผ 'alert'๋กœ ์„ค์ • div.className = "alert"; -div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; + +// 3. ๋‚ด์šฉ ์ฑ„์›Œ๋„ฃ๊ธฐ +div.innerHTML = "<strong>์•ˆ๋…•ํ•˜์„ธ์š”!</strong> ์ค‘์š” ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜์…จ์Šต๋‹ˆ๋‹ค."; ``` -We created the element, but as of now it's only in a variable. We can't see the element on the page, as it's not yet a part of the document. +์ด๋ ‡๊ฒŒ ์„ธ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์น˜๋ฉด ์š”์†Œ๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์š”์†Œ๋ฅผ ๋งŒ๋“ค๊ธด ํ–ˆ์ง€๋งŒ, ์•„์ง ์ด ์š”์†Œ๋Š” `div`๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ณ€์ˆ˜์— ๋ถˆ๊ณผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€์—” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -## ๋ฉ”์„œ๋“œ ์‚ฝ์ž…ํ•˜๊ธฐ +## ์‚ฝ์ž… ๋ฉ”์„œ๋“œ -`div`๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๊ฑธ `document` ๋‚ด ์–ด๋”˜๊ฐ€์— ์‚ฝ์ž…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `document.body`์•ˆ์—๋ผ๋˜๊ฐ€ ๋ง์ด์ฃ . +`div`๊ฐ€ ํŽ˜์ด์ง€์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•˜๋ ค๋ฉด `document` ๋‚ด ์–ด๋”˜๊ฐ€์— `div`๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. `document.body`๋กœ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” `<body>`์•ˆ ๊ฐ™์€ ๊ณณ์— ๋ง์ด์ฃ . -There's a special method `append` for that: `document.body.append(div)`. +์š”์†Œ ์‚ฝ์ž… ๋ฉ”์„œ๋“œ `append`๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ `document.body.append(div)`๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“  ์š”์†Œ ๋…ธ๋“œ๋ฅผ ํŽ˜์ด์ง€์— ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•ด๋ด…์‹œ๋‹ค. -์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด์ฃ : +์ „์ฒด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run height="80" <style> @@ -82,7 +89,7 @@ There's a special method `append` for that: `document.body.append(div)`. <script> let div = document.createElement('div'); div.className = "alert"; - div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; + div.innerHTML = "<strong>์•ˆ๋…•ํ•˜์„ธ์š”!</strong> ์ค‘์š” ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜์…จ์Šต๋‹ˆ๋‹ค."; *!* document.body.append(div); @@ -90,15 +97,21 @@ There's a special method `append` for that: `document.body.append(div)`. </script> ``` -This set of methods provides more ways to insert: +์—ฌ๊ธฐ์„œ๋Š” `document.body`์—์„œ `append`๋ฅผ ํ˜ธ์ถœํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์š”์†Œ์—๋„ `append` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์š”์†Œ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `div.append(anotherElement)`๋ฅผ ํ˜ธ์ถœํ•ด `<div>`์— ๋ฌด์–ธ๊ฐ€๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . + +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง€์›ํ•˜๋Š” ๋…ธ๋“œ ์‚ฝ์ž… ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒํ•˜๋ฉด ์ง์ ‘ ์‚ฝ์ž… ์œ„์น˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +- `node.append(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` -- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` *๋*์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `node.prepend(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` -- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` *๋งจ ์•ž*์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `node.before(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` *์ด์ „*์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `node.after(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` *๋‹ค์Œ*์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `node.replaceWith(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- `node`๋ฅผ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. + +์‚ฝ์ž… ๋ฉ”์„œ๋“œ์—” ์ž„์˜์˜ ๋…ธ๋“œ ๋ชฉ๋ก์ด๋‚˜ ๋ฌธ์ž์—ด์„ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด์„ ๋„˜๊ฒจ์ฃผ๋ฉด ์ž๋™์œผ๋กœ ํ…์ŠคํŠธ ๋…ธ๋“œ๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. -- `node.append(...nodes or strings)` -- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` ๋์— ์‚ฝ์ž…ํ•ด์ค๋‹ˆ๋‹ค. -- `node.prepend(...nodes or strings)` -- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` ๋งจ ์•ž์— ์‚ฝ์ž…ํ•ด์ค๋‹ˆ๋‹ค. -- `node.before(...nodes or strings)` โ€“- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` ์ด์ „์— ์‚ฝ์ž…ํ•ด์ค๋‹ˆ๋‹ค. -- `node.after(...nodes or strings)` โ€“- ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ `node` ๋‹ค์Œ์— ์‚ฝ์ž…ํ•ด์ค๋‹ˆ๋‹ค. -- `node.replaceWith(...nodes or strings)` โ€“- `node`๋ฅผ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. -Here's an example of using these methods to add items to a list and the text before/after it: +์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋ฉด 0, 1, 2์— ๋”ํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ธ€์ž๋“ค์ด ํ™”๋ฉด์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ```html autorun <ol id="ol"> @@ -108,24 +121,24 @@ Here's an example of using these methods to add items to a list and the text bef </ol> <script> - ol.before('before'); // insert string "before" before <ol> - ol.after('after'); // insert string "after" after <ol> + ol.before('before'); // <ol> ์•ž์— ๋ฌธ์ž์—ด 'before'๋ฅผ ์‚ฝ์ž…ํ•จ + ol.after('after'); // <ol> ๋’ค์— ๋ฌธ์ž์—ด 'after๋ฅผ ์‚ฝ์ž…ํ•จ let liFirst = document.createElement('li'); liFirst.innerHTML = 'prepend'; - ol.prepend(liFirst); // insert liFirst at the beginning of <ol> + ol.prepend(liFirst); // <ol>์˜ ์ฒซ ํ•ญ๋ชฉ์œผ๋กœ liFirst๋ฅผ ์‚ฝ์ž…ํ•จ let liLast = document.createElement('li'); liLast.innerHTML = 'append'; - ol.append(liLast); // insert liLast at the end of <ol> + ol.append(liLast); // <ol>์˜ ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์œผ๋กœ liLast๋ฅผ ์‚ฝ์ž…ํ•จ </script> ``` -Here's a visual picture what methods do: +์œ„ ์˜ˆ์‹œ์—์„œ ์‚ฌ์šฉ๋œ ๊ฐ ๋ฉ”์„œ๋“œ๋“ค์˜ ์—ญํ• ์„ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](before-prepend-append-after.svg) -๋ฆฌ์ŠคํŠธ๊ฐ€ ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ๋˜์ฃ : +์ตœ์ข… ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์งˆ ๊ฒ๋‹ˆ๋‹ค. ```html before @@ -139,82 +152,82 @@ before after ``` -์ด ๋ฉ”์„œ๋“œ๋“ค์€ ๋ณต์ˆ˜์˜ ๋…ธ๋“œ์™€ ๋ฌธ์ž์—ด์„ ํ•œ ๋ฒˆ์— ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ๋„ ํ•ด์ค๋‹ˆ๋‹ค. +์•ž์„œ ์–ธ๊ธ‰ํ•˜๊ธด ํ–ˆ์ง€๋งŒ, ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด '๋ณต์ˆ˜'์˜ ๋…ธ๋“œ์™€ ๋ฌธ์ž์—ด์„ ํ•œ ๋ฒˆ์— ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -๋ฌธ์ž์—ด๊ณผ ์š”์†Œ๋ฅผ ํ•œ ๋ฒˆ์— ์‚ฝ์ž…ํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ฃ : +๋ฌธ์ž์—ด๊ณผ ์š”์†Œ๋ฅผ ํ•œ ๋ฒˆ์— ์‚ฝ์ž…ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run <div id="div"></div> <script> - div.before('<p>Hello</p>', document.createElement('hr')); + div.before('<p>์•ˆ๋…•ํ•˜์„ธ์š”</p>', document.createElement('hr')); </script> ``` -๋ชจ๋“  ๋ฌธ์ž๋Š” *๋ฌธ์ž*๊ทธ ์ž์ฒด๋กœ ์‚ฝ์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์‚ฝ์ž… ๋ฉ”์„œ๋“œ์— ๋ฌธ์ž์—ด์„ ๋„˜๊ฒจ ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค ๋• ์ธ์ˆ˜๋กœ ๋„˜๊ธด ๋ฌธ์ž์—ด์ด 'HTML'์ด ์•„๋‹Œ '๋ฌธ์ž์—ด' ๊ทธ ํ˜•ํƒœ๋กœ ์‚ฝ์ž…๋œ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `<`๋‚˜ `>`๊ฐ™์€ ํŠน์ˆ˜๋ฌธ์ž๋Š” ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. -์œ„ ์ฝ”๋“œ ์‹คํ–‰ ํ›„ ๋‚˜ํƒ€๋‚˜๋Š” HTML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: +๋”ฐ๋ผ์„œ ์ตœ์ข… HTML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run *!* -<p>Hello</p> +<p>์•ˆ๋…•ํ•˜์„ธ์š”</p> */!* <hr> <div id="div"></div> ``` -๋ฌธ์ž์—ด์ด `elem.textContent`๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฝ์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์‚ฝ์ž… ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด์€ `elem.textContent`๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฝ์ž…๋˜๋Š” ๊ฒƒ์ด์ฃ . -์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ๋“ค์€ DOM ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ ์‚ฝ์ž…ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ ๋…ธ๋“œ ์‚ฝ์ž… ๋ฉ”์„œ๋“œ๋Š” DOM ๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด์„ ์‚ฝ์ž…ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ `elem.innerHTML`์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์ฒ˜๋Ÿผ "HTML ์ž์ฒด"๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? +๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ `elem.innerHTML`์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํƒœ๊ทธ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฌธ์ž์—ด ํ˜•ํƒœ์˜ 'HTML ๊ทธ ์ž์ฒด'๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ## insertAdjacentHTML/Text/Element -For that we can use another, pretty versatile method: `elem.insertAdjacentHTML(where, html)`. +๋˜ ๋‹ค๋ฅธ ๋‹ค์žฌ๋‹ค๋Šฅํ•œ ๋ฉ”์„œ๋“œ `elem.insertAdjacentHTML(where, html)`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -์ด ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์‚ฝ์ž…ํ•  ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” ๋ฌธ์ž์—ด์ด๊ณ  ๋ฐ˜๋“œ์‹œ ๋‹ค์Œ ๊ฐ’ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค: +`elem.insertAdjacentHTML(where, html)`์—์„œ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” `elem`์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋Š” ์ƒ๋Œ€ ์œ„์น˜๋กœ, ๋‹ค์Œ ๊ฐ’ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- `"beforebegin"` -- `elem` ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค , -- `"afterbegin"` -- `elem`์˜ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. -- `"beforeend"` -- `elem`์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. -- `"afterend"` -- `elem` ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `'beforebegin'` -- `elem` ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `'afterbegin'` -- `elem`์˜ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `'beforeend'` -- `elem`์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- `'afterend'` -- `elem` ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. -๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” HTML ๋ฌธ์ž์—ด์ด๊ณ , HTML "๊ทธ ์ž์ฒด"๋กœ ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค. +๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” HTML ๋ฌธ์ž์—ด๋กœ, ์ด HTML์€ ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๊ณ  '๊ทธ๋Œ€๋กœ' ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: ```html run <div id="div"></div> <script> - div.insertAdjacentHTML('beforebegin', '<p>Hello</p>'); - div.insertAdjacentHTML('afterend', '<p>Bye</p>'); + div.insertAdjacentHTML('beforebegin', '<p>์•ˆ๋…•ํ•˜์„ธ์š”.</p>'); + div.insertAdjacentHTML('afterend', '<p>์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”.</p>'); </script> ``` -์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€ํ•ฉ๋‹ˆ๋‹ค: +์ตœ์ข… HTML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run -<p>Hello</p> +<p>์•ˆ๋…•ํ•˜์„ธ์š”.</p> <div id="div"></div> -<p>Bye</p> +<p>์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”.</p> ``` -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด HTML์„ ํŽ˜์ด์ง€์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž„์˜์˜ HTML์„ ํŽ˜์ด์ง€์— ์‚ฝ์ž…ํ•  ๋• ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -insertAdjacentHTML์„ ์‚ฌ์šฉํ•œ ์‚ฝ์ž…์„ ๋„์‹ํ™”ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: +์•„๋ž˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ์‚ฝ์ž… ์œ„์น˜๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ•˜๋Š”์ง€๋ฅผ ํ‘œํ˜„ํ•œ ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ![](insert-adjacent.svg) -์ด ๊ทธ๋ฆผ๊ณผ ์ด์ „ ๊ทธ๋ฆผ์ด ๊ฝค ์œ ์‚ฌํ•˜๊ฒŒ ์ƒ๊ฒผ๋‹ค๋Š” ๊ฑธ ์•Œ์•„์ฐจ๋ฆฌ์‹ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์‚ฝ์ž…ํ•˜๋ ค๋Š” ์ง€์ ์€ ๋‘ ๊ทธ๋ฆผ์—์„œ ์™„์ „ํžˆ ๊ฐ™๊ณ , HTML์„ ์‚ฝ์ž…ํ•˜๋ ค๋Š” ์ ๋งŒ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑธ ๊ด€์ฐฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๊ทธ๋ฆผ๊ณผ ์œ„์ชฝ ๊ทธ๋ฆผ์ด ๊ฝค ์œ ์‚ฌํ•˜๊ฒŒ ์ƒ๊ฒผ๋„ค์š”. HTML์„ ์‚ฝ์ž…ํ•œ๋‹ค๋Š” ์ ๋งŒ ๋‹ค๋ฅด๊ณ , ์‚ฝ์ž… ์ง€์ ์€ ์ •ํ™•ํžˆ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด ๋ฉ”์„œ๋“œ์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด 2๊ฐœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค +`elem.insertAdjacentHTML(where, html)`์€ ๋‘ ๊ฐ€์ง€ ํ˜•์ œ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- `elem.insertAdjacentText(where, text)` -- ๊ฐ™์€ ๊ธฐ๋Šฅ์ด๋ฉฐ HTML๋Œ€์‹  `text(๋ฌธ์ž์—ด)`์„ ๋ฌธ์ž์—ด ๊ทธ ์ž์ฒด๋กœ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค, -- `elem.insertAdjacentElement(where, elem)` -- ์—ญ์‹œ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด๋ฉฐ, ์š”์†Œ ์‚ฝ์ž…์— ์“ฐ์ž…๋‹ˆ๋‹ค +- `elem.insertAdjacentText(where, text)` -- `insertAdjacentHTML`๊ณผ ๋ฌธ๋ฒ•์€ ๊ฐ™์€๋ฐ, HTML ๋Œ€์‹  `text`๋ฅผ '๋ฌธ์ž ๊ทธ๋Œ€๋กœ' ์‚ฝ์ž…ํ•œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. +- `elem.insertAdjacentElement(where, elem)` -- ์—ญ์‹œ ๊ฐ™์€ ๋ฌธ๋ฒ•์ธ๋ฐ, ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -์ด ๋‘ ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”์„œ๋“œ ์‹ ํƒ์Šค๋ฅผ ์œ ์‚ฌํ•˜๊ฒŒ ํ•ด ๊ตฌ์ƒ‰์„ ๊ฐ–์ถ”๋ ค๊ณ  ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋ก  ๋Œ€๋ถ€๋ถ„ `insertAdjacentHTML`๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์š”์†Œ๋‚˜ ๋ฌธ์ž๋Š” `append/prepend/before/after`๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๊ณ , ์ด ๋ฉ”์„œ๋“œ๋“ค์ด ๋” ์งง๊ณ , ์š”์†Œ ๋…ธ๋“œ๋‚˜ text ์กฐ๊ฐ์„ ์‰ฝ๊ฒŒ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +`insertAdjacentText`๊ณผ `insertAdjacentElement`๋Š” ๋ฉ”์„œ๋“œ ๊ตฌ์ƒ‰์„ ๊ฐ–์ถ”๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์š”์†Œ๋‚˜ ๋ฌธ์ž ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ๋• `append/prepend/before/after`๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์‹ค๋ฌด์—์„  ๋Œ€๋ถ€๋ถ„ `insertAdjacentHTML`์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์š”์†Œ ์‚ฝ์ž… ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ ๊ธธ์ด๊ฐ€ ์ค„์–ด๋“ค๊ณ , ๋…ธ๋“œ๋‚˜ ํ…์ŠคํŠธ ์กฐ๊ฐ์„ ์‰ฝ๊ฒŒ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ž ์ด์ œ alert ๋ฉ”์‹œ์ง€ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค: +์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์šด ๋ฉ”์„œ๋“œ `insertAdjacentHTML`๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์‹œ์ง€ ์ฐฝ ์˜ˆ์‹œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run <style> @@ -234,11 +247,11 @@ insertAdjacentHTML์„ ์‚ฌ์šฉํ•œ ์‚ฝ์ž…์„ ๋„์‹ํ™”ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค </script> ``` -## Node removal +## ๋…ธ๋“œ ์‚ญ์ œํ•˜๊ธฐ -To remove a node, there's a method `node.remove()`. +`node.remove()` ์‚ฌ์šฉํ•˜๋ฉด ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Let's make our message disappear after a second: +์ผ ์ดˆ ํ›„ ๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•ด๋ด…์‹œ๋‹ค. ```html run untrusted <style> @@ -254,7 +267,7 @@ Let's make our message disappear after a second: <script> let div = document.createElement('div'); div.className = "alert"; - div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; + div.innerHTML = "<strong>์•ˆ๋…•ํ•˜์„ธ์š”!</strong> ์ค‘์š” ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜์…จ์Šต๋‹ˆ๋‹ค."; document.body.append(div); *!* @@ -263,32 +276,32 @@ Let's make our message disappear after a second: </script> ``` -Please note: if we want to *move* an element to another place -- there's no need to remove it from the old one. +์ฐธ๊ณ ๋กœ, ์š”์†Œ ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ *์˜ฎ๊ธธ ๋•Œ* ๊ธฐ์กด์— ์žˆ๋˜ ๋…ธ๋“œ๋ฅผ ์ง€์šธ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -**All insertion methods automatically remove the node from the old place.** +**๋ชจ๋“  ๋…ธ๋“œ ์‚ฝ์ž… ๋ฉ”์„œ๋“œ๋Š” ์ž๋™์œผ๋กœ ๊ธฐ์กด์— ์žˆ๋˜ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ณณ์œผ๋กœ ๋…ธ๋“œ๋ฅผ ์˜ฎ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.** -For instance, let's swap elements: +์š”์†Œ ์œ„์น˜๋ฅผ ๋ฐ”๊พธ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run height=50 <div id="first">First</div> <div id="second">Second</div> <script> - // no need to call remove - second.after(first); // take #second and after it insert #first + // remove ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. + second.after(first); // id๊ฐ€ second์ธ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋’ค์— id๊ฐ€ first์ธ ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… </script> ``` -## ๋…ธ๋“œ ๋ณต์ œํ•˜๊ธฐ: cloneNode +## cloneNode๋กœ ๋…ธ๋“œ ๋ณต์ œํ•˜๊ธฐ -์œ„์˜ ์˜ˆ์ œ์—์„œ ์œ ์‚ฌํ•œ ๋ฉ”์‹œ์ง€ ํ•˜๋‚˜๋ฅผ ๋” ๋„์›Œ์ฃผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? +์œ„ ์˜ˆ์‹œ์—์„œ ๊ธฐ์กด ๋ฉ”์‹œ์ง€ ์ฐฝ๊ณผ ์œ ์‚ฌํ•œ ๋ฉ”์‹œ์ง€ ์ฐฝ์„ ํ•˜๋‚˜ ๋” ๋„์›Œ๋‹ฌ๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. -We could make a function and put the code there. But the alternative way would be to *clone* the existing `div` and modify the text inside it (if needed). +'๋ฉ”์‹œ์ง€ ์ฐฝ์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?'๋ผ๋Š” ์ƒ๊ฐ์ด ๋– ์˜ค๋ฅผ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ ๊ธฐ์กด์— ๋งŒ๋“ค์–ด ๋†จ๋˜ `div`๋ฅผ *๋ณต์ œ*ํ•˜๊ณ  (ํ•„์š”ํ•˜๋‹ค๋ฉด) ์•ˆ์— ์žˆ๋Š” ํ…์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -ํฐ ์š”์†Œ๋ฅผ ๋‹ค๋ฃฐ ๋• ์ด ๋Œ€์•ˆ์ด ์ข€ ๋” ๋น ๋ฅด๊ณ  ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. +๋ณต์ œํ•˜๋ ค๋Š” ์š”์†Œ๊ฐ€ ํด ๋•Œ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹  ๋ณต์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋น ๋ฅด๊ณ  ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- `elem.cloneNode(true)`๋Š” ์ž์‹ ์„ ํ˜ธ์ถœํ•œ ๋…ธ๋“œ์˜ "๊นŠ์€" ๋ณต์ œ๋ณธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ true์ด๋ฉด ํ›„์† ๋…ธ๋“œ ์ „์ฒด๋ฅผ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. `elem.cloneNode(false)`์€ ํ•ด๋‹น ๋…ธ๋“œ ํ•˜๋‚˜๋งŒ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. +- `elem.cloneNode(true)`์„ ํ˜ธ์ถœํ•˜๋ฉด `elem`์˜ '๊นŠ์€' ๋ณต์ œ๋ณธ์ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ์†์„ฑ ์ „๋ถ€์™€ ์ž์† ์š”์†Œ ์ „๋ถ€๊ฐ€ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค. `elem.cloneNode(false)`์„ ํ˜ธ์ถœํ•˜๋ฉด ํ›„์† ๋…ธ๋“œ ๋ณต์‚ฌ ์—†์ด `elem`๋งŒ ๋ณต์ œ๋ฉ๋‹ˆ๋‹ค. -์ด๋ฅผ ์ด์šฉํ•ด ๋ฉ”์‹œ์ง€ ๋„์–ด์ฃผ๊ธฐ ์˜ˆ์‹œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค: +`cloneNode`๋ฅผ ์ด์šฉํ•ด ๋ฉ”์‹œ์ง€ ์ฐฝ์„ ํ•˜๋‚˜ ๋” ๋„์›Œ๋ด…์‹œ๋‹ค. ```html run height="120" <style> @@ -307,21 +320,21 @@ We could make a function and put the code there. But the alternative way would b <script> *!* - let div2 = div.cloneNode(true); // clone the message - div2.querySelector('strong').innerHTML = '์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”!'; // change the clone + let div2 = div.cloneNode(true); // ๋ฉ”์‹œ์ง€ ์ฐฝ ๋ณต์ œ + div2.querySelector('strong').innerHTML = '์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”!'; // ๋ณต์ œํ•œ ๋ฉ”์‹œ์ง€ ์ฐฝ ๋‚ด์šฉ ์ˆ˜์ • - div.after(div2); // show the clone after the existing div + div.after(div2); // ๋ณต์ œํ•œ ๋ฉ”์‹œ์ง€ ์ฐฝ์„ ๊ธฐ์กด ๋ฉ”์‹œ์ง€ ์ฐฝ ๋‹ค์Œ์— ๋ณด์—ฌ์คŒ */!* </script> ``` ## DocumentFragment [#document-fragment] -`DocumentFragment`๋Š” ํŠน๋ณ„ํ•œ DOM ๋…ธ๋“œ ํƒ€์ž…์œผ๋กœ, ์—ฌ๋Ÿฌ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ ๊ทธ๋ฃน์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ์“ฐ์ด๋Š” ๋ž˜ํผ(wrapper) ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +`DocumentFragment`๋Š” ํŠน๋ณ„ํ•œ DOM ๋…ธ๋“œ ํƒ€์ž…์œผ๋กœ, ์—ฌ๋Ÿฌ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ ๊ทธ๋ฃน์„ ๊ฐ์‹ธ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ž˜ํผ(wrapper)์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -๋ฌธ์„œ์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ DocumentFragment์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ DocumentFragment๋ฅผ ๋ฌธ์„œ ์–ด๋”˜๊ฐ€์— ์‚ฝ์ž…ํ•˜๋ฉด, DocumentFragment๋Š” ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ๋ฌผ๋ก  DocumentFragment์•ˆ์— ๋“ค์–ด์žˆ๋˜ ๋…ธ๋“œ๋Š” ๋ฌธ์„œ์— ์ถ”๊ฐ€๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋ผ์ง€์ง€ ์•Š์ฃ . +๋ฌธ์„œ์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ `DocumentFragment`์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, `DocumentFragment`๋ฅผ ๋ฌธ์„œ ์–ด๋”˜๊ฐ€์— ์‚ฝ์ž…ํ•˜๋ฉด `DocumentFragment`๋Š” ์‚ฌ๋ผ์ง€๊ณ  `DocumentFragment`์— ์ถ”๊ฐ€ํ•œ ๋…ธ๋“œ๋งŒ ๋‚จ์Šต๋‹ˆ๋‹ค. -์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์•„๋ž˜์˜ `getListContent` ํ•จ์ˆ˜๋Š” `<li>` ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ fragment๋ฅผ ๋งŒ๋“ค๊ณ , ์ด fragment๋ฅผ `<ul>`์— ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์•„๋ž˜ ํ•จ์ˆ˜ `getListContent`๋Š” `<li>` ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ fragment๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค. ์ด fragment๋ฅผ `<ul>`์— ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```html run <ul id="ul"></ul> @@ -345,7 +358,7 @@ ul.append(getListContent()); // (*) </script> ``` -`(*)`๋กœ ํ‘œ์‹œํ•œ ๋งˆ์ง€๋ง‰ ์ค„์—์„œ `DocumentFragment`๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์ง€๋งŒ, ์ถ”๊ฐ€ํ•œ fragment๊ฐ€ ๋ฌธ์„œ์— ๋…น์•„๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง„๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ `<ul>`์— `DocumentFragment`๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ํ•œ fragment๋Š” ๋ฌธ์„œ์— '๋…น์•„๋“ค์—ˆ๊ธฐ' ๋•Œ๋ฌธ์— ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ์•„๋ž˜์™€ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. ```html <ul> @@ -355,7 +368,7 @@ ul.append(getListContent()); // (*) </ul> ``` -`DocumentFragment`๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ์ผ์€ ๋“œ๋ญ…๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ด๋ ‡๊ฒŒ ํŠน๋ณ„ํ•œ ์ข…๋ฅ˜์˜ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ๋ฅผ `DocumentFragment` ์—†์ด ๋‹ค์‹œ ์ž‘์„ฑํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +`DocumentFragment`๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ผ์€ ํ”์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์—์‹œ์ฒ˜๋Ÿผ ๋…ธ๋“œ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์„ ์ง์ ‘ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ```html run <ul id="ul"></ul> @@ -374,27 +387,27 @@ function getListContent() { } *!* -ul.append(...getListContent()); // append + "..." operator = friends! +ul.append(...getListContent()); // append ๋ฉ”์„œ๋“œ์™€ ...(์ „๊ฐœ ๊ตฌ๋ฌธ)์€ ๊ถํ•ฉ์ด ์ž˜ ๋งž์Šต๋‹ˆ๋‹ค. */!* </script> ``` -์—ฌ๊ธฐ์„œ `DocumentFragment`๋ฅผ ์–ธ๊ธ‰ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋Š” ์ด์œ ๋Š”, [template](info:template-element) ์š”์†Œ์™€ ๊ฐ™์ด `DocumentFragment`๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐœ๋…์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. template ์š”์†Œ๋Š” ์ถ”ํ›„ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์„œ `DocumentFragment`๋ฅผ ์–ธ๊ธ‰ํ•œ ์ด์œ ๋Š” [template](info:template-element) ์š”์†Œ๊ฐ™์ด `DocumentFragment`๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœํ•˜๋Š” ๋ฌธ๋ฒ•์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. template ์š”์†Œ๋Š” ์ถ”ํ›„ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -## Old-school insert/remove methods +## ๊ตฌ์‹ ์‚ฝ์ž…ยท์‚ญ์ œ ๋ฉ”์„œ๋“œ [old] -There are also "old school" DOM manipulation methods, existing for historical reasons. +ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‚จ์•„์žˆ๋Š” '๊ตฌ์‹(old school)' DOM ์กฐ์ž‘ ๋ฉ”์„œ๋“œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -These methods come from really ancient times. Nowadays, there's no reason to use them, as modern methods, such as `append`, `prepend`, `before`, `after`, `remove`, `replaceWith`, are more flexible. +์•„์ฃผ ์˜ค๋ž˜์ „์— ๋งŒ๋“ค์–ด์ง„ ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ์š”์ฆ˜์—๋Š” ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ž์„œ ๋ฐฐ์šด ๋ชจ๋˜ํ•œ ๋ฉ”์„œ๋“œ `append`, `prepend`, `before`, `after`, `remove`, `replaceWith`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข€ ๋” ์œ ์—ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -The only reason we list these methods here is that you can find them in many old scripts: +๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ตฌ์‹ ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ๊ฐœํ•ด๋“œ๋ฆฌ๋Š” ์ด์œ ๋Š” ์ž‘์„ฑ๋œ ์ง€ ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋“ค์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `parentElem.appendChild(node)` -: Appends `node` as the last child of `parentElem`. +: `parentElem`์˜ ๋งˆ์ง€๋ง‰ ์ž์‹์œผ๋กœ `node`๋ฅผ ์ถ”๊ฐ€ํ•จ - The following example adds a new `<li>` to the end of `<ol>`: + ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ƒˆ๋กœ์šด `<li>`๊ฐ€ `<ol>` ๋งˆ์ง€๋ง‰์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ```html run height=100 <ol id="list"> @@ -412,9 +425,9 @@ The only reason we list these methods here is that you can find them in many old ``` `parentElem.insertBefore(node, nextSibling)` -: Inserts `node` before `nextSibling` into `parentElem`. +: `node`๋ฅผ `parentElem`์•ˆ์˜ `nextSibling`์•ž์— ์ถ”๊ฐ€ํ•จ - The following code inserts a new list item before the second `<li>`: + ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ƒˆ๋กœ์šด `<li>`๊ฐ€ ๋‘ ๋ฒˆ์งธ `<li>` ์•ž์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ```html run height=100 <ol id="list"> @@ -431,19 +444,19 @@ The only reason we list these methods here is that you can find them in many old */!* </script> ``` - To insert `newLi` as the first element, we can do it like this: + `newLi`๋ฅผ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด `firstChild`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```js list.insertBefore(newLi, list.firstChild); ``` `parentElem.replaceChild(node, oldChild)` -: Replaces `oldChild` with `node` among children of `parentElem`. +: `parentElem`์˜ ์ž์‹ ๋…ธ๋“œ ์ค‘ `oldChild`๋ฅผ `node`๋กœ ๊ต์ฒดํ•จ `parentElem.removeChild(node)` -: Removes `node` from `parentElem` (assuming `node` is its child). +: `node`๊ฐ€ `parentElem`์˜ ์ž์‹ ๋…ธ๋“œ๋ผ๋Š” ๊ฐ€์ •ํ•˜์— `parentElem`์—์„œ `node`๋ฅผ ์‚ญ์ œํ•จ - The following example removes first `<li>` from `<ol>`: + ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด `<ol>`์—์„œ ์ฒซ ๋ฒˆ์งธ `<li>`๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ```html run height=100 <ol id="list"> @@ -458,91 +471,91 @@ The only reason we list these methods here is that you can find them in many old </script> ``` -All these methods return the inserted/removed node. In other words, `parentElem.appendChild(node)` returns `node`. But usually the returned value is not used, we just run the method. +์ด ๋ฉ”์„œ๋“œ๋“ค์€ ๋ชจ๋‘ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•œ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. `parentElem.appendChild(node)`๋Š” `node`๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ฃ . ๊ทธ๋Ÿฐ๋ฐ ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ผ์ด ๊ฑฐ์˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ๋ฅผ ๊ทธ๋ƒฅ ์‹คํ–‰๋งŒ ํ•˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. -## A word about "document.write" +## 'document.write'์— ๋Œ€ํ•œ ์ฒจ์–ธ -์›นํŽ˜์ด์ง€์— ๋ญ”๊ฐ€๋ฅผ ๋”ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์•„์ฃผ ์˜ค๋ž˜๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค: `document.write` +`document.write`๋Š” ์›นํŽ˜์ด์ง€์— ๋ญ”๊ฐ€๋ฅผ ๋”ํ•  ๋•Œ ์“ฐ๋Š” ์•„์ฃผ ์˜ค๋ž˜๋œ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. -์ด๋ ‡๊ฒŒ ์“ฐ์ž…๋‹ˆ๋‹ค: +์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html run -<p>Somewhere in the page...</p> +<p>ํŽ˜์ด์ง€ ์–ด๋”˜๊ฐ€...</p> *!* <script> - document.write('<b>Hello from JS</b>'); + document.write('<b>์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด Hello ์ž…๋ ฅ</b>'); </script> */!* -<p>The end</p> +<p>๋</p> ``` -`document.write(html)`๋ฉ”์„œ๋“œ๋Š” `html`์„ ํŽ˜์ด์ง€์— "๋™์ ์œผ๋กœ" ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค. `html`๋ฌธ์ž์—ด์ด ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฝค ์œ ์—ฐํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‚ ๊ฐœ๋ฅผ ๋‹จ ์ƒˆ์ฒ˜๋Ÿผ ๋™์ ์ธ ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`document.write(html)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `html`์ด ํŽ˜์ด์ง€ '๊ทธ ์ž๋ฆฌ์— ์ฆ‰์‹œ' ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. `html` ํ˜•์‹์˜ ๋ฌธ์ž์—ด์„ ๋™์ ์œผ๋กœ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `document.write(html)`๋Š” ๊ฝค๋‚˜ ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚ ๊ฐœ๋ฅผ ๋‹จ ์ƒˆ์ฒ˜๋Ÿผ ๋™์ ์ธ ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . -์ด ๋ฉ”์„œ๋“œ๋Š” DOM๋„ ์—†๊ณ  ๊ทธ ์–ด๋–ค ํ‘œ์ค€๋„ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์•„์ฃผ ์˜ค๋ž˜์ „์— ๋ง์ด์ฃ . ํ•˜์ง€๋งŒ ์•„์ง ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ์“ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ด์•„์žˆ์Šต๋‹ˆ๋‹ค. +`document.write`๋Š” DOM๋„ ์—†๊ณ  ๊ทธ ์–ด๋–ค ํ‘œ์ค€๋„ ์กด์žฌํ•˜์ง€ ์•Š์•˜๋˜ ๊ณผ๊ฑฐ์— ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํ‘œ์ค€์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋Š” ์•„๋‹ˆ์ง€๋งŒ ์•„์ง ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ์“ฐ์ด๊ณ  ์žˆ์–ด์„œ ์‚ด์•„๋‚จ์€ ๊ฒƒ์ด์ฃ . -์ตœ๊ทผ์— ๋“ค์–ด์„  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•œ๊ณ„ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค +๊ทผ๋ž˜์— ์ž‘์„ฑ๋œ ์Šคํฌ๋ฆฝํŠธ์—์„  ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๊ธฐ ํž˜๋“ญ๋‹ˆ๋‹ค. -**`document.write`๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋„์ค‘์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.** +์™œ๋ƒํ•˜๋ฉด **`document.write`๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋„์ค‘์—๋งŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.** -ํŽ˜์ด์ง€๊ฐ€ ๋‹ค ๋กœ๋“œ๋˜๊ณ  ๋‚˜์„œ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ์กด์˜ ์ฝ˜ํ…์ธ ๋Š” ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. +ํŽ˜์ด์ง€๊ฐ€ ๋‹ค ๋กœ๋“œ๋˜๊ณ  ๋‚˜์„œ `document.write`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ์กด์— ์žˆ๋˜ ๋ฌธ์„œ ๋‚ด์šฉ์ด ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ด…์‹œ๋‹ค: +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run -<p>์ผ ์ดˆ ํ›„ ์ด ํŽ˜์ด์ง€์˜ ์ฝ˜ํ…์ธ ๋Š” ๊ต์ฒด ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค...</p> +<p>์ผ ์ดˆ ํ›„, ์ด ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์€ ์ „๋ถ€ ๊ต์ฒด๋ฉ๋‹ˆ๋‹ค.</p> *!* <script> - // ์ผ์ดˆํ›„ document.write ์‹คํ–‰ - // ์ผ์ดˆํ›„๋Š” ํŽ˜์ด์ง€๊ฐ€ ์ด๋ฏธ ๋กœ๋“œ๋˜์–ด์žˆ๋Š” ์‹œ์ ์ด๋ฏ€๋กœ ๊ธฐ์กด ์ฝ˜ํ…์ธ ๋Š” ์‚ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + // ์ผ์ดˆ ํ›„ document.write ํ˜ธ์ถœ + // ํŽ˜์ด์ง€ ๋กœ๋“œ๊ฐ€ ๋๋‚œ ํ›„์ด๋ฏ€๋กœ ๊ธฐ์กด ๋‚ด์šฉ์ด ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. setTimeout(() => document.write('<b>...์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.</b>'), 1000); </script> */!* ``` -์œ„์—์„œ ๋‹ค๋ฃฌ ๋‹ค๋ฅธ DOM ๋ฉ”์„œ๋“œ๋“ค๊ณผ ๋‹ฌ๋ฆฌ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค ๋กœ๋“œ๋œ ์‹œ์ ์—์„  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— `document.write`๋Š” ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด DOM ๋ฉ”์„œ๋“œ์™€๋Š” ๋‹ฌ๋ฆฌ 'ํŽ˜์ด์ง€ ๋กœ๋“œ๊ฐ€ ๋‹ค ๋๋‚œ ํ›„'์—” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -That's the downside. +์•„์ฃผ ํฐ ๋‹จ์ ์ด์ฃ . -There's an upside also. Technically, when `document.write` is called while the browser is reading ("parsing") incoming HTML, and it writes something, the browser consumes it just as if it were initially there, in the HTML text. +์žฅ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” HTML์„ '์ฝ๋Š”(ํŒŒ์‹ฑํ•˜๋Š”)' ๋„์ค‘์— `document.write(HTML)`๋ฅผ ๋งŒ๋‚˜๋ฉด ํ…์ŠคํŠธ ํ˜•์‹์˜ HTML์„ ๋งˆ์น˜ ์›๋ž˜ ํŽ˜์ด์ง€์— ์žˆ์—ˆ๋˜ ๊ฒƒ ๋งˆ๋ƒฅ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค. -So it works blazingly fast, because there's *no DOM modification* involved. It writes directly into the page text, while the DOM is not yet built. +์ค‘๊ฐ„์— *DOM ์กฐ์ž‘์„ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—* ์†๋„๊ฐ€ ์•„์ฃผ ๋นจ๋ผ์ง€์ฃ . DOM ๊ตฌ์กฐ๊ฐ€ ์™„์„ฑ๋˜๊ธฐ ์ „์— ํŽ˜์ด์ง€์— ๋‚ด์šฉ์ด ์‚ฝ์ž…๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -๋งŒ์•ฝ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ฌธ์ž์—ด์„ HTML์— ๋™์ ์œผ๋กœ ๋”ํ•ด์ค˜์•ผ ํ•˜๊ณ , ์•„์ง ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋”ฉ๋˜๊ธฐ ์ „ ์‹œ์ ์ด๋ฉด์„œ ์†๋„๊ฐ€ ์ค‘์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ ์ด๋Ÿฐ ์กฐ๊ฑด์„ ํ•œ ๋ฒˆ์— ์ถฉ์กฑํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ํ”์น˜ ์•Š์ฃ . ์ด๋Ÿฐ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ˆˆ์— ๋ˆ๋‹ค๋ฉด ๊ทธ๊ฑด ๊ทธ๋ƒฅ ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ๋ผ์„œ ๊ทธ๋Ÿฐ ๊ฒ๋‹ˆ๋‹ค. +์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๊ธ€์ž๋ฅผ HTML์— ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์•„์ง ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ด๊ณ , ์†๋„๊ฐ€ ์ค‘์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด `document.write`๊ฐ€ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ ์ด๋Ÿฐ ์š”๊ตฌ ์‚ฌํ•ญ๋“ค์ด ํ•œ ๋ฒˆ์— ์ถฉ์กฑ๋˜์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์€ ํ”์น˜ ์•Š์Šต๋‹ˆ๋‹ค. `document.write`๊ฐ€ ๋ˆˆ์— ๋ˆ๋‹ค๋ฉด ๊ทธ๊ฑด ๊ทธ๋ƒฅ ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ๋ผ์„œ ๊ทธ๋Ÿด ํ™•๋ฅ ์ด ๋†’์Šต๋‹ˆ๋‹ค. ## ์š”์•ฝ -- Methods to create new nodes: - - `document.createElement(tag)` -- creates an element with the given tag, - - `document.createTextNode(value)` -- creates a text node (rarely used), - - `elem.cloneNode(deep)` -- clones the element, if `deep==true` then with all descendants. +- ๋…ธ๋“œ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ: + - `document.createElement(tag)` -- ํƒœ๊ทธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ๋งŒ๋“ฆ + - `document.createTextNode(value)` -- ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ฆ(์ž˜ ์“ฐ์ด์ง€ ์•Š์Œ) + - `elem.cloneNode(deep)` -- ์š”์†Œ๋ฅผ ๋ณต์ œํ•จ. `deep==true`์ผ ๊ฒฝ์šฐ ๋ชจ๋“  ์ž์† ์š”์†Œ๋„ ๋ณต์ œ๋จ -- Insertion and removal: - - `node.append(...nodes or strings)` -- insert into `node`, at the end, - - `node.prepend(...nodes or strings)` -- insert into `node`, at the beginning, - - `node.before(...nodes or strings)` โ€“- insert right before `node`, - - `node.after(...nodes or strings)` โ€“- insert right after `node`, - - `node.replaceWith(...nodes or strings)` โ€“- replace `node`. - - `node.remove()` โ€“- remove the `node`. +- ๋…ธ๋“œ ์‚ฝ์ž…, ์‚ญ์ œ ๋ฉ”์„œ๋“œ: + - `node.append(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` -- `node` ๋์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… + - `node.prepend(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` -- `node` ๋งจ ์•ž์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… + - `node.before(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- `node` ์ด์ „์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… + - `node.after(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- `node` ๋‹ค์Œ์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… + - `node.replaceWith(๋…ธ๋“œ๋‚˜ ๋ฌธ์ž์—ด)` โ€“- `node`๋ฅผ ๋Œ€์ฒด + - `node.remove()` โ€“- `node`๋ฅผ ์ œ๊ฑฐ - Text strings are inserted "as text". + ๋ฌธ์ž์—ด์„ ์‚ฝ์ž…, ์‚ญ์ œํ•  ๋• ๋ฌธ์ž์—ด์„ '๊ทธ๋Œ€๋กœ' ๋„ฃ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -- There are also "old school" methods: +- '๊ตฌ์‹' ๋ฉ”์„œ๋“œ: - `parent.appendChild(node)` - `parent.insertBefore(node, nextSibling)` - `parent.removeChild(node)` - `parent.replaceChild(newElem, node)` - All these methods return `node`. + ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ์ „๋ถ€ `node`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- Given a piece of HTML: `elem.insertAdjacentHTML(where, html)`, inserts depending on `where`: - - `"beforebegin"` -- insert `html` right before `elem`, - - `"afterbegin"` -- insert `html` into `elem`, at the beginning, - - `"beforeend"` -- insert `html` into `elem`, at the end, - - `"afterend"` -- insert `html` right after `elem`. +- `html`์— HTML์„ ๋„ฃ์œผ๋ฉด ๋ฉ”์„œ๋“œ `elem.insertAdjacentHTML(where, html)`์€ `where` ๊ฐ’์— ๋”ฐ๋ผ ํŠน์ • ์œ„์น˜์— HTML์„ ์‚ฝ์ž…ํ•จ + - `"beforebegin"` -- `elem` ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž… + - `"afterbegin"` -- `elem`์˜ ์ฒซ ๋ฒˆ์งธ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ์•ž์— `html`์„ ์‚ฝ์ž… + - `"beforeend"` -- `elem`์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ์š”์†Œ ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž… + - `"afterend"` -- `elem` ๋ฐ”๋กœ ๋‹ค์Œ์— `html`์„ ์‚ฝ์ž… - Also there are similar methods `elem.insertAdjacentText` and `elem.insertAdjacentElement`, they insert text strings and elements, but they are rarely used. + ๋ฌธ์ž์—ด์ด๋‚˜ ์š”์†Œ ์‚ฝ์ž…์— ์“ฐ์ด๋Š” ์œ ์‚ฌ ๋ฉ”์„œ๋“œ `elem.insertAdjacentText`์™€ `elem.insertAdjacentElement`๋„ ์žˆ๋Š”๋ฐ, ์ž˜ ์“ฐ์ด์ง€๋Š” ์•Š์Œ -- To append HTML to the page before it has finished loading: +- ํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ๋๋‚˜๊ธฐ ์ „์— HTML์„ ์‚ฝ์ž…ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ: - `document.write(html)` - After the page is loaded such a call erases the document. Mostly seen in old scripts. + ๋ฌธ์„œ ๋กœ๋”ฉ์ด ๋๋‚œ ์ƒํƒœ์—์„œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฌธ์„œ ๋‚ด์šฉ์ด ์ง€์›Œ์ง. ์˜ค๋ž˜๋œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Œ diff --git a/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg b/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg index 1811adea79..0843713cec 100644 --- a/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg +++ b/2-ui/1-document/07-modifying-document/before-prepend-append-after.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="409" height="203" viewBox="0 0 409 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="before-prepend-append-after.svg"><g id="<ol>-<li>0</li>-<li>" fill-rule="nonzero" transform="translate(18.63 60.2)"><path id="<" fill="#999" d="M0 5.53v-.406l6.594-4.018.532.868-5.558 3.29L7.14 8.498l-.532.84z"/><path id="ol" fill="#905" d="M8.568 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162A4.963 4.963 0 018.568 6.3zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zM17.836 0h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197V.938h-1.232V0z"/><path id="><" fill="#999" d="M25.732 9.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 25.53z"/><path id="li" fill="#905" d="M26.236 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H34.44V22.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="0" fill="#000" d="M50.54 24.9c0-.793.07-1.505.21-2.135.14-.63.35-1.162.63-1.596.28-.434.635-.765 1.064-.994.43-.229.938-.343 1.526-.343.625 0 1.155.112 1.589.336.434.224.786.55 1.057.98.27.43.467.959.588 1.589.121.63.182 1.351.182 2.163a9.88 9.88 0 01-.21 2.135c-.14.63-.35 1.162-.63 1.596-.28.434-.635.765-1.064.994-.43.229-.938.343-1.526.343-.616 0-1.141-.124-1.575-.371a2.956 2.956 0 01-1.064-1.043c-.275-.448-.474-.982-.595-1.603a10.713 10.713 0 01-.182-2.051zm5.698 0c0-.495-.028-.966-.084-1.414l-4.158 3.794c.159.532.397.957.714 1.274.317.317.733.476 1.246.476.821 0 1.407-.34 1.757-1.022.35-.681.525-1.717.525-3.108zm-4.536 0c0 .233.007.457.021.672.014.215.03.425.049.63l4.172-3.78c-.159-.504-.394-.905-.707-1.204-.313-.299-.735-.448-1.267-.448-.83 0-1.416.343-1.757 1.029-.34.686-.511 1.72-.511 3.101z"/><path id="</" fill="#999" d="M58.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 25.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H84.84V22.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#999" d="M92.932 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 45.53z"/><path id="li" fill="#905" d="M26.236 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H34.44V42.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="1" fill="#000" d="M51.548 48.792h2.198v-7.364l-2.24 1.568-.546-.798L54.04 40h.784v8.792h2.156V49.8h-5.432z"/><path id="</" fill="#999" d="M58.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 45.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H84.84V42.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#999" d="M92.932 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 65.53z"/><path id="li" fill="#905" d="M26.236 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H34.44V62.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="2" fill="#000" d="M56.77 62.478c0 .859-.406 1.815-1.218 2.87-.812 1.055-1.946 2.203-3.402 3.444h4.928V69.8h-6.216v-1.008c.177-.168.42-.387.728-.658.308-.27.64-.572.994-.903a29.01 29.01 0 001.085-1.071c.369-.383.702-.775 1.001-1.176.299-.401.541-.803.728-1.204a2.75 2.75 0 00.28-1.162c0-.56-.147-1.001-.441-1.323-.294-.322-.735-.483-1.323-.483-.504 0-.929.056-1.274.168a3.101 3.101 0 00-.938.49l-.476-.77c.42-.299.866-.518 1.337-.658s.987-.21 1.547-.21c.877 0 1.54.238 1.988.714.448.476.672 1.12.672 1.932z"/><path id="</" fill="#999" d="M58.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 65.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H84.84V62.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="></" fill="#999" d="M92.932 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM0 85.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L0 85.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="ol" fill="#905" d="M16.968 86.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm8.106-6.3h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V80z"/><path id=">" fill="#999" d="M34.132 89.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="rotate(90 37 184.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/><path id="Line" d="M15 178v-17"/><path id="Line-Copy" d="M15 178l15-5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="rotate(90 53.5 171.5)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.49L27.5 150.5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 225 96)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.49L27.5 150.5"/></g><path id="Line-Copy-3" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" d="M45.5 49.5l5-14"/><path id="Line-Copy-2" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" d="M45.5 49.5h14"/><text id="ol.after" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="193">ol.after</tspan></text><text id="ol.append" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="156">ol.append</tspan></text><text id="ol.prepend" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="66">ol.prepend</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 222.5 64.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/></g><text id="ol.before" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="111" y="26">ol.before</tspan></text><text id="(โ€ฆnodes-or-strings)" fill="#8B572A" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="198" y="112">(โ€ฆnodes or strings)</tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="409" height="203" viewBox="0 0 409 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="before-prepend-append-after.svg"><g id="<ol>-<li>0</li>-<li>" fill-rule="nonzero" transform="translate(18.63 60.2)"><path id="<" fill="#7E7C7B" d="M0 5.53v-.406l6.594-4.018.532.868-5.558 3.29L7.14 8.498l-.532.84z"/><path id="ol" fill="#A7333A" d="M8.568 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162A4.963 4.963 0 018.568 6.3zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zM17.836 0h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197V.938h-1.232V0z"/><path id="><" fill="#7E7C7B" d="M25.732 9.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 25.53z"/><path id="li" fill="#A7333A" d="M26.236 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H34.44V22.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="0" fill="#181717" d="M50.54 24.9c0-.793.07-1.505.21-2.135.14-.63.35-1.162.63-1.596.28-.434.635-.765 1.064-.994.43-.229.938-.343 1.526-.343.625 0 1.155.112 1.589.336.434.224.786.55 1.057.98.27.43.467.959.588 1.589.121.63.182 1.351.182 2.163a9.88 9.88 0 01-.21 2.135c-.14.63-.35 1.162-.63 1.596-.28.434-.635.765-1.064.994-.43.229-.938.343-1.526.343-.616 0-1.141-.124-1.575-.371a2.956 2.956 0 01-1.064-1.043c-.275-.448-.474-.982-.595-1.603a10.713 10.713 0 01-.182-2.051zm5.698 0c0-.495-.028-.966-.084-1.414l-4.158 3.794c.159.532.397.957.714 1.274.317.317.733.476 1.246.476.821 0 1.407-.34 1.757-1.022.35-.681.525-1.717.525-3.108zm-4.536 0c0 .233.007.457.021.672.014.215.03.425.049.63l4.172-3.78c-.159-.504-.394-.905-.707-1.204-.313-.299-.735-.448-1.267-.448-.83 0-1.416.343-1.757 1.029-.34.686-.511 1.72-.511 3.101z"/><path id="</" fill="#7E7C7B" d="M58.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 25.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H84.84V22.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#7E7C7B" d="M92.932 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 45.53z"/><path id="li" fill="#A7333A" d="M26.236 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H34.44V42.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="1" fill="#181717" d="M51.548 48.792h2.198v-7.364l-2.24 1.568-.546-.798L54.04 40h.784v8.792h2.156V49.8h-5.432z"/><path id="</" fill="#7E7C7B" d="M58.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 45.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H84.84V42.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#7E7C7B" d="M92.932 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 65.53z"/><path id="li" fill="#A7333A" d="M26.236 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H34.44V62.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="2" fill="#181717" d="M56.77 62.478c0 .859-.406 1.815-1.218 2.87-.812 1.055-1.946 2.203-3.402 3.444h4.928V69.8h-6.216v-1.008c.177-.168.42-.387.728-.658.308-.27.64-.572.994-.903a29.01 29.01 0 001.085-1.071c.369-.383.702-.775 1.001-1.176.299-.401.541-.803.728-1.204a2.75 2.75 0 00.28-1.162c0-.56-.147-1.001-.441-1.323-.294-.322-.735-.483-1.323-.483-.504 0-.929.056-1.274.168a3.101 3.101 0 00-.938.49l-.476-.77c.42-.299.866-.518 1.337-.658s.987-.21 1.547-.21c.877 0 1.54.238 1.988.714.448.476.672 1.12.672 1.932z"/><path id="</" fill="#7E7C7B" d="M58.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 65.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H84.84V62.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="></" fill="#7E7C7B" d="M92.932 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM0 85.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L0 85.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="ol" fill="#A7333A" d="M16.968 86.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm8.106-6.3h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V80z"/><path id=">" fill="#7E7C7B" d="M34.132 89.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="rotate(90 37 184.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/><path id="Line" d="M15 178v-17"/><path id="Line-Copy" d="M15 178l15-5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="rotate(90 53.5 171.5)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.491L27.5 150.5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 225 96)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.491L27.5 150.5"/></g><path id="Line-Copy-3" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M45.5 49.5l5-14"/><path id="Line-Copy-2" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M45.5 49.5h14"/><text id="ol.after" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="193">ol.after</tspan></text><text id="ol.append" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="156">ol.append</tspan></text><text id="ol.prepend" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="66">ol.prepend</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 222.5 64.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/></g><text id="ol.before" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="111" y="26">ol.before</tspan></text><text id="(โ€ฆnodes-or-strings)" fill="#643B0C" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="198" y="112">(โ€ฆnodes or strings)</tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/07-modifying-document/insert-adjacent.svg b/2-ui/1-document/07-modifying-document/insert-adjacent.svg index 4b247fd729..e26fd023a1 100644 --- a/2-ui/1-document/07-modifying-document/insert-adjacent.svg +++ b/2-ui/1-document/07-modifying-document/insert-adjacent.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="409" height="203" viewBox="0 0 409 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="insert-adjacent.svg"><g id="<ol>-<li>0</li>-<li>" fill-rule="nonzero" transform="translate(18.63 60.2)"><path id="<" fill="#999" d="M0 5.53v-.406l6.594-4.018.532.868-5.558 3.29L7.14 8.498l-.532.84z"/><path id="ol" fill="#905" d="M8.568 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162A4.963 4.963 0 018.568 6.3zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zM17.836 0h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197V.938h-1.232V0z"/><path id="><" fill="#999" d="M25.732 9.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 25.53z"/><path id="li" fill="#905" d="M26.236 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H34.44V22.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="0" fill="#000" d="M50.54 24.9c0-.793.07-1.505.21-2.135.14-.63.35-1.162.63-1.596.28-.434.635-.765 1.064-.994.43-.229.938-.343 1.526-.343.625 0 1.155.112 1.589.336.434.224.786.55 1.057.98.27.43.467.959.588 1.589.121.63.182 1.351.182 2.163a9.88 9.88 0 01-.21 2.135c-.14.63-.35 1.162-.63 1.596-.28.434-.635.765-1.064.994-.43.229-.938.343-1.526.343-.616 0-1.141-.124-1.575-.371a2.956 2.956 0 01-1.064-1.043c-.275-.448-.474-.982-.595-1.603a10.713 10.713 0 01-.182-2.051zm5.698 0c0-.495-.028-.966-.084-1.414l-4.158 3.794c.159.532.397.957.714 1.274.317.317.733.476 1.246.476.821 0 1.407-.34 1.757-1.022.35-.681.525-1.717.525-3.108zm-4.536 0c0 .233.007.457.021.672.014.215.03.425.049.63l4.172-3.78c-.159-.504-.394-.905-.707-1.204-.313-.299-.735-.448-1.267-.448-.83 0-1.416.343-1.757 1.029-.34.686-.511 1.72-.511 3.101z"/><path id="</" fill="#999" d="M58.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 25.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H84.84V22.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#999" d="M92.932 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 45.53z"/><path id="li" fill="#905" d="M26.236 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H34.44V42.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="1" fill="#000" d="M51.548 48.792h2.198v-7.364l-2.24 1.568-.546-.798L54.04 40h.784v8.792h2.156V49.8h-5.432z"/><path id="</" fill="#999" d="M58.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 45.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H84.84V42.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#999" d="M92.932 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 65.53z"/><path id="li" fill="#905" d="M26.236 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H34.44V62.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#999" d="M42.532 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="2" fill="#000" d="M56.77 62.478c0 .859-.406 1.815-1.218 2.87-.812 1.055-1.946 2.203-3.402 3.444h4.928V69.8h-6.216v-1.008c.177-.168.42-.387.728-.658.308-.27.64-.572.994-.903a29.01 29.01 0 001.085-1.071c.369-.383.702-.775 1.001-1.176.299-.401.541-.803.728-1.204a2.75 2.75 0 00.28-1.162c0-.56-.147-1.001-.441-1.323-.294-.322-.735-.483-1.323-.483-.504 0-.929.056-1.274.168a3.101 3.101 0 00-.938.49l-.476-.77c.42-.299.866-.518 1.337-.658s.987-.21 1.547-.21c.877 0 1.54.238 1.988.714.448.476.672 1.12.672 1.932z"/><path id="</" fill="#999" d="M58.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 65.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#905" d="M76.636 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H84.84V62.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="></" fill="#999" d="M92.932 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM0 85.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L0 85.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="ol" fill="#905" d="M16.968 86.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm8.106-6.3h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V80z"/><path id=">" fill="#999" d="M34.132 89.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/></g><text id="ol.insertAdjacentHTM" fill="#8B572A" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="156" y="112">ol.insertAdjacentHTML(*, html)</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="rotate(90 37 184.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/><path id="Line" d="M15 178v-17"/><path id="Line-Copy" d="M15 178l15-5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="rotate(90 53.5 171.5)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.49L27.5 150.5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 225 96)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.49L27.5 150.5"/></g><path id="Line-Copy-3" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" d="M45.5 49.5l5-14"/><path id="Line-Copy-2" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" d="M45.5 49.5h14"/><text id="afterend" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="193">afterend</tspan></text><text id="beforeend" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="156">beforeend</tspan></text><text id="afterbegin" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="66">afterbegin</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 222.5 64.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/></g><text id="beforebegin" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="111" y="26">beforebegin</tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="409" height="203" viewBox="0 0 409 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="insert-adjacent.svg"><g id="<ol>-<li>0</li>-<li>" fill-rule="nonzero" transform="translate(18.63 60.2)"><path id="<" fill="#7E7C7B" d="M0 5.53v-.406l6.594-4.018.532.868-5.558 3.29L7.14 8.498l-.532.84z"/><path id="ol" fill="#A7333A" d="M8.568 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162A4.963 4.963 0 018.568 6.3zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zM17.836 0h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197V.938h-1.232V0z"/><path id="><" fill="#7E7C7B" d="M25.732 9.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 25.53z"/><path id="li" fill="#A7333A" d="M26.236 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H34.44V22.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="0" fill="#181717" d="M50.54 24.9c0-.793.07-1.505.21-2.135.14-.63.35-1.162.63-1.596.28-.434.635-.765 1.064-.994.43-.229.938-.343 1.526-.343.625 0 1.155.112 1.589.336.434.224.786.55 1.057.98.27.43.467.959.588 1.589.121.63.182 1.351.182 2.163a9.88 9.88 0 01-.21 2.135c-.14.63-.35 1.162-.63 1.596-.28.434-.635.765-1.064.994-.43.229-.938.343-1.526.343-.616 0-1.141-.124-1.575-.371a2.956 2.956 0 01-1.064-1.043c-.275-.448-.474-.982-.595-1.603a10.713 10.713 0 01-.182-2.051zm5.698 0c0-.495-.028-.966-.084-1.414l-4.158 3.794c.159.532.397.957.714 1.274.317.317.733.476 1.246.476.821 0 1.407-.34 1.757-1.022.35-.681.525-1.717.525-3.108zm-4.536 0c0 .233.007.457.021.672.014.215.03.425.049.63l4.172-3.78c-.159-.504-.394-.905-.707-1.204-.313-.299-.735-.448-1.267-.448-.83 0-1.416.343-1.757 1.029-.34.686-.511 1.72-.511 3.101z"/><path id="</" fill="#7E7C7B" d="M58.8 25.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 25.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 20h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V20zm8.204 9.8v-.938h2.436v-5.124H84.84V22.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#7E7C7B" d="M92.932 29.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 45.53z"/><path id="li" fill="#A7333A" d="M26.236 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H34.44V42.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="1" fill="#181717" d="M51.548 48.792h2.198v-7.364l-2.24 1.568-.546-.798L54.04 40h.784v8.792h2.156V49.8h-5.432z"/><path id="</" fill="#7E7C7B" d="M58.8 45.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 45.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 40h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V40zm8.204 9.8v-.938h2.436v-5.124H84.84V42.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="><" fill="#7E7C7B" d="M92.932 49.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM16.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L16.8 65.53z"/><path id="li" fill="#A7333A" d="M26.236 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H34.44V62.8h3.556v6.062h2.38v.938H34.44zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=">" fill="#7E7C7B" d="M42.532 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/><path id="2" fill="#181717" d="M56.77 62.478c0 .859-.406 1.815-1.218 2.87-.812 1.055-1.946 2.203-3.402 3.444h4.928V69.8h-6.216v-1.008c.177-.168.42-.387.728-.658.308-.27.64-.572.994-.903a29.01 29.01 0 001.085-1.071c.369-.383.702-.775 1.001-1.176.299-.401.541-.803.728-1.204a2.75 2.75 0 00.28-1.162c0-.56-.147-1.001-.441-1.323-.294-.322-.735-.483-1.323-.483-.504 0-.929.056-1.274.168a3.101 3.101 0 00-.938.49l-.476-.77c.42-.299.866-.518 1.337-.658s.987-.21 1.547-.21c.877 0 1.54.238 1.988.714.448.476.672 1.12.672 1.932z"/><path id="</" fill="#7E7C7B" d="M58.8 65.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L58.8 65.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="li" fill="#A7333A" d="M76.636 60h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V60zm8.204 9.8v-.938h2.436v-5.124H84.84V62.8h3.556v6.062h2.38v.938H84.84zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id="></" fill="#7E7C7B" d="M92.932 69.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406l-6.608 3.808zM0 85.53v-.406l6.594-4.018.532.868-5.558 3.29 5.572 3.234-.532.84L0 85.53zm14.084-5.698l.882.392-5.11 11.536-.882-.392 5.11-11.536z"/><path id="ol" fill="#A7333A" d="M16.968 86.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm8.106-6.3h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V80z"/><path id=">" fill="#7E7C7B" d="M34.132 89.338l-.532-.84 5.572-3.234-5.558-3.29.532-.868 6.594 4.018v.406z"/></g><text id="ol.insertAdjacentHTM" fill="#643B0C" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="156" y="112">ol.insertAdjacentHTML(*, html)</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="rotate(90 37 184.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/><path id="Line" d="M15 178v-17"/><path id="Line-Copy" d="M15 178l15-5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="rotate(90 53.5 171.5)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.491L27.5 150.5"/></g><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy-Copy-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 225 96)"><path id="Line-Copy-5" d="M.257.737s21.205 7.589 21.205 93.119v67.243"/><path id="Line" d="M21.409 162.661L14.5 150.5"/><path id="Line-Copy" d="M21.476 162.491L27.5 150.5"/></g><path id="Line-Copy-3" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M45.5 49.5l5-14"/><path id="Line-Copy-2" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M45.5 49.5h14"/><text id="afterend" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="193">afterend</tspan></text><text id="beforeend" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="156">beforeend</tspan></text><text id="afterbegin" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="113" y="66">afterbegin</tspan></text><g id="Line-Copy-5-+-Line-Copy-4-+-Line-Copy-3-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="3" transform="matrix(0 -1 -1 0 222.5 64.5)"><path id="Line-Copy-5" d="M.527.625S30.885-3.5 30.885 81.25s-15.179 94.723-15.179 94.723"/></g><text id="beforebegin" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="111" y="26">beforebegin</tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/source.view/index.html b/2-ui/1-document/08-styles-and-classes/2-create-notification/source.view/index.html index b5e2f83f7d..65e274031b 100755 --- a/2-ui/1-document/08-styles-and-classes/2-create-notification/source.view/index.html +++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/source.view/index.html @@ -16,7 +16,7 @@ <h2>Notification is on the right</h2> <script> function showNotification({top = 0, right = 0, className, html}) { - /* your code */ + /* ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. */ } // test it diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md index 60930cb6cf..0fb422d99a 100644 --- a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md +++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md @@ -2,23 +2,23 @@ importance: 5 --- -# Create a notification +# ์•Œ๋ฆผ ๋งŒ๋“ค๊ธฐ -Write a function `showNotification(options)` that creates a notification: `<div class="notification">` with the given content. The notification should automatically disappear after 1.5 seconds. +์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์—ด์—ˆ์„ ๋•Œ ๋ณด์ด๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ `<div class="notification">` ์•Œ๋ฆผ์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜ `showNotification(options)`๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค. ์ด ์•Œ๋ฆผ์€ 1.5์ดˆ ํ›„์— ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. -The options are: +์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js -// shows an element with the text "Hello" near the right-top of the window +// ์ฐฝ์˜ ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ์— "Hello"๋ผ๋Š” ํ…์ŠคํŠธ๊ฐ€ ๋‹ด๊ธด ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. showNotification({ - top: 10, // 10px from the top of the window (by default 0px) - right: 10, // 10px from the right edge of the window (by default 0px) - html: "Hello!", // the HTML of notification - className: "welcome" // an additional class for the div (optional) + top: 10, // ์ฐฝ์˜ ์ƒ๋‹จ์—์„œ 10px ๋–จ์–ด์ง„ ์œ„์น˜์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค(๊ธฐ๋ณธ๊ฐ’์€ 0px). + right: 10, // ์ฐฝ์˜ ์˜ค๋ฅธ์ชฝ ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ 10px ๋–จ์–ด์ง„ ์œ„์น˜์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค(๊ธฐ๋ณธ๊ฐ’์€ 0px). + html: "Hello!", // ์•Œ๋ฆผ์˜ HTML์ž…๋‹ˆ๋‹ค. + className: "welcome" // div์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค(์„ ํƒ ์‚ฌํ•ญ). }); ``` [demo src="solution"] -Use CSS positioning to show the element at given top/right coordinates. The source document has the necessary styles. +CSS ํฌ์ง€์…”๋‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์–ด์ง„ ์ขŒํ‘œ(์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ)์— ์•Œ๋ฆผ์„ ํ‘œ์‹œํ•˜์„ธ์š”. ํ•„์š”ํ•œ ์Šคํƒ€์ผ๋“ค์€ ๋งํฌ๋ฅผ ์—ด๋ฉด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index e6357c8e0c..daa79f0eb9 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -1,37 +1,37 @@ -# Styles and classes +# ์Šคํƒ€์ผ๊ณผ ํด๋ž˜์Šค -Before we get into JavaScript's ways of dealing with styles and classes -- here's an important rule. Hopefully it's obvious enough, but we still have to mention it. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์–ด๋–ป๊ฒŒ ์Šคํƒ€์ผ๊ณผ ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ ์ „์—, ์ค‘์š”ํ•œ ๊ทœ์น™์„ ํ•˜๋‚˜ ์ง‘๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ๋งŒ ์š”์•ฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถฉ๋ถ„ํ• ์ง„ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๊ผญ ์–ธ๊ธ‰ํ•˜๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -There are generally two ways to style an element: +์š”์†Œ์— ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -1. Create a class in CSS and add it: `<div class="...">` -2. Write properties directly into `style`: `<div style="...">`. +1. CSS์— ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ์š”์†Œ์— `<div class="...">`์ฒ˜๋Ÿผ ํด๋ž˜์Šค ์ถ”๊ฐ€ํ•˜๊ธฐ +2. `<div style="...">`์ฒ˜๋Ÿผ ํ”„๋กœํผํ‹ฐ๋ฅผ `style`์— ๋ฐ”๋กœ ์จ์ฃผ๊ธฐ -JavaScript can modify both classes and `style` properties. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค์™€ `style` ํ”„๋กœํผํ‹ฐ ๋‘˜ ๋‹ค๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We should always prefer CSS classes to `style`. The latter should only be used if classes "can't handle it". +๋‘ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋ฅผ ํƒํ•˜๋ผ๋ฉด `style` ๋ณด๋‹ค CSS ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์„ ๋” ์šฐ์„ ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `style`์€ ํด๋ž˜์Šค๋ฅผ '๋‹ค๋ฃฐ ์ˆ˜ ์—†์„ ๋•Œ'๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -For example, `style` is acceptable if we calculate coordinates of an element dynamically and want to set them from JavaScript, like this: +`style`์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์˜ ์ขŒํ‘œ๋ฅผ ๋™์ ์œผ๋กœ ๊ณ„์‚ฐํ•˜๊ณ , ๊ณ„์‚ฐํ•œ ์ขŒํ‘œ๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. ```js -let top = /* complex calculations */; -let left = /* complex calculations */; +let top = /* ๋ณต์žกํ•œ ๊ณ„์‚ฐ์‹ */; +let left = /* ๋ณต์žกํ•œ ๊ณ„์‚ฐ์‹ */; -elem.style.left = left; // e.g '123px', calculated at run-time -elem.style.top = top; // e.g '456px' +elem.style.left = left; // ์˜ˆ์‹œ: '123px', ๋Ÿฐํƒ€์ž„์œผ๋กœ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +elem.style.top = top; // ์˜ˆ์‹œ: '456px' ``` -For other cases, like making the text red, adding a background icon -- describe that in CSS and then add the class (JavaScript can do that). That's more flexible and easier to support. +ํ…์ŠคํŠธ๋ฅผ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋งŒ๋“ ๋‹ค๊ฑฐ๋‚˜ ๋ฐฐ๊ฒฝ์— ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์€ CSS์— ๊ด€๋ จ ์Šคํƒ€์ผ์„ ๋ช…์‹œํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์ด ํด๋ž˜์Šค๋ฅผ ์š”์†Œ์— ์ถ”๊ฐ€ํ•ด ์ฃผ๋Š” ๋ฐฉ์‹์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์œ ์—ฐ์„ฑ์ด ํ™•๋ณด๋ผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. -## className and classList +## className๊ณผ classList -Changing a class is one of the most often used actions in scripts. +ํด๋ž˜์Šค ๋ณ€๊ฒฝ์€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์ž์ฃผ ํ•˜๊ฒŒ ๋˜๋Š” ๋™์ž‘ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. -In the ancient time, there was a limitation in JavaScript: a reserved word like `"class"` could not be an object property. That limitation does not exist now, but at that time it was impossible to have a `"class"` property, like `elem.class`. +์•„์ฃผ ์˜ค๋ž˜์ „ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—” `"class"`๊ฐ™์€ ์˜ˆ์•ฝ์–ด๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค๋Š” ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ด๋Ÿฐ ์ œ์•ฝ์‚ฌํ•ญ์ด ์‚ฌ๋ผ์กŒ์ง€๋งŒ, ๊ณผ๊ฑฐ์—” `"class"` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— `elem.class`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ์—ญ์‹œ ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. -So for classes the similar-looking property `"className"` was introduced: the `elem.className` corresponds to the `"class"` attribute. +์ด๋Ÿฐ ๋ฐฐ๊ฒฝ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค๋ฅผ ์œ„ํ•œ ํ”„๋กœํผํ‹ฐ `"className"`๊ฐ€ ๋„์ž…๋˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `elem.className`๋Š” `"class"` ์†์„ฑ์— ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```html run <body class="main page"> @@ -41,19 +41,19 @@ For instance: </body> ``` -If we assign something to `elem.className`, it replaces the whole string of classes. Sometimes that's what we need, but often we want to add/remove a single class. +`elem.className`์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋Œ€์ž…ํ•˜๋ฉด ํด๋ž˜์Šค ๋ฌธ์ž์—ด ์ „์ฒด๊ฐ€ ๋ฐ”๋€๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ์†์„ฑ๊ฐ’ ์ „์ฒด๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒŒ ์•„๋‹ˆ๊ณ  ํด๋ž˜์Šค ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋„ ์žˆ๊ธฐ ๋งˆ๋ จ์ž…๋‹ˆ๋‹ค. -There's another property for that: `elem.classList`. +์ด๋Ÿด ๋•Œ `elem.classList`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The `elem.classList` is a special object with methods to `add/remove/toggle` a single class. +`elem.classList`์—” ํด๋ž˜์Šค ํ•˜๋‚˜๋งŒ ์กฐ์ž‘ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ์ธ `add/remove/toggle`๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```html run <body class="main page"> <script> *!* - // add a class + // ํด๋ž˜์Šค ์ถ”๊ฐ€ document.body.classList.add('article'); */!* @@ -62,31 +62,31 @@ For instance: </body> ``` -So we can operate both on the full class string using `className` or on individual classes using `classList`. What we choose depends on our needs. +์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค ์†์„ฑ๊ฐ’ ์ „์ฒด๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œ๋Š” `className`์œผ๋กœ, ๊ฐœ๋ณ„ ํด๋ž˜์Šค๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” `classList`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ์ทจ์‚ฌ์„ ํƒํ•˜๋ฉด ๋˜์ฃ . -Methods of `classList`: +`classList`์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `elem.classList.add/remove("class")` -- adds/removes the class. -- `elem.classList.toggle("class")` -- adds the class if it doesn't exist, otherwise removes it. -- `elem.classList.contains("class")` -- checks for the given class, returns `true/false`. +- `elem.classList.add/remove("class")` -- `class`๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐ +- `elem.classList.toggle("class")` -- `class`๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ `class`๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—” ์ถ”๊ฐ€ +- `elem.classList.contains("class")` -- `class` ์กด์žฌ ์—ฌ๋ถ€์— ๋”ฐ๋ผ `true/false`๋ฅผ ๋ฐ˜ํ™˜ -Besides, `classList` is iterable, so we can list all classes with `for..of`, like this: +์ด ์™ธ์— `classList`๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `for..of`๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```html run <body class="main page"> <script> for (let name of document.body.classList) { - alert(name); // main, and then page + alert(name); // main๊ณผ page๊ฐ€ ์ถœ๋ ฅ๋จ } </script> </body> ``` -## Element style +## ์š”์†Œ์˜ ์Šคํƒ€์ผ -The property `elem.style` is an object that corresponds to what's written in the `"style"` attribute. Setting `elem.style.width="100px"` works the same as if we had in the attribute `style` a string `width:100px`. +ํ”„๋กœํผํ‹ฐ `elem.style`์€ ์†์„ฑ `"style"`์— ์“ฐ์ธ ๊ฐ’์— ๋Œ€์‘๋˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. `elem.style.width="100px"`์€ `style` ์†์„ฑ๊ฐ’์„ ๋ฌธ์ž์—ด `width:100px`๋กœ ์„ค์ •ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ฃ . -For multi-word property the camelCase is used: +์—ฌ๋Ÿฌ ๋‹จ์–ด๋ฅผ ์ด์–ด์„œ ๋งŒ๋“  ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค์Œ์™€ ๊ฐ™์ด ์นด๋ฉœ ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์ด๋ฆ„ ์ง“์Šต๋‹ˆ๋‹ค. ```js no-beautify background-color => elem.style.backgroundColor @@ -94,16 +94,16 @@ z-index => elem.style.zIndex border-left-width => elem.style.borderLeftWidth ``` -For instance: +์˜ˆ์‹œ: ```js run -document.body.style.backgroundColor = prompt('background color?', 'green'); +document.body.style.backgroundColor = prompt('๋ฐฐ๊ฒฝ์„ ๋ฌด์Šจ ์ƒ‰์œผ๋กœ ๋ฐ”๊ฟ€๊นŒ์š”?', 'green'); ``` -````smart header="Prefixed properties" -Browser-prefixed properties like `-moz-border-radius`, `-webkit-border-radius` also follow the same rule: a dash means upper case. +````smart header="ํŠน์ • ๋ธŒ๋ผ์šฐ์ € ์ „์šฉ ํ”„๋กœํผํ‹ฐ" +`-moz-border-radius`, `-webkit-border-radius`๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ € ๊ด€๋ จ ์ ‘๋‘์‚ฌ๊ฐ€ ๋ถ™์€ ํ”„๋กœํผํ‹ฐ(browser-prefixed property) ์—ญ์‹œ ์นด๋ฉœ ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹œ(-)๋Š” ๋Œ€๋ฌธ์ž๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js button.style.MozBorderRadius = '5px'; @@ -111,33 +111,33 @@ button.style.WebkitBorderRadius = '5px'; ``` ```` -## Resetting the style property +## style ํ”„๋กœํผํ‹ฐ ์žฌ์ง€์ •ํ•˜๊ธฐ -Sometimes we want to assign a style property, and later remove it. +`style` ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ–ˆ๋‹ค๊ฐ€ ์‹œ๊ฐ„์ด ์ง€๋‚˜ ์ด๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, to hide an element, we can set `elem.style.display = "none"`. +์š”์†Œ๋ฅผ ์ˆจ๊ธฐ๊ธฐ ์œ„ํ•ด `elem.style.display = "none"`๋ฅผ ์ ์šฉํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. -Then later we may want to remove the `style.display` as if it were not set. Instead of `delete elem.style.display` we should assign an empty string to it: `elem.style.display = ""`. +์‹œ๊ฐ„์ด ์ง€๋‚˜ ์ฒ˜์Œ๋ถ€ํ„ฐ `style.display`๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋˜๋Œ๋ฆฌ๊ณ  ์‹ถ์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋• `delete elem.style.display`๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋Œ€์‹  `elem.style.display = ""`๊ฐ™์ด ๋นˆ ๋ฌธ์ž์—ด์„ ํ• ๋‹นํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run -// if we run this code, the <body> will blink +// ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํŽ˜์ด์ง€์˜ <body>๊ฐ€ ๊นœ๋นก์ž…๋‹ˆ๋‹ค. document.body.style.display = "none"; // hide -setTimeout(() => document.body.style.display = "", 1000); // back to normal +setTimeout(() => document.body.style.display = "", 1000); // 1์ดˆ ํ›„ ๋‹ค์‹œ ์›๋ž˜ ์ƒํƒœ๋กœ ๋Œ์•„์˜ต๋‹ˆ๋‹ค. ``` -If we set `style.display` to an empty string, then the browser applies CSS classes and its built-in styles normally, as if there were no such `style.display` property at all. +์ด๋ ‡๊ฒŒ `style.display`์— ๋นˆ ๋ฌธ์ž์—ด์„ ํ• ๋‹นํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๋งˆ์น˜ ์ฒ˜์Œ๋ถ€ํ„ฐ `style.display` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ CSS ํด๋ž˜์Šค์™€ ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ ์Šคํƒ€์ผ์„ ํŽ˜์ด์ง€์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. -````smart header="Full rewrite with `style.cssText`" -Normally, we use `style.*` to assign individual style properties. We can't set the full style like `div.style="color: red; width: 100px"`, because `div.style` is an object, and it's read-only. +````smart header="`style.cssText`๋กœ ์™„์ „ํžˆ ๋‹ค์‹œ ์“ฐ๊ธฐ" +๊ฐœ๋ณ„ ์Šคํƒ€์ผ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ ์šฉํ•  ๋•Œ๋Š” ๋ณดํ†ต `style.*`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `div.style` ์€ ๊ฐ์ฒด์ด๊ณ  ์ฝ๊ธฐ ์ „์šฉ์ด๊ธฐ ๋•Œ๋ฌธ์— `div.style="color: red; width: 100px"`๊ฐ™์€ ๋ฐฉ์‹์œผ๋ก  ์ „์ฒด ์Šคํƒ€์ผ์„ ์„ค์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -To set the full style as a string, there's a special property `style.cssText`: +๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•ด ์ „์ฒด ์Šคํƒ€์ผ์„ ์„ค์ •ํ•˜๋ ค๋ฉด ํ”„๋กœํผํ‹ฐ `style.cssText`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```html run -<div id="div">Button</div> +<div id="div">๋ฒ„ํŠผ</div> <script> - // we can set special style flags like "important" here + // cssText๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด 'important' ๊ฐ™์€ ๊ทœ์น™๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. div.style.cssText=`color: red !important; background-color: yellow; width: 100px; @@ -148,27 +148,27 @@ To set the full style as a string, there's a special property `style.cssText`: </script> ``` -This property is rarely used, because such assignment removes all existing styles: it does not add, but replaces them. May occasionally delete something needed. But we can safely use it for new elements, when we know we won't delete an existing style. +`style.cssText`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด ์Šคํƒ€์ผ์— ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ „์ฒด๋ฅผ ๊ต์ฒดํ•ด๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์ž˜ ์“ฐ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž˜ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์Šคํƒ€์ผ์ด ์‹ค์ˆ˜๋กœ ์ง€์›Œ์ง„๋‹ค๋Š” ์œ„ํ—˜์ด ์žˆ์ฃ . ๊ทธ๋ ‡์ง€๋งŒ ์š”์†Œ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ , ์—ฌ๊ธฐ์— ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋•Œ๋Š” ๊ธฐ์กด ์Šคํƒ€์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— `style.cssText`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The same can be accomplished by setting an attribute: `div.setAttribute('style', 'color: red...')`. +`div.setAttribute('style', 'color: red...')`๋ฅผ ์‚ฌ์šฉํ•ด ์†์„ฑ์„ ์„ค์ •ํ•ด๋„ `style.cssText`๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```` -## Mind the units +## ๋‹จ์œ„์— ์ฃผ์˜ํ•˜๊ธฐ -Don't forget to add CSS units to values. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํƒ€์ผ ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ๋Š” ๋‹จ์œ„๋ฅผ ๋ถ™์—ฌ์ฃผ๋Š” ๊ฑธ ์žŠ์ง€ ๋ง์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -For instance, we should not set `elem.style.top` to `10`, but rather to `10px`. Otherwise it wouldn't work: +`elem.style.top`์— ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ `10px`์ด ์•„๋‹Œ `10`์„ ์„ค์ •ํ•˜๋ฉด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```html run height=100 <body> <script> *!* - // doesn't work! + // ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค! document.body.style.margin = 20; - alert(document.body.style.margin); // '' (empty string, the assignment is ignored) + alert(document.body.style.margin); // '' (๊ฐ’์ด ์ œ๋Œ€๋กœ ํ• ๋‹น๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋นˆ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.) */!* - // now add the CSS unit (px) - and it works + // CSS ๋‹จ์œ„(px)๋ฅผ ์ถ”๊ฐ€ํ•ด๋ด…์‹œ๋‹ค. ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋„ค์š”! document.body.style.margin = '20px'; alert(document.body.style.margin); // 20px @@ -178,19 +178,19 @@ For instance, we should not set `elem.style.top` to `10`, but rather to `10px`. </body> ``` -Please note: the browser "unpacks" the property `style.margin` in the last lines and infers `style.marginLeft` and `style.marginTop` from it. +์ฐธ๊ณ ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์œ„ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `style.margin`๋ฅผ '๋ถ„์„' ๋ฐ ์ถ”๋ก ํ•œ ๊ฒฐ๊ณผ๋ฅผ `style.marginLeft`์™€ `style.marginTop`์— ํ• ๋‹นํ•ด์ค๋‹ˆ๋‹ค. -## Computed styles: getComputedStyle +## getComputedStyle๋กœ ๊ณ„์‚ฐ๋œ ์Šคํƒ€์ผ ์–ป๊ธฐ -So, modifying a style is easy. But how to *read* it? +์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์‘์šฉํ•˜๋ฉด ์Šคํƒ€์ผ์„ ์‰ฝ๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์Šคํƒ€์ผ์„ *์ฝ์„ ์ˆ˜* ์žˆ์„๊นŒ์š”? -For instance, we want to know the size, margins, the color of an element. How to do it? +์š”์†Œ์˜ ํฌ๊ธฐ์™€ ๋งˆ์ง„, ์ƒ‰์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? -**The `style` property operates only on the value of the `"style"` attribute, without any CSS cascade.** +`style` ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ฝ์œผ๋ฉด ๋˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, **`style` ํ”„๋กœํผํ‹ฐ๋Š” `"style"` ์†์„ฑ์˜ ๊ฐ’์„ ์ฝ์„ ๋•Œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `style` ํ”„๋กœํผํ‹ฐ๋งŒ์œผ๋ก  CSS ์ข…์†(CSS cascade)๊ฐ’์„ ๋‹ค๋ฃจ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.** -So we can't read anything that comes from CSS classes using `elem.style`. +์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— `elem.style`๋งŒ์œผ๋กœ๋Š” CSS ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์ ์šฉํ•œ ์Šคํƒ€์ผ์„ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -For instance, here `style` doesn't see the margin: +`style` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋งˆ์ง„๊ฐ’์„ ์ฝ์„ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์ง์ ‘ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. ```html run height=60 no-beautify <head> @@ -198,35 +198,35 @@ For instance, here `style` doesn't see the margin: </head> <body> - The red text + ๋ถ‰์€ ๊ธ€์”จ <script> *!* - alert(document.body.style.color); // empty - alert(document.body.style.marginTop); // empty + alert(document.body.style.color); // ๋นˆ ๋ฌธ์ž์—ด + alert(document.body.style.marginTop); // ๋นˆ ๋ฌธ์ž์—ด */!* </script> </body> ``` -...But what if we need, say, to increase the margin by `20px`? We would want the current value of it. +๊ทธ๋ ‡๋‹ค๋ฉด ๋งˆ์ง„์„ ํ˜„์žฌ ํฌ๊ธฐ๋ณด๋‹ค `20px` ๋” ํฌ๊ฒŒ ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์›ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๋ ค๋จผ ๋จผ์ € ํ˜„์žฌ ํฌ๊ธฐ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -There's another method for that: `getComputedStyle`. +์ด๋Ÿด ๋•Œ `getComputedStyle` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The syntax is: +`getComputedStyle` ๋ฉ”์„œ๋“œ์˜ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js getComputedStyle(element, [pseudo]) ``` element -: Element to read the value for. +: ๊ฐ’์„ ์ฝ์„ ์š”์†Œ pseudo -: A pseudo-element if required, for instance `::before`. An empty string or no argument means the element itself. +: `::before`๊ฐ™์ด ์˜์‚ฌ ์š”์†Œ(pseudo-element)๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ช…์‹œํ•ด์คŒ. ๋นˆ ๋ฌธ์ž์—ด์„ ๋„˜๊ฒจ์ฃผ๊ฑฐ๋‚˜ ์•„๋ฌด๋Ÿฐ ๊ฐ’์„ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์š”์†Œ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•จ -The result is an object with styles, like `elem.style`, but now with respect to all CSS classes. +`getComputedStyle`์„ ํ˜ธ์ถœํ•˜๋ฉด `elem.style`๊ฐ™์ด ์Šคํƒ€์ผ ์ •๋ณด๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ, ์—ฌ๊ธฐ์—” `elem.style`๊ณผ๋Š” ๋‹ฌ๋ฆฌ ์ „์ฒด CSS ํด๋ž˜์Šค ์ •๋ณด๋„ ํ•จ๊ป˜ ๋‹ด๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```html run height=100 <head> @@ -237,7 +237,7 @@ For instance: <script> let computedStyle = getComputedStyle(document.body); - // now we can read the margin and the color from it + // ์ด์ œ ๋งˆ์ง„๊ณผ ์ƒ‰ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. alert( computedStyle.marginTop ); // 5px alert( computedStyle.color ); // rgb(255, 0, 0) @@ -246,23 +246,23 @@ For instance: </body> ``` -```smart header="Computed and resolved values" -There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values): +```smart header="๊ณ„์‚ฐ ๊ฐ’๊ณผ ๊ฒฐ์ • ๊ฐ’" +[CSS](https://drafts.csswg.org/cssom/#resolved-values)์—๋Š” ์†์„ฑ๊ณผ ๊ด€๋ จ๋œ ๋‘ ๊ฐ€์ง€ ๊ฐœ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค. -1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. It can look like `height:1em` or `font-size:125%`. -2. A *resolved* style value is the one finally applied to the element. Values like `1em` or `125%` are relative. The browser takes the computed value and makes all units fixed and absolute, for instance: `height:20px` or `font-size:16px`. For geometry properties resolved values may have a floating point, like `width:50.5px`. +1. *๊ณ„์‚ฐ ๊ฐ’(computed style value)* -- CSS ๊ทœ์น™๊ณผ CSS ์ƒ์†์ด ๋ชจ๋‘ ์ ์šฉ๋œ ํ›„์˜ ๊ฐ’์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์˜ ํ˜•ํƒœ๋Š” `height:1em`๋‚˜ `font-size:125%` ๊ฐ™์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. +2. *๊ฒฐ์ • ๊ฐ’(resolved style value)* -- ์š”์†Œ์— ์ตœ์ข…์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๊ฐ’์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์‚ฐ ๊ฐ’์—์„œ ์‚ฌ์šฉํ•œ `1em`๋‚˜ `125%`์€ ์ƒ๋Œ€ ๋‹จ์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒ๋Œ“๊ฐ’์ธ๋ฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ณ„์‚ฐ ๊ฐ’์„ ๋ฐ›์•„ ๋‹จ์œ„๋ฅผ ์ „ํ™˜ํ•ด `height:20px`๋‚˜ `font-size:16px`๊ฐ™์ด ๊ณ ์ • ๋‹จ์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’(์ ˆ๋Œ“๊ฐ’)์œผ๋กœ ๊ฐ’์„ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐํ•˜ ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฐ์ • ๊ฐ’์—๋Š” `width:50.5px`๊ฐ™์ด ์†Œ์ˆ˜์  ๋‹จ์œ„๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -A long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed. +`getComputedStyle`์€ ๊ณ„์‚ฐ ๊ฐ’์„ ์–ป๊ธฐ ์œ„ํ•ด์„œ ๋งŒ๋“ค์–ด์ง„ ์•„์ฃผ ์˜ค๋ž˜๋œ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ณ„์‚ฐ ๊ฐ’๋ณด๋‹ค๋Š” ๊ฒฐ์ • ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ํ›จ์”ฌ ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ‘œ์ค€์ด ๊ฐœ์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -So nowadays `getComputedStyle` actually returns the resolved value of the property, usually in `px` for geometry. +๋”ฐ๋ผ์„œ ์ง€๊ธˆ์€ `getComputedStyle`์„ ํ˜ธ์ถœํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฐ์ • ๊ฐ’์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ์ฃผ๋กœ `px`๊ฐ€ ๋‹จ์œ„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ``` -````warn header="`getComputedStyle` requires the full property name" -We should always ask for the exact property that we want, like `paddingLeft` or `marginTop` or `borderTopWidth`. Otherwise the correct result is not guaranteed. +````warn header="`getComputedStyle`์—” ํ”„๋กœํผํ‹ฐ ์ „์ฒด ์ด๋ฆ„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค." +`getComputedStyle`์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” `paddingLeft`, `marginTop`, `borderTopWidth`๊ฐ™์ด ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„ ์ „์ฒด๋ฅผ ์ •ํ™•ํžˆ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์›ํ•˜๋Š” ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. -For instance, if there are properties `paddingLeft/paddingTop`, then what should we get for `getComputedStyle(elem).padding`? Nothing, or maybe a "generated" value from known paddings? There's no standard rule here. +`paddingLeft`๋‚˜ `paddingTop`์—” ๊ฐ’์ด ์ง€์ •๋˜์–ด์žˆ๋Š”๋ฐ `getComputedStyle(elem).padding`์„ ์‚ฌ์šฉํ•ด ๊ฐ’์„ ์–ป์œผ๋ ค ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค. ์–ด๋–ค ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์„๊นŒ์š”? ์•„๋ฌด๊ฒƒ๋„ ์–ป์ง€ ๋ชปํ• ๊นŒ์š” ์•„๋‹ˆ๋ฉด ๊ฐ’์ด ์„ค์ •๋˜์–ด ์žˆ๋Š” `paddingLeft`๋‚˜ `paddingTop`์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ๊นŒ์š”? ์ด๋Ÿฐ ์ƒํ™ฉ์— ์ ์šฉํ• ๋งŒํ•œ ํ‘œ์ค€์€ ์•„์ง ์ œ์ •๋˜์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -There are other inconsistencies. As an example, some browsers (Chrome) show `10px` in the document below, and some of them (Firefox) -- do not: +๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ๋™์ž‘ ๋ฐฉ์‹์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Chrome ๊ฐ™์€ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €๋Š” ์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด `10px`์„ ์ถœ๋ ฅํ•ด์ฃผ๋Š”๋ฐ Firefox์—์„œ ๋นˆ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html run <style> @@ -272,32 +272,32 @@ There are other inconsistencies. As an example, some browsers (Chrome) show `10p </style> <script> let style = getComputedStyle(document.body); - alert(style.margin); // empty string in Firefox + alert(style.margin); // Firefox์—์„  ๋นˆ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. </script> ``` ```` -```smart header="Styles applied to `:visited` links are hidden!" -Visited links may be colored using `:visited` CSS pseudoclass. +```smart header="`:visited` ๋งํฌ ๊ด€๋ จ ์Šคํƒ€์ผ์€ ์ˆจ๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค." +๋ฐฉ๋ฌธํ•œ ์ ์ด ์žˆ๋Š” ๋งํฌ์—” `:visited`๋ผ๋Š” CSS ์˜์‚ฌ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์ƒ‰์„ ์ž…ํž ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles. +๊ทธ๋Ÿฐ๋ฐ `getComputedStyle`์„ ์‚ฌ์šฉํ•ด์„œ ์ด ์ƒ‰์„ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ƒ‰์„ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉด ์ž„์˜์˜ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ๋งํฌ๋ฅผ ๋ฐฉ๋ฌธํ–ˆ๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ `getComputedStyle`์„ ์‚ฌ์šฉํ•ด ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -JavaScript may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no sideway for an evil page to test if a link was visited and hence to break the privacy. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ๋Š” `:visited`์— ์ ์šฉ๋œ ์Šคํƒ€์ผ์„ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ CSS์—๋Š” `:visited`์— ๊ธฐํ•˜ํ•™์  ๋ณ€ํ™”๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ธˆ์ง€ํ•˜๋Š” ์ œ์•ฝ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ œ์•ฝ๋“ค์€ ์•…์˜๋ฅผ ๊ฐ€์ง„ ํŽ˜์ด์ง€๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ๋งํฌ๋ฅผ ๋ฐฉ๋ฌธํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๊ณ , ๋ฐฉ๋ฌธ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์‚ฌ์ƒํ™œ์„ ์นจํ•ดํ•  ๋งŒํ•œ ์–ด๋– ํ•œ ๊ฒƒ๋„ ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๋ ค๊ณ  ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ``` -## Summary +## ์š”์•ฝ -To manage classes, there are two DOM properties: +ํด๋ž˜์Šค๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” DOM ํ”„๋กœํผํ‹ฐ: -- `className` -- the string value, good to manage the whole set of classes. -- `classList` -- the object with methods `add/remove/toggle/contains`, good for individual classes. +- `className` -- ํด๋ž˜์Šค ์ „์ฒด๋ฅผ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๋กœ ํด๋ž˜์Šค ์ „์ฒด๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +- `classList` -- ํด๋ž˜์Šค ํ•˜๋‚˜๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. `add/remove/toggle/contains`๊ฐ€ ๊ตฌํ˜„๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ํด๋ž˜์Šค๋ฅผ ์กฐ์ž‘ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -To change the styles: +์Šคํƒ€์ผ ๋ณ€๊ฒฝ ๋ฐฉ๋ฒ•: -- The `style` property is an object with camelCased styles. Reading and writing to it has the same meaning as modifying individual properties in the `"style"` attribute. To see how to apply `important` and other rare stuff -- there's a list of methods at [MDN](mdn:api/CSSStyleDeclaration). +- `style` ํ”„๋กœํผํ‹ฐ -- ์นด๋ฉœ ํ‘œ๊ธฐ๋ฒ•์„ ์ด์šฉํ•ด ๋ณ€๊ฒฝํ•œ ์Šคํƒ€์ผ์ด ์žˆ๋Š” ๊ฐ์ฒด๋กœ, ์ด ๊ฐ์ฒด๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ์€ `"style"` ์†์„ฑ๊ณผ ๋Œ€์‘ํ•˜๋Š” ๊ฐœ๋ณ„ ํ”„๋กœํผํ‹ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `important` ๋“ฑ์˜ ๊ทœ์น™์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋ ค๋ฉด [MDN](mdn:api/CSSStyleDeclaration)์—์„œ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ดํŽด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -- The `style.cssText` property corresponds to the whole `"style"` attribute, the full string of styles. +- `style.cssText` ํ”„๋กœํผํ‹ฐ๋Š” `"style"` ์†์„ฑ ์ „์ฒด์— ๋Œ€์‘ํ•˜๋ฏ€๋กœ ์Šคํƒ€์ผ ์ „์ฒด์— ๋Œ€ํ•œ ๋ฌธ์ž์—ด์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. -To read the resolved styles (with respect to all classes, after all CSS is applied and final values are calculated): +์š”์†Œ์˜ ์Šคํƒ€์ผ ๊ฒฐ์ • ๊ฐ’์„ ์ฝ๋Š” ๋ฐฉ๋ฒ•: -- The `getComputedStyle(elem, [pseudo])` returns the style-like object with them. Read-only. +- ์Šคํƒ€์ผ ์ •๋ณด๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ `getComputedStyle(elem, [pseudo])`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ฝ๊ธฐ ์ „์šฉ์ž…๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md b/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md index be47cfd303..796039c2a1 100644 --- a/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md +++ b/2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md @@ -4,7 +4,7 @@ importance: 5 # What's the scroll from the bottom? -The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size from the bottom scroll (let's call it `scrollBottom`)? +The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size of the bottom scroll (let's call it `scrollBottom`)? Write the code that works for an arbitrary `elem`. diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html index ca9c4d579b..8f855ecfa0 100755 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html @@ -9,7 +9,7 @@ background-color: #00FF00; position: relative; } - + #ball { position: absolute; } @@ -20,7 +20,7 @@ <div id="field"> - <img src="https://js.cx/clipart/ball.svg" id="ball"> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + <img src="https://js.cx/clipart/ball.svg" height="40" width="40" id="ball"> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . </div> @@ -38,4 +38,4 @@ </body> -</html> \ No newline at end of file +</html> diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg index f5562f97a9..4ae90b1c71 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="233" height="156" viewBox="0 0 233 156"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="field.svg"><image id="Screen-Shot-2017-02-25-at-23.45.22" width="224" height="150" x="4" y="3" opacity=".7" xlink:href="data:image/png;base64,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"/><text id="(0,0)" fill="#AA2D0A" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="45" y="60">(0,0)</tspan></text><circle id="Oval" cx="15.5" cy="15.5" r="4.5" fill="#EE6B47"/><text id="clientWidth" fill="#AA2D0A" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="73" y="114">clientWidth</tspan></text><path id="Line-9" fill="#EE6B47" fill-rule="nonzero" d="M24.114 22.183l20.711 4.719-5.078 6.181 14.864 12.21-1.904 2.318-14.865-12.209-5.077 6.182-8.651-19.401z"/><path id="Line-10" fill="#EE6B47" fill-rule="nonzero" d="M197 118l19 9.5-19 9.5v-8H34v8l-19-9.5 19-9.5v8h163v-8z"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="233" height="156" viewBox="0 0 233 156"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="field.svg"><image id="Screen-Shot-2017-02-25-at-23.45.22" width="224" height="150" x="4" y="3" opacity=".7" xlink:href="data:image/png;base64,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"/><text id="(0,0)" fill="#A7333A" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="45" y="60">(0,0)</tspan></text><circle id="Oval" cx="15.5" cy="15.5" r="4.5" fill="#C06334"/><text id="clientWidth" fill="#A7333A" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="73" y="114">clientWidth</tspan></text><path id="Line-9" fill="#C06334" fill-rule="nonzero" d="M24.114 22.183l20.711 4.719-5.078 6.181 13.705 11.258 1.16.952-1.905 2.318-1.16-.952-13.704-11.258-5.078 6.183-8.651-19.401z"/><path id="Line-10" fill="#C06334" fill-rule="nonzero" d="M197 118l19 9.5-19 9.5v-8H34v8l-19-9.5 19-9.5v8h163v-8z"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md index c6fe6c3bba..afa1d8f501 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md @@ -24,17 +24,22 @@ ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px'; ``` -**Attention: the pitfall!** +Now the ball is finally centered. + +````warn header="Attention: the pitfall!" The code won't work reliably while `<img>` has no width/height: ```html <img src="ball.png" id="ball"> ``` +```` When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal `0` until the image finishes loading. -After the first load browser usually caches the image, and on next loads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`. That leads to wrong coordinates. +So the value of `ball.offsetWidth` will be `0` until the image loads. That leads to wrong coordinates in the code above. + +After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`. We should fix that by adding `width/height` to `<img>`: diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html index 9ebe6001e7..9f21e54212 100755 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html @@ -26,7 +26,7 @@ <script> - // ball.offsetWidth=0 before image loaded! + // ball.offsetWidth=0 before image loaded! // to fix: set width ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px' ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px' diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md index 57746d9217..f56e0858b7 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md @@ -10,7 +10,7 @@ Here's how the source document looks: What are coordinates of the field center? -Calculate them and use to place the ball into the center of the field: +Calculate them and use to place the ball into the center of the green field: [iframe src="solution" height=180] diff --git a/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/solution.md b/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/solution.md index 0a18bd86e1..f8425bff4d 100644 --- a/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/solution.md +++ b/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/solution.md @@ -1,6 +1,6 @@ -Differences: +๋‘˜์˜ ์ฐจ์ด์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. `clientWidth` is numeric, while `getComputedStyle(elem).width` returns a string with `px` at the end. -2. `getComputedStyle` may return non-numeric width like `"auto"` for an inline element. -3. `clientWidth` is the inner content area of the element plus paddings, while CSS width (with standard `box-sizing`) is the inner content area *without paddings*. -4. If there's a scrollbar and the browser reserves the space for it, some browser substract that space from CSS width (cause it's not available for content any more), and some do not. The `clientWidth` property is always the same: scrollbar size is substracted if reserved. +1. `clientWidth`๋Š” ์ˆซ์žํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ˜๋ฉด, `getComputedStyle(elem).width`๋Š” ๋์— `px`๊ฐ€ ๋ถ™์€ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +2. `getComputedStyle`์€ ์ธ๋ผ์ธ ์š”์†Œ์˜ ๋„ˆ๋น„๋ฅผ ๊ตฌํ•  ๋•Œ `"auto"`์™€ ๊ฐ™์€ ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +3. `clientWidth`๋Š” ์ฝ˜ํ…์ธ ์™€ ํŒจ๋”ฉ์„ ํฌํ•จํ•œ ์˜์—ญ์˜ ๋„ˆ๋น„๋ฅผ ๊ฐ€๋ฅดํ‚ค์ง€๋งŒ, (ํ‘œ์ค€ `box-sizing`๊ณผ ์—ฐ๊ด€๋œ) CSS `width`๋Š” *ํŒจ๋”ฉ์„ ์ œ์™ธํ•œ* ์ฝ˜ํ…์ธ  ์˜์—ญ์˜ ๋„ˆ๋น„๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +4. ํŽ˜์ด์ง€์— ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์žˆ๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์Šคํฌ๋กค๋ฐ” ์˜์—ญ์„ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ์—, ์–ด๋–ค ๋ธŒ๋ผ์šฐ์ €๋Š” CSS width๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋ฅผ ์ œ์™ธํ•˜๋Š” ๋ฐ˜๋ฉด(์Šคํฌ๋กค๋ฐ” ์˜์—ญ์€ ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ด์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ) ์–ด๋–ค ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋กค๋ฐ” ์˜์—ญ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. `clientWidth` ํ”„๋กœํผํ‹ฐ๋Š” ๋ธŒ๋ผ์šฐ์ € ์ข…๋ฅ˜์— ์ƒ๊ด€ ์—†์ด ํ•ญ์ƒ ๋™์ผํ•˜๊ฒŒ ์Šคํฌ๋กค๋ฐ” ์˜์—ญ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—” ์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋ฅผ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/task.md b/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/task.md index 5378c5915b..4ed6878f82 100644 --- a/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/task.md +++ b/2-ui/1-document/09-size-and-scroll/6-width-vs-clientwidth/task.md @@ -2,8 +2,8 @@ importance: 5 --- -# The difference: CSS width versus clientWidth +# CSS width์™€ clientWidth์˜ ์ฐจ์ด -What's the difference between `getComputedStyle(elem).width` and `elem.clientWidth`? +`getComputedStyle(elem).width`์™€ `elem.clientWidth`์˜ ์ฐจ์ด์ ์€ ๋ฌด์—‡์ผ๊นŒ์š”? -Give at least 3 differences. The more the better. +์ตœ์†Œ ์„ธ ๊ฐ€์ง€ ์ฐจ์ด์ ์„ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. ๋” ๋งŽ์„์ˆ˜๋ก ์ข‹์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index 7a3bf70da9..1bf3e861e3 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -1,16 +1,16 @@ -# Element size and scrolling +# ์š”์†Œ ์‚ฌ์ด์ฆˆ์™€ ์Šคํฌ๋กค -There are many JavaScript properties that allow us to read information about element width, height and other geometry features. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์š”์†Œ์˜ ๋„ˆ๋น„๋‚˜ ๋†’์ด ๊ฐ™์€ ๊ธฐํ•˜ ์ •๋ณด ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -We often need them when moving or positioning elements in JavaScript. +์ด๋Ÿฐ ํ”„๋กœํผํ‹ฐ๋Š” ์š”์†Œ๋ฅผ ์›€์ง์ด๊ฑฐ๋‚˜ ํŠน์ • ์ขŒํ‘œ์— ์œ„์น˜์‹œํ‚ฌ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Sample element +## ์ƒ˜ํ”Œ ์š”์†Œ -As a sample element to demonstrate properties we'll use the one given below: +ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒ˜ํ”Œ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ```html no-beautify <div id="example"> - ...Text... + ...ํ…์ŠคํŠธ... </div> <style> #example { @@ -23,49 +23,49 @@ As a sample element to demonstrate properties we'll use the one given below: </style> ``` -It has the border, padding and scrolling. The full set of features. There are no margins, as they are not the part of the element itself, and there are no special properties for them. +`example`์ด๋ผ๋Š” id๊ฐ€ ๋ถ™์€ ์ด ์š”์†Œ์— border์™€ padding ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ฃผ๊ณ , ์Šคํฌ๋กค๋ฐ”๋„ ์ƒ๊ธฐ๊ฒŒ ๋งŒ๋“ค์–ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‹ค์Šตํ•ด ๋ณด๊ธฐ ์ ์ ˆํ•œ ์กฐํ•ฉ์ด์ฃ . ์ฐธ๊ณ ๋กœ margin์€ ์š”์†Œ ์ž์ฒด์— ํฌํ•จ๋˜์ง€ ์•Š๊ณ , ๊ด€๋ จํ•œ ํŠน์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ”„๋กœํผํ‹ฐ๋„ ์—†์–ด์„œ CSS ํ”„๋กœํผํ‹ฐ์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. -The element looks like this: +์š”์†Œ์˜ ์ƒ๊น€์ƒˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](metric-css.svg) -You can [open the document in the sandbox](sandbox:metric). +[์ƒŒ๋“œ๋ฐ•์Šค](sandbox:metric)๋ฅผ ์—ด์–ด ์š”์†Œ๋ฅผ ์ง์ ‘ ํ™•์ธํ•ด ๋ณด์„ธ์š”. -```smart header="Mind the scrollbar" -The picture above demonstrates the most complex case when the element has a scrollbar. Some browsers (not all) reserve the space for it by taking it from the content (labeled as "content width" above). +```smart header="์Šคํฌ๋กค๋ฐ”๋ฅผ ์žŠ์ง€ ๋งˆ์„ธ์š”." +์š”์†Œ์— ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋ณต์žกํ•œ ์ƒํ™ฉ์ด ์ƒ๊น๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ๋Ÿฐ ๊ฑด ์•„๋‹ˆ์ง€๋งŒ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ฝ˜ํ…์ธ  ์˜์—ญ ๋„ˆ๋น„('content width'๋กœ ํ‘œ์‹œํ•œ ์˜์—ญ) ์ผ๋ถ€๋ฅผ ๋นŒ๋ ค ์Šคํฌ๋กค๋ฐ”๋ฅผ ์œ„์น˜์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -So, without scrollbar the content width would be `300px`, but if the scrollbar is `16px` wide (the width may vary between devices and browsers) then only `300 - 16 = 284px` remains, and we should take it into account. That's why examples from this chapter assume that there's a scrollbar. Without it, some calculations are simpler. +์ƒ˜ํ”Œ ์˜ˆ์‹œ์—์„œ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด ์ฝ˜ํ…์ธ  ์˜์—ญ ๋„ˆ๋น„๋Š” `300px`์ด์—ˆ์„ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์Šคํฌ๋กค๋ฐ”๊ฐ€ `16px`์„ ์ฐจ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ˜ํ…์ธ  ์˜์—ญ ๋„ˆ๋น„๊ฐ€ `284px`(300 - 16)์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋Š” ๋ธŒ๋ผ์šฐ์ €๋‚˜ ๋””๋ฐ”์ด์Šค๋งˆ๋‹ค ๋‹ค๋ฆ…๋‹ˆ๋‹ค). ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด ๊ณ„์‚ฐ์ด ๋งค์šฐ ์‰ฌ์› ๊ฒ ์ง€๋งŒ, ์—ฐ์Šต์„ ์œ„ํ•ด ์ƒ˜ํ”Œ ์š”์†Œ์— ์Šคํฌ๋กค๋ฐ”๋ฅผ ์ผ๋ถ€๋Ÿฌ ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค. ์š”์†Œ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋Š” ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„์„ ํ•ญ์ƒ ์—ผ๋‘์— ๋‘์„ธ์š”. ``` -```smart header="The `padding-bottom` area may be filled with text" -Usually paddings are shown empty on our illustrations, but if there's a lot of text in the element and it overflows, then browsers show the "overflowing" text at `padding-bottom`, that's normal. +```smart header="`padding-bottom` ์˜์—ญ์œผ๋กœ ํ…์ŠคํŠธ๊ฐ€ ๋„˜์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." +๊ทธ๋ฆผ์—์„  ํŒจ๋”ฉ์— ์•„๋ฌด๊ฒƒ๋„ ๋ณด์ด์ง€ ์•Š๊ฒŒ ํ•ด๋‘์—ˆ๊ธด ํ•˜์ง€๋งŒ ์š”์†Œ ๋‚ด ํ…์ŠคํŠธ๊ฐ€ ๊ธธ์–ด ๋„˜์น˜๊ฒŒ ๋  ๊ฒฝ์šฐ์—” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด ํ…์ŠคํŠธ๋“ค์„ `padding-bottom`์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ •์ƒ์ ์ธ ๋™์ž‘์ž…๋‹ˆ๋‹ค. ``` -## Geometry +## ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ -Here's the overall picture with geometry properties: +๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ(geometry property)๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](metric-all.svg) -Values of these properties are technically numbers, but these numbers are "of pixels", so these are pixel measurements. +๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์€ ์ˆซ์ž์ธ๋ฐ ๊ทธ ๋‹จ์œ„๋Š” 'ํ”ฝ์…€'์ž…๋‹ˆ๋‹ค. ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋Š” ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์ธก์ •๋œ๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -Let's start exploring the properties starting from the outside of the element. +์ด์ œ ์š”์†Œ ์ œ์ผ ๋ฐ–๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์ฐจ๊ทผ์ฐจ๊ทผ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. -## offsetParent, offsetLeft/Top +## offsetParent์™€ offsetLeft, offsetTop -These properties are rarely needed, but still they are the "most outer" geometry properties, so we'll start with them. +์ž˜ ์“ฐ์ด๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ฐ€์žฅ ๋ฐ”๊นฅ์— ์žˆ๋Š” ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ์ด๋ฏ€๋กœ offsetParent์™€ offsetLeft, offsetTop๋ถ€ํ„ฐ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(offset์€ ์š”์†Œ๊ฐ€ ํ™”๋ฉด์—์„œ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ ์ „์ฒด ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ, ์š”์†Œ์˜ ๋„ˆ๋น„์™€ ๋†’์ด์— ํŒจ๋”ฉ, ์Šคํฌ๋กค๋ฐ”, ํ…Œ๋‘๋ฆฌ๋ฅผ ํ•ฉ์นœ ํฌ๊ธฐ์ด๋ฉฐ ๋งˆ์ง„์€ ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค - ์˜ฎ๊ธด์ด). -The `offsetParent` is the nearest ancestor, that browser uses for calculating coordinates during rendering. +`offsetParent` ํ”„๋กœํผํ‹ฐ๋Š” ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, ์ขŒํ‘œ ๊ณ„์‚ฐ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ(the closest positioned ancestor element)์˜ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -That's the nearest ancestor, that satisfies following conditions: +CSS `position` ํ”„๋กœํผํ‹ฐ๊ฐ€ ์„ค์ •๋˜์–ด์žˆ๋Š” ์กฐ์ƒ ์š”์†Œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ `<td>`๋‚˜ `<th>`, ํ˜น์€ `<table>`, ์•„๋‹ˆ๋ฉด `<body>`๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— `offsetParent`์— ์˜ํ•ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ๋Š” ์•„๋ž˜ ์…‹ ์ค‘ ํ•˜๋‚˜์— ์†ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`), -2. or `<td>`, `<th>`, `<table>`, -2. or `<body>`. +1. CSS `position` ํ”„๋กœํผํ‹ฐ๊ฐ€ `absolute`๋‚˜ `relative`, `fixed`, `sticky`์ธ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ +2. `<td>`๋‚˜ `<th>`, ํ˜น์€ `<table>` +3. `<body>` -Properties `offsetLeft/offsetTop` provide x/y coordinates relative to `offsetParent` upper-left corner. +`offsetLeft`์™€ `offsetTop` ํ”„๋กœํผํ‹ฐ๋Š” `offsetParent`๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ์š”์†Œ๊ฐ€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ, ์•„๋ž˜์ชฝ์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -In the example below the inner `<div>` has `<main>` as `offsetParent` and `offsetLeft/offsetTop` shifts from its upper-left corner (`180`): +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์•ˆ์ชฝ์— ์žˆ๋Š” `<div>`์˜ `offsetParent`๋Š” `<main>`์ด๊ณ  `offsetLeft`์™€ `offsetTop`์€ ๊ฐ๊ฐ `180`์ž…๋‹ˆ๋‹ค. ```html run height=10 <main style="position: relative" id="main"> @@ -75,40 +75,40 @@ In the example below the inner `<div>` has `<main>` as `offsetParent` and `offse </main> <script> alert(example.offsetParent.id); // main - alert(example.offsetLeft); // 180 (note: a number, not a string "180px") + alert(example.offsetLeft); // 180 (์ฃผ์˜: ๋ฌธ์ž์—ด '180px'์ด ์•„๋‹Œ ์ˆซ์ž 180์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.) alert(example.offsetTop); // 180 </script> ``` ![](metric-offset-parent.svg) -There are several occasions when `offsetParent` is `null`: +๋‹ค์Œ ๊ฐ™์€ ๊ฒฝ์šฐ์—” `offsetParent`๊ฐ€ `null`์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -1. For not shown elements (`display:none` or not in the document). -2. For `<body>` and `<html>`. -3. For elements with `position:fixed`. +1. ํ™”๋ฉด์— ๋ณด์ด์ง€ ์•Š๋Š” ์š”์†Œ(CSS `display` ํ”„๋กœํผํ‹ฐ๊ฐ€ `none`์ด๊ฑฐ๋‚˜ ๋ฌธ์„œ ๋‚ด์— ์žˆ์ง€ ์•Š์€ ์š”์†Œ) +2. `<body>`์™€ `<html>` +3. `position` ํ”„๋กœํผํ‹ฐ๊ฐ€ `fixed`์ธ ์š”์†Œ -## offsetWidth/Height +## offsetWidth์™€ offsetHeight -Now let's move on to the element itself. +์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์š”์†Œ ์ž์ฒด์— ์ง‘์ค‘ํ•ด ๋ด…์‹œ๋‹ค. -These two properties are the simplest ones. They provide the "outer" width/height of the element. Or, in other words, its full size including borders. +`offsetWidth`์™€ `offsetHeight`๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ๊ฐ ์š”์†Œ '๊ฐ€์žฅ ๋ฐ”๊นฅ ๋ถ€๋ถ„(outer)'์ด ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„์™€ ๋†’์ด ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ…Œ๋‘๋ฆฌ๋ฅผ ํฌํ•จํ•œ ์š”์†Œ '์ „์ฒด'์˜ ์‚ฌ์ด์ฆˆ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ![](metric-offset-width-height.svg) -For our sample element: +์ƒ˜ํ”Œ ์š”์†Œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ `offsetWidth`์™€ `offsetHeight`๋ฅผ ๊ณ„์‚ฐํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `offsetWidth = 390` -- the outer width, can be calculated as inner CSS-width (`300px`) plus paddings (`2 * 20px`) and borders (`2 * 25px`). -- `offsetHeight = 290` -- the outer height. +- `offsetWidth = 390` -- CSS width ํ”„๋กœํผํ‹ฐ(`300px`)๋ฅผ ์‚ฌ์šฉํ•ด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ”๊นฅ ๋„ˆ๋น„์— ํŒจ๋”ฉ(`2 * 20px`)๊ณผ ํ…Œ๋‘๋ฆฌ(`2 * 25px`) ๋„ˆ๋น„๋ฅผ ๋”ํ•œ ๊ฐ’ +- `offsetHeight = 290` -- ๋ฐ”๊นฅ ๋†’์ด -````smart header="Geometry properties are zero/null for elements that are not displayed" -Geometry properties are calculated only for displayed elements. +````smart header="ํ™”๋ฉด์— ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ์š”์†Œ์˜ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ 0 ๋˜๋Š” null์ž…๋‹ˆ๋‹ค." +๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋Š” ๋ณด์ด๋Š” ์š”์†Œ(displayed element)๋ฅผ ๋Œ€์ƒ์œผ๋กœ๋งŒ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. -If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` if that's `offsetParent`). +๋”ฐ๋ผ์„œ ์š”์†Œ(ํ˜น์€ ์ด ์š”์†Œ์˜ ์กฐ์ƒ ์š”์†Œ ์ค‘ ์–ด๋–ค ๊ฒƒ์ด๋“ )์˜ CSS `display` ํ”„๋กœํผํ‹ฐ๊ฐ€ `none`์ด๊ฑฐ๋‚˜ ๋ฌธ์„œ ๋‚ด์— ํ•ด๋‹น ์š”์†Œ๊ฐ€ ์—†์œผ๋ฉด ๋ชจ๋“  ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 0์ด ๋ฉ๋‹ˆ๋‹ค(`offsetParent` ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์€ `null`). -For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or it's ancestor) has `display:none`. +์š”์†Œ๋ฅผ ๋งŒ๋“ค๊ธด ํ–ˆ์ง€๋งŒ ์•„์ง ๋ฌธ์„œ์— ์‚ฝ์ž…ํ•˜๊ธฐ ์ „์ด๋ผ๋˜๊ฐ€, ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“  ์š”์†Œ์˜ `display` ํ”„๋กœํผํ‹ฐ๊ฐ€ `none`์ด๋ฉด ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ 0, `offsetParent` ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์€ `null`์ด ๋˜๋Š” ๊ฒƒ์ด์ฃ . -We can use this to check if an element is hidden, like this: +์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•˜๋ฉด ์š”์†Œ์˜ ์ˆจ๊น€ ์ƒํƒœ ์—ฌ๋ถ€๋ฅผ ์•„๋ž˜ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js function isHidden(elem) { @@ -116,125 +116,128 @@ function isHidden(elem) { } ``` -Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes (like an empty `<div>`). +์ฐธ๊ณ ๋กœ `isHidden`์€ ์š”์†Œ๊ฐ€ ํ™”๋ฉด์— ์žˆ๊ธด ํ•˜์ง€๋งŒ ์‚ฌ์ด์ฆˆ๊ฐ€ 0์ผ ๋•Œ(๋น„์–ด์žˆ๋Š” `<div>` ๋“ฑ)๋„ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```` -## clientTop/Left +## clientTop๊ณผ clientLeft -Inside the element we have the borders. +ํ…Œ๋‘๋ฆฌ(border)๋Š” ์š”์†Œ ๋‚ด์— ์žˆ์Šต๋‹ˆ๋‹ค. -To measure them, there are properties `clientTop` and `clientLeft`. +`clientTop`๊ณผ `clientLeft`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜๋ฅผ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In our example: +์ƒ˜ํ”Œ ์˜ˆ์‹œ์—์„œ ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜๋ฅผ ๊ณ„์‚ฐํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `clientLeft = 25` -- left border width -- `clientTop = 25` -- top border width +- `clientLeft = 25` -- ์™ผ์ชฝ ํ…Œ๋‘๋ฆฌ ๋„ˆ๋น„ +- `clientTop = 25` -- ์œ„์ชฝ ํ…Œ๋‘๋ฆฌ ๋†’์ด ![](metric-client-left-top.svg) -...But to be precise -- these properties are not border width/height, but rather relative coordinates of the inner side from the outer side. +๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค `clientTop`๊ณผ `clientLeft` ํ”„๋กœํผํ‹ฐ๋Š” ํ…Œ๋‘๋ฆฌ ๋†’์ด, ๋„ˆ๋น„์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ๋Š” ํ…Œ๋‘๋ฆฌ ๋ฐ”๊นฅ์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ ํ…Œ๋‘๋ฆฌ ์•ˆ ์ƒ๋Œ€ ์ขŒํ‘œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -What's the difference? +์กฐ๊ธˆ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -It becomes visible when the document is right-to-left (the operating system is in Arabic or Hebrew languages). The scrollbar is then not on the right, but on the left, and then `clientLeft` also includes the scrollbar width. +`clientTop`๊ณผ `clientLeft`์˜ ์ฐจ์ด๋Š” ์•„๋ž์–ด๋‚˜ ํžˆ๋ธŒ๋ฆฌ์–ด์ฒ˜๋Ÿผ ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ ๊ธ€์ด ์ „๊ฐœ๋˜๋Š” ์–ธ์–ด์ผ ๋•Œ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. ์•„๋ž์–ด๊ฐ€ ์„ธํŒ…๋œ ๋ธŒ๋ผ์šฐ์ €์—์„  ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์˜ค๋ฅธ์ชฝ์ด ์•„๋‹Œ ์™ผ์ชฝ์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋˜๋Š”๋ฐ, ๊ทธ๋Ÿผ `clientLeft`์— ์Šคํฌ๋กค๋ฐ”์˜ ๋„ˆ๋น„๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. -In that case, `clientLeft` would be not `25`, but with the scrollbar width `25 + 16 = 41`. +`clientLeft`๊ฐ€ `25`๊ฐ€ ์•„๋‹Œ ์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋ฅผ ํฌํ•จํ•œ `41(25 + 16)`์ด ๋˜๋Š” ๊ฑฐ์ฃ . -Here's the example in hebrew: +ํžˆ๋ธŒ๋ฆฌ์–ด๋ฅผ ์˜ˆ์‹œ๋กœ ์ง์ ‘ ์‚ดํŽด๋ด…์‹œ๋‹ค. ![](metric-client-left-top-rtl.svg) -## clientWidth/Height +## clientWidth์™€ clientHeight -These properties provide the size of the area inside the element borders. +clientWidth์™€ clientHeight ํ”„๋กœํผํ‹ฐ๋Š” ํ…Œ๋‘๋ฆฌ ์•ˆ ์˜์—ญ์˜ ์‚ฌ์ด์ฆˆ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -They include the content width together with paddings, but without the scrollbar: +ํ…Œ๋‘๋ฆฌ ์•ˆ์—๋Š” ์ฝ˜ํ…์ธ  ๋„ˆ๋น„์™€ ํŒจ๋”ฉ์ด ํฌํ•จ๋˜๋Š”๋ฐ, ์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ![](metric-client-width-height.svg) -On the picture above let's first consider `clientHeight`. +๊ทธ๋ฆผ์—์„œ `clientHeight`๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„์„ ๋จผ์ € ์‚ดํŽด๋ด…์‹œ๋‹ค. -There's no horizontal scrollbar, so it's exactly the sum of what's inside the borders: CSS-height `200px` plus top and bottom paddings (`2 * 20px`) total `240px`. +๊ฐ€๋กœ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— `clientHeight`๋Š” ํ…Œ๋‘๋ฆฌ ์•ˆ ์˜์—ญ ์ „์ฒด๋ฅผ ๋”ํ•œ ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค. ๋†’์ด `200px`์— ์œ„, ์•„๋ž˜ ํŒจ๋”ฉ(`2 * 20px`)์„ ๋”ํ•œ ๊ฐ’์ธ `240px`์ด ๋˜์ฃ . -Now `clientWidth` -- here the content width is not `300px`, but `284px`, because `16px` are occupied by the scrollbar. So the sum is `284px` plus left and right paddings, total `324px`. +์ด์ œ `clientWidth`๋ฅผ ๊ณ„์‚ฐํ•ด ๋ด…์‹œ๋‹ค. `clientWidth`๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ์ฃผ์˜ํ•  ์ ์€ ์„ธ๋กœ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„ `16px` ๋•Œ๋ฌธ์— ์ฝ˜ํ…์ธ  ๋„ˆ๋น„๋Š” `300px`์ด ์•„๋‹Œ `284px`์ด ๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `clientWidth`๋Š” ์ฝ˜ํ…์ธ  ๋„ˆ๋น„ `284px`์— ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ํŒจ๋”ฉ(`2 * 20px`)์„ ๋”ํ•œ ๊ฐ’์ธ `324px`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -**If there are no paddings, then `clientWidth/Height` is exactly the content area, inside the borders and the scrollbar (if any).** +**ํŒจ๋”ฉ์ด ์—†์—ˆ๋‹ค๋ฉด `clientWidth`์™€ `clientHeight`๋Š” ํ…Œ๋‘๋ฆฌ์™€ ์Šคํฌ๋กค๋ฐ” ์•ˆ์ชฝ์— ์žˆ๋Š” ์ฝ˜ํ…์ธ  ์˜์—ญ์˜ ๋„ˆ๋น„, ๋†’์ด์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค.** ![](metric-client-width-nopadding.svg) -So when there's no padding we can use `clientWidth/clientHeight` to get the content area size. +๋”ฐ๋ผ์„œ ํŒจ๋”ฉ์ด ์—†๋Š” ๊ฒฝ์šฐ์—” `clientWidth`์™€ `clientHeight`๋ฅผ ์‚ฌ์šฉํ•ด ์ฝ˜ํ…์ธ  ์˜์—ญ ํฌ๊ธฐ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## scrollWidth/Height +## scrollWidth์™€ scrollHeight -These properties are like `clientWidth/clientHeight`, but they also include the scrolled out (hidden) parts: +`scrollWidth`์™€ `scrollHeight` ํ”„๋กœํผํ‹ฐ๋Š” `clientWidth`์™€ `clientHeight` ์œ ์‚ฌํ•œ๋ฐ, ์Šคํฌ๋กค๋ฐ”์— ์˜ํ•ด ๊ฐ์ถฐ์ง„ ์˜์—ญ๋„ ํฌํ•จํ•œ๋‹ค๋Š” ์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ![](metric-scroll-width-height.svg) -On the picture above: +๊ทธ๋ฆผ์„ ์‚ดํŽด๋ด…์‹œ๋‹ค. -- `scrollHeight = 723` -- is the full inner height of the content area including the scrolled out parts. -- `scrollWidth = 324` -- is the full inner width, here we have no horizontal scroll, so it equals `clientWidth`. +- `scrollWidth = 324` -- ์ˆ˜ํ‰ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ชฝ ์˜์—ญ ์ „์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” `clientWidth`์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. +- `scrollWidth = 324` -- ์Šคํฌ๋กค ๋•Œ๋ฌธ์— ๊ฐ€๋ ค์ง„ ์˜์—ญ์„ ํฌํ•จํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ ๋†’์ด ์ „์ฒด -We can use these properties to expand the element wide to its full width/height. +- `scrollHeight = 723` -- ์„ธ๋กœ ์Šคํฌ๋กค๋ฐ”์— ๊ฐ€๋ ค์ง„ ๋ถ€๋ถ„์„ ํฌํ•จํ•˜๋Š” ์ฝ˜ํ…์ธ  ์˜์—ญ ์•ˆ์ชฝ ์ „์ฒด์˜ ๋†’์ด +- `scrollWidth = 324` -- ์ฝ˜ํ…์ธ  ์˜์—ญ ์•ˆ์ชฝ ์ „์ฒด์˜ ๋„ˆ๋น„. ๊ทธ๋ฆผ์€ ๊ฐ€๋กœ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— `clientWidth`์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -Like this: +`scrollWidth`์™€ `scrollHeight`๋Š” ์š”์†Œ ํฌ๊ธฐ๋ฅผ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋งŒํผ ๋Š˜๋ฆฌ๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์˜ˆ์‹œ: ```js -// expand the element to the full content height +// ์ฝ˜ํ…์ธ ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋†’์ด๋งŒํผ ์š”์†Œ ๋†’์ด๋ฅผ ๋Š˜๋ฆผ element.style.height = `${element.scrollHeight}px`; ``` ```online -Click the button to expand the element: +๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ง์ ‘ ์š”์†Œ ํฌ๊ธฐ๋ฅผ ํ™•์žฅํ•ด ๋ด…์‹œ๋‹ค. <div id="element" style="width:300px;height:200px; padding: 0;overflow: auto; border:1px solid black;">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div> <button style="padding:0" onclick="element.style.height = `${element.scrollHeight}px`">element.style.height = `${element.scrollHeight}px`</button> ``` -## scrollLeft/scrollTop +## scrollLeft์™€ scrollTop -Properties `scrollLeft/scrollTop` are the width/height of the hidden, scrolled out part of the element. +`scrollLeft`์™€ `scrollTop`์€ ๊ฐ€๋กœ ์Šคํฌ๋กค์ด ์˜ค๋ฅธ์ชฝ, ์„ธ๋กœ ์Šคํฌ๋กค์ด ์•„๋ž˜๋กœ ์›€์ง์ž„์— ๋”ฐ๋ผ ๊ฐ€๋ ค์ง„ ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -On the picture below we can see `scrollHeight` and `scrollTop` for a block with a vertical scroll. +์„ธ๋กœ ์Šคํฌ๋กค๋ฐ”๋ฅผ ์•„๋ž˜๋กœ ์กฐ๊ธˆ ๋‚ด๋ฆฐ ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ •ํ•œ ๊ทธ๋ฆผ์„ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ด…์‹œ๋‹ค. `scrollHeight`์—์„œ `scrollTop`์ด ์–ผ๋งˆ๋งŒํผ์˜ ์˜์—ญ์„ ์ฐจ์ง€ํ•˜๋Š”์ง€๋ฅผ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ![](metric-scroll-top.svg) -In other words, `scrollTop` is "how much is scrolled up". +์ด๋ ‡๊ฒŒ `scrollTop`์€ '์„ธ๋กœ ์Šคํฌ๋กค๋ฐ”์— ์˜ํ•ด ๊ฐ€๋ ค์ ธ ๋ณด์ด์ง€ ์•Š๋Š”' ์œ„์ชฝ ์ฝ˜ํ…์ธ ์˜ ๋†’์ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -````smart header="`scrollLeft/scrollTop` can be modified" -Most of the geometry properties here are read-only, but `scrollLeft/scrollTop` can be changed, and the browser will scroll the element. +````smart header="`scrollLeft`์™€ `scrollTop`์€ ์ˆ˜์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค." +๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ ๋Œ€๋ถ€๋ถ„์€ ์ฝ๊ธฐ์ „์šฉ์ด์ง€๋งŒ `scrollLeft`์™€ `scrollTop`์€ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์š”์†Œ ๋‚ด ์Šคํฌ๋กค์ด ์›€์ง์ž…๋‹ˆ๋‹ค. ```online -If you click the element below, the code `elem.scrollTop += 10` executes. That makes the element content scroll `10px` down. +์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์Šคํฌ๋กค๋ฐ”๊ฐ€ `10px` ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ€๋„๋ก `elem.scrollTop += 10`์„ ์Šคํฌ๋ฆฝํŠธ์— ์ถ”๊ฐ€ํ•ด ๋†“์•˜์Šต๋‹ˆ๋‹ค. -<div onclick="this.scrollTop+=10" style="cursor:pointer;border:1px solid black;width:100px;height:80px;overflow:auto">Click<br>Me<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9</div> +<div onclick="this.scrollTop+=10" style="cursor:pointer;border:1px solid black;width:100px;height:80px;overflow:auto">์—ฌ๊ธฐ๋ฅผ<br>ํด๋ฆญ<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9</div> ``` -Setting `scrollTop` to `0` or `Infinity` will make the element scroll to the very top/bottom respectively. +์ด๋Ÿฐ ํŠน์ง•์„ ์ด์šฉํ•˜๋ฉด `scrollTop`์„ `0`์ด๋‚˜ `1e9`๊ฐ™์€ ์•„์ฃผ ํฐ ์ˆซ์ž๋กœ ์„ค์ •ํ•ด ์Šคํฌ๋กค๋ฐ”๋ฅผ ์ตœ์ƒ๋‹จ์ด๋‚˜ ์ตœํ•˜๋‹จ์œผ๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```` -## Don't take width/height from CSS +## CSS๋ฅผ ์‚ฌ์šฉํ•ด ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์–ป์ง€ ๋งˆ์„ธ์š” -We've just covered geometry properties of DOM elements, that can be used to get widths, heights and calculate distances. +์ง€๊ธˆ๊นŒ์ง€ ์š”์†Œ ๋„ˆ๋น„์™€ ๋†’์ด, ์š”์†Œ ํฌ์ง€์…”๋‹ ๊ด€๋ จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. -But as we know from the chapter <info:styles-and-classes>, we can read CSS-height and width using `getComputedStyle`. +๊ทธ๋Ÿฐ๋ฐ ์šฐ๋ฆฌ๋Š” <info:styles-and-classes> ์ฑ•ํ„ฐ์—์„œ `getComputedStyle`๋ฅผ ์‚ฌ์šฉํ•ด CSS๊ฐ€ ์ ์šฉ๋œ ์š”์†Œ์˜ ๋†’์ด์™€ ๋„ˆ๋น„๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋ณธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -So why not to read the width of an element with `getComputedStyle`, like this? +๊ทธ๋ ‡๋‹ค๋ฉด ์™œ `getComputedStyle`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์–ป์ง€ ๋ง๋ผ๊ณ  ํ•˜๋Š” ๊ฑธ๊นŒ์š”? ```js run let elem = document.body; -alert( getComputedStyle(elem).width ); // show CSS width for elem +alert( getComputedStyle(elem).width ); // CSS๊ฐ€ ์ ์šฉ๋œ elem์˜ ๋„ˆ๋น„ ``` -Why should we use geometry properties instead? There are two reasons: +`getComputedStyle`๊ฐ€ ์•„๋‹Œ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋„ˆ๋น„์™€ ๋†’์ด ์ •๋ณด๋ฅผ ์–ป์–ด์•ผ ํ•˜๋Š” ๋ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -1. First, CSS `width/height` depend on another property: `box-sizing` that defines "what is" CSS width and height. A change in `box-sizing` for CSS purposes may break such JavaScript. -2. Second, CSS `width/height` may be `auto`, for instance for an inline element: +1. CSS `width`์™€ `height`๋Š” ๋‹ค๋ฅธ CSS ํ”„๋กœํผํ‹ฐ์˜ ์˜ํ–ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์š”์†Œ์˜ ๋„ˆ๋น„์™€ ๋†’์ด ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•์„ '์ง€์ •'ํ•˜๋Š” `box-sizing`์ด ์ด๋Ÿฐ ํ”„๋กœํผํ‹ฐ์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ด์ฃ . `box-sizing`์„ ๋ณ€๊ฒฝํ•˜๋ฉด `getComputedStyle`๋กœ ๊ตฌํ•œ ๊ฐ’์ด ๋ถ€์ •ํ™• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +2. CSS `width`์™€ `height`๋Š” `auto`์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ผ์ธ ์š”์†Œ(inline element)๊ฐ€ ์ด๋Ÿฐ ๊ฒฝ์šฐ์— ์†ํ•ฉ๋‹ˆ๋‹ค. ```html run - <span id="elem">Hello!</span> + <span id="elem">์•ˆ๋…•ํ•˜์„ธ์š”!</span> <script> *!* @@ -243,34 +246,34 @@ Why should we use geometry properties instead? There are two reasons: </script> ``` - From the CSS standpoint, `width:auto` is perfectly normal, but in JavaScript we need an exact size in `px` that we can use in calculations. So here CSS width is useless at all. + CSS ๊ด€์ ์—์„œ ๋ณด๋ฉด `width:auto`๋Š” ์ „ํ˜€ ์ด์ƒํ•  ๊ฒŒ ์—†์–ด ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž…์žฅ์—์„  ์ •ํ™•ํ•œ `px`๊ฐ’์ด ์žˆ์–ด์•ผ ๊ณ„์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— auto๋ผ๋Š” ๊ฐ’์€ ์“ธ๋ชจ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -And there's one more reason: a scrollbar. Sometimes the code that works fine without a scrollbar starts to bug with it, because a scrollbar takes the space from the content in some browsers. So the real width available for the content is *less* than CSS width. And `clientWidth/clientHeight` take that into account. +๋‹ค๋ฅธ ํ•œ ๊ฐ€์ง€ ์ด์œ ๋Š” ์Šคํฌ๋กค๋ฐ”๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์—†์œผ๋ฉด ์ •์ƒ ๋™์ž‘ํ•˜๋Š”๋ฐ, ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ƒ๊ธฐ๋ฉด ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ผ์€ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฝ˜ํ…์ธ  ์˜์—ญ์„ ์ฐจ์ง€ํ•˜๋Š” ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค ๋ธŒ๋ผ์šฐ์ €์—์„  ์ฝ˜ํ…์ธ ๊ฐ€ ์‹ค์ œ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ์ด CSS๋กœ ์„ค์ •ํ•œ ๋„ˆ๋น„๋ณด๋‹ค *์ข์€๋ฐ*, `clientWidth`์™€ `clientHeight`๋Š” ์ด๋ฅผ ๊ณ ๋ คํ•ด ํด๋ผ์ด์–ธํŠธ ์š”์†Œ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. -...But with `getComputedStyle(elem).width` the situation is different. Some browsers (e.g. Chrome) return the real inner width, minus the scrollbar, and some of them (e.g. Firefox) -- CSS width (ignore the scrollbar). Such cross-browser differences is the reason not to use `getComputedStyle`, but rather rely on geometry properties. +๊ทธ๋Ÿฐ๋ฐ `getComputedStyle(elem).width`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒํ™ฉ์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. Chrome ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋กค๋ฐ” ๋„ˆ๋น„๋ฅผ ์ œ์™ธํ•œ ์ง„์งœ ๋‚ด๋ถ€ ๋„ˆ๋น„๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ Firefox ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋กค๋ฐ”๋ฅผ ๋ฌด์‹œํ•˜๊ณ  CSS๋กœ ์„ค์ •ํ•œ ๋„ˆ๋น„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ„ ์ฐจ์ด ๋•Œ๋ฌธ์— `getComputedStyle`์ด ์•„๋‹Œ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```online -If your browser reserves the space for a scrollbar (most browsers for Windows do), then you can test it below. +์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ์„ ๋”ฐ๋กœ ๋‘๋Š” ๋ธŒ๋ผ์šฐ์ €(Windows์—์„œ ๋Œ์•„๊ฐ€๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €)์—์„œ ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 300px์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฐ’์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [iframe src="cssWidthScroll" link border=1] -The element with text has CSS `width:300px`. +ํ…์ŠคํŠธ๊ฐ€ ๋“ค์–ด์žˆ๋Š” ์œ„ ์š”์†Œ์˜ CSS์—” `width:300px`๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค. -On a Desktop Windows OS, Firefox, Chrome, Edge all reserve the space for the scrollbar. But Firefox shows `300px`, while Chrome and Edge show less. That's because Firefox returns the CSS width and other browsers return the "real" width. +Windows๊ฐ€ ์„ค์น˜๋œ ๋ฐ์Šคํฌํ†ฑ PC์˜ Firefox, Chrome, Edge ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ชจ๋‘ ์Šคํฌ๋กค๋ฐ” ์˜์—ญ์„ ๋”ฐ๋กœ ๋–ผ์–ด๋†“์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ Windows ์ด์™ธ์˜ OS๊ฐ€ ์„ค์น˜๋œ PC์˜ Firefox์—์„œ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด `300px`์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ €๋“ค์€ '์ง„์งœ' ๋„ˆ๋น„๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ฐ˜๋ฉด Firefox๋Š” CSS๋กœ ์„ค์ •ํ•œ ๋„ˆ๋น„๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ``` -Please note that the described difference is only about reading `getComputedStyle(...).width` from JavaScript, visually everything is correct. +`getComputedStyle`๊ณผ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ์˜ ์ฐจ์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด `getComputedStyle(...).width`๋กœ ๊ฐ’์„ ์–ป๊ณ ์ž ํ•  ๋•Œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ˆˆ์œผ๋กœ ๋ดค์„ ๋• ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋‹ˆ ์ด ์ ์— ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -Elements have the following geometry properties: +์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- `offsetParent` -- is the nearest positioned ancestor or `td`, `th`, `table`, `body`. -- `offsetLeft/offsetTop` -- coordinates relative to the upper-left edge of `offsetParent`. -- `offsetWidth/offsetHeight` -- "outer" width/height of an element including borders. -- `clientLeft/clientTop` -- the distance from the upper-left outer corner the inner corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too. -- `clientWidth/clientHeight` -- the width/height of the content including paddings, but without the scrollbar. -- `scrollWidth/scrollHeight` -- the width/height of the content, just like `clientWidth/clientHeight`, but also include scrolled-out, invisible part of the element. -- `scrollLeft/scrollTop` -- width/height of the scrolled out upper part of the element, starting from its upper-left corner. +- `offsetParent` -- ์œ„์น˜ ๊ณ„์‚ฐ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ ์š”์†Œ๋‚˜ `td`, `th`, `table`, `body` +- `offsetLeft`์™€ `offsetTop` -- `offsetParent` ๊ธฐ์ค€์œผ๋กœ ์š”์†Œ๊ฐ€ ๊ฐ๊ฐ ์˜ค๋ฅธ์ชฝ, ์•„๋ž˜์ชฝ์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’ +- `offsetWidth`์™€ `offsetHeight` -- ํ…Œ๋‘๋ฆฌ๋ฅผ ํฌํ•จ ์š”์†Œ '์ „์ฒด'๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„์™€ ๋†’์ด +- `clientLeft`์™€ `clientTop` -- ์š”์†Œ ์ œ์ผ ๋ฐ–์„ ๊ฐ์‹ธ๋Š” ์˜์—ญ๊ณผ ์š”์†Œ ์•ˆ(์ฝ˜ํ…์ธ  + ํŒจ๋”ฉ)์„ ๊ฐ์‹ธ๋Š” ์˜์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋ƒ„. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์™ผ์ชฝ, ์œ„์ชฝ ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜์™€ ์ผ์น˜ํ•˜์ง€๋งŒ, ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ ๊ธ€์„ ์“ฐ๋Š” ์–ธ์–ด๊ฐ€ ์„ธํŒ…๋œ OS์—์„  `clientLeft`์— ์Šคํฌ๋กค๋ฐ” ๋‘๊ป˜๊ฐ€ ํฌํ•จ๋จ +- `clientWidth`์™€ `clientHeight` -- ์ฝ˜ํ…์ธ ์™€ ํŒจ๋”ฉ์„ ํฌํ•จํ•œ ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋กœ, ์Šคํฌ๋กค๋ฐ”๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Œ +- `scrollWidth`์™€ `scrollHeight` -- `clientWidth`, `clientHeight` ๊ฐ™์ด ์ฝ˜ํ…์ธ ์™€ ํŒจ๋”ฉ์„ ํฌํ•จํ•œ ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ, ์Šคํฌ๋กค๋ฐ”์— ์˜ํ•ด ์ˆจ๊ฒจ์ง„ ์ฝ˜ํ…์ธ  ์˜์—ญ๊นŒ์ง€ ํฌํ•จ๋จ +- `scrollLeft`์™€ `scrollTop` -- ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์˜ค๋ฅธ์ชฝ, ์•„๋ž˜๋กœ ์›€์ง์ž„์— ๋”ฐ๋ผ ๊ฐ€๋ ค์ง€๊ฒŒ ๋˜๋Š” ์š”์†Œ ์ฝ˜ํ…์ธ ์˜ ๋„ˆ๋น„์™€ ๋†’์ด -All properties are read-only except `scrollLeft/scrollTop` that make the browser scroll the element if changed. +์Šคํฌ๋กค๋ฐ”๋ฅผ ์›€์ง์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” `scrollLeft`์™€ `scrollTop`์„ ์ œ์™ธํ•œ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋Š” ์ฝ๊ธฐ ์ „์šฉ์ž…๋‹ˆ๋‹ค. diff --git a/2-ui/1-document/09-size-and-scroll/cssWidthScroll.view/index.html b/2-ui/1-document/09-size-and-scroll/cssWidthScroll.view/index.html index 2869c7ed91..00610d42d4 100755 --- a/2-ui/1-document/09-size-and-scroll/cssWidthScroll.view/index.html +++ b/2-ui/1-document/09-size-and-scroll/cssWidthScroll.view/index.html @@ -7,7 +7,7 @@ text text text text text text text text text text text text text text text text text text text text text text text text text text </div> - The element has <code>style="width:300px"</code> + ์š”์†Œ์— <code>style="width:300px"</code>๋ฅผ ์„ค์ •ํ•ด ๋†“์Œ <br> <button onclick="alert( getComputedStyle(elem).width )">alert( getComputedStyle(elem).width )</button> diff --git a/2-ui/1-document/09-size-and-scroll/metric-all.svg b/2-ui/1-document/09-size-and-scroll/metric-all.svg index 273b385288..a5dadb47f0 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-all.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-all.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="670" height="602" viewBox="0 0 670 602"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-all.svg"><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="160" y="94">Introduction</tspan> <tspan x="160" y="122" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="160" y="141" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="160" y="160" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="160" y="179" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="160" y="198" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="160" y="217" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="160" y="236" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="160" y="255" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="160" y="274" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan> <tspan x="160" y="293" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="160" y="312" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard started </tspan> <tspan x="160" y="331" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in November 1996. The first edition of this </tspan> <tspan x="160" y="350" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma Standard was adopted by the Ecma </tspan> <tspan x="160" y="369" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">General Assembly of June 1997.</tspan> <tspan x="160" y="388" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="160" y="407" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="160" y="426" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="160" y="445" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="160" y="464" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="160" y="483" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="160" y="502" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="160" y="521" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="160" y="540" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M491 162v290H117V162h374zm-25 25H142v240h324V187z"/><path id="Rectangle-2" stroke="#E8C48F" stroke-opacity=".8" stroke-width="2" d="M141 62h326v500H141z"/><text id="scrollHeight" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 592 310)"><tspan x="541.6" y="314.5">scrollHeight</tspan></text><text id="offsetHeight" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 558 310)"><tspan x="507.6" y="314.5">offsetHeight</tspan></text><text id="scrollTop" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 508 114)"><tspan x="470.2" y="118.5">scrollTop</tspan></text><path id="Line-27" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M466.5 62h148.14"/><path id="Line-28" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M492.5 163h92.14"/><path id="Line-29" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M492.5 451h92.14"/><path id="Line-33" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M467.5 189h72.14"/><path id="Line-32" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M467.5 427h72.14"/><path id="Line-26" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M466.5 561h148.14"/><path id="Line-25" fill="#EE6B47" fill-rule="nonzero" d="M605 64.5l7 14h-6v466h6l-7 14-7-14h6v-466h-6l7-14z"/><path id="Line-30" fill="#EE6B47" fill-rule="nonzero" d="M571 164.5l7 14h-6v255h6l-7 14-7-14h6v-255h-6l7-14z"/><text id="clientHeight" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 514 304)"><tspan x="463.6" y="308.5">clientHeight</tspan></text><path id="Line-34" fill="#EE6B47" fill-rule="nonzero" d="M527 191.5l7 14h-6v206h6l-7 14-7-14h6v-206h-6l7-14z"/><text id="offsetTop" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 104 83)"><tspan x="66.2" y="87.5">offsetTop</tspan></text><text id="clientLeft" fill="#C74A6C" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 130.5 237)"><tspan x="88.5" y="241.5">clientLeft</tspan></text><path id="Line-36" fill="#EE6B47" fill-rule="nonzero" d="M117 4.5l7 14h-6v128h6l-7 14-7-14h6v-128h-6l7-14z"/><path id="Line-31" fill="#EE6B47" fill-rule="nonzero" d="M521 64.5l7 14h-6v65h6l-7 14-7-14h6v-65h-6l7-14z"/><path id="Rectangle-14" fill="#FFF" fill-opacity=".88" d="M154 73h312v89H154z"/><path id="Rectangle-15" fill="#FFF" fill-opacity=".88" d="M154 451h312v93H154z"/><path id="Line-39" fill="#EE6B47" fill-rule="nonzero" d="M431 479.09l14 7-14 7-.001-6h-271.36l.001 6-14-7 14-7-.001 6h271.36l.001-6z"/><path id="Line-42" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M445.64 510v-84"/><path id="Line-43" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M141.64 510v-84"/><text id="clientWidth" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="261.3" y="478">clientWidth</tspan></text><path id="Line-41" fill="#EE6B47" fill-rule="nonzero" d="M100 156.09l14 7-14 7v-6H18.639l.001 6-14-7 14-7-.001 6H100v-6z"/><text id="clientTop" fill="#C74A6C" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147.7" y="178">clientTop</tspan></text><text id="offsetLeft" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17.5" y="154">offsetLeft</tspan></text><path id="Line-40" fill="#EE6B47" fill-rule="nonzero" d="M475 522.09l14 7-14 7-.001-6h-340.36l.001 6-14-7 14-7-.001 6h340.36l.001-6z"/><path id="Line-45" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M490.64 551V447"/><path id="Line-44" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M116.64 551V447"/><text id="offsetWidth" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="258.3" y="516">offsetWidth</tspan></text><path id="Rectangle-233" stroke="#8A704D" stroke-width="2" d="M1 1h668v600H1z"/><g id="Scrollbar" transform="translate(450 187)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><g id="Group" transform="translate(115 162)"><g id="Line-4-+-Line-5" stroke="#C74A6C" stroke-linecap="square" stroke-width="2" transform="translate(23 19)"><path id="Line-4" d="M2.5.5L0 6" transform="matrix(1 0 0 -1 0 6)"/><path id="Line-5" d="M5.5.5L3 6" transform="rotate(180 4.5 3)"/></g><g id="Line-4-+-Line-6" stroke="#C74A6C" stroke-linecap="square" stroke-width="2" transform="matrix(1 0 0 -1 23 7)"><path id="Line-4" d="M2.5.5L0 6" transform="matrix(1 0 0 -1 0 6)"/><path id="Line-5" d="M5.5.5L3 6" transform="rotate(180 4.5 3)"/></g><path id="Line-49" stroke="#C74A6C" stroke-linecap="round" stroke-linejoin="bevel" stroke-width="2" d="M26.5 26h-25"/><path id="Line-50" stroke="#C74A6C" stroke-linecap="round" stroke-linejoin="bevel" stroke-width="2" d="M26 25.5V.5"/><path id="Line-4" fill="#C74A6C" fill-rule="nonzero" d="M20.003 22.176l.91.414 5.5 2.5.911.413-.59 1.296.09.198-.225.1-.102.227-.198-.09-.385.176-5.5 2.5-.91.414-.828-1.82.91-.414 4.297-1.954-3.797-1.726-.91-.413.827-1.821zM7.997 22.176l.827 1.82-.91.414-3.798 1.726 4.298 1.954.91.413-.827 1.821-.91-.414-5.5-2.5-.387-.176-.197.09-.102-.225-.225-.102.089-.198-.59-1.296.911-.413 5.5-2.5.91-.414z"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="670" height="602" viewBox="0 0 670 602"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-all.svg"><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="160" y="94">Introduction</tspan> <tspan x="160" y="122" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="160" y="141" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="160" y="160" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="160" y="179" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="160" y="198" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="160" y="217" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="160" y="236" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="160" y="255" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="160" y="274" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan> <tspan x="160" y="293" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="160" y="312" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard started </tspan> <tspan x="160" y="331" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in November 1996. The first edition of this </tspan> <tspan x="160" y="350" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma Standard was adopted by the Ecma </tspan> <tspan x="160" y="369" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">General Assembly of June 1997.</tspan> <tspan x="160" y="388" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="160" y="407" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="160" y="426" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="160" y="445" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="160" y="464" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="160" y="483" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="160" y="502" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="160" y="521" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="160" y="540" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-1" fill="#DBAF88" d="M491 162v290H117V162h374zm-25 25H142v240h324V187z"/><path id="Rectangle-2" stroke="#DBAF88" stroke-width="2" d="M141 62h326v500H141z"/><text id="scrollHeight" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 592 310)"><tspan x="541.6" y="314.5">scrollHeight</tspan></text><text id="offsetHeight" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 552 310)"><tspan x="501.6" y="314.5">offsetHeight</tspan></text><text id="scrollTop" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 618 125)"><tspan x="580.2" y="129.5">scrollTop</tspan></text><path id="Line-27" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M466.5 62H640"/><path id="Line-28" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M492.5 163h92.14"/><path id="Line-29" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M492.5 451h92.14"/><path id="Line-33" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M467.5 189H640"/><path id="Line-32" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M467.5 427h72.14"/><path id="Line-26" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M466.5 561h148.14"/><path id="Line-25" fill="#C06334" fill-rule="nonzero" d="M605 64.5l7 14h-6v466h6l-7 14-7-14h6v-466h-6l7-14z"/><path id="Line-30" fill="#C06334" fill-rule="nonzero" d="M565 164.5l7 14h-6v255h6l-7 14-7-14h6v-255h-6l7-14z"/><text id="clientHeight" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 510 304)"><tspan x="459.6" y="308.5">clientHeight</tspan></text><path id="Line-34" fill="#C06334" fill-rule="nonzero" d="M523 191.5l7 14h-6v206h6l-7 14-7-14h6v-206h-6l7-14z"/><text id="offsetTop" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 104 83)"><tspan x="66.2" y="87.5">offsetTop</tspan></text><text id="clientLeft" fill="#166388" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 130.5 237)"><tspan x="88.5" y="241.5">clientLeft</tspan></text><path id="Line-36" fill="#C06334" fill-rule="nonzero" d="M117 4.5l7 14h-6v128h6l-7 14-7-14h6v-128h-6l7-14z"/><path id="Line-31" fill="#C06334" fill-rule="nonzero" d="M631 64.5l7 14h-6v96.499l6 .001-7 14-7-14 6-.001V78.5h-6l7-14z"/><path id="Rectangle-14" fill="#FFF" d="M154 73h312v89H154z"/><path id="Rectangle-15" fill="#FFF" d="M154 451h312v93H154z"/><path id="Line-39" fill="#C06334" fill-rule="nonzero" d="M431 479.09l14 7-14 7-.001-6h-271.36l.001 6-14-7 14-7-.001 6h271.36l.001-6z"/><path id="Line-42" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M445.64 510v-84"/><path id="Line-43" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M141.64 510v-84"/><text id="clientWidth" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="261.3" y="478">clientWidth</tspan></text><path id="Line-41" fill="#C06334" fill-rule="nonzero" d="M100 156.09l14 7-14 7v-6H18.639l.001 6-14-7 14-7-.001 6H100v-6z"/><text id="clientTop" fill="#166388" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147.7" y="178">clientTop</tspan></text><text id="offsetLeft" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17.5" y="154">offsetLeft</tspan></text><path id="Line-40" fill="#C06334" fill-rule="nonzero" d="M475 522.09l14 7-14 7-.001-6h-340.36l.001 6-14-7 14-7-.001 6h340.36l.001-6z"/><path id="Line-45" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M490.64 551V447"/><path id="Line-44" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M116.64 551V447"/><text id="offsetWidth" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="258.3" y="516">offsetWidth</tspan></text><path id="Rectangle-233" stroke="#AF6E24" stroke-width="2" d="M1 1h668v600H1z"/><g id="Group" transform="translate(450 187)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><g id="Group" transform="translate(115.676 162.5)"><g id="Line-4-+-Line-5" stroke="#166388" stroke-linecap="square" stroke-width="2" transform="translate(22.324 18.5)"><path id="Line-4" d="M2.5.5L0 6" transform="matrix(1 0 0 -1 0 6)"/><path id="Line-5" d="M5.5.5L3 6" transform="rotate(180 4.5 3)"/></g><g id="Line-4-+-Line-6" stroke="#166388" stroke-linecap="square" stroke-width="2" transform="matrix(1 0 0 -1 22.324 6.5)"><path id="Line-4" d="M2.5.5L0 6" transform="matrix(1 0 0 -1 0 6)"/><path id="Line-5" d="M5.5.5L3 6" transform="rotate(180 4.5 3)"/></g><path id="Line-49" fill="#166388" stroke="#166388" stroke-linecap="round" stroke-linejoin="bevel" stroke-width="2" d="M25.824 25.5h-25"/><path id="Line-50" fill="#166388" stroke="#166388" stroke-linecap="round" stroke-linejoin="bevel" stroke-width="2" d="M25.324 25V0"/><path id="Line-4" fill="#166388" fill-rule="nonzero" d="M19.328 21.676l.91.414 5.5 2.5.91.413-.589 1.296.09.198-.226.1-.102.227-.198-.09-.385.176-5.5 2.5-.91.414-.828-1.82.91-.414 4.297-1.954-3.797-1.726-.91-.413.828-1.821zM7.32 21.676l.828 1.82-.91.414-3.798 1.726 4.298 1.954.91.413-.827 1.821-.91-.414-5.5-2.5-.387-.176-.196.09-.103-.225-.225-.102.089-.198L0 25.003l.91-.413 5.5-2.5.91-.414z"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg index 12bc456a68..dd9e17cf8b 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="359" height="316" viewBox="0 0 359 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="0%" x2="62.299%" y1="47.096%" y2="47.096%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#FFF" stop-opacity="0"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-3" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-left-top-rtl.svg"><path fill="#FFF" d="M0 0h359v316H0z"/><path id="ื”ื™ื-ืฉืคืช-ืชืกืจื™ื˜-ืžืคื•ืจืฉืช" fill="#5A4739" d="M336.484 135v-10.031h4.047V135h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047zm-20.39-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM302.063 135v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V135h-4.329zm-31.954 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.368 2.993l.282 2.312c2.718 0 4.89-.453 6.515-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.794 4.359-13.899 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L262.671 135h-14.5zm-22.969 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L233.516 135h-8.313zm-33.547 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L199.969 135h-8.313zm-18.265 0l-1.766-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.876.157 1.573.469 2.094.938.875.791 1.313 2.047 1.313 3.765 0 2.292-.662 4.506-1.985 6.641s-3.104 3.854-5.343 5.156c-2.26 1.313-5.22 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.088-.687 5.265-1.531 1.938-1.407 2.907-3.25 2.907-5.531 0-.938-.328-1.57-.985-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.157 9.453zM162.297 135v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.531-4.625h5.047c3.135 0 5.229.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.148V135h-4.047zm-14.047-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM122.375 135l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm222.344 38l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.22 2.008 1.051 1.338 1.676 3.257 1.874 5.757l.531 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L348.953 173h-4.234zm-19.344 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L339.874 173h-14.5zm-7.14 0v-9.594c0-1.927-.32-3.252-.962-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V173h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.198.797.296 2.18.296 4.149V173h-4.046zm-30.516 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.566 5.445-1.696 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.281 2.312c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.265-5.192 4.265-10.827v-1.891h4.329v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zM250 173l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V173h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L258.313 173H250zm-31.422 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L222.813 173h-4.234zm-19.25 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L215.53 173h-16.203zm-7.516 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V173h-4.047zm-23.015 0l-1.766-14.078h-2.515l1.547-4.625h11.078c2.093 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.105 3.854-5.344 5.156c-2.26 1.313-5.219 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.089-.687 5.266-1.531 1.937-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.657-.328-1.948-.492-3.875-.492h-4.47l1.157 9.453zM146.531 173l-1.765-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.218 1.969-8.875 1.969zm3.453-4.625c2.334-.177 4.089-.687 5.266-1.531 1.938-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.156 9.453zM119.531 173l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V173h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 173h-8.313zm288.766 38v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.665l-.703-.671c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V211h-4.328zm-8.438 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V211h-4.047zm-23.718 0l1.546-4.625h9.641v-4.438c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.829l1.547-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L392.344 211H376.14zm-4.016-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-11.594 0h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-27.328 10.891v-14.61h4.047v14.61h-4.047zm-2.515-18.703l1.546-4.625h10.844c1.99 0 3.39.088 4.203.266.813.177 1.495.541 2.047 1.093.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.36 8.547-2.239 2.646-5.13 4.537-8.671 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.985-1.883-.656-.317-1.958-.476-3.906-.476h-10.39zM312.594 211l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-6.516-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM277.766 211v-14.078h-2.485l1.547-4.625h10.485c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562L293.578 211h-15.812zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687h-4.813v9.453zM243.86 211v-10.031h4.047V211h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V211h-4.047zm-37.594 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L224.094 211h-4.235zm-7.453 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V211h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V211h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L192.969 211h-8.313zm-19.703 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.079-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.304-1.927.304-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.546 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V211h-4.329zm-22.14 0l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.547-4.625h4.921l-.359-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L147.047 211h-4.234zm-23.282 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V211h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 211h-8.313zm318.844 38.39l1.594-4.718c2.041-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-21.86-.39l-2.202-17.5 3.921-1.578 1.172 9.25c1.136-.281 1.933-.945 2.39-1.992.46-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.28 2.312c2.72 0 4.891-.453 6.517-1.36 2.843-1.583 4.265-5.192 4.265-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-6.546-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zm-24.016 6.657l1.594-4.72c2.042-.228 3.687-.838 4.937-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-8.89-.391v-9.594c0-1.927-.32-3.252-.961-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V249h-4.046zm-23.72 0l1.548-4.625h9.64v-4.438c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.828l1.546-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L369.547 249h-16.203zm-29.859 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.608-4.32-.407-.463-1.683-.695-3.829-.695h-5.828l1.547-4.625h4.953c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L339.688 249h-16.204zm-20.046 0v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V249h-4.329zm-24.266 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.329l1.547-4.625h8.579c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V249h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L287.484 249h-8.312zm-7.094 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V249h-4.047zm-14.047-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM219.86 249v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V249h-4.329zm-4.937-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM192.75 249l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.234-.948-.678-2.224-1.245-3.828-1.704l1.843-3.437c1.73.427 3.297 1.047 4.703 1.86.907.53 1.532 1.182 1.875 1.952.344.771.516 1.922.516 3.453v7.188L202.328 249h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-9.938 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V249h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.234-.948-.678-2.224-1.245-3.828-1.704l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.453v7.188L149.86 249h-9.578zm-17.906 0l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm258.422 38v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.156V287h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V287h-4.047zm-29.25 0l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.093-1.578a28.973 28.973 0 004.938 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-20.594 0v-10.031h4.047V287h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V287h-4.047zm-48.61 2.781l1.563-4.672c1.667 0 3.459-.28 5.375-.843l-3.36-14.985 3.876-1.36 3.265 14.563c1.636-1.24 2.774-2.78 3.415-4.625.64-1.843.96-4.484.96-7.921v-1.641h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zm-14.796-2.39l1.594-4.72c2.041-.228 3.687-.838 4.937-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.642-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-15.938-6.657h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zM236.656 287v-14.078h-9.531l1.547-4.625h16.094l-1.547 4.625h-2.516V287h-4.047zm-12.86-6.266h-4.062c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM196.547 287v-14.078h-9.53l1.547-4.625h16.093l-1.547 4.625h-2.515V287h-4.047zm-28.25 0l1.392-4.234h10.468v-4.157c0-1.948-.192-3.205-.578-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L182.796 287h-14.5zm-8.75 0v-14.078h-9.53l1.547-4.625h16.093l-1.547 4.625h-2.515V287h-4.047zm-28.25 0l1.392-4.234h10.468v-4.157c0-1.948-.192-3.205-.578-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L145.796 287h-14.5zm-7.155 4.625v-14.281c0-2.032-.36-3.344-1.079-3.938-1.041-.875-2.328-1.552-3.859-2.031l1.86-3.453c1.875.562 3.53 1.37 4.968 2.422.834.614 1.401 1.364 1.703 2.25.302.885.454 2.255.454 4.11v14.921h-4.047zM426.797 325v-10.031h4.047V325h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.296 2.177.296 4.156V325h-4.046zm-36.422 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.447 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V325h-4.328zm-4.938-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.954-.718-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM376.86 325l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.454v7.187L386.438 325h-9.579zm-17.906 0l-2.234-17.688 3.922-1.39 1.796 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.916 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.291 3.568-5.687 4.704c-2.01.958-4.85 1.437-8.516 1.437zm-9.937 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.198.797.296 2.18.296 4.149V325h-4.046zm-24.625 0l1.562-4.625h5.516v-6.078c0-1.646-.354-2.724-1.063-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.297 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.516 1.922.516 3.454v7.187L333.969 325h-9.578zm-17.907 0l-2.234-17.688 3.922-1.39 1.797 14.453c2.666 0 4.794-.615 6.383-1.844 1.588-1.229 2.382-2.87 2.382-4.922 0-2.24-1.208-3.359-3.625-3.359-.645 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.917 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437-1.395 2-3.291 3.568-5.687 4.704-2.01.958-4.849 1.437-8.516 1.437zm-32.359 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.197.797.296 2.18.296 4.149v6.562h2.5L290.33 325h-16.204zm-19.219 0l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.094-1.578a28.973 28.973 0 004.937 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-8.687 0v-14.078h-9.531l1.546-4.625h16.094l-1.547 4.625h-2.515V325h-4.047zm-40.422 0v-10.031h4.047V325h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V325h-4.047zm-32.813.39l1.594-4.718c2.042-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-21.125 4.235v-14.61h4.047v14.61h-4.047zm-2.516-18.703l1.547-4.625h10.844c1.99 0 3.39.088 4.203.265.813.178 1.495.542 2.047 1.094.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.36 8.547-2.239 2.646-5.13 4.537-8.671 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.985-1.883-.656-.317-1.958-.476-3.906-.476h-10.39zM155.625 325v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V325h-4.047zm-25.516 0v-14.078h-2.53l1.562-4.625h10.89c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149V325h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.203V325h-4.047zm-9.656 0v-5.016h5.016V325h-5.016zm249.906 38v-10.031h4.047V363h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-36.86 0l-2.202-17.5 3.921-1.578 1.172 9.25c1.136-.281 1.933-.945 2.391-1.992.458-1.047.688-2.716.688-5.008v-1.875h4.343v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.281 2.312c2.719 0 4.89-.453 6.516-1.36 2.843-1.583 4.265-5.192 4.265-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.234.671c-.136.396-.203.74-.203 1.032 0 1.01.87 1.583 2.609 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.969-2.703 7.125 1.734c2.312.563 3.815 1.284 4.507 2.164.693.88 1.04 2.503 1.04 4.868v6.078L339.656 363h-14.5zm-20.656 0v-10.031h4.047V363H304.5zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-48.14 0l2.265-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.195 5.664L274.188 363h-4.235zm-7.376 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V363h-4.047zm-31.14 0v-14.078h-2.532l1.563-4.625h10.89c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149V363h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.204V363h-4.047zm-6.344-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zM198.204 363l1.546-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L214.405 363h-16.203zm-21.032 0v-10.031h4.047V363h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625H187c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-46.97 0v-.516c0-2.677.282-4.971.845-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V363h-4.328zm-24.265 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V363h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 363h-8.313zm285.016 31.734h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM378.812 401l1.532-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.761-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.957.312 1.77.87 2.437 1.671 1.062 1.271 1.593 3.063 1.593 5.375 0 1.844-.49 4.032-1.468 6.563L391.5 401h-12.688zm-7.453 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V401h-4.047zm-20.843.39l1.593-4.718c2.042-.23 3.688-.839 4.938-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.695-.484h-5.563v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-8.891-.39v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V401h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.546-4.625h8.579c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L322.188 401h-8.313zm-30.688 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.136-.281 1.932-.945 2.39-1.992.46-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.368 2.993l.282 2.312c2.719 0 4.89-.453 6.515-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.794 4.359-13.899 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L275.75 401h-14.5zm-22.969 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.197.792.296 2.177.296 4.156V401h-4.046v-9.063c0-2.416-.204-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L246.594 401h-8.313zm-31.234 0v-10.031h4.047V401h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V401h-4.047zm-39.72 0l1.548-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.546-4.625h8.578c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L189.234 401h-8.312zm-13.171.39l-1.594-3.859c2.334-1.135 4.724-2.724 7.172-4.765l-.39-2.485c-.23-1.427-.566-2.398-1.008-2.914-.443-.515-1.42-1.075-2.93-1.68l-.89-.359 1.75-3.406c2.562.844 4.317 1.687 5.265 2.531.625.563 1.055 1.177 1.29 1.844.233.667.517 2.094.85 4.281l.61 4c.448 2.938.89 5.078 1.328 6.422h-4.36c-.28-1.115-.577-2.594-.89-4.438-1.542 1.553-3.61 3.162-6.203 4.829zm-5.375-6.656h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM147.281 401v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V401h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 401h-8.313zm218.406 38v-10.031h4.047V439h-4.046zm13.594 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V439h-4.047zm-35.687 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.828l1.546-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L332.047 439h-16.203zm-18.61 0l-1.765-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.313 2.047 1.313 3.765 0 2.292-.662 4.506-1.985 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.218 1.969-8.875 1.969zm3.454-4.625c2.333-.177 4.088-.687 5.265-1.531 1.938-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.156 9.453zm-11.125-1.64H285.5c.73-2.667 1.094-4.574 1.094-5.72 0-.822-.36-1.473-1.078-1.952-.72-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM263.375 439l-1.766-14.078h-2.515l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.219 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.089-.687 5.266-1.531 1.937-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.657-.328-1.948-.492-3.875-.492h-4.47l1.157 9.453zm-11.125-1.64h-4.062c.729-2.667 1.093-4.574 1.093-5.72 0-.822-.359-1.473-1.078-1.952-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM224.781 439l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V439h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L233.094 439h-8.313zm-102.89 0v-23.125h4.812v9.39h9.563v-9.39h4.812V439h-4.812v-10.547h-9.563V439h-4.812zm30.703 0v-19.953h-8.281v-3.172h21.39v3.172h-8.281V439h-4.828zm16.344 0v-23.125h6.375l5.562 16.266 5.734-16.266h5.594V439h-4.437v-17.453l-5.641 15.906h-3.875l-5.531-16.14V439h-3.781zm29.046 0v-23.125h4.813v19.844h10.422V439h-15.235zm204.094 38v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V477h-4.047zm-25.625 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.195 5.664L380.688 477h-4.235zm-19.984 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.447 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V477h-4.328zm-20.328 0l1.39-4.234H348v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.781-.234.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.969-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.039 2.503 1.039 4.868v6.078L350.64 477h-14.5zm-20.11 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.993l.281 2.312c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-9.969 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V477h-4.046zm-33.375 0l1.547-4.625h4.032c-.823-2.115-1.235-4.708-1.235-7.781v-1.672h-2.328l1.547-4.625h8.578c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V477h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078L281 477h-8.313zm-29.515 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L259.375 477h-16.203zm-18.156 0l1.53-4.625h8.735c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.958.312 1.77.87 2.437 1.671 1.062 1.271 1.594 3.063 1.594 5.375 0 1.844-.49 4.032-1.47 6.563L237.704 477h-12.687zm-7.547 4.625v-18.703h-10l1.547-4.625h12.5v23.328h-4.047zm-36.453-4.234l1.593-4.72c2.042-.228 3.688-.838 4.938-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.696-.484h-5.562v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-5.391-6.657h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM148.828 477l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.093-1.578a28.973 28.973 0 004.938 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-7.078 0v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V477h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V477h-4.047zm207.406 31.734h-4.062c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-11.593 0h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zM297.656 515l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.993l.281 2.312c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-10.047 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V515h-4.047zm-25.625 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L266.219 515h-4.235zm-3.953-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.954-.718-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM219.86 515v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V515h-4.329zm-4.937-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM192.75 515l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.843-3.437c1.73.427 3.297 1.047 4.703 1.86.907.53 1.532 1.182 1.875 1.952.344.771.516 1.922.516 3.454v7.187L202.328 515h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.704c-2.01.958-4.849 1.437-8.515 1.437zm-9.938 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V515h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.454v7.187L149.86 515h-9.578zm-17.906 0l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.704c-2.01.958-4.85 1.437-8.516 1.437zm212.14 38l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.758l.531 6.687-1.531 4.625h-9.031l1.547-4.625h4.921l-.359-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L338.75 553h-4.234zm-23.28 0l1.546-4.625h4.031c-.822-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.296 2.177.296 4.157V553h-4.046v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078L319.547 553h-8.313zm-7.173 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V553h-4.046zm-25.515 0v-14.078h-2.531l1.562-4.625h10.89c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149V553h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.203V553h-4.047zm-20.485 0l1.532-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.761-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.957.312 1.77.87 2.437 1.672 1.062 1.27 1.593 3.062 1.593 5.375 0 1.843-.49 4.03-1.468 6.562L270.75 553h-12.688zm-21.156 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.758l.53 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L241.14 553h-4.235zm-3.953-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM204.641 553v-14.078h-2.485l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L220.453 553h-15.812zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687h-4.813v9.453zm-20.953-1.64h-4.063c.73-2.667 1.094-4.574 1.094-5.72 0-.822-.36-1.473-1.078-1.952-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM172.656 553v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V553h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V553h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L153.219 553h-8.313zm-7.094 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V553h-4.047zm-17.359 0v-5.016h5.016V553h-5.016zm322.688 38.39l1.593-4.718c2.042-.23 3.688-.839 4.938-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.695-.484h-5.563v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-22.594-.39l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.938 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.531 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.296-5.031-1.126 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L424.781 591h-4.234zm-21.625 2.781l1.562-4.672c1.667 0 3.459-.28 5.375-.843L402.5 573.28l3.875-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zM380.078 591l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.992l.281 2.313c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-23.562 0v-10.031h4.046V591h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V591h-4.047zm-21.78 0h-1.923v-5.016h5.016v3.891c0 4.094-1.672 6.14-5.016 6.14v-1.734c1.282 0 1.922-.927 1.922-2.781v-.5zm-31.204 0l1.531-4.625h8.735c.864-1.99 1.296-3.682 1.296-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.782 0 3.151.156 4.11.469.958.312 1.77.87 2.437 1.672 1.063 1.27 1.594 3.062 1.594 5.375 0 1.843-.49 4.03-1.469 6.562L329.813 591h-12.688zm-3.953-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM298.078 591v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V591h-4.047zm-25.14 0v-14.078h-2.485l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L288.75 591h-15.813zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687H277v9.453zM265.203 591h-1.922v-5.016h5.016v3.891c0 4.094-1.672 6.14-5.016 6.14v-1.734c1.282 0 1.922-.927 1.922-2.781v-.5zm-20.484 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.149V591h-4.047zm-17.547 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V591h-4.047zm-23.719 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L219.655 591h-16.203zm-30.594 0v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V591h-4.329zm-24.265 0l1.547-4.625h4.03c-.822-2.115-1.233-4.708-1.233-7.781v-1.672h-2.329l1.547-4.625h8.578c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V591H164.5v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695H157v1.375c0 3.354.48 6.047 1.438 8.078L156.905 591h-8.312zm-7.094 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.135 0 5.23.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.149V591H141.5zm-14.047-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM406.016 629v-10.031h4.046V629h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V629h-4.047zm-36.421 0v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V629h-4.329zm-4.938-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM356.078 629l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.843-3.437c1.73.427 3.297 1.047 4.704 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.453v7.188L365.656 629h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.848 1.438-8.515 1.438zm-9.938 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.282 1.375a3.773 3.773 0 011.218 1.992c.198.797.297 2.18.297 4.149V629h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.453v7.188L313.188 629h-9.579zm-17.906 0l-2.234-17.688 3.922-1.39 1.796 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.916 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.291 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm-34.078 0v-10.031h4.047V629h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V629h-4.047zm-37.594 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.532 6.687-1.532 4.625h-9.03l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L231.86 629h-4.234zm-7.453 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V629h-4.047zm-13.531 0v-14.078h-9.532l1.547-4.625h16.094l-1.547 4.625h-2.516V629h-4.046zm-16.282 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.282 1.375a3.773 3.773 0 011.218 1.992c.198.797.297 2.18.297 4.149V629h-4.047zm-24.625 0l1.563-4.625h5.516v-6.078c0-1.646-.355-2.724-1.063-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.453v7.188L175.312 629h-9.578zm-3.625-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.72-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zm-11.593 0h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM122.203 629v-14.078h-2.484l1.547-4.625h10.484c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562L138.016 629h-15.813zm4.063-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.828-.687h-4.812v9.453zM401.844 667l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.22 2.008 1.051 1.338 1.676 3.257 1.874 5.758l.531 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L406.078 667h-4.234zm-20.422 0l-2.203-17.5 3.922-1.578 1.171 9.25c1.136-.281 1.933-.945 2.391-1.992.458-1.047.688-2.716.688-5.008v-1.875h4.343v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.992l.281 2.313c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.265-5.192 4.265-10.827v-1.891h4.329v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-18.969.39l1.594-4.718c2.042-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-20.687-.39l1.546-4.625h9.641v-4.438c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.829l1.547-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L357.969 667h-16.203zm-4.016-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM309.437 667v-14.078h-2.484l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L325.25 667h-15.813zm4.063-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687H313.5v9.453zM276.078 667l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.992l.281 2.313c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-21.937 0l1.39-4.234H266v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.782-.234.672c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.969-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.039 2.503 1.039 4.867v6.079L268.64 667h-14.5zm-20.657 0v-10.031h4.047V667h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V667h-4.047zm-38.234 0v-7.016c0-2.354.682-4.343 2.047-5.968L206 651.938l1.719-4.016 11.094 4.719-1.672 4.062-3.125-1.36c-.75.938-1.125 2.256-1.125 3.954V667h-4.047zm-9.735 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V667h-4.047zm-11.734 0v-5.016h5.016V667h-5.016zm-32.156 0v-10.031h4.047V667h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V667h-4.047zm-20.391-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM120.797 667v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V667h-4.328zm275.937 31.734h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zM380.031 705v-14.078H370.5l1.547-4.625h16.094l-1.547 4.625h-2.516V705h-4.047zm-16.36 0v-9.594c0-1.927-.32-3.252-.96-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V705h-4.047zm-26.093 2.781l1.563-4.672c1.666 0 3.458-.28 5.375-.843l-3.36-14.985 3.875-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.345v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.154 4.88-5.79 6.64-3.697 2.469-7.635 3.703-11.812 3.703zM318.188 705v-10.031h4.046V705h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V705h-4.047zm-46.234 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L301.75 705h-16.203zm-21.688 2.781l1.563-4.672c1.667 0 3.458-.28 5.375-.843l-3.36-14.985 3.875-1.36 3.266 14.563c1.636-1.24 2.774-2.78 3.414-4.625.64-1.843.961-4.484.961-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.154 4.88-5.79 6.64-3.697 2.469-7.635 3.703-11.812 3.703zm-2.375-9.047h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zm-27.328 10.891v-14.61h4.047v14.61h-4.047zm-2.515-18.703l1.547-4.625h10.843c1.99 0 3.39.088 4.203.265.813.178 1.495.542 2.047 1.094.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.359 8.547-2.24 2.646-5.13 4.537-8.672 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.984-1.883-.657-.317-1.959-.476-3.907-.476h-10.39zM224.406 705v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V705h-4.047zm-38.734 0l1.531-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.151.156 4.11.469.958.312 1.77.87 2.437 1.672 1.063 1.27 1.594 3.062 1.594 5.375 0 1.843-.49 4.03-1.469 6.562L198.359 705h-12.687zm-20.422 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.566 5.445-1.696 7.054-1.13 1.61-2.92 2.607-5.367 2.992l.281 2.313c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-21.938 0l1.391-4.234h10.469v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.782-.234.672c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.969-2.703 7.125 1.734c2.312.563 3.815 1.284 4.508 2.164.692.88 1.039 2.503 1.039 4.867v6.079L157.813 705h-14.5zm-20.656 0v-10.031h4.047V705h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.546-4.625h11.172c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V705h-4.047zm169.5 38v-10.031h4.047V743h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V743h-4.047zm-37.594 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.532 6.687-1.532 4.625h-9.03l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L285.984 743h-4.234zm-7.453 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V743h-4.047zm-22.703 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-21.813 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L245.984 743h-16.203zm-21.687 2.781l1.562-4.672c1.667 0 3.459-.28 5.375-.843l-3.36-14.985 3.876-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zM186.39 743l1.547-4.625h4.03c-.822-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V743h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078l-1.53 4.625h-8.313zm-29.516 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L173.08 743h-16.204zm-9.125 0v-14.078h-9.531l1.547-4.625h16.093l-1.547 4.625h-2.515V743h-4.047zm-28.25 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.782-.234.672c-.136.396-.204.74-.204 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.867v6.079L134 743h-14.5z"/><path id="Rectangle-1" stroke="#EE6B47" stroke-width="2" d="M117 106h282v198H117z"/><g id="Rectangle-209-+-Rectangle-208" fill="#EBCB9D" transform="translate(15 14)"><path id="Rectangle-209" d="M0 1h50v300H0z"/><path id="Rectangle-208" d="M165.5-129.5h50v311h-50z" transform="rotate(-90 190.5 26)"/></g><path id="Rectangle-5" fill="url(#linearGradient-1)" d="M45-7h275v447H45z" transform="rotate(-180 182.5 216.5)"/><path id="Rectangle-6" fill="#FFF" d="M319 8h162v399H319z"/><g id="Group-2" transform="translate(65 65)"><rect id="Rectangle-19" width="20" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="20" height="19" x=".5" y=".5" fill="url(#linearGradient-2)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M10.5 7l4.2 6H6.3z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="20" height="19" x=".5" y=".5" fill="url(#linearGradient-2)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M10.5 7l4.2 6H6.3z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-3)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="20" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(5.25 20)"><path id="Rectangle-22" d="M.5.5H10v1H.5z"/><path id="Rectangle-23" d="M.5 3.5H10v1H.5z"/><path id="Rectangle-24" d="M.5 6.5H10v1H.5z"/><path id="Rectangle-25" d="M.5 9.5H10v1H.5z"/></g></g></g><path id="Line-7" fill="#EE6B47" fill-rule="nonzero" d="M65.41 15.68l7 14h-6.001v20h6.001l-7 14-7-14h5.999v-20H58.41l7-14z"/><path id="Line-28" fill="#EE6B47" fill-rule="nonzero" d="M72 57.68l14 7-14 7-.001-6h-42.59l.001 6-14-7 14-7-.001 6h42.59l.001-6z"/><text id="clientTop:25px-=-bor" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="78.7" y="43" fill="#EE6B47">clientTop:</tspan> <tspan x="150.7" y="43" fill="#3B86C4">25px </tspan> <tspan x="186.7" y="43" fill="#EE6B47">= border</tspan></text><text id="clientLeft:41px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 40.32 125)"><tspan x="-13.68" y="129" fill="#EE6B47">clientLeft:</tspan> <tspan x="65.52" y="129" fill="#3B86C4">41px</tspan></text><g id="Rectangle-8-+-Rectangle-7" transform="translate(-42 -3)"><path id="Rectangle-8" fill="url(#linearGradient-1)" d="M86.5-85.5h275v447h-275z" transform="rotate(-90 224 138)"/><path id="Rectangle-7" fill="#FFF" d="M152 156h162v399H152z" transform="rotate(90 233 355.5)"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="359" height="316" viewBox="0 0 359 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="0%" x2="62.299%" y1="47.096%" y2="47.096%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#FFF"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-3" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-left-top-rtl.svg"><path fill="#FFF" d="M0 0h359v316H0z"/><path id="ื”ื™ื-ืฉืคืช-ืชืกืจื™ื˜-ืžืคื•ืจืฉืช" fill="#643B0C" d="M336.484 135v-10.031h4.047V135h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047zm-20.39-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM302.063 135v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V135h-4.329zm-31.954 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.368 2.993l.282 2.312c2.718 0 4.89-.453 6.515-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.794 4.359-13.899 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L262.671 135h-14.5zm-22.969 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L233.516 135h-8.313zm-33.547 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V135h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L199.969 135h-8.313zm-18.265 0l-1.766-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.876.157 1.573.469 2.094.938.875.791 1.313 2.047 1.313 3.765 0 2.292-.662 4.506-1.985 6.641s-3.104 3.854-5.343 5.156c-2.26 1.313-5.22 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.088-.687 5.265-1.531 1.938-1.407 2.907-3.25 2.907-5.531 0-.938-.328-1.57-.985-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.157 9.453zM162.297 135v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.531-4.625h5.047c3.135 0 5.229.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.148V135h-4.047zm-14.047-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM122.375 135l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm222.344 38l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.22 2.008 1.051 1.338 1.676 3.257 1.874 5.757l.531 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L348.953 173h-4.234zm-19.344 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L339.874 173h-14.5zm-7.14 0v-9.594c0-1.927-.32-3.252-.962-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V173h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.198.797.296 2.18.296 4.149V173h-4.046zm-30.516 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.566 5.445-1.696 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.281 2.312c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.265-5.192 4.265-10.827v-1.891h4.329v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zM250 173l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V173h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L258.313 173H250zm-31.422 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L222.813 173h-4.234zm-19.25 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L215.53 173h-16.203zm-7.516 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V173h-4.047zm-23.015 0l-1.766-14.078h-2.515l1.547-4.625h11.078c2.093 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.105 3.854-5.344 5.156c-2.26 1.313-5.219 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.089-.687 5.266-1.531 1.937-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.657-.328-1.948-.492-3.875-.492h-4.47l1.157 9.453zM146.531 173l-1.765-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.218 1.969-8.875 1.969zm3.453-4.625c2.334-.177 4.089-.687 5.266-1.531 1.938-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.156 9.453zM119.531 173l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V173h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 173h-8.313zm288.766 38v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.665l-.703-.671c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V211h-4.328zm-8.438 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V211h-4.047zm-23.718 0l1.546-4.625h9.641v-4.438c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.829l1.547-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L392.344 211H376.14zm-4.016-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-11.594 0h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-27.328 10.891v-14.61h4.047v14.61h-4.047zm-2.515-18.703l1.546-4.625h10.844c1.99 0 3.39.088 4.203.266.813.177 1.495.541 2.047 1.093.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.36 8.547-2.239 2.646-5.13 4.537-8.671 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.985-1.883-.656-.317-1.958-.476-3.906-.476h-10.39zM312.594 211l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-6.516-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM277.766 211v-14.078h-2.485l1.547-4.625h10.485c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562L293.578 211h-15.812zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687h-4.813v9.453zM243.86 211v-10.031h4.047V211h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V211h-4.047zm-37.594 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L224.094 211h-4.235zm-7.453 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V211h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V211h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L192.969 211h-8.313zm-19.703 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.079-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.304-1.927.304-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.546 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V211h-4.329zm-22.14 0l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.547-4.625h4.921l-.359-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L147.047 211h-4.234zm-23.282 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V211h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 211h-8.313zm318.844 38.39l1.594-4.718c2.041-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-21.86-.39l-2.202-17.5 3.921-1.578 1.172 9.25c1.136-.281 1.933-.945 2.39-1.992.46-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.28 2.312c2.72 0 4.891-.453 6.517-1.36 2.843-1.583 4.265-5.192 4.265-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-6.546-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zm-24.016 6.657l1.594-4.72c2.042-.228 3.687-.838 4.937-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-8.89-.391v-9.594c0-1.927-.32-3.252-.961-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V249h-4.046zm-23.72 0l1.548-4.625h9.64v-4.438c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.828l1.546-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L369.547 249h-16.203zm-29.859 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.608-4.32-.407-.463-1.683-.695-3.829-.695h-5.828l1.547-4.625h4.953c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L339.688 249h-16.204zm-20.046 0v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V249h-4.329zm-24.266 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.329l1.547-4.625h8.579c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V249h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L287.484 249h-8.312zm-7.094 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V249h-4.047zm-14.047-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM219.86 249v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.665l-.703-.671c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V249h-4.329zm-4.937-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM192.75 249l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.234-.948-.678-2.224-1.245-3.828-1.704l1.843-3.437c1.73.427 3.297 1.047 4.703 1.86.907.53 1.532 1.182 1.875 1.952.344.771.516 1.922.516 3.453v7.188L202.328 249h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-9.938 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V249h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.234-.948-.678-2.224-1.245-3.828-1.704l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.453v7.188L149.86 249h-9.578zm-17.906 0l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm258.422 38v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.156V287h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V287h-4.047zm-29.25 0l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.093-1.578a28.973 28.973 0 004.938 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-20.594 0v-10.031h4.047V287h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V287h-4.047zm-48.61 2.781l1.563-4.672c1.667 0 3.459-.28 5.375-.843l-3.36-14.985 3.876-1.36 3.265 14.563c1.636-1.24 2.774-2.78 3.415-4.625.64-1.843.96-4.484.96-7.921v-1.641h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zm-14.796-2.39l1.594-4.72c2.041-.228 3.687-.838 4.937-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.642-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-15.938-6.657h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zM236.656 287v-14.078h-9.531l1.547-4.625h16.094l-1.547 4.625h-2.516V287h-4.047zm-12.86-6.266h-4.062c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM196.547 287v-14.078h-9.53l1.547-4.625h16.093l-1.547 4.625h-2.515V287h-4.047zm-28.25 0l1.392-4.234h10.468v-4.157c0-1.948-.192-3.205-.578-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L182.796 287h-14.5zm-8.75 0v-14.078h-9.53l1.547-4.625h16.093l-1.547 4.625h-2.515V287h-4.047zm-28.25 0l1.392-4.234h10.468v-4.157c0-1.948-.192-3.205-.578-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.374-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L145.796 287h-14.5zm-7.155 4.625v-14.281c0-2.032-.36-3.344-1.079-3.938-1.041-.875-2.328-1.552-3.859-2.031l1.86-3.453c1.875.562 3.53 1.37 4.968 2.422.834.614 1.401 1.364 1.703 2.25.302.885.454 2.255.454 4.11v14.921h-4.047zM426.797 325v-10.031h4.047V325h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.296 2.177.296 4.156V325h-4.046zm-36.422 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.447 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V325h-4.328zm-4.938-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.954-.718-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM376.86 325l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.454v7.187L386.438 325h-9.579zm-17.906 0l-2.234-17.688 3.922-1.39 1.796 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.916 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.291 3.568-5.687 4.704c-2.01.958-4.85 1.437-8.516 1.437zm-9.937 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.198.797.296 2.18.296 4.149V325h-4.046zm-24.625 0l1.562-4.625h5.516v-6.078c0-1.646-.354-2.724-1.063-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.297 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.516 1.922.516 3.454v7.187L333.969 325h-9.578zm-17.907 0l-2.234-17.688 3.922-1.39 1.797 14.453c2.666 0 4.794-.615 6.383-1.844 1.588-1.229 2.382-2.87 2.382-4.922 0-2.24-1.208-3.359-3.625-3.359-.645 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.917 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437-1.395 2-3.291 3.568-5.687 4.704-2.01.958-4.849 1.437-8.516 1.437zm-32.359 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.197.797.296 2.18.296 4.149v6.562h2.5L290.33 325h-16.204zm-19.219 0l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.094-1.578a28.973 28.973 0 004.937 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-8.687 0v-14.078h-9.531l1.546-4.625h16.094l-1.547 4.625h-2.515V325h-4.047zm-40.422 0v-10.031h4.047V325h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V325h-4.047zm-32.813.39l1.594-4.718c2.042-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-21.125 4.235v-14.61h4.047v14.61h-4.047zm-2.516-18.703l1.547-4.625h10.844c1.99 0 3.39.088 4.203.265.813.178 1.495.542 2.047 1.094.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.36 8.547-2.239 2.646-5.13 4.537-8.671 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.985-1.883-.656-.317-1.958-.476-3.906-.476h-10.39zM155.625 325v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V325h-4.047zm-25.516 0v-14.078h-2.53l1.562-4.625h10.89c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149V325h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.203V325h-4.047zm-9.656 0v-5.016h5.016V325h-5.016zm249.906 38v-10.031h4.047V363h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.171c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-36.86 0l-2.202-17.5 3.921-1.578 1.172 9.25c1.136-.281 1.933-.945 2.391-1.992.458-1.047.688-2.716.688-5.008v-1.875h4.343v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.993l.281 2.312c2.719 0 4.89-.453 6.516-1.36 2.843-1.583 4.265-5.192 4.265-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.234.671c-.136.396-.203.74-.203 1.032 0 1.01.87 1.583 2.609 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.969-2.703 7.125 1.734c2.312.563 3.815 1.284 4.507 2.164.693.88 1.04 2.503 1.04 4.868v6.078L339.656 363h-14.5zm-20.656 0v-10.031h4.047V363H304.5zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-48.14 0l2.265-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.195 5.664L274.188 363h-4.235zm-7.376 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V363h-4.047zm-31.14 0v-14.078h-2.532l1.563-4.625h10.89c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149V363h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.204V363h-4.047zm-6.344-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zM198.204 363l1.546-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L214.405 363h-16.203zm-21.032 0v-10.031h4.047V363h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625H187c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V363h-4.047zm-46.97 0v-.516c0-2.677.282-4.971.845-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V363h-4.328zm-24.265 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V363h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 363h-8.313zm285.016 31.734h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM378.812 401l1.532-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.761-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.957.312 1.77.87 2.437 1.671 1.062 1.271 1.593 3.063 1.593 5.375 0 1.844-.49 4.032-1.468 6.563L391.5 401h-12.688zm-7.453 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V401h-4.047zm-20.843.39l1.593-4.718c2.042-.23 3.688-.839 4.938-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.695-.484h-5.563v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-8.891-.39v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V401h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.546-4.625h8.579c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L322.188 401h-8.313zm-30.688 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.136-.281 1.932-.945 2.39-1.992.46-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.368 2.993l.282 2.312c2.719 0 4.89-.453 6.515-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.794 4.359-13.899 4.359zm-21.937 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.781-.235.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.868v6.078L275.75 401h-14.5zm-22.969 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.197.792.296 2.177.296 4.156V401h-4.046v-9.063c0-2.416-.204-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L246.594 401h-8.313zm-31.234 0v-10.031h4.047V401h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.684-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V401h-4.047zm-39.72 0l1.548-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.546-4.625h8.578c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L189.234 401h-8.312zm-13.171.39l-1.594-3.859c2.334-1.135 4.724-2.724 7.172-4.765l-.39-2.485c-.23-1.427-.566-2.398-1.008-2.914-.443-.515-1.42-1.075-2.93-1.68l-.89-.359 1.75-3.406c2.562.844 4.317 1.687 5.265 2.531.625.563 1.055 1.177 1.29 1.844.233.667.517 2.094.85 4.281l.61 4c.448 2.938.89 5.078 1.328 6.422h-4.36c-.28-1.115-.577-2.594-.89-4.438-1.542 1.553-3.61 3.162-6.203 4.829zm-5.375-6.656h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM147.281 401v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V401h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V401h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L127.844 401h-8.313zm218.406 38v-10.031h4.047V439h-4.046zm13.594 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V439h-4.047zm-35.687 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.828l1.546-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L332.047 439h-16.203zm-18.61 0l-1.765-14.078h-2.516l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.313 2.047 1.313 3.765 0 2.292-.662 4.506-1.985 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.218 1.969-8.875 1.969zm3.454-4.625c2.333-.177 4.088-.687 5.265-1.531 1.938-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.656-.328-1.948-.492-3.875-.492h-4.469l1.156 9.453zm-11.125-1.64H285.5c.73-2.667 1.094-4.574 1.094-5.72 0-.822-.36-1.473-1.078-1.952-.72-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM263.375 439l-1.766-14.078h-2.515l1.547-4.625h11.078c2.094 0 3.578.078 4.453.234.875.157 1.573.469 2.094.938.875.791 1.312 2.047 1.312 3.765 0 2.292-.661 4.506-1.984 6.641s-3.104 3.854-5.344 5.156c-2.26 1.313-5.219 1.969-8.875 1.969zm3.453-4.625c2.333-.177 4.089-.687 5.266-1.531 1.937-1.407 2.906-3.25 2.906-5.531 0-.938-.328-1.57-.984-1.899-.657-.328-1.948-.492-3.875-.492h-4.47l1.157 9.453zm-11.125-1.64h-4.062c.729-2.667 1.093-4.574 1.093-5.72 0-.822-.359-1.473-1.078-1.952-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM224.781 439l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.156V439h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L233.094 439h-8.313zm-102.89 0v-23.125h4.812v9.39h9.563v-9.39h4.812V439h-4.812v-10.547h-9.563V439h-4.812zm30.703 0v-19.953h-8.281v-3.172h21.39v3.172h-8.281V439h-4.828zm16.344 0v-23.125h6.375l5.562 16.266 5.734-16.266h5.594V439h-4.437v-17.453l-5.641 15.906h-3.875l-5.531-16.14V439h-3.781zm29.046 0v-23.125h4.813v19.844h10.422V439h-15.235zm204.094 38v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V477h-4.047zm-25.625 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.53 6.688-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.195 5.664L380.688 477h-4.235zm-19.984 0v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.447 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V477h-4.328zm-20.328 0l1.39-4.234H348v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.781-.234.671c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.046 0-.917.375-2.438 1.125-4.563l.969-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.039 2.503 1.039 4.868v6.078L350.64 477h-14.5zm-20.11 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.993l.281 2.312c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-9.969 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V477h-4.046zm-33.375 0l1.547-4.625h4.032c-.823-2.115-1.235-4.708-1.235-7.781v-1.672h-2.328l1.547-4.625h8.578c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.156V477h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078L281 477h-8.313zm-29.515 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L259.375 477h-16.203zm-18.156 0l1.53-4.625h8.735c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.958.312 1.77.87 2.437 1.671 1.062 1.271 1.594 3.063 1.594 5.375 0 1.844-.49 4.032-1.47 6.563L237.704 477h-12.687zm-7.547 4.625v-18.703h-10l1.547-4.625h12.5v23.328h-4.047zm-36.453-4.234l1.593-4.72c2.042-.228 3.688-.838 4.938-1.827 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.696-.484h-5.562v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-5.391-6.657h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM148.828 477l1.36-4.14h8.468c-3.833-3.709-6.713-8.162-8.64-13.36l4.093-1.578a28.973 28.973 0 004.938 8.875c1.469-1.781 2.203-3.943 2.203-6.485v-2.015h4.344v1.312c0 3.97-1.36 7.214-4.078 9.735 1.573 1.614 2.974 2.791 4.203 3.531l-1.39 4.125h-15.5zm-7.078 0v-9.594c0-1.927-.32-3.252-.96-3.976-.642-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.244.864.367 2.25.367 4.156V477h-4.047zm-11.844 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V477h-4.047zm207.406 31.734h-4.062c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.72-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zm-11.593 0h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.735-1.25l2.094-3.89c2.552.51 4.331 1.21 5.336 2.101s1.508 2.206 1.508 3.946c0 1.094-.25 2.76-.75 5l-.406 1.765zM297.656 515l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.993l.281 2.312c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.58 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-10.047 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.156V515h-4.047zm-25.625 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.757l.531 6.688-1.531 4.625h-9.031l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L266.219 515h-4.235zm-3.953-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.954-.718-.479-1.963-.895-3.734-1.25l2.094-3.89c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM219.86 515v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V515h-4.329zm-4.937-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.954-.719-.479-1.964-.895-3.734-1.25l2.093-3.89c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM192.75 515l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.843-3.437c1.73.427 3.297 1.047 4.703 1.86.907.53 1.532 1.182 1.875 1.952.344.771.516 1.922.516 3.454v7.187L202.328 515h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.704c-2.01.958-4.849 1.437-8.515 1.437zm-9.938 0v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V515h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.454v7.187L149.86 515h-9.578zm-17.906 0l-2.234-17.688 3.921-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.415.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.687 4.704c-2.01.958-4.85 1.437-8.516 1.437zm212.14 38l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.758l.531 6.687-1.531 4.625h-9.031l1.547-4.625h4.921l-.359-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L338.75 553h-4.234zm-23.28 0l1.546-4.625h4.031c-.822-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.296 2.177.296 4.157V553h-4.046v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078L319.547 553h-8.313zm-7.173 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.208 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V553h-4.046zm-25.515 0v-14.078h-2.531l1.562-4.625h10.89c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149V553h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.203V553h-4.047zm-20.485 0l1.532-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.761-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.15.156 4.11.469.957.312 1.77.87 2.437 1.672 1.062 1.27 1.593 3.062 1.593 5.375 0 1.843-.49 4.03-1.468 6.562L270.75 553h-12.688zm-21.156 0l2.266-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.219 2.008 1.052 1.338 1.677 3.257 1.875 5.758l.53 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.497 3.007-2.195 5.664L241.14 553h-4.235zm-3.953-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM204.641 553v-14.078h-2.485l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L220.453 553h-15.812zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687h-4.813v9.453zm-20.953-1.64h-4.063c.73-2.667 1.094-4.574 1.094-5.72 0-.822-.36-1.473-1.078-1.952-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM172.656 553v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V553h-4.047zm-27.75 0l1.547-4.625h4.031c-.823-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V553h-4.047v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-3.063v1.375c0 3.354.48 6.047 1.438 8.078L153.219 553h-8.313zm-7.094 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.28 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V553h-4.047zm-17.359 0v-5.016h5.016V553h-5.016zm322.688 38.39l1.593-4.718c2.042-.23 3.688-.839 4.938-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.961-1.844-.64-.323-1.873-.484-3.695-.484h-5.563v-9.625l4.047-1.36v6.36h4.062c2.5 0 4.243.36 5.227 1.078.984.719 1.476 1.984 1.476 3.797 0 3.437-1.317 6.49-3.953 9.156-2.635 2.667-6 4.354-10.093 5.063zm-22.594-.39l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.938 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.531 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.296-5.031-1.126 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L424.781 591h-4.234zm-21.625 2.781l1.562-4.672c1.667 0 3.459-.28 5.375-.843L402.5 573.28l3.875-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zM380.078 591l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.992l.281 2.313c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-23.562 0v-10.031h4.046V591h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V591h-4.047zm-21.78 0h-1.923v-5.016h5.016v3.891c0 4.094-1.672 6.14-5.016 6.14v-1.734c1.282 0 1.922-.927 1.922-2.781v-.5zm-31.204 0l1.531-4.625h8.735c.864-1.99 1.296-3.682 1.296-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.782 0 3.151.156 4.11.469.958.312 1.77.87 2.437 1.672 1.063 1.27 1.594 3.062 1.594 5.375 0 1.843-.49 4.03-1.469 6.562L329.813 591h-12.688zm-3.953-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM298.078 591v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.071-1.711l2-3.797c2.448.448 4.208 1.15 5.281 2.11.708.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V591h-4.047zm-25.14 0v-14.078h-2.485l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L288.75 591h-15.813zm4.062-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687H277v9.453zM265.203 591h-1.922v-5.016h5.016v3.891c0 4.094-1.672 6.14-5.016 6.14v-1.734c1.282 0 1.922-.927 1.922-2.781v-.5zm-20.484 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.048c3.135 0 5.229.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.149V591h-4.047zm-17.547 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V591h-4.047zm-23.719 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L219.655 591h-16.203zm-30.594 0v-.516c0-2.677.282-4.971.844-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.183 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V591h-4.329zm-24.265 0l1.547-4.625h4.03c-.822-2.115-1.233-4.708-1.233-7.781v-1.672h-2.329l1.547-4.625h8.578c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V591H164.5v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695H157v1.375c0 3.354.48 6.047 1.438 8.078L156.905 591h-8.312zm-7.094 0v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.891l1.531-4.625h5.047c3.135 0 5.23.458 6.281 1.375a3.773 3.773 0 011.219 1.992c.198.797.297 2.18.297 4.149V591H141.5zm-14.047-6.266h-4.062c.729-2.666 1.093-4.573 1.093-5.718 0-.823-.359-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.507 2.206 1.507 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM406.016 629v-10.031h4.046V629h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V629h-4.047zm-36.421 0v-.516c0-2.677.28-4.971.843-6.882.563-1.912 1.51-3.8 2.844-5.664l-.703-.672c-1.136-1.063-2.162-1.948-3.078-2.657l3.687-2.687c2.448 1.937 5.037 4.51 7.766 7.719.625-1.084 1.039-2.032 1.242-2.844.203-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.485 2.578c-2.062-3.709-4.864-7.355-8.406-10.938-1.26 1.958-1.89 4.948-1.89 8.969V629h-4.329zm-4.938-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM356.078 629l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.843-3.437c1.73.427 3.297 1.047 4.704 1.86.906.53 1.53 1.182 1.875 1.952.343.771.515 1.922.515 3.453v7.188L365.656 629h-9.578zm-17.906 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.493 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.848 1.438-8.515 1.438zm-9.938 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.282 1.375a3.773 3.773 0 011.218 1.992c.198.797.297 2.18.297 4.149V629h-4.047zm-24.625 0l1.563-4.625h5.515v-6.078c0-1.646-.354-2.724-1.062-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.453v7.188L313.188 629h-9.579zm-17.906 0l-2.234-17.688 3.922-1.39 1.796 14.453c2.667 0 4.795-.615 6.383-1.844 1.589-1.229 2.383-2.87 2.383-4.922 0-2.24-1.208-3.359-3.625-3.359-.646 0-1.338.104-2.078.313l1.406-4.36a9.102 9.102 0 012.235-.297c1.916 0 3.414.576 4.492 1.727 1.078 1.15 1.617 2.747 1.617 4.789 0 2.292-.698 4.437-2.094 6.437s-3.291 3.568-5.687 4.703c-2.01.959-4.85 1.438-8.516 1.438zm-34.078 0v-10.031h4.047V629h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V629h-4.047zm-37.594 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.532 6.687-1.532 4.625h-9.03l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L231.86 629h-4.234zm-7.453 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V629h-4.047zm-13.531 0v-14.078h-9.532l1.547-4.625h16.094l-1.547 4.625h-2.516V629h-4.046zm-16.282 0v-9.063c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.282 1.375a3.773 3.773 0 011.218 1.992c.198.797.297 2.18.297 4.149V629h-4.047zm-24.625 0l1.563-4.625h5.516v-6.078c0-1.646-.355-2.724-1.063-3.235-.948-.677-2.224-1.244-3.828-1.703l1.844-3.437c1.729.427 3.296 1.047 4.703 1.86.906.53 1.531 1.182 1.875 1.952.344.771.515 1.922.515 3.453v7.188L175.312 629h-9.578zm-3.625-6.266h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.72-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zm-11.593 0h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.735-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM122.203 629v-14.078h-2.484l1.547-4.625h10.484c3.135 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562L138.016 629h-15.813zm4.063-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.828-.687h-4.812v9.453zM401.844 667l2.265-8.688c.417-1.593.625-2.692.625-3.296 0-1.24-1.057-2.907-3.171-5l3.609-2.094c1.146.958 2.125 2.265 2.937 3.922 1.667-2.615 3.667-3.922 6-3.922 1.76 0 3.167.67 4.22 2.008 1.051 1.338 1.676 3.257 1.874 5.758l.531 6.687-1.53 4.625h-9.032l1.547-4.625h4.922l-.36-4.797c-.25-3.354-1.349-5.031-3.297-5.031-1.125 0-2.07.56-2.836 1.68-.765 1.12-1.497 3.007-2.195 5.664L406.078 667h-4.234zm-20.422 0l-2.203-17.5 3.922-1.578 1.171 9.25c1.136-.281 1.933-.945 2.391-1.992.458-1.047.688-2.716.688-5.008v-1.875h4.343v1.719c0 3.093-.565 5.445-1.695 7.054-1.13 1.61-2.92 2.607-5.367 2.992l.281 2.313c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.265-5.192 4.265-10.827v-1.891h4.329v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-18.969.39l1.594-4.718c2.042-.23 3.687-.839 4.937-1.828 1.948-1.542 2.922-3.406 2.922-5.594 0-.906-.32-1.52-.96-1.844-.641-.323-1.873-.484-3.696-.484h-5.563v-9.625l4.047-1.36v6.36h4.063c2.5 0 4.242.36 5.226 1.078.985.719 1.477 1.984 1.477 3.797 0 3.437-1.318 6.49-3.953 9.156-2.636 2.667-6 4.354-10.094 5.063zm-20.687-.39l1.546-4.625h9.641v-4.438c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.827-.695h-5.829l1.547-4.625h4.954c3.135 0 5.229.458 6.28 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L357.969 667h-16.203zm-4.016-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.335 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM309.437 667v-14.078h-2.484l1.547-4.625h10.484c3.136 0 5.23.458 6.282 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562L325.25 667h-15.813zm4.063-4.625h9.25v-4.438c0-2.427-.203-3.87-.61-4.328-.406-.458-1.682-.687-3.827-.687H313.5v9.453zM276.078 667l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.565 5.445-1.696 7.054-1.13 1.61-2.919 2.607-5.367 2.992l.281 2.313c2.72 0 4.891-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.742 12.782-3.162 2.906-7.795 4.359-13.899 4.359zm-21.937 0l1.39-4.234H266v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.782-.234.672c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.969-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.039 2.503 1.039 4.867v6.079L268.64 667h-14.5zm-20.657 0v-10.031h4.047V667h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V667h-4.047zm-38.234 0v-7.016c0-2.354.682-4.343 2.047-5.968L206 651.938l1.719-4.016 11.094 4.719-1.672 4.062-3.125-1.36c-.75.938-1.125 2.256-1.125 3.954V667h-4.047zm-9.735 0v-9.594c0-1.927-.32-3.252-.96-3.976-.641-.724-1.998-1.295-4.07-1.711l2-3.797c2.447.448 4.207 1.15 5.28 2.11.709.635 1.185 1.385 1.43 2.25.245.864.367 2.25.367 4.155V667h-4.047zm-11.734 0v-5.016h5.016V667h-5.016zm-32.156 0v-10.031h4.047V667h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.618-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.281 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V667h-4.047zm-20.391-6.266h-4.063c.73-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.078-1.953-.719-.48-1.964-.896-3.734-1.25l2.093-3.891c2.552.51 4.331 1.21 5.336 2.101 1.006.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.406 1.765zM120.797 667v-.516c0-2.677.281-4.971.844-6.882.562-1.912 1.51-3.8 2.843-5.664l-.703-.672c-1.135-1.063-2.161-1.948-3.078-2.657l3.688-2.687c2.448 1.937 5.036 4.51 7.765 7.719.625-1.084 1.04-2.032 1.242-2.844.204-.813.305-1.927.305-3.344v-1.156h4.328v.906c0 3.521-1.182 6.568-3.547 9.14a41.618 41.618 0 014.422 6.47l-3.484 2.578c-2.063-3.709-4.865-7.355-8.406-10.938-1.26 1.958-1.891 4.948-1.891 8.969V667h-4.328zm275.937 31.734h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zM380.031 705v-14.078H370.5l1.547-4.625h16.094l-1.547 4.625h-2.516V705h-4.047zm-16.36 0v-9.594c0-1.927-.32-3.252-.96-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V705h-4.047zm-26.093 2.781l1.563-4.672c1.666 0 3.458-.28 5.375-.843l-3.36-14.985 3.875-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.345v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.154 4.88-5.79 6.64-3.697 2.469-7.635 3.703-11.812 3.703zM318.188 705v-10.031h4.046V705h-4.046zm13.593 0v-9.063c0-2.416-.205-3.856-.617-4.32-.411-.463-1.685-.695-3.82-.695h-12.047l1.547-4.625h11.172c3.135 0 5.229.458 6.28 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V705h-4.047zm-46.234 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L301.75 705h-16.203zm-21.688 2.781l1.563-4.672c1.667 0 3.458-.28 5.375-.843l-3.36-14.985 3.875-1.36 3.266 14.563c1.636-1.24 2.774-2.78 3.414-4.625.64-1.843.961-4.484.961-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.154 4.88-5.79 6.64-3.697 2.469-7.635 3.703-11.812 3.703zm-2.375-9.047h-4.062c.729-2.666 1.094-4.573 1.094-5.718 0-.823-.36-1.474-1.079-1.953-.718-.48-1.963-.896-3.734-1.25l2.094-3.891c2.552.51 4.33 1.21 5.336 2.101 1.005.891 1.508 2.206 1.508 3.946 0 1.094-.25 2.76-.75 5l-.407 1.765zm-27.328 10.891v-14.61h4.047v14.61h-4.047zm-2.515-18.703l1.547-4.625h10.843c1.99 0 3.39.088 4.203.265.813.178 1.495.542 2.047 1.094.802.813 1.203 1.98 1.203 3.5 0 3.052-1.12 5.901-3.359 8.547-2.24 2.646-5.13 4.537-8.672 5.672l1.672-4.969c1.656-.469 3.036-1.383 4.14-2.742 1.105-1.36 1.657-2.82 1.657-4.383 0-.937-.328-1.565-.984-1.883-.657-.317-1.959-.476-3.907-.476h-10.39zM224.406 705v-9.063c0-2.416-.203-3.856-.61-4.32-.405-.463-1.681-.695-3.827-.695h-5.89l1.53-4.625h5.047c3.136 0 5.23.458 6.281 1.375a3.773 3.773 0 011.22 1.992c.197.797.296 2.18.296 4.149V705h-4.047zm-38.734 0l1.531-4.625h8.734c.865-1.99 1.297-3.682 1.297-5.078 0-1.646-.38-2.787-1.14-3.422-.76-.635-2.13-.953-4.11-.953h-5.406l1.531-4.625h5.094c1.781 0 3.151.156 4.11.469.958.312 1.77.87 2.437 1.672 1.063 1.27 1.594 3.062 1.594 5.375 0 1.843-.49 4.03-1.469 6.562L198.359 705h-12.687zm-20.422 0l-2.203-17.5 3.922-1.578 1.172 9.25c1.135-.281 1.932-.945 2.39-1.992.459-1.047.688-2.716.688-5.008v-1.875h4.344v1.719c0 3.093-.566 5.445-1.696 7.054-1.13 1.61-2.92 2.607-5.367 2.992l.281 2.313c2.719 0 4.89-.453 6.516-1.36 2.844-1.583 4.266-5.192 4.266-10.827v-1.891h4.328v1.562c0 5.615-1.581 9.875-4.743 12.782-3.161 2.906-7.794 4.359-13.898 4.359zm-21.938 0l1.391-4.234h10.469v-4.157c0-1.948-.193-3.205-.578-3.773-.386-.568-1.386-1.065-3-1.492l-2.985-.782-.234.672c-.135.396-.203.74-.203 1.032 0 1.01.87 1.583 2.61 1.718l-1.079 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.969-2.703 7.125 1.734c2.312.563 3.815 1.284 4.508 2.164.692.88 1.039 2.503 1.039 4.867v6.079L157.813 705h-14.5zm-20.656 0v-10.031h4.047V705h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.047l1.546-4.625h11.172c3.136 0 5.23.458 6.282 1.375a3.733 3.733 0 011.234 1.984c.198.792.297 2.177.297 4.157V705h-4.047zm169.5 38v-10.031h4.047V743h-4.047zm13.594 0v-9.063c0-2.416-.206-3.856-.617-4.32-.412-.463-1.685-.695-3.82-.695h-12.048l1.547-4.625h11.172c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V743h-4.047zm-37.594 0l2.266-8.688c.416-1.593.625-2.692.625-3.296 0-1.24-1.058-2.907-3.172-5l3.61-2.094c1.145.958 2.124 2.265 2.937 3.922 1.666-2.615 3.666-3.922 6-3.922 1.76 0 3.166.67 4.218 2.008s1.677 3.257 1.875 5.758l.532 6.687-1.532 4.625h-9.03l1.546-4.625h4.922l-.36-4.797c-.25-3.354-1.348-5.031-3.296-5.031-1.125 0-2.07.56-2.836 1.68-.766 1.12-1.498 3.007-2.196 5.664L285.984 743h-4.234zm-7.453 0v-9.594c0-1.927-.32-3.252-.961-3.976-.64-.724-1.997-1.295-4.07-1.711l2-3.797c2.448.448 4.208 1.15 5.28 2.11.71.635 1.186 1.385 1.43 2.25.245.864.368 2.25.368 4.155V743h-4.047zm-22.703 0l-2.235-17.688 3.922-1.39 1.797 14.453c2.667 0 4.794-.615 6.383-1.844 1.588-1.229 2.383-2.87 2.383-4.922 0-2.24-1.209-3.359-3.625-3.359-.646 0-1.339.104-2.078.313l1.406-4.36a9.102 9.102 0 012.234-.297c1.917 0 3.414.576 4.492 1.727 1.079 1.15 1.618 2.747 1.618 4.789 0 2.292-.698 4.437-2.094 6.437s-3.292 3.568-5.688 4.703c-2.01.959-4.849 1.438-8.515 1.438zm-21.813 0l1.547-4.625h9.64v-4.438c0-2.416-.202-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.136 0 5.23.458 6.281 1.375a3.734 3.734 0 011.235 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L245.984 743h-16.203zm-21.687 2.781l1.562-4.672c1.667 0 3.459-.28 5.375-.843l-3.36-14.985 3.876-1.36 3.266 14.563c1.635-1.24 2.773-2.78 3.414-4.625.64-1.843.96-4.484.96-7.922v-1.64h4.344v1.156c0 3.99-.612 7.318-1.836 9.985-1.224 2.666-3.153 4.88-5.789 6.64-3.698 2.469-7.635 3.703-11.812 3.703zM186.39 743l1.547-4.625h4.03c-.822-2.115-1.234-4.708-1.234-7.781v-1.672h-2.328l1.547-4.625h8.578c3.136 0 5.23.458 6.281 1.375a3.733 3.733 0 011.235 1.984c.198.792.297 2.177.297 4.157V743h-4.047v-9.063c0-2.416-.203-3.856-.61-4.32-.406-.463-1.682-.695-3.828-.695h-3.062v1.375c0 3.354.479 6.047 1.437 8.078l-1.53 4.625h-8.313zm-29.516 0l1.547-4.625h9.64v-4.438c0-2.416-.203-3.856-.609-4.32-.406-.463-1.682-.695-3.828-.695h-5.828l1.547-4.625h4.953c3.135 0 5.229.458 6.281 1.375a3.734 3.734 0 011.234 1.992c.198.797.297 2.18.297 4.149v6.562h2.5L173.08 743h-16.204zm-9.125 0v-14.078h-9.531l1.547-4.625h16.093l-1.547 4.625h-2.515V743h-4.047zm-28.25 0l1.39-4.234h10.47v-4.157c0-1.948-.193-3.205-.579-3.773-.385-.568-1.385-1.065-3-1.492l-2.984-.782-.234.672c-.136.396-.204.74-.204 1.032 0 1.01.87 1.583 2.61 1.718l-1.078 3.25c-3.5-.323-5.25-1.671-5.25-4.047 0-.916.375-2.437 1.125-4.562l.968-2.703 7.125 1.734c2.313.563 3.815 1.284 4.508 2.164.693.88 1.04 2.503 1.04 4.867v6.079L134 743h-14.5z"/><path id="Rectangle-1" stroke="#C06334" stroke-width="2" d="M117 106h282v198H117z"/><g id="Rectangle-209-+-Rectangle-208" fill="#DBAF88" transform="translate(15 14)"><path id="Rectangle-209" d="M0 1h50v300H0z"/><path id="Rectangle-208" d="M165.5-129.5h50v311h-50z" transform="rotate(-90 190.5 26)"/></g><path id="Rectangle-5" fill="url(#linearGradient-1)" d="M45-7h275v447H45z" transform="rotate(-180 182.5 216.5)"/><path id="Rectangle-6" fill="#FFF" d="M319 8h162v399H319z"/><g id="Group-2" transform="translate(65 65)"><rect id="Rectangle-19" width="20" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="20" height="19" x=".5" y=".5" fill="url(#linearGradient-2)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M10.5 7l4.2 6H6.3z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="20" height="19" x=".5" y=".5" fill="url(#linearGradient-2)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M10.5 7l4.2 6H6.3z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-3)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="20" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(5.25 20)"><path id="Rectangle-22" d="M.5.5H10v1H.5z"/><path id="Rectangle-23" d="M.5 3.5H10v1H.5z"/><path id="Rectangle-24" d="M.5 6.5H10v1H.5z"/><path id="Rectangle-25" d="M.5 9.5H10v1H.5z"/></g></g></g><path id="Line-7" fill="#C06334" fill-rule="nonzero" d="M65.41 15.68l7 14h-6.001v20h6.001l-7 14-7-14h5.999v-20H58.41l7-14z"/><path id="Line-28" fill="#C06334" fill-rule="nonzero" d="M72 57.68l14 7-14 7-.001-6h-42.59l.001 6-14-7 14-7-.001 6h42.59l.001-6z"/><text id="clientTop:25px-=-bor" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="78.7" y="43" fill="#C06334">clientTop:</tspan> <tspan x="150.7" y="43" fill="#1C85B5">25px </tspan> <tspan x="186.7" y="43" fill="#C06334">= border</tspan></text><text id="clientLeft:41px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 40.32 125)"><tspan x="-13.68" y="129" fill="#C06334">clientLeft:</tspan> <tspan x="65.52" y="129" fill="#1C85B5">41px</tspan></text><g id="Rectangle-8-+-Rectangle-7" transform="translate(-42 -3)"><path id="Rectangle-8" fill="url(#linearGradient-1)" d="M86.5-85.5h275v447h-275z" transform="rotate(-90 224 138)"/><path id="Rectangle-7" fill="#FFF" d="M152 156h162v399H152z" transform="rotate(90 233 355.5)"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg index 5708047d41..968590466e 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="353" height="316" viewBox="0 0 353 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="0%" x2="62.299%" y1="47.096%" y2="47.096%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#FFF" stop-opacity="0"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-left-top.svg"><path fill="#FFF" d="M0 0h353v316H0z"/><path id="Rectangle-206" fill="#EBCB9D" d="M12 15h50v300H12z"/><path id="Rectangle-207" fill="#EBCB9D" d="M177.5-115.5h50v311h-50z" transform="rotate(-90 202.5 40)"/><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="32" font-weight="bold"><tspan x="102" y="134">Introduction</tspan> <tspan x="102" y="183" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="102" y="216" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">several originating technologies, </tspan> <tspan x="102" y="249" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">the most well known being </tspan> <tspan x="102" y="282" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">JavaScript (Netscape) and JScript </tspan> <tspan x="102" y="315" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="102" y="348" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">invented by Brendan Eich at </tspan> <tspan x="102" y="381" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Netscape and first appeared in </tspan> <tspan x="102" y="414" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">that companyโ€™s Navigator 2.0 </tspan> <tspan x="102" y="447" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">browser. It has appeared in all </tspan> <tspan x="102" y="480" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">subsequent browsers from </tspan> <tspan x="102" y="513" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Netscape and in all browsers </tspan> <tspan x="102" y="546" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">from Microsoft starting with </tspan> <tspan x="102" y="579" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="102" y="612" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">The development of this </tspan> <tspan x="102" y="645" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Standard started in November </tspan> <tspan x="102" y="678" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">1996. The first edition of this </tspan> <tspan x="102" y="711" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Ecma Standard was adopted by </tspan> <tspan x="102" y="744" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">the Ecma General Assembly of </tspan> <tspan x="102" y="777" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">June 1997.</tspan></text><path id="Rectangle-5" fill="url(#linearGradient-1)" d="M42-7h275v447H42z" transform="rotate(-180 179.5 216.5)"/><path id="Rectangle-6" fill="#FFF" d="M316 8h162v399H316z"/><path id="Line-7" fill="#EE6B47" fill-rule="nonzero" d="M62.41 15.68l7 14h-6.001v20h6.001l-7 14-7-14h5.999v-20H55.41l7-14z"/><path id="Line-28" fill="#EE6B47" fill-rule="nonzero" d="M46.41 57.68l14 7-14 7-.001-6h-20l.001 6-14-7 14-7-.001 6h20l.001-6z"/><text id="clientTop:25px-=-bor" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="75.7" y="43" fill="#EE6B47">clientTop:</tspan> <tspan x="147.7" y="43" fill="#3B86C4">25px </tspan> <tspan x="183.7" y="43" fill="#EE6B47">= border</tspan></text><text id="clientLeft:25px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 37.32 136)"><tspan x="-16.68" y="140" fill="#EE6B47">clientLeft:</tspan> <tspan x="62.52" y="140" fill="#3B86C4">25px</tspan></text><g id="Rectangle-8-+-Rectangle-7" transform="translate(-45 -3)"><path id="Rectangle-8" fill="url(#linearGradient-1)" d="M86.5-85.5h275v447h-275z" transform="rotate(-90 224 138)"/><path id="Rectangle-7" fill="#FFF" d="M152 156h162v399H152z" transform="rotate(90 233 355.5)"/></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="353" height="316" viewBox="0 0 353 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="0%" x2="62.299%" y1="47.096%" y2="47.096%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#FFF"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-left-top.svg"><path fill="#FFF" d="M0 0h353v316H0z"/><path id="Rectangle-206" fill="#DBAF88" d="M12 15h50v300H12z"/><path id="Rectangle-207" fill="#DBAF88" d="M177.5-115.5h50v311h-50z" transform="rotate(-90 202.5 40)"/><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="32" font-weight="bold"><tspan x="102" y="134">Introduction</tspan> <tspan x="102" y="183" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="102" y="216" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">several originating </tspan> <tspan x="102" y="249" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">technologies, the most well </tspan> <tspan x="102" y="282" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">known being JavaScript </tspan> <tspan x="102" y="315" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">(Netscape) and JScript </tspan> <tspan x="102" y="348" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="102" y="381" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">invented by Brendan Eich at </tspan> <tspan x="102" y="414" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Netscape and first appeared in </tspan> <tspan x="102" y="447" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">that companyโ€™s Navigator 2.0 </tspan> <tspan x="102" y="480" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">browser. It has appeared in all </tspan> <tspan x="102" y="513" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">subsequent browsers from </tspan> <tspan x="102" y="546" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Netscape and in all browsers </tspan> <tspan x="102" y="579" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">from Microsoft starting with </tspan> <tspan x="102" y="612" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="102" y="645" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">The development of this </tspan> <tspan x="102" y="678" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Standard started in November </tspan> <tspan x="102" y="711" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">1996. The first edition of this </tspan> <tspan x="102" y="744" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">Ecma Standard was adopted by </tspan> <tspan x="102" y="777" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">the Ecma General Assembly of </tspan> <tspan x="102" y="810" font-family="OpenSans-Regular, Open Sans" font-size="24" font-weight="normal">June 1997.</tspan></text><path id="Rectangle-5" fill="url(#linearGradient-1)" d="M42-7h275v447H42z" transform="rotate(-180 179.5 216.5)"/><path id="Rectangle-6" fill="#FFF" d="M316 8h162v399H316z"/><path id="Line-7" fill="#C06334" fill-rule="nonzero" d="M62.41 15.68l7 14h-6.001v20h6.001l-7 14-7-14h5.999v-20H55.41l7-14z"/><path id="Line-28" fill="#C06334" fill-rule="nonzero" d="M46.41 57.68l14 7-14 7-.001-6h-20l.001 6-14-7 14-7-.001 6h20l.001-6z"/><text id="clientTop:25px-=-bor" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="75.7" y="43" fill="#C06334">clientTop:</tspan> <tspan x="147.7" y="43" fill="#1C85B5">25px </tspan> <tspan x="183.7" y="43" fill="#C06334">= border</tspan></text><text id="clientLeft:25px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 37.32 136)"><tspan x="-16.68" y="140" fill="#C06334">clientLeft:</tspan> <tspan x="62.52" y="140" fill="#1C85B5">25px</tspan></text><g id="Rectangle-8-+-Rectangle-7" transform="translate(-45 -3)"><path id="Rectangle-8" fill="url(#linearGradient-1)" d="M86.5-85.5h275v447h-275z" transform="rotate(-90 224 138)"/><path id="Rectangle-7" fill="#FFF" d="M152 156h162v399H152z" transform="rotate(90 233 355.5)"/></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg index fe4b3c69d7..83864b4c57 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="500" height="493" viewBox="0 0 500 493"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-width-height.svg"><path id="Rectangle-2" fill="#E8C48F" fill-opacity=".88" d="M411 130v290H21V130h390zm-25 25H46v240h340V155z"/><path id="Rectangle-1" stroke="#EE6B47" stroke-width="2" d="M67 177v199h283V177H67z"/><g id="Scrollbar" transform="translate(370 155)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="12.9" y="75" fill="#EE6B47">border</tspan> <tspan x="20.1" y="89" fill="#3B86C4">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="32.3" y="45" fill="#EE6B47">padding</tspan> <tspan x="43.1" y="59" fill="#3B86C4">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="139.1" y="109" fill="#EE6B47">content width:</tspan> <tspan x="239.9" y="109" fill="#3B86C4">284px</tspan></text><path id="Line-15" fill="#EE6B47" fill-rule="nonzero" d="M336.5 110l14 7-14 7v-6H82.679l.001 6-14-7 14-7-.001 6H336.5v-6z"/><path id="Line-14" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M21.48 93v43"/><path id="Line-13" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M47.48 93v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="376.9" y="76" fill="#EE6B47">border</tspan> <tspan x="384.1" y="90" fill="#3B86C4">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="339.3" y="16" fill="#EE6B47">padding</tspan> <tspan x="350.1" y="30" fill="#3B86C4">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="349.1" y="48" fill="#EE6B47">scrollbar</tspan> <tspan x="367.1" y="62" fill="#3B86C4">16px</tspan></text><path id="Line-17" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371.48 93v43"/><path id="Line-20" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M385.48 93v43"/><path id="Line-18" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M410.48 93v41"/><path id="Line-16" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M66.48 93v41"/><path id="Line-19" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.48 93v41"/><text id="clientWidth-=-20+284" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="80.3" y="473" fill="#EE6B47">clientWidth = </tspan> <tspan x="197.9" y="473" fill="#3B86C4">20+284+20 </tspan> <tspan x="281.9" y="473" fill="#F38158">=</tspan> <tspan x="290.3" y="473" fill="#3B86C4"> 324px</tspan></text><path id="Line-24" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M46.5 376v88.142"/><path id="Line-25" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M370.5 376v88.142"/><path id="Line-22" fill="#EE6B47" fill-rule="nonzero" d="M354 445.071l14 7-14 7v-6.001H62v6.001l-14-7 14-7v5.999h292v-5.999z"/><text id="clientHeight:240px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 488.5 277.5)"><tspan x="412.9" y="282" fill="#EE6B47">clientHeight:</tspan> <tspan x="522.1" y="282" fill="#3B86C4">240px</tspan></text><path id="Line-27" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M365.5 156h120"/><path id="Line-28" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M365.5 394h120"/><path id="Line-26" fill="#EE6B47" fill-rule="nonzero" d="M476 160l7 14-6-.001V375h6l-7 14-7-14h6V173.999l-6 .001 7-14z"/><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 422.5 274)"><tspan x="379.3" y="278" fill="#EE6B47">height:</tspan> <tspan x="429.7" y="278" fill="#3B86C4">200px</tspan></text><path id="Line-3" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.5 175h88.142"/><path id="Line-2" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.5 377h88.142"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M435 177.5l7 14h-6V360h6l-7 14-7-14h6V191.5h-6l7-14z"/><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="69" y="193">Introduction</tspan> <tspan x="69" y="221" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="69" y="240" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="69" y="259" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="69" y="278" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="69" y="297" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="69" y="316" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="69" y="335" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="69" y="354" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="69" y="373" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="500" height="493" viewBox="0 0 500 493"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-width-height.svg"><path id="Rectangle-2" fill="#DBAF88" d="M411 130v290H21V130h390zm-25 25H46v240h340V155z"/><path id="Rectangle-1" stroke="#C06334" stroke-width="2" d="M350 177v199H67V177h283z"/><g id="Group" transform="translate(370 155)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="12.9" y="75" fill="#C06334">border</tspan> <tspan x="20.1" y="89" fill="#1C85B5">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="32.3" y="45" fill="#C06334">padding</tspan> <tspan x="43.1" y="59" fill="#1C85B5">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="139.1" y="109" fill="#C06334">content width:</tspan> <tspan x="239.9" y="109" fill="#1C85B5">284px</tspan></text><path id="Line-15" fill="#C06334" fill-rule="nonzero" d="M336.5 110l14 7-14 7v-6H82.679l.001 6-14-7 14-7-.001 6H336.5v-6z"/><path id="Line-14" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M21.48 93v43"/><path id="Line-13" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M47.48 93v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="376.9" y="76" fill="#C06334">border</tspan> <tspan x="384.1" y="90" fill="#1C85B5">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="339.3" y="16" fill="#C06334">padding</tspan> <tspan x="350.1" y="30" fill="#1C85B5">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="349.1" y="48" fill="#C06334">scrollbar</tspan> <tspan x="367.1" y="62" fill="#1C85B5">16px</tspan></text><path id="Line-17" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371.48 93v43"/><path id="Line-20" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M385.48 93v43"/><path id="Line-18" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M410.48 93v41"/><path id="Line-16" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M66.48 93v41"/><path id="Line-19" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.48 93v41"/><text id="clientWidth-=-20+284" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="80.3" y="473" fill="#C06334">clientWidth = </tspan> <tspan x="197.9" y="473" fill="#1C85B5">20+284+20 </tspan> <tspan x="281.9" y="473" fill="#C06334">=</tspan> <tspan x="290.3" y="473" fill="#1C85B5"> 324px</tspan></text><path id="Line-24" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M46.5 376v88.142"/><path id="Line-25" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M370.5 376v88.142"/><path id="Line-22" fill="#C06334" fill-rule="nonzero" d="M354 445.071l14 7-14 7v-6.001H62v6.001l-14-7 14-7v5.999h292v-5.999z"/><text id="clientHeight:240px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 488.5 277.5)"><tspan x="412.9" y="282" fill="#C06334">clientHeight:</tspan> <tspan x="522.1" y="282" fill="#1C85B5">240px</tspan></text><path id="Line-27" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M365.5 156h120"/><path id="Line-28" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M365.5 394h120"/><path id="Line-26" fill="#C06334" fill-rule="nonzero" d="M476 160l7 14-6-.001V375h6l-7 14-7-14h6V173.999l-6 .001 7-14z"/><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 422.5 274)"><tspan x="379.3" y="278" fill="#C06334">height:</tspan> <tspan x="429.7" y="278" fill="#1C85B5">200px</tspan></text><path id="Line-3" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.5 175h88.142"/><path id="Line-2" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M353.5 377h88.142"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M435 177.5l7 14h-6V360h6l-7 14-7-14h6V191.5h-6l7-14z"/><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="69" y="193">Introduction</tspan> <tspan x="69" y="221" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="69" y="240" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="69" y="259" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="69" y="278" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="69" y="297" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="69" y="316" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="69" y="335" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="69" y="354" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="69" y="373" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg b/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg index 62de5f5721..330d2a7c04 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-width-nopadding.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="409" height="467" viewBox="0 0 409 467"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-width-nopadding.svg"><path fill="#FFF" d="M0 0h409v467H0z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M389 131v250H35V131h354zm-25 25H60v200h304V156z"/><text id="clientWidth:284px-=-" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="84.7" y="399.642" fill="#EE6B47">clientWidth:</tspan> <tspan x="171.1" y="399.642" fill="#3B86C4">284px </tspan> <tspan x="214.3" y="399.642" fill="#EE6B47">= content width</tspan></text><path id="Line-44" fill="#EE6B47" fill-rule="nonzero" d="M329.68 402.642l14 7-14 7-.001-6.001h-252l.001 6-14-7 14-7-.001 6h252l.001-6z"/><text id="CSS-width:-300px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="145.9" y="429.642" fill="#F38158">CSS width:</tspan> <tspan x="217.9" y="429.642" fill="#3B86C4"> 300px</tspan></text><path id="Line-47" fill="#EE6B47" fill-rule="nonzero" d="M349 427.642l14 7-14 7v-6.001H76.679l.001 6-14-7 14-7-.001 6H349v-6z"/><text id="Introduction-This-Ec" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="62" y="173">Introduction</tspan> <tspan x="62" y="201" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="62" y="220" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="62" y="239" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="62" y="258" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="62" y="277" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="62" y="296" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="62" y="315" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="62" y="334" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="62" y="353" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan></text><ellipse id="Oval-5" cx="191" cy="58.858" fill="#FFF9EB" stroke="#EE6B47" stroke-width="2" rx="76" ry="43.5"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M192 103v11.638h6l-7 14-7-14h6V103h2z"/><text id="padding:-0;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="16" font-weight="normal"><tspan x="136" y="52">padding: 0;</tspan> <tspan x="136" y="70">width: 300px;</tspan></text><g id="Group-2" transform="translate(348 156)"><rect id="Rectangle-19" width="15" height="199" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 200)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><path id="Line-46" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M60.5 354.642v96"/><path id="Line-45" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M345.5 354.642V414"/><path id="Line-48" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M363.5 354.642v96"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="409" height="467" viewBox="0 0 409 467"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-client-width-nopadding.svg"><path fill="#FFF" d="M0 0h409v467H0z"/><path id="Rectangle-1" fill="#DBAF88" d="M389 131v250H35V131h354zm-25 25H60v200h304V156z"/><text id="clientWidth:284px-=-" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="84.7" y="399.642" fill="#C06334">clientWidth:</tspan> <tspan x="171.1" y="399.642" fill="#1C85B5">284px </tspan> <tspan x="214.3" y="399.642" fill="#C06334">= content width</tspan></text><path id="Line-44" fill="#C06334" fill-rule="nonzero" d="M329.68 402.642l14 7-14 7-.001-6.001h-252l.001 6-14-7 14-7-.001 6h252l.001-6z"/><text id="CSS-width:-300px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="145.9" y="429.642" fill="#C06334">CSS width:</tspan> <tspan x="217.9" y="429.642" fill="#1C85B5"> 300px</tspan></text><path id="Line-47" fill="#C06334" fill-rule="nonzero" d="M349 427.642l14 7-14 7v-6.001H76.679l.001 6-14-7 14-7-.001 6H349v-6z"/><text id="Introduction-This-Ec" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="62" y="173">Introduction</tspan> <tspan x="62" y="201" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="62" y="220" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="62" y="239" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="62" y="258" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="62" y="277" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="62" y="296" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="62" y="315" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="62" y="334" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="62" y="353" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan></text><ellipse id="Oval-5" cx="191" cy="58.858" fill="#FBF2EC" stroke="#C06334" stroke-width="2" rx="76" ry="43.5"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M192 103v11.638h6l-7 14-7-14h6V103h2z"/><text id="padding:-0;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="16" font-weight="normal"><tspan x="136" y="52">padding: 0;</tspan> <tspan x="136" y="70">width: 300px;</tspan></text><g id="Group-2" transform="translate(348 156)"><rect id="Rectangle-19" width="15" height="199" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 200)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><path id="Line-46" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M60.5 354.642v96"/><path id="Line-45" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M345.5 354.642V414"/><path id="Line-48" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M363.5 354.642v96"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-css.svg b/2-ui/1-document/09-size-and-scroll/metric-css.svg index e910a9c875..13aa62afd0 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-css.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-css.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="566" height="469" viewBox="0 0 566 469"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-css.svg"><path id="Rectangle-1" stroke="#EE6B47" stroke-width="2" d="M177 184v199h283V184H177z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M521 139v290H131V139h390zm-25 25H156v240h340V164z"/><g id="Scrollbar" transform="translate(480 163)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="padding:20px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="7" y="176" fill="#EE6B47">padding:</tspan> <tspan x="64.6" y="176" fill="#3B86C4">20px</tspan></text><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 530.5 282)"><tspan x="487.3" y="286" fill="#EE6B47">height:</tspan> <tspan x="537.7" y="286" fill="#3B86C4">200px</tspan></text><path id="Line" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M461.5 183h88.142"/><path id="Line-3" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 184h88.142"/><path id="Line-4" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 162h88.142"/><path id="Line-2" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M461.5 385h88.142"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M543 185.5l7 14h-6V368h6l-7 14-7-14h6V199.5h-6l7-14z"/><text id="padding:20px-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="7" y="396" fill="#EE6B47">padding:</tspan> <tspan x="64.6" y="396" fill="#3B86C4">20px</tspan></text><path id="Line-5" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 404h88.142"/><path id="Line-6" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 382h88.142"/><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="122.9" y="83" fill="#EE6B47">border</tspan> <tspan x="130.1" y="97" fill="#3B86C4">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="142.3" y="53" fill="#EE6B47">padding</tspan> <tspan x="153.1" y="67" fill="#3B86C4">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="249.1" y="117" fill="#EE6B47">content width:</tspan> <tspan x="349.9" y="117" fill="#3B86C4">284px</tspan></text><path id="Line-21" fill="#EE6B47" fill-rule="nonzero" d="M446.5 118l14 7-14 7v-6H192.679l.001 6-14-7 14-7-.001 6H446.5v-6z"/><path id="Line-14" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M131.48 101v43"/><path id="Line-13" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M157.48 101v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="486.9" y="84" fill="#EE6B47">border</tspan> <tspan x="494.1" y="98" fill="#3B86C4">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="449.3" y="24" fill="#EE6B47">padding</tspan> <tspan x="460.1" y="38" fill="#3B86C4">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="459.1" y="56" fill="#EE6B47">scrollbar</tspan> <tspan x="477.1" y="70" fill="#3B86C4">16px</tspan></text><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="178" y="200">Introduction</tspan> <tspan x="178" y="228" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="178" y="247" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="178" y="266" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="178" y="285" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="178" y="304" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="178" y="323" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="178" y="342" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="178" y="361" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and in </tspan> <tspan x="178" y="380" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">all browsers from Microsoft starting with</tspan> <tspan x="178" y="399" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan></text><path id="Line-17" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M481.48 101v43"/><path id="Line-20" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M495.48 101v43"/><path id="Line-18" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M520.48 101v41"/><path id="Line-16" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M176.48 101v41"/><path id="Line-19" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M463.48 101v41"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="566" height="469" viewBox="0 0 566 469"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-css.svg"><path id="Rectangle-1" stroke="#C06334" stroke-width="2" d="M460 184v199H177V184h283z"/><path id="Rectangle-1" fill="#DBAF88" d="M521 139v290H131V139h390zm-25 25H156v240h340V164z"/><g id="Group" transform="translate(480 163)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="padding:20px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="7" y="176" fill="#C06334">padding:</tspan> <tspan x="64.6" y="176" fill="#1C85B5">20px</tspan></text><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 530.5 282)"><tspan x="487.3" y="286" fill="#C06334">height:</tspan> <tspan x="537.7" y="286" fill="#1C85B5">200px</tspan></text><path id="Line" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M461.5 183h88.142"/><path id="Line-3" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 184h88.142"/><path id="Line-4" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 162h88.142"/><path id="Line-2" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M461.5 385h88.142"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M543 185.5l7 14h-6V368h6l-7 14-7-14h6V199.5h-6l7-14z"/><text id="padding:20px-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="7" y="396" fill="#C06334">padding:</tspan> <tspan x="64.6" y="396" fill="#1C85B5">20px</tspan></text><path id="Line-5" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 404h88.142"/><path id="Line-6" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M93.5 382h88.142"/><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="122.9" y="83" fill="#C06334">border</tspan> <tspan x="130.1" y="97" fill="#1C85B5">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="142.3" y="53" fill="#C06334">padding</tspan> <tspan x="153.1" y="67" fill="#1C85B5">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="249.1" y="117" fill="#C06334">content width:</tspan> <tspan x="349.9" y="117" fill="#1C85B5">284px</tspan></text><path id="Line-21" fill="#C06334" fill-rule="nonzero" d="M446.5 118l14 7-14 7v-6H192.679l.001 6-14-7 14-7-.001 6H446.5v-6z"/><path id="Line-14" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M131.48 101v43"/><path id="Line-13" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M157.48 101v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="486.9" y="84" fill="#C06334">border</tspan> <tspan x="494.1" y="98" fill="#1C85B5">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="449.3" y="24" fill="#C06334">padding</tspan> <tspan x="460.1" y="38" fill="#1C85B5">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="459.1" y="56" fill="#C06334">scrollbar</tspan> <tspan x="477.1" y="70" fill="#1C85B5">16px</tspan></text><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="178" y="200">Introduction</tspan> <tspan x="178" y="228" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="178" y="247" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="178" y="266" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="178" y="285" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="178" y="304" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="178" y="323" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="178" y="342" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="178" y="361" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="178" y="380" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with</tspan> <tspan x="178" y="399" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan></text><path id="Line-17" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M481.48 101v43"/><path id="Line-20" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M495.48 101v43"/><path id="Line-18" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M520.48 101v41"/><path id="Line-16" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M176.48 101v41"/><path id="Line-19" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M463.48 101v41"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg index d72a201389..9e247639be 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="597" height="520" viewBox="0 0 597 520"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-3" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-4" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><pattern id="pattern-1" width="30" height="30" x="-12" y="-6" patternUnits="userSpaceOnUse"><use xlink:href="#image-2"/></pattern><image id="image-2" width="30" height="30" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAEGWlDQ1BrQ0dDb2xvclNwYWNlR2VuZXJpY1JHQgAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia219thzg25abkRE/BpDc3pqvphHvRFys2weqvp+krbWKIX7nhDbzLOItiM8358pTwdirqpPFnMF2xLc1WvLyOwTAibpbmvHHcvttU57y5+XqNZrLe3lE/Pq8eUj2fXKfOe3pfOjzhJYtB/yll5SDFcSDiH+hRkH25+L+sdxKEAMZahrlSX8ukqMOWy/jXW2m6M9LDBc31B9LFuv6gVKg/0Szi3KAr1kGq1GMjU/aLbnq6/lRxc4XfJ98hTargX++DbMJBSiYMIe9Ck1YAxFkKEAG3xbYaKmDDgYyFK0UGYpfoWYXG+fAPPI6tJnNwb7ClP7IyF+D+bjOtCpkhz6CFrIa/I6sFtNl8auFXGMTP34sNwI/JhkgEtmDz14ySfaRcTIBInmKPE32kxyyE2Tv+thKbEVePDfW/byMM1Kmm0XdObS7oGD/MypMXFPXrCwOtoYjyyn7BV29/MZfsVzpLDdRtuIZnbpXzvlf+ev8MvYr/Gqk4H/kV/G3csdazLuyTMPsbFhzd1UabQbjFvDRmcWJxR3zcfHkVw9GfpbJmeev9F08WW8uDkaslwX6avlWGU6NRKz0g/SHtCy9J30o/ca9zX3Kfc19zn3BXQKRO8ud477hLnAfc1/G9mrzGlrfexZ5GLdn6ZZrrEohI2wVHhZywjbhUWEy8icMCGNCUdiBlq3r+xafL549HQ5jH+an+1y+LlYBifuxAvRN/lVVVOlwlCkdVm9NOL5BE4wkQ2SMlDZU97hX86EilU/lUmkQUztTE6mx1EEPh7OmdqBtAvv8HdWpbrJS6tJj3n0CWdM6busNzRV3S9KTYhqvNiqWmuroiKgYhshMjmhTh9ptWhsF7970j/SbMrsPE1suR5z7DMC+P/Hs+y7ijrQAlhyAgccjbhjPygfeBTjzhNqy28EdkUh8C+DU9+z2v/oyeH791OncxHOs5y2AtTc7nb/f73TWPkD/qwBnjX8BoJ98VQNcC+8AAADqSURBVEgN7ZVdDgIhDISl19KrrOFoBD2KXsOjkO1slAQBaVjovthHdjIfP7Otcc69iOjK9ThVijVn/nQbqTMzTCWbNDjkEfANfAQ8grXhCVgTnoG14EWwBrwKng0n7/0FkFJZa5+8voQQWDZWRzNMJZv8d66hg4DzUfVLUq3ZsxMwkv2G33kELoJR2a3LwIAjlUh7a/7u0RXBGvAqeDacfv3seGNcd6vJ9OianavHVHIYsycgeI7vkvptbywVj9TFcI00xS20/CJYIv5ca8tUokvAmvAMrAUvgjXgVfBsOCEogJRqVvNAJ1wBMfROw+AwCxUAAAAASUVORK5CYII="/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-offset-parent.svg"><path fill="#FFF" d="M0 0h597v520H0z"/><path id="Rectangle-10" fill="url(#pattern-1)" fill-opacity=".5" stroke="#E9E9E9" stroke-width="3" d="M19.5 25.5h558v479h-558z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M552 185v290H178V185h374zm-25 25H203v240h324V210z"/><text id="offsetTop:180px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 163 104.32)"><tspan x="100" y="108.82" fill="#EE6B47">offsetTop:</tspan> <tspan x="184" y="108.82" fill="#3B86C4">180px</tspan></text><text id="offsetLeft:180px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="34.3" y="179.32" fill="#EE6B47">offsetLeft:</tspan> <tspan x="126.7" y="179.32" fill="#3B86C4">180px</tspan></text><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="223" y="247">Introduction</tspan> <tspan x="223" y="275" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="223" y="294" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="223" y="313" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="223" y="332" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="223" y="351" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape </tspan> <tspan x="223" y="370" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">and first appeared in that companyโ€™s </tspan> <tspan x="223" y="389" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Navigator 2.0 browser. It has appeared </tspan> <tspan x="223" y="408" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all subsequent browsers from </tspan> <tspan x="223" y="427" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Netscape and in all browsers from </tspan> <tspan x="223" y="446" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft</tspan></text><path id="Line-40" fill="#EE6B47" fill-rule="nonzero" d="M179 26.5l7 14h-6v128.82h6l-7 14-7-14h6V40.5h-6l7-14z"/><path id="Line-41" fill="#EE6B47" fill-rule="nonzero" d="M163.41 179.91l14 7-14 7v-6H34.589l.001 6-14-7 14-7-.001 6H163.41v-6z"/><circle id="Oval-2" cx="203" cy="211" r="2" fill="#3B86C4"/><circle id="Oval-2" cx="179" cy="186" r="3" fill="#3B86C4"/><ellipse id="Oval-6" cx="364.25" cy="104" fill="#FFF9EB" stroke="#EE6B47" stroke-width="2" rx="100" ry="50"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M366 156.379v11.638h6l-7 14-7-14h6v-11.638h2z"/><text id="position:-absolute;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="296.5" y="95.793">position: absolute;</tspan> <tspan x="296.5" y="110.793">left: 180px;</tspan> <tspan x="296.5" y="125.793">top: 180px;</tspan></text><text id="offsetParent-<MAIN>-" fill="#8A704D" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="20.5" y="19.379">offsetParent <MAIN> </tspan></text><text id="<DIV>" fill="#8A704D" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="183.5" y="180.379"><DIV></tspan></text><g id="Scrollbar" transform="translate(511 210)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-3)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-3)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-4)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="597" height="520" viewBox="0 0 597 520"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-3" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-4" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><pattern id="pattern-1" width="30" height="30" x="-12" y="-6" patternUnits="userSpaceOnUse"><use xlink:href="#image-2"/></pattern><image id="image-2" width="30" height="30" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAHqADAAQAAAABAAAAHgAAAADKQTcFAAAA/UlEQVRIDe3VXQ6DIAwA4LUea7uCIeFdD+f2bDReYbvGbqLOmmEEAQ2T8jJeDEnTr+VPaJrmnWVZmef58+IYbdtex3G8nxkHMZIeKRKoyRT4DKfAF5gb12BOfANz4VaYA3fCsXHsuu5GiG0IIV4AUPR9X50dhzGSHiny/3Kd+iPwvdnaqeZ8szWYTvYXfwzDUEgp936VwXFoXiO6QoQiYlXXtfeq/RK36VgVQijhU/LS13lonBOmAkKTquLN7zof0sQMUHPqlDreW/aQuCmnfy9Dkh5pBtbtx9hLtXrmd97jFPhyuLjxBaal4MQ1mBPfwFy4FebAnXBsPNnL9QFH9tNXxu42ugAAAABJRU5ErkJggg=="/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-offset-parent.svg"><path fill="#FFF" d="M0 0h597v520H0z"/><path id="Rectangle-10" fill="url(#pattern-1)" fill-opacity=".5" stroke="#D1CFCD" stroke-width="3" d="M19.5 25.5h558v479h-558z"/><path id="Rectangle-1" fill="#DBAF88" d="M552 185v290H178V185h374zm-25 25H203v240h324V210z"/><text id="offsetTop:180px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 163 104.32)"><tspan x="100" y="108.82" fill="#C06334">offsetTop:</tspan> <tspan x="184" y="108.82" fill="#1C85B5">180px</tspan></text><text id="offsetLeft:180px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="34.3" y="179.32" fill="#C06334">offsetLeft:</tspan> <tspan x="126.7" y="179.32" fill="#1C85B5">180px</tspan></text><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="223" y="247">Introduction</tspan> <tspan x="223" y="275" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="223" y="294" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="223" y="313" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="223" y="332" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="223" y="351" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape </tspan> <tspan x="223" y="370" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">and first appeared in that companyโ€™s </tspan> <tspan x="223" y="389" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Navigator 2.0 browser. It has appeared </tspan> <tspan x="223" y="408" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all subsequent browsers from </tspan> <tspan x="223" y="427" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Netscape and in all browsers from </tspan> <tspan x="223" y="446" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft</tspan></text><path id="Line-40" fill="#C06334" fill-rule="nonzero" d="M179 26.5l7 14h-6v128.82h6l-7 14-7-14h6V40.5h-6l7-14z"/><path id="Line-41" fill="#C06334" fill-rule="nonzero" d="M163.41 179.91l14 7-14 7v-6H34.589l.001 6-14-7 14-7-.001 6H163.41v-6z"/><circle id="Oval-2" cx="203" cy="211" r="2" fill="#1C85B5"/><circle id="Oval-2" cx="179" cy="186" r="3" fill="#1C85B5"/><ellipse id="Oval-6" cx="364.25" cy="104" fill="#FBF2EC" stroke="#C06334" stroke-width="2" rx="100" ry="50"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M366 156.379v11.638h6l-7 14-7-14h6v-11.638h2z"/><text id="position:-absolute;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="296.5" y="95.793">position: absolute;</tspan> <tspan x="296.5" y="110.793">left: 180px;</tspan> <tspan x="296.5" y="125.793">top: 180px;</tspan></text><text id="offsetParent-<MAIN>-" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="20.5" y="19.379">offsetParent <MAIN> </tspan></text><text id="<DIV>" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="183.5" y="180.379"><DIV></tspan></text><g id="Group" transform="translate(511 210)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-3)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-3)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-4)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg index 76e20b1bc3..49bdccda78 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="508" height="509" viewBox="0 0 508 509"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-offset-width-height.svg"><path id="Rectangle-2" fill="#E8C48F" fill-opacity=".88" d="M420 130v290H30V130h390zm-25 25H55v240h340V155z"/><path id="Rectangle-1" stroke="#EE6B47" stroke-width="2" d="M76 177v199h283V177H76z"/><g id="Scrollbar" transform="translate(379 155)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="21.9" y="75" fill="#EE6B47">border</tspan> <tspan x="29.1" y="89" fill="#3B86C4">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="41.3" y="45" fill="#EE6B47">padding</tspan> <tspan x="52.1" y="59" fill="#3B86C4">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="148.1" y="109" fill="#EE6B47">content width:</tspan> <tspan x="248.9" y="109" fill="#3B86C4">284px</tspan></text><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 429.5 274)"><tspan x="386.3" y="278" fill="#EE6B47">height:</tspan> <tspan x="436.7" y="278" fill="#3B86C4">200px</tspan></text><path id="Line" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M360.5 175h88.142"/><path id="Line-2" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M360.5 377h88.142"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M442 177.5l7 14h-6V360h6l-7 14-7-14h6V191.5h-6l7-14z"/><path id="Line-15" fill="#EE6B47" fill-rule="nonzero" d="M345.5 110l14 7-14 7v-6H91.679l.001 6-14-7 14-7-.001 6H345.5v-6z"/><path id="Line-14" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M30.48 93v43"/><path id="Line-13" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M56.48 93v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="385.9" y="76" fill="#EE6B47">border</tspan> <tspan x="393.1" y="90" fill="#3B86C4">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="348.3" y="16" fill="#EE6B47">padding</tspan> <tspan x="359.1" y="30" fill="#3B86C4">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="358.1" y="48" fill="#EE6B47">scrollbar</tspan> <tspan x="376.1" y="62" fill="#3B86C4">16px</tspan></text><path id="Line-17" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M380.48 93v43"/><path id="Line-20" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M394.48 93v43"/><path id="Line-18" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M419.48 93v41"/><path id="Line-16" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M75.48 93v41"/><path id="Line-19" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M362.48 93v41"/><text id="offsetWidth-=-25+20+" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="56.5" y="484" fill="#EE6B47">offsetWidth = </tspan> <tspan x="174.1" y="484" fill="#3B86C4">25+20+284+20+16+25 </tspan> <tspan x="333.7" y="484" fill="#F38158">=</tspan> <tspan x="342.1" y="484" fill="#3B86C4"> 390px</tspan></text><path id="Line-24" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M30.5 419v78"/><path id="Line-25" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M419.5 419v80"/><path id="Line-22" fill="#EE6B47" fill-rule="nonzero" d="M403 456.071l14 7-14 7v-6.001H47.089l.001 6.001-14-7 14-7-.001 5.999H403v-5.999z"/><text id="offsetHeight:290px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 483.5 280.5)"><tspan x="407.9" y="285" fill="#EE6B47">offsetHeight:</tspan> <tspan x="517.1" y="285" fill="#3B86C4">290px</tspan></text><path id="Line-27" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M417.5 131h88.142"/><path id="Line-28" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M417.5 420h88.142"/><path id="Line-26" fill="#EE6B47" fill-rule="nonzero" d="M469 132.59l7 14-6-.001V405.41h6l-7 14-7-14h6V146.589l-6 .001 7-14z"/><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="79" y="193">Introduction</tspan> <tspan x="79" y="221" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="79" y="240" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="79" y="259" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="79" y="278" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="79" y="297" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="79" y="316" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="79" y="335" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="79" y="354" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="79" y="373" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="508" height="509" viewBox="0 0 508 509"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-offset-width-height.svg"><path id="Rectangle-2" fill="#DBAF88" d="M420 130v290H30V130h390zm-25 25H55v240h340V155z"/><path id="Rectangle-1" stroke="#C06334" stroke-width="2" d="M359 177v199H76V177h283z"/><g id="Group" transform="translate(379 155)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g><text id="border" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="21.9" y="75" fill="#C06334">border</tspan> <tspan x="29.1" y="89" fill="#1C85B5">25px</tspan></text><text id="padding" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="41.3" y="45" fill="#C06334">padding</tspan> <tspan x="52.1" y="59" fill="#1C85B5">20px</tspan></text><text id="content-width:284px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="148.1" y="109" fill="#C06334">content width:</tspan> <tspan x="248.9" y="109" fill="#1C85B5">284px</tspan></text><text id="height:200px" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 429.5 274)"><tspan x="386.3" y="278" fill="#C06334">height:</tspan> <tspan x="436.7" y="278" fill="#1C85B5">200px</tspan></text><path id="Line" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M360.5 175h88.142"/><path id="Line-2" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M360.5 377h88.142"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M442 177.5l7 14h-6V360h6l-7 14-7-14h6V191.5h-6l7-14z"/><path id="Line-15" fill="#C06334" fill-rule="nonzero" d="M345.5 110l14 7-14 7v-6H91.679l.001 6-14-7 14-7-.001 6H345.5v-6z"/><path id="Line-14" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M30.48 93v43"/><path id="Line-13" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M56.48 93v41"/><text id="border-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="385.9" y="76" fill="#C06334">border</tspan> <tspan x="393.1" y="90" fill="#1C85B5">25px</tspan></text><text id="padding-2" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="348.3" y="16" fill="#C06334">padding</tspan> <tspan x="359.1" y="30" fill="#1C85B5">20px</tspan></text><text id="scrollbar" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="358.1" y="48" fill="#C06334">scrollbar</tspan> <tspan x="376.1" y="62" fill="#1C85B5">16px</tspan></text><path id="Line-17" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M380.48 93v43"/><path id="Line-20" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M394.48 93v43"/><path id="Line-18" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M419.48 93v41"/><path id="Line-16" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M75.48 93v41"/><path id="Line-19" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M362.48 93v41"/><text id="offsetWidth-=-25+20+" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="56.5" y="484" fill="#C06334">offsetWidth = </tspan> <tspan x="174.1" y="484" fill="#1C85B5">25+20+284+20+16+25 </tspan> <tspan x="333.7" y="484" fill="#C06334">=</tspan> <tspan x="342.1" y="484" fill="#1C85B5"> 390px</tspan></text><path id="Line-24" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M30.5 419v78"/><path id="Line-25" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M419.5 419v80"/><path id="Line-22" fill="#C06334" fill-rule="nonzero" d="M403 456.071l14 7-14 7v-6.001H47.089l.001 6.001-14-7 14-7-.001 5.999H403v-5.999z"/><text id="offsetHeight:290px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 483.5 280.5)"><tspan x="407.9" y="285" fill="#C06334">offsetHeight:</tspan> <tspan x="517.1" y="285" fill="#1C85B5">290px</tspan></text><path id="Line-27" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M417.5 131h88.142"/><path id="Line-28" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M417.5 420h88.142"/><path id="Line-26" fill="#C06334" fill-rule="nonzero" d="M469 132.59l7 14-6-.001V405.41h6l-7 14-7-14h6V146.589l-6 .001 7-14z"/><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="79" y="193">Introduction</tspan> <tspan x="79" y="221" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="79" y="240" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="79" y="259" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="79" y="278" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="79" y="297" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="79" y="316" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="79" y="335" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="79" y="354" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="79" y="373" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting </tspan> <tspan x="79" y="392" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">with </tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg index 3c00bed00c..c6d14d0f38 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="489" height="542" viewBox="0 0 489 542"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-scroll-top.svg"><path fill="#FFF" d="M0 0h489v542H0z"/><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="94" y="54">Introduction</tspan> <tspan x="94" y="82" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="94" y="101" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="94" y="120" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="94" y="139" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="94" y="158" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="94" y="177" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="94" y="196" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="94" y="215" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="94" y="234" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan> <tspan x="94" y="253" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="94" y="272" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard started </tspan> <tspan x="94" y="291" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in November 1996. The first edition of this </tspan> <tspan x="94" y="310" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma Standard was adopted by the Ecma </tspan> <tspan x="94" y="329" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">General Assembly of June 1997.</tspan> <tspan x="94" y="348" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="94" y="367" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="94" y="386" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="94" y="405" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="94" y="424" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="94" y="443" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="94" y="462" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="94" y="481" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="94" y="500" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M425 122v290H51V122h374zm-25 25H76v240h324V147z"/><path id="Rectangle-2" stroke="#E8C48F" stroke-opacity=".8" stroke-width="2" d="M75 22h326v500H75z"/><text id="scrollTop" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 16.5 84)"><tspan x="-15.9" y="88">scrollTop</tspan></text><path id="Line-43" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M9.5 147h66.14"/><path id="Line-42" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M10.5 21h66.14"/><path id="Line-39" fill="#EE6B47" fill-rule="nonzero" d="M35 20.5l7 14h-6v97.819l6 .001-7 14-7-14 6-.001V34.5h-6l7-14z"/><path id="Rectangle-14" fill="#FFF" fill-opacity=".8" d="M88 33h312v89H88z"/><path id="Rectangle-15" fill="#FFF" fill-opacity=".8" d="M88 411h312v89H88z"/><text id="scrollHeight:723px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 449 270)"><tspan x="373.4" y="274.5" fill="#EE6B47">scrollHeight:</tspan> <tspan x="482.6" y="274.5" fill="#3B86C4">723px</tspan></text><path id="Line-27" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M393.5 22h78.14"/><path id="Line-28" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M393.5 522h78.14"/><path id="Line-25" fill="#EE6B47" fill-rule="nonzero" d="M462 24.5l7 14h-6v466h6l-7 14-7-14h6v-466h-6l7-14z"/><g id="Scrollbar" transform="translate(384 147)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="489" height="542" viewBox="0 0 489 542"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-scroll-top.svg"><path fill="#FFF" d="M0 0h489v542H0z"/><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="94" y="54">Introduction</tspan> <tspan x="94" y="82" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="94" y="101" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="94" y="120" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="94" y="139" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="94" y="158" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="94" y="177" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="94" y="196" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. It has appeared in all </tspan> <tspan x="94" y="215" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">subsequent browsers from Netscape and </tspan> <tspan x="94" y="234" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all browsers from Microsoft starting with </tspan> <tspan x="94" y="253" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Internet Explorer 3.0.</tspan> <tspan x="94" y="272" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard started </tspan> <tspan x="94" y="291" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in November 1996. The first edition of this </tspan> <tspan x="94" y="310" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma Standard was adopted by the Ecma </tspan> <tspan x="94" y="329" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">General Assembly of June 1997.</tspan> <tspan x="94" y="348" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="94" y="367" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="94" y="386" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="94" y="405" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="94" y="424" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="94" y="443" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="94" y="462" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="94" y="481" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="94" y="500" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-1" fill="#DBAF88" d="M425 122v290H51V122h374zm-25 25H76v240h324V147z"/><path id="Rectangle-2" stroke="#DBAF88" stroke-width="2" d="M75 22h326v500H75z"/><text id="scrollTop" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" transform="rotate(-90 16.5 84)"><tspan x="-15.9" y="88">scrollTop</tspan></text><path id="Line-43" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M9.5 147h66.14"/><path id="Line-42" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M10.5 21h66.14"/><path id="Line-39" fill="#C06334" fill-rule="nonzero" d="M35 20.5l7 14h-6v97.819l6 .001-7 14-7-14 6-.001V34.5h-6l7-14z"/><path id="Rectangle-14" fill="#FFF" d="M88 33h312v89H88z"/><path id="Rectangle-15" fill="#FFF" d="M88 411h312v89H88z"/><text id="scrollHeight:723px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 449 270)"><tspan x="373.4" y="274.5" fill="#C06334">scrollHeight:</tspan> <tspan x="482.6" y="274.5" fill="#1C85B5">723px</tspan></text><path id="Line-27" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M393.5 22h78.14"/><path id="Line-28" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M393.5 522h78.14"/><path id="Line-25" fill="#C06334" fill-rule="nonzero" d="M462 24.5l7 14h-6v466h6l-7 14-7-14h6v-466h-6l7-14z"/><g id="Group" transform="translate(384 147)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg index 29e25eb6f5..0c3d299528 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="463" height="524" viewBox="0 0 463 524"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#F1F1F1"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-scroll-width-height.svg"><path fill="#FFF" d="M0 0h463v524H0z"/><text id="Introduction" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="66" y="54">Introduction</tspan> <tspan x="66" y="82" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="66" y="101" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="66" y="120" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="66" y="139" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="66" y="158" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape </tspan> <tspan x="66" y="177" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">and first appeared in that companyโ€™s </tspan> <tspan x="66" y="196" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Navigator 2.0 browser. It has appeared </tspan> <tspan x="66" y="215" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all subsequent browsers from </tspan> <tspan x="66" y="234" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Netscape and in all browsers from </tspan> <tspan x="66" y="253" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="66" y="272" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0.</tspan> <tspan x="66" y="291" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard </tspan> <tspan x="66" y="310" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. The first </tspan> <tspan x="66" y="329" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition of this Ecma Standard was </tspan> <tspan x="66" y="348" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly </tspan> <tspan x="66" y="367" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">of June 1997.</tspan> <tspan x="66" y="386" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to </tspan> <tspan x="66" y="405" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">ISO/IEC JTC 1 for adoption under the </tspan> <tspan x="66" y="424" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">fast-track procedure, and approved as </tspan> <tspan x="66" y="443" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">international standard ISO/IEC 16262, in </tspan> <tspan x="66" y="462" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">April 1998. The Ecma General Assembly </tspan> <tspan x="66" y="481" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">of June 1998 approved the second </tspan> <tspan x="66" y="500" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition of ECMA-262 to keep it fully </tspan> <tspan x="66" y="519" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">aligned with ISO/IEC 16262. Changes </tspan> <tspan x="66" y="538" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">between the first and the second </tspan> <tspan x="66" y="557" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-15" fill="#FFF" fill-opacity=".8" d="M58 410h312v111H58z"/><path id="Rectangle-14" fill="#FFF" fill-opacity=".8" d="M58 35h312v89H58z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M395 123v290H21V123h374zm-25 25H46v240h324V148z"/><path id="Rectangle-2" stroke="#E8C48F" stroke-opacity=".8" stroke-width="2" d="M45 22h326v502H45z"/><text id="scrollHeight:723px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 426 270.5)"><tspan x="350.4" y="275" fill="#EE6B47">scrollHeight:</tspan> <tspan x="459.6" y="275" fill="#3B86C4">723px</tspan></text><path id="Line-27" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371 22h78"/><path id="Line-26" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371 524h78"/><path id="Line-25" fill="#EE6B47" fill-rule="nonzero" d="M439 26l7 14h-6v466h6l-7 14-7-14h6V40h-6l7-14z"/><path id="Line-39" fill="#EE6B47" fill-rule="nonzero" d="M335.36 102l14 7-14 7-.001-6H64v6l-14-7 14-7v6h271.359l.001-6z"/><path id="Line-42" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M352 154v-54"/><path id="Line-43" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M47 154v-54"/><text id="scrollWidth-=-324px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="149.2" y="105" fill="#EE6B47">scrollWidth = </tspan> <tspan x="266.8" y="105" fill="#3B86C4">324px</tspan></text><g id="Scrollbar" transform="translate(354 148)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#F3F2F2" stroke="#E9E9E9" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#CFCFCF" rx="3"/><path id="Triangle-1" fill="#92979F" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#CFCFCF" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D8D8D8" stroke="#979797" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="463" height="524" viewBox="0 0 463 524"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient><linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#D1CFCD"/></linearGradient></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="metric-scroll-width-height.svg"><path fill="#FFF" d="M0 0h463v524H0z"/><text id="Introduction" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold"><tspan x="66" y="54">Introduction</tspan> <tspan x="66" y="82" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="66" y="101" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="66" y="120" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="66" y="139" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="66" y="158" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape </tspan> <tspan x="66" y="177" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">and first appeared in that companyโ€™s </tspan> <tspan x="66" y="196" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Navigator 2.0 browser. It has appeared </tspan> <tspan x="66" y="215" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">in all subsequent browsers from </tspan> <tspan x="66" y="234" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Netscape and in all browsers from </tspan> <tspan x="66" y="253" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="66" y="272" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0.</tspan> <tspan x="66" y="291" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The development of this Standard </tspan> <tspan x="66" y="310" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. The first </tspan> <tspan x="66" y="329" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition of this Ecma Standard was </tspan> <tspan x="66" y="348" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly </tspan> <tspan x="66" y="367" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">of June 1997.</tspan> <tspan x="66" y="386" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to </tspan> <tspan x="66" y="405" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">ISO/IEC JTC 1 for adoption under the </tspan> <tspan x="66" y="424" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">fast-track procedure, and approved as </tspan> <tspan x="66" y="443" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">international standard ISO/IEC 16262, in </tspan> <tspan x="66" y="462" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">April 1998. The Ecma General Assembly </tspan> <tspan x="66" y="481" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">of June 1998 approved the second </tspan> <tspan x="66" y="500" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition of ECMA-262 to keep it fully </tspan> <tspan x="66" y="519" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">aligned with ISO/IEC 16262. Changes </tspan> <tspan x="66" y="538" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">between the first and the second </tspan> <tspan x="66" y="557" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle-15" fill="#FFF" d="M58 410h312v111H58z"/><path id="Rectangle-14" fill="#FFF" d="M58 35h312v89H58z"/><path id="Rectangle-1" fill="#DBAF88" d="M395 123v290H21V123h374zm-25 25H46v240h324V148z"/><path id="Rectangle-2" stroke="#DBAF88" stroke-width="2" d="M45 22h326v502H45z"/><text id="scrollHeight:723px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" transform="rotate(-90 426 270.5)"><tspan x="350.4" y="275" fill="#C06334">scrollHeight:</tspan> <tspan x="459.6" y="275" fill="#1C85B5">723px</tspan></text><path id="Line-27" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371 22h78"/><path id="Line-26" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M371 524h78"/><path id="Line-25" fill="#C06334" fill-rule="nonzero" d="M439 26l7 14h-6v466h6l-7 14-7-14h6V40h-6l7-14z"/><path id="Line-39" fill="#C06334" fill-rule="nonzero" d="M335.36 102l14 7-14 7-.001-6H64v6l-14-7 14-7v6h271.359l.001-6z"/><path id="Line-42" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M352 154v-54"/><path id="Line-43" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M47 154v-54"/><text id="scrollWidth-=-324px" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="149.2" y="105" fill="#C06334">scrollWidth = </tspan> <tspan x="266.8" y="105" fill="#1C85B5">324px</tspan></text><g id="Group" transform="translate(354 148)"><rect id="Rectangle-19" width="15" height="239" x=".5" y=".5" fill="#D1CFCD" stroke="#D1CFCD" rx="3"/><g id="Rectangle-18-+-Triangle-1"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-2" transform="matrix(1 0 0 -1 0 240)"><rect id="Rectangle-18" width="15" height="19" x=".5" y=".5" fill="url(#linearGradient-1)" stroke="#D1CFCD" rx="3"/><path id="Triangle-1" fill="#7E7C7B" d="M8 7l3.2 6H4.8z"/></g><g id="Rectangle-18-+-Triangle-3-+-Group" transform="translate(0 50)"><g id="Rectangle-18-+-Triangle-3" fill="url(#linearGradient-2)" stroke="#D1CFCD" transform="matrix(1 0 0 -1 0 51)"><rect id="Rectangle-18" width="15" height="50" x=".5" y=".5" rx="3"/></g><g id="Group" fill="#D1CFCD" stroke="#7E7C7B" transform="translate(4 20)"><path id="Rectangle-22" d="M.5.5h7v1h-7z"/><path id="Rectangle-23" d="M.5 3.5h7v1h-7z"/><path id="Rectangle-24" d="M.5 6.5h7v1h-7z"/><path id="Rectangle-25" d="M.5 9.5h7v1h-7z"/></g></g></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/10-size-and-scroll-window/article.md b/2-ui/1-document/10-size-and-scroll-window/article.md index 3060561511..6018859b93 100644 --- a/2-ui/1-document/10-size-and-scroll-window/article.md +++ b/2-ui/1-document/10-size-and-scroll-window/article.md @@ -1,50 +1,50 @@ -# Window sizes and scrolling +# ๋ธŒ๋ผ์šฐ์ € ์ฐฝ ์‚ฌ์ด์ฆˆ์™€ ์Šคํฌ๋กค -How to find out the width and height of the browser window? How to get the full width and height of the document, including the scrolled out part? How to scroll the page using JavaScript? +๋ธŒ๋ผ์šฐ์ € ์ฐฝ์ด ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ์Šคํฌ๋กค ๋•Œ๋ฌธ์— ๋ณด์ด์ง€ ์•Š๋Š” ์˜์—ญ์„ ํฌํ•จํ•˜์—ฌ ๋ฌธ์„œ ์ „์ฒด๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„์™€ ๋†’์ด๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŽ˜์ด์ง€๋ฅผ ์Šคํฌ๋กค ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? -For most such requests, we can use the root document element `document.documentElement`, that corresponds to `<html>` tag. But there are additional methods and peculiarities important enough to consider. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ์œ„์™€ ๊ฐ™์€ ๋ฌผ์Œ์— ๋‹ต์„ ์ฃผ๋Š” ๋ฃจํŠธ ๋ฌธ์„œ ์š”์†Œ์ธ `document.documentElement`๋ฅผ ์‚ดํŽด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. `document.documentElement`๋Š” `<html>` ํƒœ๊ทธ์™€ ์ƒ์‘ํ•˜๋Š” ์š”์†Œ๋กœ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์œ ์šฉํ•œ ๋ฉ”์„œ๋“œ์ด๊ธด ํ•˜์ง€๋งŒ ๋ช‡ ๊ฐ€์ง€ ์ฃผ์˜ํ•  ์ ์ด ์žˆ์–ด ๊ฐ™์ด ์‚ดํŽด๋ด…์‹œ๋‹ค. -## Width/height of the window +## ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์˜ ๋„ˆ๋น„์™€ ๋†’์ด -To get window width and height we can use `clientWidth/clientHeight` of `document.documentElement`: +์ฐฝ์ด ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์•Œ๋ ค๋ฉด `document.documentElement`์˜ `clientWidth`์™€ `clientHeight`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ![](document-client-width-height.svg) ```online -For instance, this button shows the height of your window: +์•„๋ž˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ง์ ‘ ์ฐฝ ๋†’์ด๋ฅผ ์ถœ๋ ฅํ•ด๋ณด์„ธ์š”. <button onclick="alert(document.documentElement.clientHeight)">alert(document.documentElement.clientHeight)</button> ``` -````warn header="Not `window.innerWidth/Height`" -Browsers also support properties `window.innerWidth/innerHeight`. They look like what we want. So why not to use them instead? +````warn header="`window` ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ `document.documentElement`๋ฅผ ์“ฐ๋Š” ์ด์œ " +๋ธŒ๋ผ์šฐ์ €์˜ `window` ๊ฐ์ฒด ์—ญ์‹œ `innerWidth`์™€ `innerHeight` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์จ๋„ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ฐฝ ํฌ๊ธฐ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ ์™œ `document.documentElement`์˜ `clientWidth`๋‚˜ `clientHeight`๋ฅผ ์“ฐ๋Š” ๊ฑธ๊นŒ์š”? -If there exists a scrollbar, and it occupies some space, `clientWidth/clientHeight` provide the width/height without it (subtract it). In other words, they return width/height of the visible part of the document, available for the content. +์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ƒ๊ธฐ๋ฉด ์Šคํฌ๋กค๋ฐ” ์—ญ์‹œ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋Š”๋ฐ, `clientWidth`๋‚˜ `clientHeight`๋Š” ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„์„ ์ œ์™ธํ•ด์„œ ๋„ˆ๋น„๋‚˜ ๋†’์ด ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋ˆˆ์— ๋ณด์ด๋Š” ๋ฌธ์„œ์—์„œ ์ฝ˜ํ…์ธ ๊ฐ€ ์‹ค์ œ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋  ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด์ฃ . -...And `window.innerWidth/innerHeight` include the scrollbar. +๊ทธ๋Ÿฐ๋ฐ `window.innerWidth/innerHeight`๋Š” ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ์„ ํฌํ•จํ•ด ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. -If there's a scrollbar, and it occupies some space, then these two lines show different values: +์Šคํฌ๋กค๋ฐ”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์Šคํฌ๋กค ๋ฐ” ์—ญ์‹œ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋Š”๋ฐ, ์ด๋Ÿด ๋•Œ `window`๊ฐ์ฒด์™€ `document.documentElement`์˜ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋“ค์€ ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ```js run -alert( window.innerWidth ); // full window width -alert( document.documentElement.clientWidth ); // window width minus the scrollbar +alert( window.innerWidth ); // ์ „์ฒด ์ฐฝ ๋„ˆ๋น„ +alert( document.documentElement.clientWidth ); // ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ์„ ์ œ์™ธํ•œ ์ฐฝ ๋„ˆ๋น„ ``` -In most cases we need the *available* window width: to draw or position something. That is: inside scrollbars if there are any. So we should use `documentElement.clientHeight/Width`. +์ฐฝ ์‚ฌ์ด์ฆˆ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋Š” ์Šคํฌ๋กค ๋ฐ” ์•ˆ์ชฝ์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ทธ๋ฆฌ๊ฑฐ๋‚˜ ์œ„์น˜์‹œํ‚ฌ ๋•Œ๊ฐ€ ๋Œ€๋‹ค์ˆ˜์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `documentElement`์˜ `clientHeight/clientWidth`๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```` -```warn header="`DOCTYPE` is important" -Please note: top-level geometry properties may work a little bit differently when there's no `<!DOCTYPE HTML>` in HTML. Odd things are possible. +```warn header="`DOCTYPE`์„ ๊ผญ ์จ์ฃผ์„ธ์š”." +๊ธฐํ•˜ ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ๋Š” HTML์— ๋ฌธ์„œ์— `<!DOCTYPE HTML>`์ด ๋ช…์‹œ๋˜์–ด์žˆ์ง€ ์•Š์œผ๋ฉด ์ด์ƒํ•˜๊ฒŒ ๋™์ž‘ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๊ทผ๊ฑฐ๋ฅผ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฐ’์ด ํˆญ ํŠ€์–ด๋‚˜์˜ฌ ์ˆ˜ ์žˆ์ฃ . -In modern HTML we should always write `DOCTYPE`. +๊ทธ๋Ÿฌ๋‹ˆ ์•ž์œผ๋กœ๋Š” ํ•ญ์ƒ HTML์— `DOCTYPE`์„ ๋ช…์‹œํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค. ``` -## Width/height of the document +## ๋ฌธ์„œ์˜ ๋„ˆ๋น„์™€ ๋†’์ด -Theoretically, as the root document element is `documentElement.clientWidth/Height`, and it encloses all the content, we could measure document full size as `documentElement.scrollWidth/scrollHeight`. +์ด๋ก ์ƒ `document.documentElement`๋Š” ๋ฌธ์„œ์˜ ๋ฃจํŠธ ์š”์†Œ์— ์ƒ์‘ํ•˜๊ณ , ๋ฃจํŠธ ์š”์†Œ์—” ์ฝ˜ํ…์ธ  ์ „๋ถ€๊ฐ€ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” ๋ฌธ์„œ์˜ ์ „์ฒด ํฌ๊ธฐ๋ฅผ `document.documentElement`์˜ `scrollWidth`์™€ `scrollHeight`๋ฅผ ์‚ฌ์šฉํ•ด ์žฌ๋ฉด ๋˜์ง€ ์•Š๋ƒ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. -But on that element, for the whole page, these properties do not work as intended. In Chrome/Safari/Opera if there's no scroll, then `documentElement.scrollHeight` may be even less than `documentElement.clientHeight`! Sounds like a nonsense, weird, right? +๊ทธ๋Ÿฐ๋ฐ ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ–ˆ์„ ๋•Œ, `document.documentElement`์˜ ํ”„๋กœํ”ผํ„ฐ๋“ค์€ ์šฐ๋ฆฌ๊ฐ€ ์˜ˆ์ƒํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Chrome์ด๋‚˜ Safari, Opera์—์„œ ์Šคํฌ๋กค์ด ์—†๋Š” ๊ฒฝ์šฐ `documentElement.scrollHeight`๋Š” `documentElement.clientHeight`๋ณด๋‹ค ์ž‘์„ ๋•Œ๊ฐ€ ์žˆ์ฃ . ์˜ˆ์ƒํ•˜๊ธฐ์—” ๊ฐ™์€ ๊ฐ’์ด์–ด์•ผ ํ•˜๋Š”๋ฐ๋„ ๋ง์ž…๋‹ˆ๋‹ค. -To reliably obtain the full document height, we should take the maximum of these properties: +์ •ํ™•ํ•œ ๋ฌธ์„œ ์ „์ฒด ๋†’์ด ๊ฐ’์„ ์–ป์œผ๋ ค๋ฉด ์•„๋ž˜ ์—ฌ์„ฏ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’ ์ค‘ ์ตœ๋Œ“๊ฐ’์„ ๊ณจ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js run let scrollHeight = Math.max( @@ -53,104 +53,104 @@ let scrollHeight = Math.max( document.body.clientHeight, document.documentElement.clientHeight ); -alert('Full document height, with scrolled out part: ' + scrollHeight); +alert('์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ๋ถ„์„ ํฌํ•จํ•œ ์ „์ฒด ๋ฌธ์„œ ๋†’์ด: ' + scrollHeight); ``` -Why so? Better don't ask. These inconsistencies come from ancient times, not a "smart" logic. +๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๋ฌธ์„œ ์ „์ฒด ๋†’์ด๋ฅผ ๊ตฌํ•ด์•ผ ํ•˜๋Š” ๊ฑธ๊นŒ์š”? ์ด์œ ๋Š” ์•Œ์•„๋ณด์ง€ ์•Š๋Š” ๊ฒŒ ๋‚ซ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์ƒํ•œ ๊ณ„์‚ฐ๋ฒ•์€ ์•„์ฃผ ์˜ค๋ž˜ ์ „๋ถ€ํ„ฐ ์žˆ์—ˆ๊ณ  ๊ทธ๋‹ค์ง€ ๋…ผ๋ฆฌ์ ์ด์ง€ ์•Š์€ ์ด์œ ๋กœ ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -## Get the current scroll [#page-scroll] +## ์Šคํฌ๋กค ์ •๋ณด ์–ป๊ธฐ [#page-scroll] -DOM elements have their current scroll state in `elem.scrollLeft/scrollTop`. +DOM ์š”์†Œ์˜ ํ˜„์žฌ ์Šคํฌ๋กค ์ƒํƒœ(์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ์˜์—ญ์— ๋Œ€ํ•œ ์ •๋ณด)๋Š” `scrollLeft`์™€ `scrollTop` ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For document scroll `document.documentElement.scrollLeft/Top` works in most browsers, except oldler WebKit-based ones, like Safari (bug [5991](https://bugs.webkit.org/show_bug.cgi?id=5991)), where we should use `document.body` instead of `document.documentElement`. +๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฌธ์„œ์˜ ์Šคํฌ๋กค ์ƒํƒœ๋Š” `document.documentElement`์˜ `scrollLeft`๋‚˜ `scrollTop`์„ ์ด์šฉํ•ด ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ๊ตฌ๋ฒ„์ „ WebKit์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„  ๋ฒ„๊ทธ([5991](https://bugs.webkit.org/show_bug.cgi?id=5991)) ๋•Œ๋ฌธ์— `document.documentElement`๊ฐ€ ์•„๋‹Œ `document.body`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ์›ํ•˜๋Š” ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Luckily, we don't have to remember these peculiarities at all, because the scroll is available in the special properties `window.pageXOffset/pageYOffset`: +์ด์ฏค ๋˜๋ฉด ์Šคํฌ๋กค ํฌ์ง€์…˜ ์ •๋ณด๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €๋ณ„ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๊นŒ์ง€ ๋‹ค ํ•ด์•ผ ํ•˜๋‚˜ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ `window`๊ฐ์ฒด์˜ `pageXOffset`๊ณผ `pageYOffset`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ € ์ƒ๊ด€์—†์ด ์Šคํฌ๋กค ์ •๋ณด๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ด๋Ÿฐ ์˜ˆ์™ธ ์ƒํ™ฉ์„ ์™ธ์›Œ๋‘์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ```js run -alert('Current scroll from the top: ' + window.pageYOffset); -alert('Current scroll from the left: ' + window.pageXOffset); +alert('์„ธ๋กœ ์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ์œ„์ชฝ ์˜์—ญ ๋†’์ด: ' + window.pageYOffset); +alert('๊ฐ€๋กœ ์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ์™ผ์ชฝ ์˜์—ญ ๋„ˆ๋น„: ' + window.pageXOffset); ``` -These properties are read-only. +์ฐธ๊ณ ๋กœ ์ด ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -## Scrolling: scrollTo, scrollBy, scrollIntoView [#window-scroll] +## scrollTo, scrollBy๋กœ ์Šคํฌ๋กค ์ƒํƒœ ๋ณ€๊ฒฝํ•˜๊ธฐ [#window-scroll] ```warn -To scroll the page from JavaScript, its DOM must be fully built. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํฌ๋กค์„ ์›€์ง์ด๋ ค๋ฉด DOM์ด ์™„์ „ํžˆ ๋งŒ๋“ค์–ด์ง„ ์ƒํƒœ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -For instance, if we try to scroll the page from the script in `<head>`, it won't work. +`<head>`์— ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ์—์„œ ํŽ˜์ด์ง€ ์ „์ฒด์˜ ์Šคํฌ๋กค์„ ์›€์ง์ด๋ ค ํ•˜๋ฉด ์ž˜ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -Regular elements can be scrolled by changing `scrollTop/scrollLeft`. +์ผ๋ฐ˜ ์š”์†Œ์˜ ์Šคํฌ๋กค ์ƒํƒœ๋Š” `scrollTop`์ด๋‚˜ `scrollLeft`๋กœ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We can do the same for the page using `document.documentElement.scrollTop/Left` (except Safari, where `document.body.scrollTop/Left` should be used instead). +ํŽ˜์ด์ง€ ์ „์ฒด์˜ ์Šคํฌ๋กค ์ƒํƒœ ์—ญ์‹œ `document.documentElement`์˜ `scrollTop/scrollLeft`๋ฅผ ์‚ฌ์šฉํ•ด ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜์ฃ (๋‹ค๋งŒ, Safari๋Š” `document.body`์˜ `scrollTop/scrollLeft`๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค). -Alternatively, there's a simpler, universal solution: special methods [window.scrollBy(x,y)](mdn:api/Window/scrollBy) and [window.scrollTo(pageX,pageY)](mdn:api/Window/scrollTo). +๊ทธ๋Ÿฐ๋ฐ ์ด๋ณด๋‹ค ๋” ํŽธํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ € ์ƒ๊ด€์—†์ด ์“ธ ์ˆ˜ ์žˆ๋Š” ๋Œ€์•ˆ์ด ์žˆ๊ธดํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ [window.scrollBy(x,y)](mdn:api/Window/scrollBy)์™€ [window.scrollTo(pageX,pageY)](mdn:api/Window/scrollTo)์ž…๋‹ˆ๋‹ค. -- The method `scrollBy(x,y)` scrolls the page *relative to its current position*. For instance, `scrollBy(0,10)` scrolls the page `10px` down. +- `scrollBy(x,y)`๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽ˜์ด์ง€์˜ ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ํ˜„์žฌ ํฌ์ง€์…˜์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ๋Œ€์ ์œผ๋กœ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. `scrollBy(0,10)`๋Š” ๋ฌธ์„œ์˜ ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ํ˜„์žฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์Šคํฌ๋กค์„ `10px`์•„๋ž˜๋กœ ๋‚ด๋ฆฐ๊ฒƒ ์ฒ˜๋Ÿผ ์›€์ง์—ฌ์ฃผ์ฃ . ```online - The button below demonstrates this: + ์•„๋ž˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ง์ ‘ ์‹ค์Šตํ•ด๋ด…์‹œ๋‹ค. <button onclick="window.scrollBy(0,10)">window.scrollBy(0,10)</button> ``` -- The method `scrollTo(pageX,pageY)` scrolls the page *to absolute coordinates*, so that the top-left corner of the visible part has coordinates `(pageX, pageY)` relative to the document's top-left corner. It's like setting `scrollLeft/scrollTop`. +- ๋ฐ˜๋ฉด `scrollTo(pageX,pageY)`๋ฉ”์„œ๋“œ๋Š” *์ ˆ๋Œ€ ์ขŒํ‘œ*๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŽ˜์ด์ง€ ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ˆˆ์— ๋ณด์ด๋Š” ์˜์—ญ์˜ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ์˜ ์ขŒํ‘œ๊ฐ€ ๋ฌธ์„œ ์ „์ฒด์˜ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ `(pageX, pageY)`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋งˆ์น˜ `scrollLeft`์™€ `scrollTop` ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์›€์ง์ด๋Š” ๊ฑฐ์ฃ . - To scroll to the very beginning, we can use `scrollTo(0,0)`. + ๊ทธ๋ž˜์„œ `scrollTo(0,0)`์„ ํ˜ธ์ถœํ•˜๋ฉด ๋ฌธ์„œ ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ์ฒ˜์Œ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```online <button onclick="window.scrollTo(0,0)">window.scrollTo(0,0)</button> ``` -These methods work for all browsers the same way. +๊ทธ๋ฆฌ๊ณ  ์ด ๋‘ ๋ฉ”์„œ๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ € ์ข…๋ฅ˜์— ์ƒ๊ด€์—†์ด ๋™์ผํ•œ ๋™์ž‘์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ## scrollIntoView -For completeness, let's cover one more method: [elem.scrollIntoView(top)](mdn:api/Element/scrollIntoView). +์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ [elem.scrollIntoView(top)](mdn:api/Element/scrollIntoView)๋ฅผ ๋จธ๋ฆฟ์†์— ์ถ”๊ฐ€ํ•ด ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ์™„๋ฒฝํžˆ ๋งˆ์Šคํ„ฐ ํ•ด๋ด…์‹œ๋‹ค. -The call to `elem.scrollIntoView(top)` scrolls the page to make `elem` visible. It has one argument: +`elem.scrollIntoView(top)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ „์ฒด ํŽ˜์ด์ง€ ์Šคํฌ๋กค์ด ์›€์ง์—ฌ `elem`์ด ๋ˆˆ์— ๋ณด์ด๋Š” ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. `elem.scrollIntoView`๋Š” ์ธ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋ฐ›๋Š”๋ฐ, ์ธ์ˆ˜์— ๋”ฐ๋ผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- if `top=true` (that's the default), then the page will be scrolled to make `elem` appear on the top of the window. The upper edge of the element is aligned with the window top. -- if `top=false`, then the page scrolls to make `elem` appear at the bottom. The bottom edge of the element is aligned with the window bottom. +- `top`์ด `true`(๋””ํดํŠธ)์ธ ๊ฒฝ์šฐ, `elem`์ด ์ฐฝ ์ œ์ผ ์œ„์— ๋ณด์ด๋„๋ก ์Šคํฌ๋กค ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. `elem`์˜ ์œ„์ชฝ ๋ชจ์„œ๋ฆฌ๊ฐ€ ์ฐฝ์˜ ์œ„์ชฝ ๋ชจ์„œ๋ฆฌ์™€ ์ผ์น˜ํ•˜๊ฒŒ ๋˜์ฃ . +- `top`์ด `false`์ธ ๊ฒฝ์šฐ, `elem`์ด ์ฐฝ ๊ฐ€์žฅ ์•„๋ž˜์— ๋ณด์ด๋„๋ก ์Šคํฌ๋กค ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. `elem`์˜ ์•„๋ž˜์ชฝ ๋ชจ์„œ๋ฆฌ๊ฐ€ ์ฐฝ์˜ ์•„๋ž˜์ชฝ ๋ชจ์„œ๋ฆฌ์™€ ์ผ์น˜ํ•˜๊ฒŒ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค. ```online -The button below scrolls the page to make itself show at the window top: +๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ง์ ‘ ์‹ค์Šตํ•ด๋ด…์‹œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ฒ„ํŠผ ์ƒ๋‹จ์ด ์ฐฝ ์ œ์ผ ๊ผญ๋Œ€๊ธฐ๋กœ ๋ถ™๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <button onclick="this.scrollIntoView()">this.scrollIntoView()</button> -And this button scrolls the page to show it at the bottom: +๋‘ ๋ฒˆ์งธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ฒ„ํŠผ์˜ ์•„๋ž˜ ๋ชจ์„œ๋ฆฌ๊ฐ€ ์ฐฝ ๋ฐ‘์œผ๋กœ ๋ถ™๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <button onclick="this.scrollIntoView(false)">this.scrollIntoView(false)</button> ``` -## Forbid the scrolling +## ์Šคํฌ๋กค ๋ง‰๊ธฐ -Sometimes we need to make the document "unscrollable". For instance, when we need to cover it with a large message requiring immediate attention, and we want the visitor to interact with that message, not with the document. +๋•Œ์— ๋”ฐ๋ผ ๋ฌธ์„œ ์Šคํฌ๋กค๋ฐ”๋ฅผ '๊ณ ์ •' ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ˜๋“œ์‹œ ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ์ค‘์š”ํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์–ด์„œ ์ด ๋ฉ”์‹œ์ง€๋ฅผ ํ™”๋ฉด์— ํฌ๊ฒŒ ๋„์šฐ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กค์„ ์›€์ง์—ฌ ๋‹ค๋ฅธ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณด์ง€ ๋ชปํ•˜๊ฒŒ ํ•œ ์ƒํƒœ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ฒŒ ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -To make the document unscrollable, it's enough to set `document.body.style.overflow = "hidden"`. The page will freeze on its current scroll. +์ด๋Ÿด ๋•Œ `document.body.style.overflow = "hidden"`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋™์ž‘ํ•˜๋ฉด ํŽ˜์ด์ง€์˜ ์Šคํฌ๋กค๋ฐ” ์œ„์น˜๊ฐ€ '๊ณ ์ •' ๋ฉ๋‹ˆ๋‹ค. ```online -Try it: +์ง์ ‘ ์‹ค์Šตํ•ด๋ด…์‹œ๋‹ค. <button onclick="document.body.style.overflow = 'hidden'">document.body.style.overflow = 'hidden'</button> <button onclick="document.body.style.overflow = ''">document.body.style.overflow = ''</button> -The first button freezes the scroll, the second one resumes it. +์œ„์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์Šคํฌ๋กค๋ฐ”๊ฐ€ ๊ณ ์ •๋˜์—ˆ๋‹ค๊ฐ€, ์•„๋ž˜ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ณ ์ •์ด ํ•ด์ œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -We can use the same technique to "freeze" the scroll for other elements, not just for `document.body`. +์ด ๋ฐฉ๋ฒ•์€ `document.body`์š”์†Œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์š”์†Œ์˜ ์Šคํฌ๋กค์„ ๊ณ ์ •์‹œํ‚ฌ ๋•Œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The drawback of the method is that the scrollbar disappears. If it occupied some space, then that space is now free, and the content "jumps" to fill it. +๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฐฉ๋ฒ•์€ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋ฐ”๋Š” ์ผ์ • ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋Š”๋ฐ, ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด ํ•ด๋‹น ๊ณต๊ฐ„์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด ์ฝ˜ํ…์ธ ๊ฐ€ ๊ฐ‘์ž๊ธฐ '์›€์ง์ด๋Š”' ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -That looks a bit odd, but can be worked around if we compare `clientWidth` before and after the freeze, and if it increased (the scrollbar disappeared) then add `padding` to `document.body` in place of the scrollbar, to keep the content width the same. +์ด๋ ‡๊ฒŒ ํŽ˜์ด์ง€ ์ „์ฒด์˜ ์Šคํฌ๋กค ์ƒํƒœ๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋ณ€๊ฒฝ๋˜๋ฉด ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„  ์ด์ƒํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” ์Šคํฌ๋กค๋ฐ”๋ฅผ ๊ณ ์ •์‹œํ‚ค๊ธฐ ์ „๊ณผ ํ›„์˜ `clientWidth`๊ฐ’์„ ๋น„๊ตํ•ด์„œ ํ•ด๋‹น ์ฆ์ƒ์„ ๋ณด์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์‚ฌ๋ผ์งˆ ๋• `clientWidth`๊ฐ’์ด ์ปค์ง€๋Š”๋ฐ ์ด๋•Œ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์ฐจ์ง€ํ–ˆ๋˜ ์˜์—ญ๋งŒํผ `document.body`์— `padding`์„ ์ค˜์„œ ์ฝ˜ํ…์ธ  ์ „์ฒด์˜ ๋„ˆ๋น„๋ฅผ ์Šคํฌ๋กค๋ฐ”๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „๊ณผ ๊ฐ™์€ ๊ฐ’์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -Geometry: +๊ธฐํ•˜ ํ”„๋กœํผํ‹ฐ: -- Width/height of the visible part of the document (content area width/height): `document.documentElement.clientWidth/Height` -- Width/height of the whole document, with the scrolled out part: +- ์‚ฌ์šฉ์ž ๋ˆˆ์— ๋ณด์ด๋Š” ๋ฌธ์„œ(์ฝ˜ํ…์ธ ๊ฐ€ ์‹ค์ œ ๋ณด์—ฌ์ง€๋Š” ์˜์—ญ)์˜ ๋„ˆ๋น„์™€ ๋†’์ด: `document.documentElement.clientWidth/clientHeight` +- ์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ์˜์—ญ์„ ํฌํ•จํ•œ ๋ฌธ์„œ ์ „์ฒด์˜ ๋„ˆ๋น„์™€ ๋†’์ด: ```js let scrollHeight = Math.max( @@ -160,11 +160,11 @@ Geometry: ); ``` -Scrolling: +์Šคํฌ๋กค ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ: -- Read the current scroll: `window.pageYOffset/pageXOffset`. -- Change the current scroll: +- ํ˜„์žฌ ์Šคํฌ๋กค ์ •๋ณด ์ฝ๊ธฐ: `window.pageYOffset/pageXOffset`. +- ์Šคํฌ๋กค ์ƒํƒœ ๋ณ€๊ฒฝ์‹œํ‚ค๊ธฐ: - - `window.scrollTo(pageX,pageY)` -- absolute coordinates, - - `window.scrollBy(x,y)` -- scroll relative the current place, - - `elem.scrollIntoView(top)` -- scroll to make `elem` visible (align with the top/bottom of the window). + - `window.scrollTo(pageX,pageY)` -- ์ ˆ๋Œ€ ์ขŒํ‘œ + - `window.scrollBy(x,y)` -- ํ˜„์žฌ ์Šคํฌ๋กค ์ƒํƒœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ƒ๋Œ€์ ์œผ๋กœ ์Šคํฌ๋กค ์ •๋ณด ๋ณ€๊ฒฝ + - `elem.scrollIntoView(top)` -- `elem`์ด ๋ˆˆ์— ๋ณด์ด๋„๋ก ์Šคํฌ๋กค ์ƒํƒœ ๋ณ€๊ฒฝ(์ธ์ˆ˜์— ๋”ฐ๋ผ ์ฐฝ ์ตœ์ƒ๋‹จ, ์ตœํ•˜๋‹จ์— ํ•ด๋‹น ์š”์†Œ๊ฐ€ ๋…ธ์ถœ๋˜๋„๋ก ์ฒ˜๋ฆฌ) diff --git a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg index b0dff4d4e1..65e77ae805 100644 --- a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg +++ b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="508" height="203" viewBox="0 0 508 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="document-client-width-height.svg"><g id="noun_69008_cc" fill="#E8C48E" transform="translate(275 8)"><path id="Shape" d="M179.188 145H3.813C1.708 145 0 143.369 0 141.375V3.625C0 1.631 1.708 0 3.813 0h175.375C181.284 0 183 1.631 183 3.625v137.75c0 1.994-1.716 3.625-3.813 3.625zM7.625 137.75h167.75V7.25H7.625v130.5z"/><path id="Shape" d="M175.375 36.25H7.625c-2.104 0-3.813-1.631-3.813-3.625S5.521 29 7.626 29h167.75c2.097 0 3.813 1.631 3.813 3.625s-1.716 3.625-3.813 3.625zM61.32 126.578c-1.266 0-2.508-.595-3.233-1.682L34.892 89.849a3.486 3.486 0 01.16-4.082l23.195-29.906c1.25-1.631 3.63-1.964 5.33-.746 1.693 1.188 2.059 3.458.8 5.067l-21.646 27.92 21.807 32.951c1.12 1.69.587 3.937-1.197 4.988a3.936 3.936 0 01-2.02.537zM122 126.578a3.802 3.802 0 01-2.028-.559c-1.784-1.058-2.326-3.298-1.197-4.988l21.807-32.95-21.655-27.928c-1.25-1.617-.892-3.878.8-5.067 1.694-1.197 4.08-.849 5.33.76l23.188 29.907a3.462 3.462 0 01.16 4.082L125.21 124.88c-.709 1.102-1.944 1.697-3.21 1.697zM76.25 119.937a4.07 4.07 0 01-1.86-.457c-1.838-.979-2.494-3.183-1.465-4.959l30.18-51.359c1.03-1.755 3.34-2.385 5.2-1.37 1.83.978 2.486 3.175 1.457 4.937l-30.18 51.359c-.701 1.182-1.998 1.849-3.332 1.849zM22.875 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625zM38.125 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625zM53.375 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625z"/></g><text id="documentElement.clie" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="12" y="101">documentElement.clientHeight</tspan></text><text id="documentElement.clie" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="257" y="195">documentElement.clientWidth</tspan></text><path id="Line-3-Copy" fill="#EE6B47" fill-rule="nonzero" d="M431.025 158.653l19 9.5-19 9.5-.001-8h-132v8l-19-9.5 19-9.5v8h132v-8z"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M256.5 45l9.5 19-8-.001v64l8 .001-9.5 19-9.5-19 8-.001v-64L247 64l9.5-19z"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="508" height="203" viewBox="0 0 508 203"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="document-client-width-height.svg"><g id="noun_69008_cc" fill="#DBAF88" transform="translate(275 8)"><path id="Shape" d="M179.188 145H3.813C1.708 145 0 143.369 0 141.375V3.625C0 1.631 1.708 0 3.813 0h175.375C181.284 0 183 1.631 183 3.625v137.75c0 1.994-1.716 3.625-3.813 3.625zM7.625 137.75h167.75V7.25H7.625v130.5z"/><path id="Shape" d="M175.375 36.25H7.625c-2.104 0-3.813-1.631-3.813-3.625S5.521 29 7.626 29h167.75c2.097 0 3.813 1.631 3.813 3.625s-1.716 3.625-3.813 3.625zM61.32 126.578c-1.266 0-2.508-.595-3.233-1.682L34.892 89.849a3.486 3.486 0 01.16-4.082l23.195-29.906c1.25-1.631 3.63-1.964 5.33-.746 1.693 1.188 2.059 3.458.8 5.067l-21.646 27.92 21.807 32.951c1.12 1.69.587 3.937-1.197 4.988a3.936 3.936 0 01-2.02.537zM122 126.578a3.802 3.802 0 01-2.028-.559c-1.784-1.058-2.326-3.298-1.197-4.988l21.807-32.95-21.655-27.928c-1.25-1.617-.892-3.878.8-5.067 1.694-1.197 4.08-.849 5.33.76l23.188 29.907a3.462 3.462 0 01.16 4.082L125.21 124.88c-.709 1.102-1.944 1.697-3.21 1.697zM76.25 119.937a4.07 4.07 0 01-1.86-.457c-1.838-.979-2.494-3.183-1.465-4.959l30.18-51.359c1.03-1.755 3.34-2.385 5.2-1.37 1.83.978 2.486 3.175 1.457 4.937l-30.18 51.359c-.701 1.182-1.998 1.849-3.332 1.849zM22.875 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625zM38.125 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625zM53.375 18.125c0 2.003-1.706 3.625-3.813 3.625-2.106 0-3.812-1.622-3.812-3.625s1.706-3.625 3.813-3.625c2.106 0 3.812 1.622 3.812 3.625z"/></g><text id="documentElement.clie" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="12" y="101">documentElement.clientHeight</tspan></text><text id="documentElement.clie" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="257" y="195">documentElement.clientWidth</tspan></text><path id="Line-3-Copy" fill="#C06334" fill-rule="nonzero" d="M431.025 158.653l19 9.5-19 9.5-.001-8h-132v8l-19-9.5 19-9.5v8h132v-8z"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M256.5 45l9.5 19-8-.001v64l8 .001-9.5 19-9.5-19 8-.001v-64L247 64l9.5-19z"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md b/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md index f3547096fa..4101d4915a 100644 --- a/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md +++ b/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md @@ -1,6 +1,6 @@ # Outer corners -Outer corners are basically what we get from [elem.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect). +Outer corners are basically what we get from [elem.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect). Coordinates of the upper-left corner `answer1` and the bottom-right corner `answer2`: diff --git a/2-ui/1-document/11-coordinates/3-position-at-absolute/solution.view/index.html b/2-ui/1-document/11-coordinates/3-position-at-absolute/solution.view/index.html index d627bee84f..56c95d5ec8 100644 --- a/2-ui/1-document/11-coordinates/3-position-at-absolute/solution.view/index.html +++ b/2-ui/1-document/11-coordinates/3-position-at-absolute/solution.view/index.html @@ -28,8 +28,8 @@ let box = elem.getBoundingClientRect(); return { - top: box.top + pageYOffset, - left: box.left + pageXOffset + top: box.top + window.pageYOffset, + left: box.left + window.pageXOffset }; } diff --git a/2-ui/1-document/11-coordinates/4-position-inside-absolute/solution.view/index.html b/2-ui/1-document/11-coordinates/4-position-inside-absolute/solution.view/index.html index 7e841397ba..b89db37900 100644 --- a/2-ui/1-document/11-coordinates/4-position-inside-absolute/solution.view/index.html +++ b/2-ui/1-document/11-coordinates/4-position-inside-absolute/solution.view/index.html @@ -26,8 +26,8 @@ let box = elem.getBoundingClientRect(); return { - top: box.top + pageYOffset, - left: box.left + pageXOffset + top: box.top + window.pageYOffset, + left: box.left + window.pageXOffset }; } diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md index a000ba37a1..cd3d1c8cb4 100644 --- a/2-ui/1-document/11-coordinates/article.md +++ b/2-ui/1-document/11-coordinates/article.md @@ -1,42 +1,42 @@ -# Coordinates +# ์ขŒํ‘œ -To move elements around we should be familiar with coordinates. +์š”์†Œ๋ฅผ ์›€์ง์ด๋ ค๋ฉด ์ขŒํ‘œ(coordinates)์— ์ต์ˆ™ํ•ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Most JavaScript methods deal with one of two coordinate systems: +๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ ๋‘ ์ขŒํ‘œ ์ฒด๊ณ„ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. -1. **Relative to the window** - similar to `position:fixed`, calculated from the window top/left edge. - - we'll denote these coordinates as `clientX/clientY`, the reasoning for such name will become clear later, when we study event properties. -2. **Relative to the document** - similar to `position:absolute` in the document root, calculated from the document top/left edge. - - we'll denote them `pageX/pageY`. +1. **์ฐฝ ๊ธฐ์ค€** - `position:fixed`์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ฐฝ(window) ๋งจ ์œ„ ์™ผ์ชฝ ๋ชจ์„œ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. + - ์•ž์œผ๋กœ ์šฐ๋ฆฌ๋Š” ์ด ์ขŒํ‘œ๋ฅผ `clientX/clientY`๋กœ ํ‘œ์‹œํ•  ์˜ˆ์ •์ธ๋ฐ, ์™œ ์ด๋Ÿฐ ์ด๋ฆ„์„ ์“ฐ๋Š”์ง€๋Š” ๋‚˜์ค‘์— event ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ณต๋ถ€ํ•  ๋•Œ ๋ช…ํ™•ํ•ด์ง‘๋‹ˆ๋‹ค. +2. **๋ฌธ์„œ ๊ธฐ์ค€** - ๋ฌธ์„œ(document) ์ตœ์ƒ๋‹จ(root)์—์„œ `position:absolute`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋ฌธ์„œ ๋งจ ์œ„ ์™ผ์ชฝ ๋ชจ์„œ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. + - ์ด ์ขŒํ‘œ๋Š” `pageX/pageY`๋กœ ํ‘œ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -When the page is scrolled to the very beginning, so that the top/left corner of the window is exactly the document top/left corner, these coordinates equal each other. But after the document shifts, window-relative coordinates of elements change, as elements move across the window, while document-relative coordinates remain the same. +์Šคํฌ๋กค์„ ์›€์ง์ด๊ธฐ ์ „์—๋Š” ์ฐฝ์˜ ๋งจ ์œ„ ์™ผ์ชฝ ๋ชจ์„œ๋ฆฌ๊ฐ€ ๋ฌธ์„œ์˜ ๋งจ ์œ„ ์™ผ์ชฝ ๋ชจ์„œ๋ฆฌ์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์Šคํฌ๋กค์ด ์›€์ง์ด๋ฉด์„œ ๋ฌธ์„œ๊ฐ€ ์ด๋™ํ•˜๋ฉด ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์ง€๋งŒ, ์ฐฝ ๋‚ด ์š”์†Œ๋Š” ์›€์ง์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฐฝ ๊ธฐ์ค€ ์š”์†Œ ์ขŒํ‘œ๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. -On this picture we take a point in the document and demonstrate its coordinates before the scroll (left) and after it (right): +๋‹ค์Œ ๊ทธ๋ฆผ์€ ๋ฌธ์„œ ๋‚ด ํ•œ ์ง€์ ์˜ ์Šคํฌ๋กค์ด ์›€์ง์ด๊ธฐ ์ „(์™ผ์ชฝ)๊ณผ ํ›„(์˜ค๋ฅธ์ชฝ) ์ขŒํ‘œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ![](document-and-window-coordinates-scrolled.svg) -When the document scrolled: -- `pageY` - document-relative coordinate stayed the same, it's counted from the document top (now scrolled out). -- `clientY` - window-relative coordinate did change (the arrow became shorter), as the same point became closer to window top. +๋ฌธ์„œ๊ฐ€ ์Šคํฌ๋กค ๋˜์—ˆ์„ ๋•Œ: +- `pageY` - ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” ๋ฌธ์„œ ๋งจ ์œ„(์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์—์„  ์Šคํฌ๋กค ๋˜์–ด ๋ณด์ด์ง€ ์•Š์Œ)๋ถ€ํ„ฐ ๊ณ„์‚ฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋กค ํ›„ ๊ฐ’์€ ์ „๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. +- `clientY` - ๋ฌธ์„œ๊ฐ€ ์Šคํฌ๋กค ๋˜๋ฉด์„œ ํ•ด๋‹น ์ง€์ ์ด ์ฐฝ ์ƒ๋‹จ๊ณผ ๊ฐ€๊นŒ์›Œ์กŒ๊ธฐ ๋•Œ๋ฌธ์— ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๊ฐ€ ๋ณ€ํ–ˆ์Šต๋‹ˆ๋‹ค(ํ™”์‚ดํ‘œ๊ฐ€ ์งง์•„์ง). -## Element coordinates: getBoundingClientRect +## getBoundingClientRect๋กœ ์š”์†Œ ์ขŒํ‘œ ์–ป๊ธฐ -The method `elem.getBoundingClientRect()` returns window coordinates for a minimal rectangle that encloses `elem` as an object of built-in [DOMRect](https://www.w3.org/TR/geometry-1/#domrect) class. +`elem.getBoundingClientRect()` ๋ฉ”์„œ๋“œ๋Š” `elem`์„ ๊ฐ์‹ธ๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋„ค๋ชจ์˜ ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ [DOMRect](https://www.w3.org/TR/geometry-1/#domrect) ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -Main `DOMRect` properties: +`DOMRect`์˜ ์ฃผ์š” ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `x/y` -- X/Y-coordinates of the rectangle origin relative to window, -- `width/height` -- width/height of the rectangle (can be negative). +- `x`์™€ `y` -- ์š”์†Œ๋ฅผ ๊ฐ์‹ธ๋Š” ๋„ค๋ชจ์˜ ์ฐฝ ๊ธฐ์ค€ X, Y ์ขŒํ‘œ +- `width`์™€ `height` -- ์š”์†Œ๋ฅผ ๊ฐ์‹ธ๋Š” ๋„ค๋ชจ์˜ ๋„ˆ๋น„, ๋†’์ด(์Œ์ˆ˜๋„ ๊ฐ€๋Šฅ) -Additionally, there are derived properties: +`x`์™€ `y`, `width`์™€ `height` ์ด์™ธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒŒ์ƒ ํ”„๋กœํผํ‹ฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -- `top/bottom` -- Y-coordinate for the top/bottom rectangle edge, -- `left/right` -- X-coordinate for the left/right rectangle edge. +- `top`๊ณผ `bottom` -- ์š”์†Œ๋ฅผ ๊ฐ์‹ธ๋Š” ๋„ค๋ชจ์˜ ์œ„์ชฝ ๋ชจ์„œ๋ฆฌ, ์•„๋ž˜์ชฝ ๋ชจ์„œ๋ฆฌ์˜ Y ์ขŒํ‘œ +- `left`์™€ `right` -- ์š”์†Œ๋ฅผ ๊ฐ์‹ธ๋Š” ๋„ค๋ชจ์˜ ์™ผ์ชฝ ๋ชจ์„œ๋ฆฌ, ์˜ค๋ฅธ์ชฝ ๋ชจ์„œ๋ฆฌ์˜ X ์ขŒํ‘œ ```online -For instance click this button to see its window coordinates: +์•„๋ž˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ฐฝ ๊ธฐ์ค€ ๋ฒ„ํŠผ ์ขŒํ‘œ๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. -<p><input id="brTest" type="button" value="Get coordinates using button.getBoundingClientRect() for this button" onclick='showRect(this)'/></p> +<p><input id="brTest" type="button" value="button.getBoundingClientRect()๋กœ ๋ฒ„ํŠผ ์ขŒํ‘œ ์–ป๊ธฐ" onclick='showRect(this)'/></p> <script> function showRect(elem) { @@ -53,66 +53,66 @@ right:${r.right} } </script> -If you scroll the page and repeat, you'll notice that as window-relative button position changes, its window coordinates (`y/top/bottom` if you scroll vertically) change as well. +ํŽ˜์ด์ง€๋ฅผ ์กฐ๊ธˆ์”ฉ ์Šคํฌ๋กค ํ•˜๋ฉด์„œ ์ฐฝ ๊ธฐ์ค€ ๋ฒ„ํŠผ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ขŒํ‘ฏ๊ฐ’์ด ๋ฐ”๋€Œ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ˆ˜์ง ์Šคํฌ๋กค ์‹œ `y`, `top`, `bottom` ๊ฐ’์ด ๋ณ€ํ•จ). ``` -Here's the picture of `elem.getBoundingClientRect()` output: +`elem.getBoundingClientRect()`์˜ ๊ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](coordinates.svg) -As you can see, `x/y` and `width/height` fully describe the rectangle. Derived properties can be easily calculated from them: +๊ทธ๋ฆผ์„ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” `x`, `y`์™€ `width`, `height` ๋งŒ์œผ๋กœ ๋„ค๋ชจ ์˜์—ญ์„ ์™„์ „ํžˆ ๋ฌ˜์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ํŒŒ์ƒ ํ”„๋กœํผํ‹ฐ๋“ค์€ `x`, `y`, `width`, `height`๋ฅผ ์‚ฌ์šฉํ•ด ์‰ฝ๊ฒŒ ๊ณ„์‚ฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - `left = x` - `top = y` - `right = x + width` - `bottom = y + height` -Please note: +`elem.getBoundingClientRect()`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- Coordinates may be decimal fractions, such as `10.5`. That's normal, internally browser uses fractions in calculations. We don't have to round them when setting to `style.left/top`. -- Coordinates may be negative. For instance, if the page is scrolled so that `elem` is now above the window, then `elem.getBoundingClientRect().top` is negative. +- ์ขŒํ‘œ๋Š” `10.5`์ฒ˜๋Ÿผ ์†Œ์ˆ˜์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ์ขŒํ‘œ ๊ณ„์‚ฐ์— ์†Œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ์ •์ƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `style.left/top`์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ’์„ ๋ฐ˜์˜ฌ๋ฆผํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +- ์ขŒํ‘œ๋Š” ์Œ์ˆ˜์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€๊ฐ€ ์Šคํฌ๋กค ๋˜์–ด `elem`์ด window ์œ„๋กœ ๋ฐ€๋ ค๋‚ฌ์„ ๋•Œ `elem.getBoundingClientRect().top`์€ ์Œ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -```smart header="Why derived properties are needed? Why does `top/left` exist if there's `x/y`?" -Mathematically, a rectangle is uniquely defined with its starting point `(x,y)` and the direction vector `(width,height)`. So the additional derived properties are for convenience. +```smart header="์™œ ํŒŒ์ƒ ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•„์š”ํ•œ๊ฐ€์š”? `x`, `y`๊ฐ€ ์žˆ๋Š”๋ฐ `top`, `left`๋Š” ์™œ ์กด์žฌํ•˜๋‚˜์š”?" +์ˆ˜ํ•™์ ์œผ๋กœ ์‚ฌ๊ฐํ˜•์€ ์‹œ์ž‘ ์ง€์ ์ธ `(x,y)`์™€ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ `(width,height)`๋งŒ์œผ๋กœ๋„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ํŒŒ์ƒ ํ”„๋กœํผํ‹ฐ๋Š” ํŽธ์˜๋ฅผ ์œ„ํ•ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. -Technically it's possible for `width/height` to be negative, that allows for "directed" rectangle, e.g. to represent mouse selection with properly marked start and end. +์ด๋ก ์ƒ `width`์™€ `height`๋Š” '๋ฐฉํ–ฅ์ด ์žˆ๋Š”' ์‚ฌ๊ฐํ˜•์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ ์Œ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ์‹œ: ์‹œ์ž‘๊ณผ ๋ ์ง€์ ์„ ์ง€์ •ํ•˜๊ณ  ๋งˆ์šฐ์Šค๋กœ ๋“œ๋ž˜๊ทธํ•ด ์˜์—ญ์„ ํ‘œ์‹œํ•  ๋•Œ). -Here's a rectangle with negative `width` and `height` (e.g. `width=-200`, `height=-100`): +์‚ฌ๊ฐํ˜•์ด ์˜ค๋ฅธ์ชฝ ์•„๋ž˜์—์„œ ์‹œ์ž‘ํ•ด ์™ผ์ชฝ ์œ„๋กœ '์˜ฌ๋ผ๊ฐ€๋ฉด' `width`์™€ `height`๋Š” ์Œ์ˆ˜๊ฐ€ ๋˜์ฃ . -![](coordinates-negative.svg) +`width`๊ณผ `height`๊ฐ€ ์Œ์ˆ˜์ธ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(`width=-200`, `height=-100`). -The rectangle starts at its bottom-right corner and then spans left/up, as negative `width/height` lead it backwards by coordinates. +![](coordinates-negative.svg) -As you can see, `left/top` are not `x/y` here. So these are actually not duplicates. Their formula can be adjusted to cover negative `width/height`, that's simple enough, but rarely needed, as the result of `elem.getBoundingClientRect()` always has positive width/height. +๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ์‚ฌ๋ก€์—์„œ `left`์™€ `top`์€ `x`๋‚˜ `y`์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -Here we mention negative `width/height` only for you to understand why these seemingly duplicate properties are not actually duplicates. +์ด๋ก ์ƒ ์ฐจ์ด๊ฐ€ ์žˆ๊ธด ํ•˜์ง€๋งŒ ์‹ค์ œ `elem.getBoundingClientRect()`์˜ `width`์™€ `height`๋Š” ํ•ญ์ƒ ์–‘์ˆ˜์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„  ํŒŒ์ƒ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์™œ ๋”ฐ๋กœ ์กด์žฌํ•˜๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด `width`์™€ `height`๊ฐ€ ์Œ์ˆ˜์ธ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ``` -```warn header="Internet Explorer and Edge: no support for `x/y`" -Internet Explorer and Edge don't support `x/y` properties for historical reasons. +```warn header="Internet Explorer๋Š” `x`, `y`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค." +Internet Explorer๋Š” ์˜ˆ์ „๋ถ€ํ„ฐ `x`, `y` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. -So we can either make a polywill (add getters in `DomRect.prototype`) or just use `top/left`, as they are always the same as `x/y` for positive `width/height`, in particular in the result of `elem.getBoundingClientRect()`. +Internet Explorer์—์„  `DomRect.prototype`์— getter๋ฅผ ์ถ”๊ฐ€ํ•ด ํด๋ฆฌํ•„์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ `elem.getBoundingClientRect()`์˜ `width`, `height`๊ฐ€ ์–‘์ˆ˜์ธ ๊ฒฝ์šฐ์— `top`, `left`๋Š” `x`, `y`์™€ ๊ฐ™๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ด์šฉํ•ด ๋Œ€์‹  `x`, `y` ๋Œ€์‹  `top`, `left`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ``` -```warn header="Coordinates right/bottom are different from CSS position properties" -There are obvious similarities between window-relative coordinates and CSS `position:fixed`. +```warn header="right, bottom ์ขŒํ‘œ๋Š” CSS position ํ”„๋กœํผํ‹ฐ์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค." +์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ์™€ CSS `position:fixed` ์‚ฌ์ด์—๋Š” ๋ช…๋ฐฑํ•œ ์œ ์‚ฌ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -But in CSS positioning, `right` property means the distance from the right edge, and `bottom` property means the distance from the bottom edge. +๊ทธ๋Ÿฌ๋‚˜ CSS์—์„œ `right` ํ”„๋กœํผํ‹ฐ๋Š” ์˜ค๋ฅธ์ชฝ ๋ชจ์„œ๋ฆฌ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ, `bottom` ํ”„๋กœํผํ‹ฐ๋Š” ์•„๋ž˜ ๋ชจ์„œ๋ฆฌ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -If we just look at the picture above, we can see that in JavaScript it is not so. All window coordinates are counted from the top-left corner, including these ones. +์œ„ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ๊ทธ ์ฐจ์ด๋ฅผ ํ•œ ๋ฒˆ์— ๋ณผ ์ˆ˜ ์žˆ์ฃ . ๊ทธ๋Ÿฌ๋‹ˆ `right`, `bottom`์„ ํฌํ•จํ•œ ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ์‚ฌ์šฉํ•  ๋• ์ธก์ • ๊ธฐ์ค€์ด ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ๋ผ๋Š” ์‚ฌ์‹ค์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ``` ## elementFromPoint(x, y) [#elementFromPoint] -The call to `document.elementFromPoint(x, y)` returns the most nested element at window coordinates `(x, y)`. +`document.elementFromPoint(x, y)`์„ ํ˜ธ์ถœํ•˜๋ฉด ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ `(x, y)`์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ค‘์ฒฉ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -The syntax is: +๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let elem = document.elementFromPoint(x, y); ``` -For instance, the code below highlights and outputs the tag of the element that is now in the middle of the window: +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฐฝ ์ •์ค‘์•™์— ์žˆ๋Š” ์š”์†Œ์˜ ํƒœ๊ทธ๊ฐ€ ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋˜๊ณ , ํ•ด๋‹น ์š”์†Œ๊ฐ€ ๋ถ‰์€์ƒ‰์œผ๋กœ ๊ฐ•์กฐ๋ฉ๋‹ˆ๋‹ค. ```js run let centerX = document.documentElement.clientWidth / 2; @@ -124,43 +124,43 @@ elem.style.background = "red"; alert(elem.tagName); ``` -As it uses window coordinates, the element may be different depending on the current scroll position. +`document.elementFromPoint(x, y)`๋Š” ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์Šคํฌ๋กค ์œ„์น˜์— ๊ฐ•์กฐ๋˜๋Š” ์š”์†Œ๋Š” ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -````warn header="For out-of-window coordinates the `elementFromPoint` returns `null`" -The method `document.elementFromPoint(x,y)` only works if `(x,y)` are inside the visible area. +````warn header="์ฐฝ๋ฐ– ์ขŒํ‘œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ `elementFromPoint`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `null`์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค." +`document.elementFromPoint(x,y)` ๋ฉ”์„œ๋“œ๋Š” `(x,y)`๊ฐ€ ๋ณด์ด๋Š” ์˜์—ญ ์•ˆ(์ฐฝ ์•ˆ)์— ์žˆ์„ ๋•Œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -If any of the coordinates is negative or exceeds the window width/height, then it returns `null`. +์ขŒํ‘œ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์Œ์ˆ˜์ด๊ฑฐ๋‚˜ ์ฐฝ์˜ ๋„ˆ๋น„, ๋†’์ด๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด `null`์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. -Here's a typical error that may occur if we don't check for it: +์ด๋Ÿฐ ํŠน์ง•์„ ๋ชจ๋ฅด๊ณ  ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ „ํ˜•์ ์ธ ์‹ค์ˆ˜๋ฅผ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ```js let elem = document.elementFromPoint(x, y); -// if the coordinates happen to be out of the window, then elem = null +// ์š”์†Œ๊ฐ€ ์ฐฝ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋ฉด lem = null *!* -elem.style.background = ''; // Error! +elem.style.background = ''; // ์—๋Ÿฌ! */!* ``` ```` -## Using for "fixed" positioning +## ์š”์†Œ๋ฅผ ์ฐฝ ๋‚ด ํŠน์ • ์ขŒํ‘œ์— ๊ณ ์ •ํ•˜๊ธฐ -Most of time we need coordinates in order to position something. +์ขŒํ‘œ๋Š” ๋Œ€๋ถ€๋ถ„ ๋ฌด์–ธ๊ฐ€๋ฅผ ์œ„์น˜์‹œํ‚ค๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -To show something near an element, we can use `getBoundingClientRect` to get its coordinates, and then CSS `position` together with `left/top` (or `right/bottom`). +์š”์†Œ ๊ทผ์ฒ˜์— ๋ฌด์–ธ๊ฐ€๋ฅผ ํ‘œ์‹œํ•  ๋•Œ์—๋Š” `getBoundingClientRect`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์˜ ์ขŒํ‘œ๋ฅผ ์–ป๊ณ  CSS `position`์„ `left/top`(๋˜๋Š” `right/bottom`)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์„œ ํ‘œ์‹œํ•˜์ฃ . -For instance, the function `createMessageUnder(elem, html)` below shows the message under `elem`: +์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜ `createMessageUnder(elem, html)` ํ•จ์ˆ˜๋Š” `elem` ์•„๋ž˜์ชฝ์— ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ```js let elem = document.getElementById("coords-show-mark"); function createMessageUnder(elem, html) { - // create message element + // ๋ฉ”์‹œ์ง€๊ฐ€ ๋‹ด๊ธธ ์š”์†Œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. let message = document.createElement('div'); - // better to use a css class for the style here + // ์š”์†Œ๋ฅผ ์Šคํƒ€์ผ๋ง ํ•  ๋• css ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. message.style.cssText = "position:fixed; color: red"; *!* - // assign coordinates, don't forget "px"! + // ์ขŒํ‘œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ "px"์„ ํ•จ๊ป˜ ์จ์ฃผ๋Š” ๊ฑธ ์žŠ์ง€ ๋งˆ์„ธ์š”! let coords = elem.getBoundingClientRect(); message.style.left = coords.left + "px"; @@ -172,58 +172,60 @@ function createMessageUnder(elem, html) { return message; } -// Usage: -// add it for 5 seconds in the document -let message = createMessageUnder(elem, 'Hello, world!'); +// ์‚ฌ์šฉ๋ฒ•: +// ๋ฌธ์„œ ์•ˆ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋„์šฐ๊ณ , 5์ดˆ ๋™์•ˆ๋งŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +let message = createMessageUnder(elem, '๋…๋„๋Š” ์šฐ๋ฆฌ๋•…!'); document.body.append(message); setTimeout(() => message.remove(), 5000); ``` ```online -Click the button to run it: +์ง์ ‘ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์œ„ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•ด ๋ด…์‹œ๋‹ค. -<button id="coords-show-mark">Button with id="coords-show-mark", the message will appear under it</button> +<button id="coords-show-mark">id๊ฐ€ "coords-show-mark"์ธ ๋ฒ„ํŠผ์ด ์—ฌ๊ธฐ ์žˆ๊ณ , ๋ฉ”์‹œ์ง€๋Š” ๊ทธ ์•„๋ž˜์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.</button> ``` -The code can be modified to show the message at the left, right, below, apply CSS animations to "fade it in" and so on. That's easy, as we have all the coordinates and sizes of the element. +์œ„ ์˜ˆ์‹œ๋ฅผ ์‘์šฉํ•˜๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ์™ผ์ชฝ ์ด๋‚˜ ์˜ค๋ฅธ์ชฝ, ์•„๋ž˜์— ํ‘œ์‹œํ•  ์ˆ˜๋„ ์žˆ๊ณ  CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•˜๋ฉด 'fade-in' ๋“ฑ์˜ ํšจ๊ณผ๋„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ขŒํ‘ฏ๊ฐ’๊ณผ ์š”์†Œ์˜ ํฌ๊ธฐ๋งŒ ์•Œ๋ฉด ์†์‰ฝ๊ฒŒ ์›ํ•˜๋Š” ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์ฃ . -But note the important detail: when the page is scrolled, the message flows away from the button. +๊ทธ๋Ÿฐ๋ฐ ์˜ˆ์‹œ์—์„œ ๋ญ”๊ฐ€ ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์šด ๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. ํŽ˜์ด์ง€๋ฅผ ์Šคํฌ๋กค ํ•˜๋ฉด ๋ฉ”์‹œ์ง€๊ฐ€ ๋ฒ„ํŠผ์—์„œ ๋–จ์–ด์ง€๋„ค์š”. -The reason is obvious: the message element relies on `position:fixed`, so it remains at the same place of the window while the page scrolls away. +๋ฉ”์‹œ์ง€๊ฐ€ ๋ฒ„ํŠผ์—์„œ ๋–จ์–ด์ง€๋Š” ์ด์œ ๋Š” ์•„์ฃผ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€ ์š”์†Œ๊ฐ€ `position:fixed`์ด๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๊ฐ€ ์Šคํฌ๋กค ๋˜์–ด๋„ ์ฐฝ ๊ธฐ์ค€ ๋™์ผํ•œ ์œ„์น˜์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -To change that, we need to use document-based coordinates and `position:absolute`. +์ด๋Ÿฐ ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์šด ํ˜„์ƒ์„ ๊ฐœ์„ ํ•˜๋ ค๋ฉด ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ์™€ `position:absolute`๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -## Document coordinates [#getCoords] +## ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ [#getCoords] -Document-relative coordinates start from the upper-left corner of the document, not the window. +๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” ์ฐฝ์ด ์•„๋‹Œ ๋ฌธ์„œ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. -In CSS, window coordinates correspond to `position:fixed`, while document coordinates are similar to `position:absolute` on top. +CSS์™€ ๋น„๊ตํ•˜์ž๋ฉด ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” `position:fixed`์— ํ•ด๋‹นํ•˜๊ณ  ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” ๋งจ ์œ„ ๊ธฐ์ค€ `position:absolute`์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. -We can use `position:absolute` and `top/left` to put something at a certain place of the document, so that it remains there during a page scroll. But we need the right coordinates first. +๋ฌธ์„œ ๋‚ด ํŠน์ • ์ขŒํ‘œ์— ๋ฌด์–ธ๊ฐ€๋ฅผ ์œ„์น˜์‹œํ‚ค๊ณ  ์‹ถ์„ ๋• `position:absolute`์™€ `top, `left`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋กค ์ด๋™์— ์ƒ๊ด€์—†์ด ํ•ด๋‹น ์š”์†Œ๋ฅผ ํ•œ ์ขŒํ‘œ์— ๋จธ๋ฌผ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ ค๋ฉด ์šฐ์„  ์ •ํ™•ํ•œ ์ขŒํ‘œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -There's no standard method to get the document coordinates of an element. But it's easy to write it. +๊ทธ๋Ÿฐ๋ฐ ์š”์†Œ์˜ ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„์ง ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ฃผ ์‰ฝ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The two coordinate systems are connected by the formula: -- `pageY` = `clientY` + height of the scrolled-out vertical part of the document. -- `pageX` = `clientX` + width of the scrolled-out horizontal part of the document. +๋‘ ์ขŒํ‘œ ์ฒด๊ณ„(์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ์™€ ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ)๋Š” ๋‹ค์Œ ์ˆ˜์‹์„ ํ†ตํ•ด ์—ฐ๊ด€์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- `pageY` = `clientY` + ๋ฌธ์„œ์—์„œ ์„ธ๋กœ ๋ฐฉํ–ฅ ์Šคํฌ๋กค์— ์˜ํ•ด ๋ฐ€๋ ค๋‚œ ๋ถ€๋ถ„์˜ ๋†’์ด +- `pageX` = `clientX` + ๋ฌธ์„œ์—์„œ ๊ฐ€๋กœ ๋ฐฉํ–ฅ ์Šคํฌ๋กค์— ์˜ํ•ด ๋ฐ€๋ ค๋‚œ ๋ถ€๋ถ„์˜ ๋„ˆ๋น„ -The function `getCoords(elem)` will take window coordinates from `elem.getBoundingClientRect()` and add the current scroll to them: +๋‹ค์Œ ํ•จ์ˆ˜ `getCoords(elem)`๋Š” `elem.getBoundingClientRect()`์„ ์‚ฌ์šฉํ•ด ์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ์–ป๊ณ  ์—ฌ๊ธฐ์— ์Šคํฌ๋กค์— ์˜ํ•ด ๊ฐ€๋ ค์ง„ ์˜์—ญ์˜ ๋„ˆ๋น„๋‚˜ ๋†’์ด๋ฅผ ๋”ํ•ฉ๋‹ˆ๋‹ค. ```js -// get document coordinates of the element +// ์š”์†Œ์˜ ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. function getCoords(elem) { let box = elem.getBoundingClientRect(); return { - top: box.top + pageYOffset, - left: box.left + pageXOffset + top: box.top + window.pageYOffset, + right: box.right + window.pageXOffset, + bottom: box.bottom + window.pageYOffset, + left: box.left + window.pageXOffset }; } ``` -If in the example above we used it with `position:absolute`, then the message would stay near the element on scroll. +๊ทธ๋Ÿฐ๋ฐ ์œ„ ์˜ˆ์‹œ์—์„œ `position:absolute`์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์Šคํฌ๋กค์„ ํ•ด๋„ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ฒ„ํŠผ ์š”์†Œ ๊ทผ์ฒ˜์— ๋จธ๋ฌผ๋ €์„ ๊ฒ๋‹ˆ๋‹ค. -The modified `createMessageUnder` function: +์ด๋ฅผ ๋ฐ˜์˜ํ•œ ํ•จ์ˆ˜ `createMessageUnder`๋ฅผ ๊ฐ™์ด ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js function createMessageUnder(elem, html) { @@ -241,13 +243,13 @@ function createMessageUnder(elem, html) { } ``` -## Summary +## ์š”์•ฝ -Any point on the page has coordinates: +ํŽ˜์ด์ง€ ๋‚ด ๋ชจ๋“  ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ขŒํ‘œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. -1. Relative to the window -- `elem.getBoundingClientRect()`. -2. Relative to the document -- `elem.getBoundingClientRect()` plus the current page scroll. +1. ์ฐฝ ๊ธฐ์ค€ -- `elem.getBoundingClientRect()` +2. ๋ฌธ์„œ ๊ธฐ์ค€ -- `elem.getBoundingClientRect()`์™€ ํ˜„์žฌ ์Šคํฌ๋กค ์ƒํƒœ -Window coordinates are great to use with `position:fixed`, and document coordinates do well with `position:absolute`. +์ฐฝ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” `position:fixed`์™€ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๊ณ  ๋ฌธ์„œ ๊ธฐ์ค€ ์ขŒํ‘œ๋Š” `position:absolute`์™€ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. -Both coordinate systems have their "pro" and "contra", there are times we need one or the other one, just like CSS `position` `absolute` and `fixed`. +๋‘ ์ขŒํ‘œ ์ฒด๊ณ„ ๋ชจ๋‘ ์žฅ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. CSS์˜ `position`, `absolute`, `fixed`์ฒ˜๋Ÿผ ์ด๊ฒŒ ํ•„์š”ํ•  ๋•Œ๋„ ์žˆ๊ณ  ์ €๊ฒŒ ํ•„์š”ํ•  ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/coordinates-negative.svg b/2-ui/1-document/11-coordinates/coordinates-negative.svg index 347c96d8a0..4f2e78687c 100644 --- a/2-ui/1-document/11-coordinates/coordinates-negative.svg +++ b/2-ui/1-document/11-coordinates/coordinates-negative.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="521" height="355" viewBox="0 0 521 355"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><filter id="filter-1" width="118%" height="209.1%" x="-9%" y="-54.5%" filterUnits="objectBoundingBox"><feGaussianBlur in="SourceGraphic" stdDeviation="4"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="coordinates-negative.svg"><g id="noun_69008_cc" fill="#E8C48E" transform="translate(13 11)"><path id="Shape" d="M455.313 330H9.688C4.34 330 0 326.288 0 321.75V8.25C0 3.713 4.34 0 9.688 0h445.625C460.64 0 465 3.712 465 8.25v313.5c0 4.538-4.36 8.25-9.688 8.25zM9.432 318.939h444.25V11.06H9.432V318.94z"/><path id="Shape" d="M19.674 46C14.334 46 10 44.875 10 43.5s4.334-2.5 9.674-2.5h425.652c5.32 0 9.674 1.125 9.674 2.5s-4.353 2.5-9.674 2.5H19.674zM31 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5zM59 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5zM87 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5z"/></g><text id="bottom" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="414" y="196">bottom</tspan></text><path id="Line-30-Copy-2" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M392.5 290v37"/><path id="Line-29-Copy" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M394 288h69"/><text id="(x,y)" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="395" y="305">(x,y)</tspan></text><text id="(x,y)-copy" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="395" y="305">(x,y)</tspan></text><text id="left" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="50" y="129">left</tspan></text><path id="Line-Copy" fill="#999" fill-rule="nonzero" d="M410 56.5v213h8l-9.5 19-9.5-19h8v-213h3z"/><text id="right" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="188" y="323">right</tspan></text><path id="Line-3-Copy-2" fill="#999" fill-rule="nonzero" d="M371.498 295.5l19 9.5-19 9.5-.001-8H21.502v-3h349.995v-8z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M393 113v175H118V113h275zm-10.643 10H129.015v155h253.342V123z"/><text id="Introduction-This-Ec" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".7"><tspan x="139" y="148">Introduction</tspan> <tspan x="139" y="176" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="139" y="195" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">several originating technologies, </tspan> <tspan x="139" y="214" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">the most well known being </tspan> <tspan x="139" y="233" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JavaScript (Netscape) and JScript </tspan> <tspan x="139" y="252" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="139" y="271" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at </tspan></text><text id="top" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="90">top</tspan></text><path id="Line-3" fill="#999" fill-rule="nonzero" d="M100.548 104.403l18.95 9.6-19.05 9.4.041-8.001-78-.41.017-3 77.999.41.043-8z"/><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M118.076 113.232l21.132 2.162-4.288 6.754 257.148 163.24-1.608 2.532-257.148-163.239-4.287 6.754-10.95-18.203z"/><path id="Line-3-Copy" fill="#999" fill-rule="nonzero" d="M118.998 56.5L119 94.499h8l-9.498 19.001-9.501-19H116l-.002-38h3z"/><g id="Group" transform="rotate(32.5 -148.357 454.177)"><path id="Rectangle" fill="#FFF" d="M0 0h133v22H0z" filter="url(#filter-1)"/><text id="(width,height)" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="8.682" y="15.378">(width,height)</tspan></text></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="521" height="355" viewBox="0 0 521 355"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><filter id="filter-1" width="118%" height="209.1%" x="-9%" y="-54.5%" filterUnits="objectBoundingBox"><feGaussianBlur in="SourceGraphic" stdDeviation="4"/></filter></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="coordinates-negative.svg"><g id="noun_69008_cc" fill="#DBAF88" transform="translate(13 11)"><path id="Shape" d="M455.313 330H9.688C4.34 330 0 326.288 0 321.75V8.25C0 3.713 4.34 0 9.688 0h445.625C460.64 0 465 3.712 465 8.25v313.5c0 4.538-4.36 8.25-9.688 8.25zM9.432 318.939h444.25V11.06H9.432V318.94z"/><path id="Shape" d="M19.674 46C14.334 46 10 44.875 10 43.5s4.334-2.5 9.674-2.5h425.652c5.32 0 9.674 1.125 9.674 2.5s-4.353 2.5-9.674 2.5H19.674zM31 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5zM59 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5zM87 27.5c0 3.039-2.461 5.5-5.5 5.5a5.498 5.498 0 01-5.5-5.5c0-3.039 2.461-5.5 5.5-5.5s5.5 2.461 5.5 5.5z"/></g><text id="bottom" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="414" y="196">bottom</tspan></text><path id="Line-30-Copy-2" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M392.5 290v37"/><path id="Line-29-Copy" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M394 288h69"/><text id="(x,y)" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="395" y="305">(x,y)</tspan></text><text id="(x,y)-copy" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="395" y="305">(x,y)</tspan></text><text id="left" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="50" y="129">left</tspan></text><path id="Line-Copy" fill="#7E7C7B" fill-rule="nonzero" d="M410 56.5v213h8l-9.5 19-9.5-19h8v-213h3z"/><text id="right" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="188" y="323">right</tspan></text><path id="Line-3-Copy-2" fill="#7E7C7B" fill-rule="nonzero" d="M371.498 295.5l19 9.5-19 9.5-.001-8H21.502v-3h349.995v-8z"/><path id="Rectangle-1" fill="#DBAF88" d="M393 113v175H118V113h275zm-10.643 10H129.015v155h253.342V123z"/><text id="Introduction-This-Ec" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".7"><tspan x="139" y="148">Introduction</tspan> <tspan x="139" y="176" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="139" y="195" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">several originating technologies, </tspan> <tspan x="139" y="214" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">the most well known being </tspan> <tspan x="139" y="233" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JavaScript (Netscape) and JScript </tspan> <tspan x="139" y="252" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="139" y="271" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at </tspan></text><text id="top" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="90">top</tspan></text><path id="Line-3" fill="#7E7C7B" fill-rule="nonzero" d="M100.548 104.403l18.95 9.6-19.05 9.4.041-8.001-76.5-.402-1.5-.008.017-3 1.5.008 76.499.402.043-8z"/><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M118.076 113.232l21.132 2.162-4.288 6.754 255.882 162.436 1.266.804-1.608 2.532-1.266-.804-255.882-162.435-4.287 6.754-10.95-18.203z"/><path id="Line-3-Copy" fill="#7E7C7B" fill-rule="nonzero" d="M118.998 56.5V58L119 94.499h8l-9.498 19.001-9.501-19H116l-.002-36.5v-1.5h3z"/><g id="Group" transform="rotate(32.5 -148.357 454.177)"><path id="Rectangle" fill="#FFF" d="M0 0h133v22H0z" filter="url(#filter-1)"/><text id="(width,height)" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="8.682" y="15.378">(width,height)</tspan></text></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/coordinates.svg b/2-ui/1-document/11-coordinates/coordinates.svg index 2d789c1cfd..169fc41027 100644 --- a/2-ui/1-document/11-coordinates/coordinates.svg +++ b/2-ui/1-document/11-coordinates/coordinates.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="521" height="411" viewBox="0 0 521 411"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="coordinates.svg"><g id="noun_69008_cc" fill="#E8C48E" transform="translate(13 11)"><path id="Shape" d="M490.563 386H10.438C4.676 386 0 381.658 0 376.35V9.65C0 4.342 4.676 0 10.438 0h480.125C496.303 0 501 4.343 501 9.65v366.7c0 5.308-4.697 9.65-10.438 9.65zm-480.4-12.939h478.642V12.94H10.162V373.06z"/><path id="Shape" d="M20.859 54.1c-5.753 0-10.422-1.147-10.422-2.55 0-1.402 4.67-2.55 10.422-2.55H479.4c5.732 0 10.422 1.148 10.422 2.55 0 1.403-4.69 2.55-10.422 2.55H20.86zM33.8 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0zM63.988 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0zM94.177 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0z"/></g><text id="height" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="417" y="208">height</tspan></text><text id="bottom" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="451" y="311">bottom</tspan></text><path id="Line-28" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M395 293h103"/><path id="Line-30" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M392 296v74.5"/><path id="Line-30-Copy" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M119 296v46"/><path id="Line-29" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M396 120h30"/><text id="x" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="62" y="113">x</tspan></text><text id="left" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="50" y="135">left</tspan></text><text id="y" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="79">y</tspan></text><text id="width" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="234" y="339">width</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M414 118.5V273h8l-9.5 19-9.5-19h8V118.5h3z"/><path id="Line-Copy" fill="#999" fill-rule="nonzero" d="M476 65v208h8l-9.5 19-9.5-19h8V65h3z"/><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M371 309l19 9.5-19 9.5-.001-8H116v-3h254.999l.001-8z"/><path id="Line-3" fill="#EE6B47" fill-rule="nonzero" d="M100.05 109.903l18.95 9.6-19.05 9.4.042-8.001-78-.41.016-3 78 .41.042-8z"/><text id="right" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="180" y="375">right</tspan></text><path id="Line-3-Copy-2" fill="#999" fill-rule="nonzero" d="M371 350l19 9.5-19 9.5v-8H21.005v-3H371v-8z"/><path id="Line-3-Copy" fill="#EE6B47" fill-rule="nonzero" d="M119 65l.003 35.749h8l-9.498 19.001-9.502-19h8L116 65h3z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M392.629 119v175H118V119h274.629zM382 129H129v155h253V129z"/><text id="Introduction-This-Ec" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".8"><tspan x="138.946" y="153.8">Introduction</tspan> <tspan x="138.946" y="181.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="138.946" y="200.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">several originating technologies, </tspan> <tspan x="138.946" y="219.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">the most well known being </tspan> <tspan x="138.946" y="238.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JavaScript (Netscape) and JScript </tspan> <tspan x="138.946" y="257.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="138.946" y="276.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at </tspan></text><text id="top" fill="#999" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="96">top</tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="521" height="411" viewBox="0 0 521 411"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="coordinates.svg"><g id="noun_69008_cc" fill="#DBAF88" transform="translate(13 11)"><path id="Shape" d="M490.563 386H10.438C4.676 386 0 381.658 0 376.35V9.65C0 4.342 4.676 0 10.438 0h480.125C496.303 0 501 4.343 501 9.65v366.7c0 5.308-4.697 9.65-10.438 9.65zm-480.4-12.939h478.642V12.94H10.162V373.06z"/><path id="Shape" d="M20.859 54.1c-5.753 0-10.422-1.147-10.422-2.55 0-1.402 4.67-2.55 10.422-2.55H479.4c5.732 0 10.422 1.148 10.422 2.55 0 1.403-4.69 2.55-10.422 2.55H20.86zM33.8 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0zM63.988 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0zM94.177 31.627a6.024 6.024 0 11-12.05 0 6.024 6.024 0 1112.05 0z"/></g><text id="height" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="417" y="208">height</tspan></text><text id="bottom" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="451" y="311">bottom</tspan></text><path id="Line-28" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M395 293h103"/><path id="Line-30" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M392 296v74.5"/><path id="Line-30-Copy" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M119 296v46"/><path id="Line-29" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M396 120h30"/><text id="x" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="62" y="113">x</tspan></text><text id="left" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="50" y="135">left</tspan></text><text id="y" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="79">y</tspan></text><text id="width" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="234" y="339">width</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M414 118.5V273h8l-9.5 19-9.5-19h8V118.5h3z"/><path id="Line-Copy" fill="#7E7C7B" fill-rule="nonzero" d="M476 65v208h8l-9.5 19-9.5-19h8V65h3z"/><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M371 309l19 9.5-19 9.5-.001-8H116v-3h254.999l.001-8z"/><path id="Line-3" fill="#C06334" fill-rule="nonzero" d="M100.05 109.903l18.95 9.6-19.05 9.4.042-8.001-76.5-.402-1.5-.008.016-3 1.5.008 76.5.402.042-8z"/><text id="right" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="180" y="375">right</tspan></text><path id="Line-3-Copy-2" fill="#7E7C7B" fill-rule="nonzero" d="M371 350l19 9.5-19 9.5v-8H21.005v-3H371v-8z"/><path id="Line-3-Copy" fill="#C06334" fill-rule="nonzero" d="M119 65v1.5l.003 34.249h8l-9.498 19.001-9.502-19h8L116 66.5V65h3z"/><path id="Rectangle-1" fill="#DBAF88" d="M392.629 119v175H118V119h274.629zM382 129H129v155h253V129z"/><text id="Introduction-This-Ec" fill="#643B0C" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".8"><tspan x="138.946" y="153.8">Introduction</tspan> <tspan x="138.946" y="181.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on </tspan> <tspan x="138.946" y="200.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">several originating technologies, </tspan> <tspan x="138.946" y="219.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">the most well known being </tspan> <tspan x="138.946" y="238.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JavaScript (Netscape) and JScript </tspan> <tspan x="138.946" y="257.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">(Microsoft). The language was </tspan> <tspan x="138.946" y="276.8" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at </tspan></text><text id="top" fill="#7E7C7B" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="125" y="96">top</tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/document-and-window-coordinates-scrolled.svg b/2-ui/1-document/11-coordinates/document-and-window-coordinates-scrolled.svg index 204f02c85f..f03317f0c3 100644 --- a/2-ui/1-document/11-coordinates/document-and-window-coordinates-scrolled.svg +++ b/2-ui/1-document/11-coordinates/document-and-window-coordinates-scrolled.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="728" height="358" viewBox="0 0 728 358"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="document-and-window-coordinates-scrolled.svg"><path fill="#FFF" d="M0 0h728v358H0z"/><text id="Introduction-This-Ec" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".7"><tspan x="34" y="176">Introduction</tspan> <tspan x="34" y="204" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="34" y="223" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="34" y="242" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="34" y="261" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="34" y="280" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="34" y="299" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="34" y="318" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. </tspan> <tspan x="34" y="337" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan> <tspan x="34" y="356" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">It has appeared in all subsequent browsers </tspan> <tspan x="34" y="375" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">from Netscape and in all browsers from </tspan> <tspan x="34" y="394" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="34" y="413" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0. The development of this Standard </tspan> <tspan x="34" y="432" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. </tspan> <tspan x="34" y="451" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The first edition of this Ecma Standard was </tspan> <tspan x="34" y="470" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly of </tspan> <tspan x="34" y="489" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">June 1997.</tspan> <tspan x="34" y="508" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="34" y="527" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="34" y="546" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="34" y="565" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="34" y="584" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="34" y="603" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="34" y="622" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="34" y="641" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="34" y="660" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><text id="๐Ÿ˜" fill="#5A4739" font-family="AppleColorEmoji, Apple Color Emoji" font-size="18" font-weight="normal"><tspan x="139" y="330">๐Ÿ˜</tspan></text><path id="Line-39" fill="#EE6B47" fill-rule="nonzero" d="M150.5 131v167h6l-7 14-7-14h6V131h2z"/><text id="pageY" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="157" y="155">pageY</tspan></text><text id="clientY" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="156.4" y="177">clientY</tspan></text><path id="Line-39-Copy" fill="#EE6B47" fill-rule="nonzero" d="M126 315.5l14 7-14 7-.001-6.001L12 323.5v-2l113.999-.001.001-5.999z"/><text id="pageX" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="23" y="316">pageX</tspan></text><text id="clientX" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="22.4" y="337">clientX</tspan></text><g id="np_browser_551045_E8C48F" fill="#E8C48F" fill-rule="nonzero" transform="translate(-1 68)"><path id="Shape" d="M22.8 0C7.76 0 0 8.157 0 24v242c0 15.843 7.759 24 22.8 24h309.346c15.042 0 21.854-7.157 21.854-23V24c0-15.843-6.812-24-21.854-24H22.8zm-5.425 15.286h318.177c2.535 0 4.187 2.012 4.187 5.1L338 55.328H13.188V20.386c0-3.088 1.652-5.1 4.187-5.1zm21.159 13.857c-3.902 0-7.067 3.327-7.067 7.428S34.632 44 38.534 44s7.067-3.328 7.067-7.429c0-4.1-3.165-7.428-7.067-7.428zm31.467 0c-3.902 0-7.068 3.327-7.068 7.428S66.1 44 70.001 44c3.901 0 7.067-3.328 7.067-7.429 0-4.1-3.166-7.428-7.067-7.428zm31.466 0c-3.901 0-7.067 3.327-7.067 7.428S97.566 44 101.467 44c3.902 0 7.068-3.328 7.068-7.429 0-4.1-3.166-7.428-7.068-7.428zM14 71.172h324l1.865 198.376c0 2.782-1.651 4.595-4.186 4.595H17.5c-2.535 0-4.187-1.813-4.187-4.595L14 71.172z"/></g><text id="Introduction-This-Ec" fill="#5A4739" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".7"><tspan x="409" y="34">Introduction</tspan> <tspan x="409" y="62" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="409" y="81" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="409" y="100" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="409" y="119" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="409" y="138" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="409" y="157" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="409" y="176" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. </tspan> <tspan x="409" y="195" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan> <tspan x="409" y="214" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">It has appeared in all subsequent browsers </tspan> <tspan x="409" y="233" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">from Netscape and in all browsers from </tspan> <tspan x="409" y="252" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="409" y="271" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0. The development of this Standard </tspan> <tspan x="409" y="290" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. </tspan> <tspan x="409" y="309" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The first edition of this Ecma Standard was </tspan> <tspan x="409" y="328" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly of </tspan> <tspan x="409" y="347" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">June 1997.</tspan> <tspan x="409" y="366" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="409" y="385" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="409" y="404" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="409" y="423" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="409" y="442" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="409" y="461" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="409" y="480" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="409" y="499" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="409" y="518" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle" fill="#FFF" d="M392 87h307v42H392z" opacity=".6"/><g id="np_browser_551045_E8C48F" fill="#E8C48F" fill-rule="nonzero" transform="translate(374 71)"><path id="Shape" d="M22.8 0C7.76 0 0 8.157 0 24v242c0 15.843 7.759 24 22.8 24h309.346c15.042 0 21.854-7.157 21.854-23V24c0-15.843-6.812-24-21.854-24H22.8zm-5.425 15.286h318.177c2.535 0 4.187 2.012 4.187 5.1L338 55.328H13.188V20.386c0-3.088 1.652-5.1 4.187-5.1zm21.159 13.857c-3.902 0-7.067 3.327-7.067 7.428S34.632 44 38.534 44s7.067-3.328 7.067-7.429c0-4.1-3.165-7.428-7.067-7.428zm31.467 0c-3.902 0-7.068 3.327-7.068 7.428S66.1 44 70.001 44c3.901 0 7.067-3.328 7.067-7.429 0-4.1-3.166-7.428-7.067-7.428zm31.466 0c-3.901 0-7.067 3.327-7.067 7.428S97.566 44 101.467 44c3.902 0 7.068-3.328 7.068-7.429 0-4.1-3.166-7.428-7.068-7.428zM14 71.172h324l1.865 198.376c0 2.782-1.651 4.595-4.186 4.595H17.5c-2.535 0-4.187-1.813-4.187-4.595L14 71.172z"/></g><path id="Rectangle-2" stroke="#E8C48F" stroke-opacity=".8" stroke-width="2" d="M387 7h326v351H387z"/><path id="Rectangle-14" fill="#FFF" fill-opacity=".8" d="M395 8h312v61H395z"/><path id="Line-39" fill="#EE6B47" fill-rule="nonzero" d="M519.5 7v159h6l-7 14-7-14h6V7h2z"/><path id="Line-39-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M532.5 137v29h6l-7 14-7-14h6v-29h2z"/><text id="pageY" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="525" y="23">pageY</tspan></text><text id="clientY" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="542.4" y="172">clientY</tspan></text><path id="Line-39-Copy" fill="#EE6B47" fill-rule="nonzero" d="M501 182.5l14 7-14 7-.001-6.001L388 190.5v-2l112.999-.001.001-5.999z"/><text id="pageX" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="398" y="183">pageX</tspan></text><text id="clientX" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="397.4" y="204">clientX</tspan></text><text id="๐Ÿ˜" fill="#5A4739" font-family="AppleColorEmoji, Apple Color Emoji" font-size="18" font-weight="normal"><tspan x="514" y="197">๐Ÿ˜</tspan></text></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="728" height="358" viewBox="0 0 728 358"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="document-and-window-coordinates-scrolled.svg"><path fill="#FFF" d="M0 0h728v358H0z"/><text id="Introduction-This-Ec" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".5"><tspan x="34" y="176">Introduction</tspan> <tspan x="34" y="204" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="34" y="223" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="34" y="242" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="34" y="261" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="34" y="280" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="34" y="299" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="34" y="318" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. </tspan> <tspan x="34" y="337" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan> <tspan x="34" y="356" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">It has appeared in all subsequent browsers </tspan> <tspan x="34" y="375" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">from Netscape and in all browsers from </tspan> <tspan x="34" y="394" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="34" y="413" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0. The development of this Standard </tspan> <tspan x="34" y="432" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. </tspan> <tspan x="34" y="451" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The first edition of this Ecma Standard was </tspan> <tspan x="34" y="470" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly of </tspan> <tspan x="34" y="489" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">June 1997.</tspan> <tspan x="34" y="508" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="34" y="527" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="34" y="546" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="34" y="565" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="34" y="584" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="34" y="603" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="34" y="622" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="34" y="641" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="34" y="660" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><text id="๐Ÿ˜" fill="#643B0C" font-family="AppleColorEmoji, Apple Color Emoji" font-size="18" font-weight="normal"><tspan x="139" y="330">๐Ÿ˜</tspan></text><path id="Line-39" fill="#C06334" fill-rule="nonzero" d="M150.5 131v167h6l-7 14-7-14h6V131h2z"/><text id="pageY" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="157" y="155">pageY</tspan></text><text id="clientY" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="156.4" y="177">clientY</tspan></text><path id="Line-39-Copy" fill="#C06334" fill-rule="nonzero" d="M126 315.5l14 7-14 7-.001-6.001L13 323.5h-1v-2h1l112.999-.001.001-5.999z"/><text id="pageX" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="23" y="316">pageX</tspan></text><text id="clientX" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="22.4" y="337">clientX</tspan></text><g id="np_browser_551045_E8C48F" fill="#DBAF88" fill-rule="nonzero" transform="translate(-1 68)"><path id="Shape" d="M22.8 0C7.76 0 0 8.157 0 24v242c0 15.843 7.759 24 22.8 24h309.346c15.042 0 21.854-7.157 21.854-23V24c0-15.843-6.812-24-21.854-24H22.8zm-5.425 15.286h318.177c2.535 0 4.187 2.012 4.187 5.1L338 55.328H13.188V20.386c0-3.088 1.652-5.1 4.187-5.1zm21.159 13.857c-3.902 0-7.067 3.327-7.067 7.428S34.632 44 38.534 44s7.067-3.328 7.067-7.429c0-4.1-3.165-7.428-7.067-7.428zm31.467 0c-3.902 0-7.068 3.327-7.068 7.428S66.1 44 70.001 44c3.901 0 7.067-3.328 7.067-7.429 0-4.1-3.166-7.428-7.067-7.428zm31.466 0c-3.901 0-7.067 3.327-7.067 7.428S97.566 44 101.467 44c3.902 0 7.068-3.328 7.068-7.429 0-4.1-3.166-7.428-7.068-7.428zM14 71.172h324l1.865 198.376c0 2.782-1.651 4.595-4.186 4.595H17.5c-2.535 0-4.187-1.813-4.187-4.595L14 71.172z"/></g><text id="Introduction-This-Ec" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="16" font-weight="bold" opacity=".5"><tspan x="409" y="34">Introduction</tspan> <tspan x="409" y="62" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">This Ecma Standard is based on several </tspan> <tspan x="409" y="81" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">originating technologies, the most well </tspan> <tspan x="409" y="100" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">known being JavaScript (Netscape) and </tspan> <tspan x="409" y="119" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">JScript (Microsoft). The language was </tspan> <tspan x="409" y="138" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">invented by Brendan Eich at Netscape and </tspan> <tspan x="409" y="157" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">first appeared in that companyโ€™s Navigator </tspan> <tspan x="409" y="176" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">2.0 browser. </tspan> <tspan x="409" y="195" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"> </tspan> <tspan x="409" y="214" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">It has appeared in all subsequent browsers </tspan> <tspan x="409" y="233" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">from Netscape and in all browsers from </tspan> <tspan x="409" y="252" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Microsoft starting with Internet Explorer </tspan> <tspan x="409" y="271" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">3.0. The development of this Standard </tspan> <tspan x="409" y="290" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">started in November 1996. </tspan> <tspan x="409" y="309" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">The first edition of this Ecma Standard was </tspan> <tspan x="409" y="328" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">adopted by the Ecma General Assembly of </tspan> <tspan x="409" y="347" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">June 1997.</tspan> <tspan x="409" y="366" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">That Ecma Standard was submitted to ISO/</tspan> <tspan x="409" y="385" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">IEC JTC 1 for adoption under the fast-track </tspan> <tspan x="409" y="404" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">procedure, and approved as international </tspan> <tspan x="409" y="423" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">standard ISO/IEC 16262, in April 1998. The </tspan> <tspan x="409" y="442" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Ecma General Assembly of June 1998 </tspan> <tspan x="409" y="461" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">approved the second edition of ECMA-262 </tspan> <tspan x="409" y="480" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">to keep it fully aligned with ISO/IEC 16262. </tspan> <tspan x="409" y="499" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">Changes between the first and the second </tspan> <tspan x="409" y="518" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal">edition are editorial in nature.</tspan></text><path id="Rectangle" fill="#FFF" d="M392 87h307v42H392z" opacity=".6"/><g id="np_browser_551045_E8C48F" fill="#DBAF88" fill-rule="nonzero" transform="translate(374 71)"><path id="Shape" d="M22.8 0C7.76 0 0 8.157 0 24v242c0 15.843 7.759 24 22.8 24h309.346c15.042 0 21.854-7.157 21.854-23V24c0-15.843-6.812-24-21.854-24H22.8zm-5.425 15.286h318.177c2.535 0 4.187 2.012 4.187 5.1L338 55.328H13.188V20.386c0-3.088 1.652-5.1 4.187-5.1zm21.159 13.857c-3.902 0-7.067 3.327-7.067 7.428S34.632 44 38.534 44s7.067-3.328 7.067-7.429c0-4.1-3.165-7.428-7.067-7.428zm31.467 0c-3.902 0-7.068 3.327-7.068 7.428S66.1 44 70.001 44c3.901 0 7.067-3.328 7.067-7.429 0-4.1-3.166-7.428-7.067-7.428zm31.466 0c-3.901 0-7.067 3.327-7.067 7.428S97.566 44 101.467 44c3.902 0 7.068-3.328 7.068-7.429 0-4.1-3.166-7.428-7.068-7.428zM14 71.172h324l1.865 198.376c0 2.782-1.651 4.595-4.186 4.595H17.5c-2.535 0-4.187-1.813-4.187-4.595L14 71.172z"/></g><path id="Rectangle-2" stroke="#DBAF88" stroke-width="2" d="M387 7h326v351H387z"/><path id="Rectangle-14" fill="#FFF" d="M395 8h312v61H395z"/><path id="Line-39" fill="#C06334" fill-rule="nonzero" d="M519.5 7v159h6l-7 14-7-14h6V7h2z"/><path id="Line-39-Copy-2" fill="#C06334" fill-rule="nonzero" d="M531.014 141.987l2 .027-.014 1-.311 23 6 .082L531.5 180l-6.81-14.093 5.999.08.311-23 .014-1z"/><text id="pageY" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="525" y="23">pageY</tspan></text><text id="clientY" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="542.4" y="172">clientY</tspan></text><path id="Line-39-Copy" fill="#C06334" fill-rule="nonzero" d="M501 182.5l14 7-14 7-.001-6.001L389 190.5h-1v-2h1l111.999-.001.001-5.999z"/><text id="pageX" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="398" y="183">pageX</tspan></text><text id="clientX" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold"><tspan x="397.4" y="204">clientX</tspan></text><text id="๐Ÿ˜" fill="#643B0C" font-family="AppleColorEmoji, Apple Color Emoji" font-size="18" font-weight="normal"><tspan x="514" y="197">๐Ÿ˜</tspan></text></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html index 7228a45de3..01972866ce 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html @@ -7,13 +7,13 @@ <body> - <input type="button" id="hider" value="Click to hide the text" /> + <input type="button" id="hider" value="Text๋ฅผ ์ˆจ๊ธฐ๋ ค๋ฉด ํด๋ฆญํ•˜์„ธ์š”." /> <div id="text">Text</div> <script> - // Here it doesn't matter how we hide the text, - // could also use style.display: + // ํ…์ŠคํŠธ๋ฅผ ์ˆจ๊ธฐ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•œ๋ฐ, ๊ทธ ๋ฐฉ๋ฒ•์€ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + // style.display๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. document.getElementById('hider').onclick = function() { document.getElementById('text').hidden = true; } diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/source.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/source.view/index.html index 17c5be6d13..a9f5d14c1a 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/source.view/index.html +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/source.view/index.html @@ -7,12 +7,12 @@ <body> - <input type="button" id="hider" value="Click to hide the text" /> + <input type="button" id="hider" value="Text๋ฅผ ์ˆจ๊ธฐ๋ ค๋ฉด ํด๋ฆญํ•˜์„ธ์š”." /> <div id="text">Text</div> <script> - /* your code */ + /* ์ฝ”๋“œ๋ฅผ ์—ฌ๊ธฐ์— ์ž‘์„ฑํ•˜์„ธ์š” */ </script> </body> diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/task.md b/2-ui/2-events/01-introduction-browser-events/01-hide-other/task.md index 7cb0cb0c99..26721a018c 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/task.md +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/task.md @@ -2,10 +2,10 @@ importance: 5 --- -# Hide on click +# ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํŠน์ • ์š”์†Œ ์ˆจ๊ธฐ๊ธฐ -Add JavaScript to the `button` to make `<div id="text">` disappear when we click it. +`button`์„ ํด๋ฆญํ•˜๋ฉด `<div id="text">`๊ฐ€ ์‚ฌ๋ผ์ง€๋„๋ก `button`์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ด…์‹œ๋‹ค. -The demo: +๋ฐ๋ชจ: [iframe border=1 src="solution" height=80] diff --git a/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/solution.md b/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/solution.md index cded5b622a..4de59e204a 100644 --- a/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/solution.md +++ b/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/solution.md @@ -1,4 +1,4 @@ -Can use `this` in the handler to reference "the element itself" here: +ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์— `this`๋ฅผ ์‚ฌ์šฉํ•ด '์š”์†Œ ์ž์ฒด'๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run height=50 <input type="button" onclick="this.hidden=true" value="Click to hide"> diff --git a/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/task.md b/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/task.md index 9ee8f18e14..f78da86009 100644 --- a/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/task.md +++ b/2-ui/2-events/01-introduction-browser-events/02-hide-self-onclick/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Hide self +# ํด๋ฆญ๋œ ์š”์†Œ ์ˆจ๊ธฐ๊ธฐ -Create a button that hides itself on click. +ํด๋ฆญ ์‹œ ์ž์‹ ์„ ์ˆจ๊ธฐ๋Š” ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ```online -Like this: +์˜ˆ์‹œ: <input type="button" onclick="this.hidden=true" value="Click to hide"> ``` diff --git a/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/solution.md b/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/solution.md index d569f0e4d3..8e52bebdf0 100644 --- a/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/solution.md +++ b/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/solution.md @@ -1,8 +1,8 @@ -The answer: `1` and `2`. +์ •๋‹ต: `1`๊ณผ `2`๊ฐ€ ์–ผ๋Ÿฟ ์ฐฝ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. -The first handler triggers, because it's not removed by `removeEventListener`. To remove the handler we need to pass exactly the function that was assigned. And in the code a new function is passed, that looks the same, but is still another function. +`removeEventListener`๊ฐ€ ์žˆ์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ ํ•ธ๋“ค๋Ÿฌ๋Š”`removeEventListener`์— ์˜ํ•ด ์ง€์›Œ์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ญ์ œํ•˜๋ ค๋ฉด ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ์‹œ ์‚ฌ์šฉํ•œ ํ•จ์ˆ˜๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `removeEventListener`์— ์ฒซ ๋ฒˆ์งธ ํ•ธ๋“ค๋Ÿฌ์˜ ํ•จ์ˆ˜์™€ ๋˜‘๊ฐ™์ด ์ƒ๊ธด ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ–ˆ์ง€๋งŒ, ์—„์—ฐํžˆ ๋‹ค๋ฅธ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— `removeEventListener`๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ฒซ ๋ฒˆ์งธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ง€์›Œ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -To remove a function object, we need to store a reference to it, like this: +์ด๋ฏธ ๋“ฑ๋กํ•œ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์‚ญ์ œํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js function handler() { @@ -13,4 +13,4 @@ button.addEventListener("click", handler); button.removeEventListener("click", handler); ``` -The handler `button.onclick` works independently and in addition to `addEventListener`. +ํ•ธ๋“ค๋Ÿฌ `button.onclick`์€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `addEventListener`์™€ ํ•จ๊ป˜ ๋™์ž‘ํ•˜์˜€์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/task.md b/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/task.md index f8cd75d5a7..2212028134 100644 --- a/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/task.md +++ b/2-ui/2-events/01-introduction-browser-events/03-which-handlers-run/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Which handlers run? +# ์–ด๋–ค ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋ ๊นŒ์š” -There's a button in the variable. There are no handlers on it. +๋ณ€์ˆ˜ ์•ˆ์— ๋ฒ„ํŠผ์ด ์žˆ์ง€๋งŒ ๋ฒ„ํŠผ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๋Š” ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. -Which handlers run on click after the following code? Which alerts show up? +์ด๋Ÿฐ ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—, ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์‹คํ–‰๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ์–ด๋–ค ์–ผ๋Ÿฟ ์ฐฝ์ด ๋ณด์ผ๊นŒ์š”? ```js no-beautify button.addEventListener("click", () => alert("1")); diff --git a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg index 73dcee5f22..fc26b023c5 100644 --- a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg +++ b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/move-ball-coords.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="521" height="330" viewBox="0 0 521 330"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><filter id="filter-2" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/></filter><path id="path-1" d="M263 170v21.429l5.25-5.358 4.375 8.929h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H277L263 170z"/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="move-ball-coords.svg"><g id="noun_69008_cc" fill="#E8C48E" transform="translate(12 6)"><path id="Shape" d="M10.438 316C4.676 316 0 312.445 0 308.1V7.9C0 3.555 4.676 0 10.438 0h480.125C496.303 0 501 3.555 501 7.9v300.2c0 4.345-4.697 7.9-10.438 7.9H10.438zm-.276-12h478.643V12.939H10.162V304z"/><path id="Shape" d="M20.859 54.1c-5.753 0-10.422-1.147-10.422-2.55 0-1.402 4.67-2.55 10.422-2.55H479.4c5.732 0 10.422 1.148 10.422 2.55 0 1.403-4.69 2.55-10.422 2.55H20.86zM33.75 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6zM63.938 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6zM94.127 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6z"/></g><image id="Screen-Shot-2017-02-25-at-23.45.22" width="224" height="150" x="183" y="100" xlink:href="data:image/png;base64,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"/><text id="ball.style.left" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="174" y="262">ball.style.left</tspan></text><text id="?" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="40" font-weight="normal"><tspan x="217.5" y="229">?</tspan></text><text id="fieldCoords.left" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="48.9" y="189.32">fieldCoords.left</tspan></text><text id="event.clientX" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="59.7" y="161.32">event.clientX</tspan></text><path id="Line-41" fill="#EE6B47" fill-rule="nonzero" d="M168.41 187.91l14 7-14 7v-6H39.589l.001 6-14-7 14-7-.001 6H168.41v-6z"/><path id="Line-41-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M248 160.91l14 7-14 7v-6H39.589l.001 6-14-7 14-7-.001 6H248v-6z"/><g id="ball" opacity=".7" transform="translate(261 168)"><circle id="Oval-4" cx="18.753" cy="18.753" r="18.753" fill="#FFF"/><path id="Shape" fill="#000" fill-rule="nonzero" d="M37.792 18.204a.229.229 0 00-.003-.123l-.004-.016a18.9 18.9 0 00-6.003-12.94c-.445-.461-1.107-1.006-1.863-1.534A19.043 19.043 0 0012.899.935c-.412.106-.98.322-1.64.622a18.593 18.593 0 00-3.53 2.014A18.856 18.856 0 004.68 6.344c-6.874 7.794-6.085 19.762 1.758 26.679a19.043 19.043 0 004.876 3.128c.254.121.465.194.645.272 7.417 2.964 15.919.96 21.169-4.992 3.216-3.65 4.87-8.343 4.663-13.227zm-.677-.785l-.05-.135c-.387-1.04-1.095-2.957-2.828-4.492-.255-3.228-1.405-5.115-2.43-6.774a18.297 18.297 0 015.308 11.401zM24.485 3.158a.476.476 0 00.044-.013c1.666.291 4.245 1.237 6.464 2.748a.274.274 0 00.03.068c.06.1.214.347.214.347.99 1.6 2.109 3.414 2.362 6.494-1.007.741-1.724 1.531-2.42 2.295-.414.456-.84.925-1.326 1.383-1.63-1.516-4.52-2.813-7.641-3.42-.306-1.35-.919-3.854-2.423-6.628l.116-.132c2.418-2.743 3.269-2.9 4.255-3.08.105-.019.213-.039.325-.062zm-8.729 15.517l6.255-5.001c3.137.597 6.025 1.903 7.547 3.413.372 1.153.468 3.636.54 5.464.035.935.069 1.754.127 2.246-2.457 2.24-5.717 4.539-6.78 4.778l-6.843-2.677c-.512-2.867-.662-4.83-.846-8.223zm.205 8.273l-4.955 3.485a.249.249 0 00-.148-.012c-.923.192-4.479-2.415-6.21-3.929a.264.264 0 00-.065-.04c-.073-.495-.23-1.125-.408-1.84-.469-1.885-1.05-4.221-.528-5.673l.028-.028c.006-.007.013-.015.018-.024.339-.487.665-.908 1-1.286 1.058-1.2 2.256-2.053 4.12-2.927l.379.276c1.735 1.266 4.094 2.99 5.927 3.8.185 3.374.335 5.339.842 8.198zM9.35 3.678c.07-.079.145-.147.233-.226l.049-.044c.185-.102.424-.243.702-.405.653-.381 1.546-.905 2.527-1.398a18.483 18.483 0 018.294-.832c0 .093.052.18.137.223.17.089.343.172.515.255.733.354 1.432.692 2.073 1.37-1.001.19-2.025.496-4.464 3.262l-.156.177c-2.457-.245-5.282-.38-7.822.37-.94-1.119-1.73-1.651-2.429-2.123l-.019-.013c.153-.357.266-.51.36-.616zM1.413 15.43a.25.25 0 00-.398-.123 1.375 1.375 0 00-.076.066 18.024 18.024 0 014.08-8.465c.12-.1.274-.233.448-.385.724-.63 2.41-2.101 2.946-1.847a13.536 13.536 0 00.092.063l.147.1c.652.44 1.39.937 2.258 1.96-.78 1.657-2.416 5.752-2.408 7.314-1.927.907-3.177 1.802-4.288 3.062-.295.334-.584.699-.878 1.108l-.106-.1c-.557-.52-1.396-1.306-1.817-2.753zm5.438 17.124a18.323 18.323 0 01-3.95-4.92c.691-.195 1.023-.323 1.411-.586.638.539 4.586 3.827 6.334 4.006a36.692 36.692 0 003.055 4.295c-.572.352-1.042.473-1.648.437a18.311 18.311 0 01-5.202-3.232zm6.469 3.698c.295-.108.593-.268.92-.49 2.756.407 5.828.152 7.99-.152.031.021.066.034.105.04.52.068 2.062.226 3.92.015a18.292 18.292 0 01-12.935.587zm18.778-4.768a.256.256 0 00-.042.181 17.964 17.964 0 01-3.83 3.004.236.236 0 00-.111.003c-2.244.59-4.392.479-5.354.382.433-1.078.73-2.68.902-4.876 1.262-.352 4.456-2.594 7.01-4.925.636.105 1.07.204 1.421.286.858.198 1.25.29 2.81.086-.201 1.17-.765 2.896-2.806 5.86zm2.797-3.623c.438-1.046.605-1.827.69-2.448a.237.237 0 00-.014-.125c.39-.886 1.186-3.392 1.594-5.443a18.028 18.028 0 01-2.27 8.016z"/></g><g id="Default"><use fill="#000" filter="url(#filter-2)" xlink:href="#path-1"/><path fill="#FFF" stroke="#D60000" d="M271.703 184.786a230.958 230.958 0 012.035 3.992l.273.553c.743 1.514 1.326 2.773 1.702 3.694.138.339.08.706-.104 1.1-.094.203-.221.41-.373.619a5.679 5.679 0 01-.503.605l-.147.151h-2.273l-4.2-8.574-5.613 5.727v-23.878l15.69 16.01h-6.487z"/></g><path id="Line-16-Copy-2" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M195.535 180.945s20.728 10.637 32.233 10.637c11.504 0 32.232-10.637 32.232-10.637"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="521" height="330" viewBox="0 0 521 330"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><defs><filter id="filter-2" width="195.6%" height="153.8%" x="-42.9%" y="-25.8%" filterUnits="objectBoundingBox"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0.0941176471 0 0 0 0 0.0901960784 0 0 0 0 0.0901960784 0 0 0 1 0"/></filter><path id="path-1" d="M263 170v21.429l5.25-5.358 4.375 8.929h1.75s1.13-1.161.875-1.786c-1.203-2.947-4.375-8.928-4.375-8.928H277L263 170z"/></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="move-ball-coords.svg"><g id="noun_69008_cc" fill="#DBAF88" transform="translate(12 6)"><path id="Shape" d="M10.438 316C4.676 316 0 312.445 0 308.1V7.9C0 3.555 4.676 0 10.438 0h480.125C496.303 0 501 3.555 501 7.9v300.2c0 4.345-4.697 7.9-10.438 7.9H10.438zm-.276-12h478.643V12.939H10.162V304z"/><path id="Shape" d="M20.859 54.1c-5.753 0-10.422-1.147-10.422-2.55 0-1.402 4.67-2.55 10.422-2.55H479.4c5.732 0 10.422 1.148 10.422 2.55 0 1.403-4.69 2.55-10.422 2.55H20.86zM33.75 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6zM63.938 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6zM94.127 31.6c0 3.315-2.685 6-6 6s-6-2.685-6-6 2.685-6 6-6 6 2.685 6 6z"/></g><image id="Screen-Shot-2017-02-25-at-23.45.22" width="224" height="150" x="183" y="100" xlink:href="data:image/png;base64,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"/><text id="ball.style.left" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="174" y="262">ball.style.left</tspan></text><text id="?" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="40" font-weight="normal"><tspan x="217.5" y="229">?</tspan></text><text id="fieldCoords.left" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="48.9" y="189.32">fieldCoords.left</tspan></text><text id="event.clientX" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="59.7" y="161.32">event.clientX</tspan></text><path id="Line-41" fill="#C06334" fill-rule="nonzero" d="M168.41 187.91l14 7-14 7v-6H39.589l.001 6-14-7 14-7-.001 6H168.41v-6z"/><path id="Line-41-Copy-2" fill="#C06334" fill-rule="nonzero" d="M248 160.91l14 7-14 7v-6H39.589l.001 6-14-7 14-7-.001 6H248v-6z"/><g id="ball" opacity=".7" transform="translate(261 168)"><circle id="Oval-4" cx="18.753" cy="18.753" r="18.753" fill="#FFF"/><path id="Shape" fill="#181717" fill-rule="nonzero" d="M37.792 18.204a.229.229 0 00-.003-.123l-.004-.016a18.9 18.9 0 00-6.003-12.94c-.445-.461-1.107-1.006-1.863-1.534A19.043 19.043 0 0012.899.935c-.412.106-.98.322-1.64.622a18.593 18.593 0 00-3.53 2.014A18.856 18.856 0 004.68 6.344c-6.874 7.794-6.085 19.762 1.758 26.679a19.043 19.043 0 004.876 3.128c.254.121.465.194.645.272 7.417 2.964 15.919.96 21.169-4.992 3.216-3.65 4.87-8.343 4.663-13.227zm-.677-.785l-.05-.135c-.387-1.04-1.095-2.957-2.828-4.492-.255-3.228-1.405-5.115-2.43-6.774a18.297 18.297 0 015.308 11.401zM24.485 3.158a.476.476 0 00.044-.013c1.666.291 4.245 1.237 6.464 2.748a.274.274 0 00.03.068c.06.1.214.347.214.347.99 1.6 2.109 3.414 2.362 6.494-1.007.741-1.724 1.531-2.42 2.295-.414.456-.84.925-1.326 1.383-1.63-1.516-4.52-2.813-7.641-3.42-.306-1.35-.919-3.854-2.423-6.628l.116-.132c2.418-2.743 3.269-2.9 4.255-3.08.105-.019.213-.039.325-.062zm-8.729 15.517l6.255-5.001c3.137.597 6.025 1.903 7.547 3.413.372 1.153.468 3.636.54 5.464.035.935.069 1.754.127 2.246-2.457 2.24-5.717 4.539-6.78 4.778l-6.843-2.677c-.512-2.867-.662-4.83-.846-8.223zm.205 8.273l-4.955 3.485a.249.249 0 00-.148-.012c-.923.192-4.479-2.415-6.21-3.929a.264.264 0 00-.065-.04c-.073-.495-.23-1.125-.408-1.84-.469-1.885-1.05-4.221-.528-5.673l.028-.028c.006-.007.013-.015.018-.024.339-.487.665-.908 1-1.286 1.058-1.2 2.256-2.053 4.12-2.927l.379.276c1.735 1.266 4.094 2.99 5.927 3.8.185 3.374.335 5.339.842 8.198zM9.35 3.678c.07-.079.145-.147.233-.226l.049-.044c.185-.102.424-.243.702-.405.653-.381 1.546-.905 2.527-1.398a18.483 18.483 0 018.294-.832c0 .093.052.18.137.223.17.089.343.172.515.255.733.354 1.432.692 2.073 1.37-1.001.19-2.025.496-4.464 3.262l-.156.177c-2.457-.245-5.282-.38-7.822.37-.94-1.119-1.73-1.651-2.429-2.123l-.019-.013c.153-.357.266-.51.36-.616zM1.413 15.43a.25.25 0 00-.398-.123 1.375 1.375 0 00-.076.066 18.024 18.024 0 014.08-8.465c.12-.1.274-.233.448-.385.724-.63 2.41-2.101 2.946-1.847a13.536 13.536 0 00.092.063l.147.1c.652.44 1.39.937 2.258 1.96-.78 1.657-2.416 5.752-2.408 7.314-1.927.907-3.177 1.802-4.288 3.062-.295.334-.584.699-.878 1.108l-.106-.1c-.557-.52-1.396-1.306-1.817-2.753zm5.438 17.124a18.323 18.323 0 01-3.95-4.92c.691-.195 1.023-.323 1.411-.586.638.539 4.586 3.827 6.334 4.006a36.692 36.692 0 003.055 4.295c-.572.352-1.042.473-1.648.437a18.311 18.311 0 01-5.202-3.232zm6.469 3.698c.295-.108.593-.268.92-.49 2.756.407 5.828.152 7.99-.152.031.021.066.034.105.04.52.068 2.062.226 3.92.015a18.292 18.292 0 01-12.935.587zm18.778-4.768a.256.256 0 00-.042.181 17.964 17.964 0 01-3.83 3.004.236.236 0 00-.111.003c-2.244.59-4.392.479-5.354.382.433-1.078.73-2.68.902-4.876 1.262-.352 4.456-2.594 7.01-4.925.636.105 1.07.204 1.421.286.858.198 1.25.29 2.81.086-.201 1.17-.765 2.896-2.806 5.86zm2.797-3.623c.438-1.046.605-1.827.69-2.448a.237.237 0 00-.014-.125c.39-.886 1.186-3.392 1.594-5.443a18.028 18.028 0 01-2.27 8.016z"/></g><g id="Default"><use fill="#000" filter="url(#filter-2)" xlink:href="#path-1"/><path fill="#FFF" stroke="#A7333A" d="M262.5 168.775l15.69 16.01h-6.488c.886 1.695 3.06 5.91 4.01 8.24.318.776-.979 2.324-.979 2.324h0l-2.42.151-4.2-8.574-5.613 5.727v-23.878z"/></g><path id="Line-16-Copy-2" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M195.535 180.945s20.728 10.637 32.233 10.637c11.504 0 32.232-10.637 32.232-10.637"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg index 2c92df87de..5bb161f6cb 100644 --- a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg +++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel1.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="488" height="246" viewBox="0 0 488 246"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="carousel1.svg"><rect id="Rectangle-18" width="63" height="63" x="41.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-19" width="63" height="63" x="109.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-20" width="63" height="63" x="177.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-21" width="63" height="63" x="245.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-22" width="63" height="63" x="313.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-23" width="63" height="63" x="381.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><text id="โ€ฆ-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="24" font-weight="normal"><tspan x="406" y="131">โ€ฆ</tspan></text><path id="Rectangle-24" stroke="#EE6B47" stroke-width="2" d="M38 95h412v70H38z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M261 42v171H19V42h242zm-17 17H36v137h208V59z"/><text id="div-(container)" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="82.5" y="32">div (container)</tspan></text><text id="130x130" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="13" font-weight="normal"><tspan x="46" y="133">130x130</tspan></text><text id="ul-(width:-9999px)" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="71.5" y="82">ul (width: 9999px)</tspan></text><path id="Rectangle-36" fill="#FFF" d="M447 90h16v84h-16z"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="488" height="246" viewBox="0 0 488 246"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="carousel1.svg"><rect id="Rectangle-18" width="63" height="63" x="41.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-19" width="63" height="63" x="109.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-20" width="63" height="63" x="177.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-21" width="63" height="63" x="245.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-22" width="63" height="63" x="313.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-23" width="63" height="63" x="381.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><text id="โ€ฆ-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="24" font-weight="normal"><tspan x="406" y="131">โ€ฆ</tspan></text><path id="Rectangle-24" stroke="#C06334" stroke-width="2" d="M38 95h412v70H38z"/><path id="Rectangle-1" fill="#DBAF88" d="M261 42v171H19V42h242zm-17 17H36v137h208V59z"/><text id="div-(container)" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="82.5" y="32">div (container)</tspan></text><text id="130x130" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="13" font-weight="normal"><tspan x="46" y="133">130x130</tspan></text><text id="ul-(width:-9999px)" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="71.5" y="82">ul (width: 9999px)</tspan></text><path id="Rectangle-36" fill="#FFF" d="M447 90h16v84h-16z"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg index 3f53a7691d..81aea5b89e 100644 --- a/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg +++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/carousel2.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="639" height="246" viewBox="0 0 639 246"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="carousel2.svg"><rect id="Rectangle-18" width="63" height="63" x="41.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-19" width="63" height="63" x="109.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-20" width="63" height="63" x="177.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-21" width="63" height="63" x="245.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-22" width="63" height="63" x="313.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-23" width="63" height="63" x="381.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" rx="10"/><rect id="Rectangle-26" width="63" height="63" x="449.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-25" width="63" height="63" x="517.5" y="98.5" fill="#FFF9EB" stroke="#8A704D" stroke-width="3" opacity=".5" rx="10"/><text id="โ€ฆ-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="24" font-weight="normal"><tspan x="542" y="131">โ€ฆ</tspan></text><path id="Rectangle-24" stroke="#EE6B47" stroke-width="2" d="M38 95h546v70H38z"/><path id="Rectangle-1" fill="#E8C48F" fill-opacity=".88" d="M467 42v171H225V42h242zm-17 17H242v137h208V59z"/><text id="div-(container)" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="288.5" y="32">div (container)</tspan></text><text id="130x130" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="13" font-weight="normal"><tspan x="252" y="133">130x130</tspan></text><text id="ul-(margin-left:--35" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="246.5" y="82">ul (margin-left: -350px)</tspan></text><path id="Rectangle-36" fill="#FFF" d="M582 83h16v84h-16z"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="639" height="246" viewBox="0 0 639 246"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="carousel2.svg"><rect id="Rectangle-18" width="63" height="63" x="41.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-19" width="63" height="63" x="109.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-20" width="63" height="63" x="177.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-21" width="63" height="63" x="245.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-22" width="63" height="63" x="313.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-23" width="63" height="63" x="381.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" rx="10"/><rect id="Rectangle-26" width="63" height="63" x="449.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><rect id="Rectangle-25" width="63" height="63" x="517.5" y="98.5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="3" opacity=".5" rx="10"/><text id="โ€ฆ-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="24" font-weight="normal"><tspan x="542" y="131">โ€ฆ</tspan></text><path id="Rectangle-24" stroke="#C06334" stroke-width="2" d="M38 95h546v70H38z"/><path id="Rectangle-1" fill="#DBAF88" d="M467 42v171H225V42h242zm-17 17H242v137h208V59z"/><text id="div-(container)" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="288.5" y="32">div (container)</tspan></text><text id="130x130" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="13" font-weight="normal"><tspan x="252" y="133">130x130</tspan></text><text id="ul-(margin-left:--35" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="246.5" y="82">ul (margin-left: -350px)</tspan></text><path id="Rectangle-36" fill="#FFF" d="M582 83h16v84h-16z"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.md b/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.md index 41de7e1f3f..1c6b52ceac 100644 --- a/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.md +++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.md @@ -1,6 +1,6 @@ The images ribbon can be represented as `ul/li` list of images `<img>`. -Normally, such a ribbon is wide, but we put a fixed-size `<div>` around to "cut" it, so that only a part of the ribbon is visibble: +Normally, such a ribbon is wide, but we put a fixed-size `<div>` around to "cut" it, so that only a part of the ribbon is visible: ![](carousel1.svg) diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index 74005fc25e..87fb6d2645 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -1,62 +1,62 @@ # ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ ์†Œ๊ฐœ -*์ด๋ฒคํŠธ(event)* ๋Š” ๋ฌด์–ธ๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค๋Š” ์‹ ํ˜ธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  DOM ๋…ธ๋“œ๋Š” ์ด๋Ÿฐ ์‹ ํ˜ธ๋ฅผ ๋งŒ๋“ค์–ด ๋ƒ…๋‹ˆ๋‹ค(์ด๋ฒคํŠธ๋Š” DOM์—๋งŒ ํ•œ์ •๋˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค). +*์ด๋ฒคํŠธ(event)* ๋Š” ๋ฌด์–ธ๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค๋Š” ์‹ ํ˜ธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  DOM ๋…ธ๋“œ๋Š” ์ด๋Ÿฐ ์‹ ํ˜ธ๋ฅผ ๋งŒ๋“ค์–ด ๋ƒ…๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, ์ด๋ฒคํŠธ๋Š” DOM์—๋งŒ ํ•œ์ •๋˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๋Š” DOM ์ด๋ฒคํŠธ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. ์ž ์‹œ ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค: +์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์œ ์šฉํ•œ DOM ์ด๋ฒคํŠธ๋Š” ๋ฌด์—‡์ด ์žˆ๋Š”์ง€ ์ž ์‹œ ์‚ดํŽด๋ด…์‹œ๋‹ค. -**๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ(Mouse events):** -- `click` -- ์š”์†Œ(element) ์œ„์—์„œ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ (ํ„ฐ์น˜์Šคํฌ๋ฆฐ์ด ์žˆ๋Š” ์žฅ์น˜์—์„  ํƒญ ํ–ˆ์„ ๋•Œ). -- `contextmenu` -- ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ. -- `mouseover` / `mouseout` -- ๋งˆ์šฐ์Šค๋ฅผ ์š”์†Œ ์œ„๋กœ ์›€์ง์˜€์„ ๋•Œ / ๋งˆ์šฐ์Šค๊ฐ€ ์š”์†Œ ๋ฐ–์œผ๋กœ ์›€์ง์˜€์„ ๋•Œ. -- `mousedown` / `mouseup` -- ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  ์žˆ์„ ๋•Œ / ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋—„ ๋•Œ. -- `mousemove` -- ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ผ ๋•Œ. +**๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ:** +- `click` -- ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ(ํ„ฐ์น˜์Šคํฌ๋ฆฐ์ด ์žˆ๋Š” ์žฅ์น˜์—์„  ํƒญ ํ–ˆ์„ ๋•Œ) ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +- `contextmenu` -- ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +- `mouseover`์™€ `mouseout` -- ๋งˆ์šฐ์Šค ์ปค์„œ๋ฅผ ์š”์†Œ ์œ„๋กœ ์›€์ง์˜€์„ ๋•Œ, ์ปค์„œ๊ฐ€ ์š”์†Œ ๋ฐ–์œผ๋กœ ์›€์ง์˜€์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +- `mousedown`๊ณผ `mouseup` -- ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  ์žˆ์„ ๋•Œ, ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋—„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +- `mousemove` -- ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -**ํผ ์š”์†Œ ์ด๋ฒคํŠธ(Form element events):** -- `submit` -- ์‚ฌ์šฉ์ž๊ฐ€ `<form>`์„ ์ œ์ถœํ•  ๋•Œ. -- `focus` -- ์‚ฌ์šฉ์ž๊ฐ€ `<input>`๊ณผ ๊ฐ™์€ ์š”์†Œ์— ํฌ์ปค์Šค ํ•  ๋•Œ. +**ํผ ์š”์†Œ ์ด๋ฒคํŠธ:** +- `submit` -- ์‚ฌ์šฉ์ž๊ฐ€ `<form>`์„ ์ œ์ถœํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +- `focus` -- ์‚ฌ์šฉ์ž๊ฐ€ `<input>`๊ณผ ๊ฐ™์€ ์š”์†Œ์— ํฌ์ปค์Šค ํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -**ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ(Keyboard events):** -- `keydown` ์™€ `keyup` -- ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅด๊ฑฐ๋‚˜ ๋—„ ๋•Œ. +**ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ:** +- `keydown`๊ณผ `keyup` -- ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฑฐ๋‚˜ ๋—„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -**๋ฌธ์„œ ์ด๋ฒคํŠธ(Document events):** -- `DOMContentLoaded` -- HTML์ด ์ „๋ถ€ ๋กœ๋“œ๋˜๊ณ  ์ฒ˜๋ฆฌ๋˜์–ด์„œ, DOM ์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ. +**๋ฌธ์„œ ์ด๋ฒคํŠธ:** +- `DOMContentLoaded` -- HTML์ด ์ „๋ถ€ ๋กœ๋“œ ๋ฐ ์ฒ˜๋ฆฌ๋˜์–ด DOM ์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -**CSS ์ด๋ฒคํŠธ(CSS events):** -- `transitionend` -- CSS-์• ๋‹ˆ๋ฉ”์ด์…˜(CSS-animation)์ด ์ข…๋ฃŒ๋˜์—ˆ์„ ๋•Œ. +**CSS ์ด๋ฒคํŠธ:** +- `transitionend` -- CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์ข…๋ฃŒ๋˜์—ˆ์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ์ œ์—์„œ ๋ช‡๋ช‡ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -## ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ(Event handlers) +## ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ -์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•˜๋ ค๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์‹œ์ ์— ์‹คํ–‰๋˜๋Š” *ํ•ธ๋“ค๋Ÿฌ(handler)* ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•˜๋ ค๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ธ *ํ•ธ๋“ค๋Ÿฌ(handler)* ๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋Š” ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์— ์–ด๋–ป๊ฒŒ ๋ฐ˜์‘ํ• ์ง€๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ์‚ดํŽด๋ด…์‹œ๋‹ค. -### HTML-์†์„ฑ(HTML-attribute) +### HTML ์†์„ฑ -ํ•ธ๋“ค๋Ÿฌ๋Š” HTML ์•ˆ์—์„œ `on<event>`์™€ ๊ฐ™์€ ์†์„ฑ์„ ํ†ตํ•ด ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +HTML ์•ˆ์˜ `on<event>` ์†์„ฑ์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์ด `onclick`์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด `input`ํƒœ๊ทธ์— `click`ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์•„๋ž˜ ๊ฐ™์ด `input` ํƒœ๊ทธ์˜ `onclick` ์†์„ฑ์— `click` ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ ๊ฐ™์ด ๋ง์ด์ฃ . ```html run -<input value="Click me" *!*onclick="alert('ํด๋ฆญ!')"*/!* type="button"> +<input value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”." *!*onclick="alert('ํด๋ฆญ!')"*/!* type="button"> ``` -๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ•˜๋ฉด `onclick`์•ˆ์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด `onclick` ์•ˆ์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. -`onclick`์•ˆ์˜ ๋”ฐ์˜ดํ‘œ์— ์ฃผ๋ชฉํ•ด์ฃผ์„ธ์š”. ์†์„ฑ๊ฐ’์ด ์ด๋ฏธ ์Œ๋”ฐ์˜ดํ‘œ๋กœ ๋‘˜๋Ÿฌ ์Œ“์—ฌ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์ ์„ ์žŠ๊ณ  `onclick="alert("ํด๋ฆญ!")"`๊ณผ ๊ฐ™์ด ์†์„ฑ๊ฐ’ ๋‚ด๋ถ€์— ๋˜ ์Œ๋”ฐ์˜ดํ‘œ๋ฅผ ์“ฐ๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•ด์•ผ ํ•  ๊ฒƒ์€ ์†์„ฑ๊ฐ’ ๋‚ด์—์„œ ์‚ฌ์šฉ๋œ ๋”ฐ์˜ดํ‘œ์ž…๋‹ˆ๋‹ค. ์†์„ฑ๊ฐ’ ์ „์ฒด๊ฐ€ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋‘˜๋Ÿฌ์‹ธ์—ฌ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์€ ๋”ฐ์˜ดํ‘œ๋กœ ๋‘˜๋Ÿฌ์Œ“์Šต๋‹ˆ๋‹ค. `onclick="alert("ํด๋ฆญ!")"`๊ณผ ๊ฐ™์ด ์†์„ฑ๊ฐ’ ๋‚ด๋ถ€์— ๋˜ ํฐ๋”ฐ์˜ดํ‘œ๋ฅผ ์“ฐ๋ฉด ์ฝ”๋“œ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -HTML-์†์„ฑ(HTML-attribute)๊ฐ’์— ๊ธด ์ฝ”๋“œ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฑด ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ฝ”๋“œ๊ฐ€ ๊ธธ๋‹ค๋ฉด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. +๊ธด ์ฝ”๋“œ๋ฅผ HTML ์†์„ฑ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ฝ”๋“œ๊ฐ€ ๊ธธ๋‹ค๋ฉด, ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด `countRabbits()`ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค: +์•„๋ž˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํ•จ์ˆ˜ `countRabbits()`์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ```html autorun height=50 <script> function countRabbits() { for(let i=1; i<=3; i++) { - alert("Rabbit number " + i); + alert(`ํ† ๋ผ ${i}๋งˆ๋ฆฌ`); } } </script> @@ -64,42 +64,40 @@ HTML-์†์„ฑ(HTML-attribute)๊ฐ’์— ๊ธด ์ฝ”๋“œ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฑด ์ถ”์ฒœํ•˜์ง€ <input type="button" *!*onclick="countRabbits()"*/!* value="ํ† ๋ผ๋ฅผ ์„ธ๋ด…์‹œ๋‹ค!"> ``` -HTML ์†์„ฑ์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, `ONCLICK`์€ `onClick`์ด๋‚˜ `onCLICK`๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋Œ€๊ฐœ ์†์„ฑ๊ฐ’์€ `onclick`์™€ ๊ฐ™์ด ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. +HTML ์†์„ฑ์€ ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, `ONCLICK`์€ `onClick`์ด๋‚˜ `onCLICK`๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์†์„ฑ๊ฐ’์€ ๋Œ€๊ฐœ `onclick` ๊ฐ™์ด ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ### DOM ํ”„๋กœํผํ‹ฐ -DOM ํ”„๋กœํผํ‹ฐ(property) `on<event>`์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +DOM ํ”„๋กœํผํ‹ฐ `on<event>`์„ ์‚ฌ์šฉํ•ด๋„ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `elem.onclick`์„ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ: ```html autorun -<input id="elem" type="button" value="ํด๋ฆญํ•ด์ฃผ์„ธ์š”"> +<input id="elem" type="button" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."> <script> *!* elem.onclick = function() { - alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค'); + alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.'); }; */!* </script> ``` -HTML-์†์„ฑ์„ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์†์„ฑ์„ ์ฝ๊ณ , ์†์„ฑ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  DOM ํ”„๋กœํผํ‹ฐ์— ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ๋ฅผ HTML ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์†์„ฑ๊ฐ’์„ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒ์„ฑ๋œ ํ•จ์ˆ˜๋ฅผ DOM ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. -๋”ฐ๋ผ์„œ DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“  ์œ„ ์˜ˆ์‹œ๋Š” HTML ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ์˜ˆ์‹œ์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“  ์œ„ ์˜ˆ์‹œ๋Š” HTML ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ๋ฐ”๋กœ ์œ„์ชฝ ์˜ˆ์‹œ์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. -**ํ•ธ๋“ค๋Ÿฌ๋Š” ํ•ญ์ƒ DOM ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค: HTML-์†์„ฑ์„ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.** +์•„๋ž˜ ๋‘ ์˜ˆ์‹œ๋Š” ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ๋‘ ์ฝ”๋“œ๋Š” ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค: - -1. HTML๋งŒ ์‚ฌ์šฉ: +1. HTML๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ```html autorun height=50 - <input type="button" *!*onclick="alert('ํด๋ฆญ!')"*/!* value="๋ฒ„ํŠผ"> + <input type="button" *!*onclick="alert('ํด๋ฆญ!')"*/!* value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."> ``` -2. HTML๊ณผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉ: +2. HTML๊ณผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ```html autorun height=50 - <input type="button" id="button" value="๋ฒ„ํŠผ"> + <input type="button" id="button" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."> <script> *!* button.onclick = function() { @@ -109,48 +107,50 @@ HTML-์†์„ฑ์„ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์†์„ฑ์„ </script> ``` -**`onclick` ํ”„๋กœํผํ‹ฐ๋Š” ์œ ์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ณต์ˆ˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.** +๋‘ ์˜ˆ์‹œ์˜ ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ๋ฐ”๋กœ ์ฒซ ๋ฒˆ์งธ ์˜ˆ์‹œ์—์„œ๋Š” HTML ์†์„ฑ์„ ์‚ฌ์šฉํ•ด button.onclick์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ์˜ˆ์‹œ์—์„œ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +**`onclick` ํ”„๋กœํผํ‹ฐ๋Š” ๋‹จ ํ•˜๋‚˜๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ณต์ˆ˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.** -์•„๋ž˜์˜ ์˜ˆ์ œ์™€ ๊ฐ™์ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด, ๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฎ์–ด์”Œ์›Œ ์ง‘๋‹ˆ๋‹ค: +์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•˜๋ฉด, ๊ธฐ์กด ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฎ์–ด์”Œ์›Œ์ง‘๋‹ˆ๋‹ค. ```html run height=50 autorun -<input type="button" id="elem" onclick="alert('์ด์ „')" value="ํด๋ฆญํ•ด์ฃผ์„ธ์š”"> +<input type="button" id="elem" onclick="alert('์ด์ „')" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."> <script> *!* elem.onclick = function() { // ๊ธฐ์กด์— ์ž‘์„ฑ๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฎ์–ด์”€ - alert('์ดํ›„'); // ์ด ๊ฒฝ๊ณ ์ฐฝ๋งŒ ๋ณด์ž…๋‹ˆ๋‹ค + alert('์ดํ›„'); // ์ด ๊ฒฝ๊ณ ์ฐฝ๋งŒ ๋ณด์ž…๋‹ˆ๋‹ค. }; */!* </script> ``` -ํ•œํŽธ, ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ•ธ๋“ค๋Ÿฌ์— ์ง์ ‘ ํ• ๋‹นํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค: - -```js -function sayThanks() { - alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!'); -} - -elem.onclick = sayThanks; -``` - -ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `elem.onclick = null`๊ณผ ๊ฐ™์ด null์„ ํ• ๋‹นํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `elem.onclick = null` ๊ฐ™์ด null์„ ํ• ๋‹นํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ## this๋กœ ์š”์†Œ์— ์ ‘๊ทผํ•˜๊ธฐ -ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์— ์“ฐ์ธ `this`๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋œ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์— ์“ฐ์ธ `this`์˜ ๊ฐ’์€ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋œ ์š”์†Œ์ž…๋‹ˆ๋‹ค. -์•„๋ž˜ ์ฝ”๋“œ์˜ `this.innerHTML`์—์„œ this๋Š” `button`์„ ์ฐธ์กฐํ•˜๋ฏ€๋กœ `button`์„ ํด๋ฆญํ•˜๋ฉด ๊ทธ ์•ˆ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์•„๋ž˜ ์˜ˆ์‹œ์˜`this.innerHTML`์—์„œ this๋Š” `button`์ด๋ฏ€๋กœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฒ„ํŠผ ์•ˆ์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ```html height=50 autorun -<button onclick="alert(this.innerHTML)">ํด๋ฆญํ•ด์ฃผ์„ธ์š”</button> +<button onclick="alert(this.innerHTML)">ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.</button> ``` ## ์ž์ฃผ ํ•˜๋Š” ์‹ค์ˆ˜ -์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ, ์•„๋ž˜์˜ ์ฃผ์˜์‚ฌํ•ญ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. +์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋Š” ์•„๋ž˜ ์ฃผ์˜์‚ฌํ•ญ์„ ํ•ญ์ƒ ์—ผ๋‘์— ๋‘์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -**ํ•จ์ˆ˜๋Š” `sayThanks`์™€ ๊ฐ™์ด ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `sayThanks()`๊ณผ ๊ฐ™์ด ์“ฐ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** +์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ํ•ธ๋“ค๋Ÿฌ์— ํ• ๋‹นํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. + +```js +function sayThanks() { + alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!'); +} + +elem.onclick = sayThanks; +``` + +์ด๋•Œ ํ•จ์ˆ˜๋Š” `sayThanks`์ฒ˜๋Ÿผ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `sayThanks()`๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js // ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ• @@ -160,102 +160,97 @@ button.onclick = sayThanks; button.onclick = sayThanks(); ``` -`sayThanks()`์™€ ๊ฐ™์ด ๊ด„ํ˜ธ๋ฅผ ๋ง๋ถ™์ด๊ฒŒ ๋˜๋ฉด, ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์ œ์˜ ๋งˆ์ง€๋ง‰ ์ค„์—์„  ํ•จ์ˆ˜ํ˜ธ์ถœ์˜ *๊ฒฐ๊ด(result)๊ฐ’*์ด ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. `onclick`์—” (ํ•จ์ˆ˜๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—)`undefined`์ด ํ• ๋‹น๋˜๊ณ , ์ด๋ฒคํŠธ๊ฐ€ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +`sayThanks()` ๊ฐ™์ด ๊ด„ํ˜ธ๋ฅผ ๋ง๋ถ™์ด๋Š” ๊ฒƒ์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์˜ ๋งˆ์ง€๋ง‰ ์ค„์ฒ˜๋Ÿผ sayThanks()๋ฅผ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ *๊ฒฐ๊ด(result)๊ฐ’*์ด ํ• ๋‹น๋˜์ฃ . ํ•จ์ˆ˜ `sayThanks`๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด `onclick` ํ”„๋กœํผํ‹ฐ์—” `undefined`์ด ํ• ๋‹น๋˜๋ฏ€๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -...On the other hand, in the markup we do need the parentheses: +๊ทธ๋Ÿฐ๋ฐ, HTML ์†์„ฑ๊ฐ’์—๋Š” ๊ด„ํ˜ธ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```html <input type="button" id="button" onclick="sayThanks()"> ``` -The difference is easy to explain. When the browser reads the attribute, it creates a handler function with *body from its content*: `sayThanks()`. +๋ธŒ๋ผ์šฐ์ €๋Š” ์†์„ฑ๊ฐ’์„ ์ฝ๊ณ , ์†์„ฑ๊ฐ’์„ *ํ•จ์ˆ˜ ๋ณธ๋ฌธ*์œผ๋กœ ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -So the markup generates this property: +๋ธŒ๋ผ์šฐ์ €๋Š” `onclick` ํ”„๋กœํผํ‹ฐ์— ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜์ฃ . ```js button.onclick = function() { *!* - sayThanks(); // ์†์„ฑ ๋‚ด์šฉ + sayThanks(); // ์†์„ฑ๊ฐ’ */!* }; ``` -**๋ฌธ์ž์—ด(strings)๋ณด๋‹ค๋Š” ํ•จ์ˆ˜๋ฅผ ์“ฐ์„ธ์š”.** - -`elem.onclick = "alert(1)"`์€ ์ž˜ ์ž‘๋™ํ•˜๊ธด ํ•ฉ๋‹ˆ๋‹ค(์—ญ์ฃผ: ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ๋ฌธ์ž์—ด์„ ๋Œ€์ž…). ํ˜ธํ™˜์„ฑ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋„๋ก ๋งŒ๋“ค์–ด์กŒ์ง€๋งŒ, ์ด ๋ฐฉ๋ฒ•์„ ์“ฐ์ง€ ์•Š๊ธฐ๋ฅผ ๊ฐ•๋ ฅํžˆ ๊ถŒ๊ณ ํ•ฉ๋‹ˆ๋‹ค. +**`setAttribute`๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ๋งˆ์„ธ์š”.** -**`setAttribute`๋ฅผ ์จ์„œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ๋งˆ์„ธ์š”.** - -์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: +์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js run no-beautify // <body>๋ฅผ ํด๋ฆญํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -// ์†์„ฑ์€ ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, ํ•จ์ˆ˜๊ฐ€ ๋ฌธ์ž์—ด์ด ๋˜์–ด๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค +// ์†์„ฑ์€ ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, ํ•จ์ˆ˜๊ฐ€ ๋ฌธ์ž์—ด์ด ๋˜์–ด๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. document.body.setAttribute('onclick', function() { alert(1) }); ``` -**DOM-ํ”„๋กœํผํ‹ฐ๋Š” ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.** +**DOM ํ”„๋กœํผํ‹ฐ๋Š” ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.** -ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ์‹œ `elem.onclick`๋Š” ๊ดœ์ฐฎ์ง€๋งŒ, `elem.ONCLICK`๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. DOM ํ”„๋กœํผํ‹ฐ๋Š” ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ์‹œ `elem.onclick`์€ ๊ดœ์ฐฎ์ง€๋งŒ, `elem.ONCLICK`์€ ์•ˆ๋ฉ๋‹ˆ๋‹ค. DOM ํ”„๋กœํผํ‹ฐ๋Š” ๋Œ€ยท์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ## addEventListener -HTML-์†์„ฑ๊ณผ DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ๋ฐฉ์‹์—” ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ์— ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ์ด์ฃ . +HTML ์†์„ฑ๊ณผ DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ๋ฐฉ์‹์—” ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ์— ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ์ด์ฃ . -์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋ฆญ ์‹œ ๋ฒ„ํŠผ์„ ๊ฐ•์กฐํ•˜๋ฉด์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด ๋ด…์‹œ๋‹ค. +๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฒ„ํŠผ์„ ๊ฐ•์กฐํ•˜๋ฉด์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด ๋ด…์‹œ๋‹ค. -๋‘ ๊ฐœ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด DOM ํ”„๋กœํผํ‹ฐ๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ ํ•  ๊ฒ๋‹ˆ๋‹ค: +๋‘ ๊ฐœ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•  ๊ฒ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ธฐ์กด ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฎ์–ด์”Œ์›Œ ์ง„๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ```js no-beautify input.onclick = function() { alert(1); } // ... -input.onclick = function() { alert(2); } // ์ด์ „์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ต์ฒดํ•จ +input.onclick = function() { alert(2); } // ์ด์ „ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฎ์–ด์”€ ``` -์›น ํ‘œ์ค€์„ ์ง€ํ‚ค๋Š” ๊ฐœ๋ฐœ์ž๋“ค์€ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์ด ๋ฌธ์ œ๋ฅผ ์ธ์ง€ํ–ˆ๊ณ , `addEventListener` ์™€ `removeEventListener` ๋ผ๋Š” ํŠน๋ณ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ด€๋ฆฌํ•˜์ž๋Š” ๋Œ€์•ˆ์„ ์ œ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ง์ด์ฃ . +์›น ํ‘œ์ค€์— ๊ด€์—ฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์€ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์ด ๋ฌธ์ œ๋ฅผ ์ธ์ง€ํ•˜๊ณ , `addEventListener` ์™€ `removeEventListener` ๋ผ๋Š” ํŠน๋ณ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ด€๋ฆฌํ•˜์ž๋Š” ๋Œ€์•ˆ์„ ์ œ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ง์ด์ฃ . -ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋”ํ•ด์ค„ ๋• ๋‹ค์Œ์˜ syntax(๊ตฌ๋ฌธ) ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค: +๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js -element.addEventListener(event, handler[, options]); +element.addEventListener(event, handler, [options]); ``` `event` -: ์ด๋ฒคํŠธ ์ด๋ฆ„, e.g. `"click"`. +: ์ด๋ฒคํŠธ ์ด๋ฆ„(์˜ˆ: `"click"`) `handler` : ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜ `options` -: ์•„๋ž˜์™€ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ์ถ”๊ฐ€์ ์ธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค: - - `once`: `true`์ด๋ฉด ํ˜ธ์ถœํ•  ๋•Œ listener๊ฐ€ ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. - - `capture`: ์–ด๋А ๋‹จ๊ณ„์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ค„์•ผ ํ•˜๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๋กœ, <info:bubbling-and-capturing>์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. `{capture: false/true}`๋Š” `options`์„ `false/true`๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ณผ๊ฑฐ์—” `options` ์ž์ฒด๊ฐ€ `false/true` ๊ฐ’์„ ๊ฐ€์ง€๋Š” ํ”„๋กœํผํ‹ฐ์˜€์Šต๋‹ˆ๋‹ค. - - `passive`: true์ผ ๊ฒฝ์šฐ, listener์—์„œ ์ง€์ •ํ•œ ํ•จ์ˆ˜๊ฐ€ preventDefault()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. <info:default-browser-action>์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. - +: ์•„๋ž˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด + - `once`: `true`์ด๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ ๋  ๋•Œ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. + - `capture`: ์–ด๋А ๋‹จ๊ณ„์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ค„์•ผ ํ•˜๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๋กœ, ๊ด€๋ จ ๋‚ด์šฉ์€ <info:bubbling-and-capturing> ์ฑ•ํ„ฐ์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ํ˜ธํ™˜์„ฑ ์œ ์ง€๋ฅผ ์œ„ํ•ด `options`๋ฅผ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ `false/true`๋กœ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ, ์ด๋Š” `{capture: false/true}`๋Š” ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. + - `passive`: `true`์ด๋ฉด ๋ฆฌ์Šค๋„ˆ์—์„œ ์ง€์ •ํ•œ ํ•จ์ˆ˜๊ฐ€ `preventDefault()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <info:default-browser-action>์—์„œ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. -ํ•ธ๋“ค๋Ÿฌ ์‚ญ์ œ๋Š” `removeEventListener`๋กœ ํ•ฉ๋‹ˆ๋‹ค: +ํ•ธ๋“ค๋Ÿฌ ์‚ญ์ œ๋Š” `removeEventListener`๋กœ ํ•ฉ๋‹ˆ๋‹ค. ```js -element.removeEventListener(event, handler[, options]); +element.removeEventListener(event, handler, [options]); ``` -````warn header="์‚ญ์ œ๋Š” ๋™์ผํ•œ ํ•จ์ˆ˜๋งŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค" -ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ญ์ œํ•˜๋ ค๋ฉด, ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ์‹œ ์‚ฌ์šฉํ•œ ํ•จ์ˆ˜๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +````warn header="์‚ญ์ œ๋Š” ๋™์ผํ•œ ํ•จ์ˆ˜๋งŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." +ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ญ์ œํ•˜๋ ค๋ฉด ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น ์‹œ ์‚ฌ์šฉํ•œ ํ•จ์ˆ˜๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: +์•„๋ž˜์™€ ๊ฐ™์ด ์ด๋ฒคํŠธ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ์‚ญ์ œํ•˜๋ฉด ์›ํ•˜๋Š” ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js no-beautify -elem.addEventListener( "click" , () => alert('Thanks!')); +elem.addEventListener( "click" , () => alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!')); // .... -elem.removeEventListener( "click", () => alert('Thanks!')); +elem.removeEventListener( "click", () => alert('๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!')); ``` -`removeEventListener`๋ฅผ ์ผ์ง€๋งŒ, ํ•ธ๋“ค๋Ÿฌ๋Š” ์ง€์›Œ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `removeEventListener`๊ฐ€ ํ• ๋‹น๋œ ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋˜‘๊ฐ™์ง€๋งŒ, ๊ทธ๊ฑด ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. (์—ญ์ฃผ: ์ด๋ ‡๊ฒŒ `addEventListener`๋กœ ์ถ”๊ฐ€ํ•œ ์ต๋ช… ํ•จ์ˆ˜๋Š” ์ œ๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.) +`removeEventListener`๋ฅผ ์ผ์ง€๋งŒ, ํ•ธ๋“ค๋Ÿฌ๋Š” ์ง€์›Œ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `removeEventListener`๊ฐ€ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•œ ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋˜‘๊ฐ™๊ฒŒ ์ƒ๊ฒผ์ง€๋งŒ ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‹ค๋ฅธ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -์ด๋ ‡๊ฒŒ ํ•ด์•ผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค: +์œ„ ์˜ˆ์‹œ๋ฅผ ์ œ๋Œ€๋กœ ๊ณ ์น˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js function handler() { - alert( 'Thanks!' ); + alert( '๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!' ); } input.addEventListener("click", handler); @@ -263,13 +258,13 @@ input.addEventListener("click", handler); input.removeEventListener("click", handler); ``` -์ฃผ์˜ํ•˜์„ธ์š” -- ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š์œผ๋ฉด, ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์šธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. `addEventListener`๋ฅผ ํ†ตํ•ด ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ "๋ถˆ๋Ÿฌ์˜ฌ" ๋ฐฉ๋ฒ•์ด ์ „ํ˜€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +๋ณ€์ˆ˜์— ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ €์žฅํ•ด ๋†“์ง€ ์•Š์œผ๋ฉด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์šธ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ํ•ญ์ƒ ๊ธฐ์–ตํ•ด ๋†“์œผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด `addEventListener`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ '๋ถˆ๋Ÿฌ์˜ฌ' ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ```` -`addEventListener`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ : +`addEventListener`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run no-beautify -<input id="elem" type="button" value="Click me"/> +<input id="elem" type="button" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."/> <script> function handler1() { @@ -281,130 +276,118 @@ input.removeEventListener("click", handler); } *!* - elem.onclick = () => alert("์•ˆ๋…•ํ•˜์„ธ์š”"); + elem.onclick = () => alert("์•ˆ๋…•ํ•˜์„ธ์š”."); elem.addEventListener("click", handler1); // ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! elem.addEventListener("click", handler2); // ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! */!* </script> ``` -์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด ํ•ธ๋“ค๋Ÿฌ๋Š” DOM-ํ”„๋กœํผํ‹ฐ์™€ `addEventListener` *๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•*์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋ก  ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋งŒ์„ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. - -````warn header="์–ด๋–ค ์ด๋ฒคํŠธ๋Š” `addEventListener`์™€ ํ•จ๊ป˜ ์จ์•ผ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค" -DOM-ํ”„๋กœํผํ‹ฐ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์—†๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๋ฌด์กฐ๊ฑด `addEventListener`๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. - -`transitionend` (CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋๋‚˜๋ฉด ๋ฐœ์ƒ) ์ด๋ฒคํŠธ๊ฐ€ ๊ทธ ์˜ˆ์ž…๋‹ˆ๋‹ค. - -์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์„ธ์š”. ๋Œ€๋ถ€๋ถ„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‘ ๋ฒˆ์งธ ํ•ธ๋“ค๋Ÿฌ๋งŒ ์ž‘๋™ํ•˜๊ณ , ์ฒซ ๋ฒˆ์งธ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒ๋‹ˆ๋‹ค. +์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด ํ•ธ๋“ค๋Ÿฌ๋Š” DOM ํ”„๋กœํผํ‹ฐ์™€ `addEventListener` ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• *๋‘ ๊ฐ€์ง€*๋ฅผ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๊ฐœ๋Š” ๋‘ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋งŒ์„ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. -```html run -<style> - input { - transition: width 1s; - width: 100px; - } +````warn header="์–ด๋–ค ์ด๋ฒคํŠธ๋Š” `addEventListener`๋ฅผ ์จ์•ผ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." +DOM ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•  ์ˆ˜ ์—†๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ช‡๋ช‡ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด๋ฒคํŠธ๋Š” ๋ฌด์กฐ๊ฑด `addEventListener`๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. - .wide { - width: 300px; - } -</style> +๋ฌธ์„œ๋ฅผ ์ฝ๊ณ  DOM ํŠธ๋ฆฌ ์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์ด๋ฒคํŠธ์ธ `DOMContentLoaded`๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. -<input type="button" id="elem" onclick="this.classList.toggle('wide')" value="Click me"> - -<script> - elem.ontransitionend = function() { - alert("DOM property"); // ์‹คํ–‰ ์•ˆ ๋จ - }; +```js +// ์ด ์–ผ๋Ÿฟ์ฐฝ์€ ์ ˆ๋Œ€ ๋œจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +document.onDOMContentLoaded = function() { + alert("DOM์ด ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."); +}; +``` -*!* - elem.addEventListener("transitionend", function() { - alert("addEventListener"); // ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์ข…๋ฃŒ๋˜๋ฉด ๋‚˜ํƒ€๋‚จ - }); -*/!* -</script> +```js +// ์ด ์–ผ๋Ÿฟ์ฐฝ์€ ์ œ๋Œ€๋กœ ๋œน๋‹ˆ๋‹ค. +document.addEventListener("DOMContentLoaded", function() { + alert("DOM์ด ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."); +}); ``` +์ด์ฒ˜๋Ÿผ `addEventListener`๋Š” ์ข€ ๋” ๋ฒ”์šฉ์ ์ž…๋‹ˆ๋‹ค. `addEventListener`๋ฅผ ์จ์•ผ๋งŒ ๋™์ž‘ํ•˜๋Š” ์ด๋ฒคํŠธ๋“ค์€ ์˜ˆ์™ธ์ ์ธ ๊ฒฝ์šฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```` -## ์ด๋ฒคํŠธ ๊ฐ์ฒด(Event object) +## ์ด๋ฒคํŠธ ๊ฐ์ฒด -์ด๋ฒคํŠธ๋ฅผ ์ž˜ ๋‹ค๋ฃจ๋ ค๋ฉด ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ์ƒ์„ธํžˆ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. "click" ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€, "keypress" ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ๋Š”์ง€ ๋“ฑ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ๋ฅผ ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ๋ ค๋ฉด ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ์ƒ์„ธํžˆ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. 'click' ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€, 'keydown' ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ๋Š”์ง€ ๋“ฑ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” *์ด๋ฒคํŠธ ๊ฐ์ฒด(event object)*๋ผ๋Š” ๊ฑธ ๋งŒ๋“ค๊ณ , ์ด๋ฒคํŠธ์— ๊ด€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ์ด ์ด๋ฒคํŠธ ๊ฐ์ฒด์— ๋„ฃ์€ ๋‹ค์Œ, ํ•ธ๋“ค๋Ÿฌ์— ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” *์ด๋ฒคํŠธ ๊ฐ์ฒด(event object)*๋ผ๋Š” ๊ฒƒ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ด๋ฒคํŠธ์— ๊ด€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋„ฃ์€ ๋‹ค์Œ, ํ•ธ๋“ค๋Ÿฌ์— ์ธ์ˆ˜ ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ์ด๋ฒคํŠธ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋งˆ์šฐ์Šค ์ขŒํ‘œ ์ •๋ณด๋ฅผ ์–ป์–ด๋‚ด๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค: +์•„๋ž˜๋Š” ์ด๋ฒคํŠธ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํฌ์ธํ„ฐ ์ขŒํ‘œ ์ •๋ณด๋ฅผ ์–ป์–ด๋‚ด๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ```html run -<input type="button" value="Click me" id="elem"> +<input type="button" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”." id="elem"> <script> elem.onclick = function(*!*event*/!*) { - // ์ด๋ฒคํŠธ ํƒ€์ž…๊ณผ, ์š”์†Œ, ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ขŒํ‘œ๋ฅผ ๋ณด์—ฌ์คŒ - alert(event.type + " at " + event.currentTarget); - alert("Coordinates: " + event.clientX + ":" + event.clientY); + // ์ด๋ฒคํŠธ ํƒ€์ž…๊ณผ ์š”์†Œ, ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ขŒํ‘œ๋ฅผ ๋ณด์—ฌ์คŒ + alert(event.type + " ์ด๋ฒคํŠธ๊ฐ€ " + event.currentTarget + "์—์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."); + alert("์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ณณ์˜ ์ขŒํ‘œ๋Š” " + event.clientX + ":" + event.clientY +"์ž…๋‹ˆ๋‹ค."); }; </script> ``` -์•„๋ž˜๋Š” `์ด๋ฒคํŠธ` ๊ฐ์ฒด์—์„œ ์ง€์›ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค: +`์ด๋ฒคํŠธ` ๊ฐ์ฒด์—์„œ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ์ค‘ ์ผ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. `event.type` : ์ด๋ฒคํŠธ ํƒ€์ž…, ์œ„ ์˜ˆ์‹œ์—์„  `"click"`. `event.currentTarget` -: Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from `event.currentTarget`. +: ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์š”์†Œ. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ณณ์— ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—” `this`๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’๊ณผ ๊ฐ™์Œ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๊ฑฐ๋‚˜ ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ๊ณณ์— ๋ฐ”์ธ๋”ฉํ•œ ๊ฒฝ์šฐ์—” `event.currentTarget`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ์š”์†Œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ `event.clientX / event.clientY` -: ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์—์„œ, ์ปค์„œ์˜ ์ƒ๋Œ€ ์ขŒํ‘œ(์—ญ์ฃผ: ๋ชจ๋‹ˆํ„ฐ ๊ธฐ์ค€์˜ ์ขŒํ‘œ๊ฐ€ ์•„๋‹Œ, ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ๊ธฐ์ค€ ์ขŒํ‘œ) +: ํฌ์ธํ„ฐ ๊ด€๋ จ ์ด๋ฒคํŠธ์—์„œ, ์ปค์„œ์˜ ์ƒ๋Œ€ ์ขŒํ‘œ(๋ชจ๋‹ˆํ„ฐ ๊ธฐ์ค€ ์ขŒํ‘œ๊ฐ€ ์•„๋‹Œ, ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ๊ธฐ์ค€ ์ขŒํ‘œ - ์˜ฎ๊ธด์ด) -์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ํƒ€์ž…์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ ๊ฐ์ฒด์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ์ถ”ํ›„ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์ด๋ฒคํŠธ๋ฅผ ํ•™์Šตํ•˜๋ฉด์„œ, ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋„ ์ƒ์„ธํžˆ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ํƒ€์ž…์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ ๊ฐ์ฒด์—์„œ ์ œ๊ณตํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ถ”ํ›„ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์ด๋ฒคํŠธ๋ฅผ ํ•™์Šตํ•˜๋ฉด์„œ ์ด๋ฒคํŠธ๋ณ„ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋„ ์ƒ์„ธํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -````smart header="์ด๋ฒคํŠธ ๊ฐ์ฒด๋Š” HTML์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค" -ํ•ธ๋“ค๋Ÿฌ๋ฅผ HTML์—์„œ ํ• ๋‹นํ•œ ๊ฒฝ์šฐ์—๋„, `event` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ : +````smart header="์ด๋ฒคํŠธ ๊ฐ์ฒด๋Š” HTML ํ•ธ๋“ค๋Ÿฌ ์•ˆ์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค." +HTML์—์„œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•œ ๊ฒฝ์šฐ์—๋„ ์•„๋ž˜์™€ ๊ฐ™์ด `event` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html autorun height=60 <input type="button" onclick="*!*alert(event.type)*/!*" value="์ด๋ฒคํŠธ ํƒ€์ž…"> ``` -์ด๊ฒŒ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์†์„ฑ์„ ์ฝ์„ ๋•Œ, `function(event) { alert(event.type) }` ๊ฐ™์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” `"event"`๋กœ ๋ถˆ๋ฆฌ๊ณ , ํ•จ์ˆ˜ ๋ชธ์ฒด๋Š” ์†์„ฑ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค +๋ธŒ๋ผ์šฐ์ €๋Š” ์†์„ฑ์„ ์ฝ๊ณ  `function(event) { alert(event.type) }` ๊ฐ™์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” `"event"`๋กœ ๋ถˆ๋ฆฌ๊ณ , ํ•จ์ˆ˜ ๋ณธ๋ฌธ์€ ์†์„ฑ๊ฐ’ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ```` -## ๊ฐ์ฒด ํ•ธ๋“ค๋Ÿฌ: handleEvent +## ๊ฐ์ฒด ํ˜•ํƒœ์˜ ํ•ธ๋“ค๋Ÿฌ์™€ handleEvent -We can assign not just a function, but an object as an event handler using `addEventListener`. When an event occurs, its `handleEvent` method is called. +`addEventListener`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ์ฒด๋ฅผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ์ฒด์— ๊ตฌํ˜„ํ•œ `handleEvent` ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -์˜ˆ: +์˜ˆ์‹œ: ```html run -<button id="elem">ํด๋ฆญํ•ด์ฃผ์„ธ์š”</button> +<button id="elem">ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.</button> <script> - elem.addEventListener('click', { + let obj = { handleEvent(event) { - alert(event.type + " at " + event.currentTarget); + alert(event.type + " ์ด๋ฒคํŠธ๊ฐ€ " + event.currentTarget + "์—์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."); } - }); + }; + + elem.addEventListener('click', obj); </script> ``` -As we can see, when `addEventListener` receives an object as the handler, it calls `object.handleEvent(event)` in case of an event. +๋ณด์‹œ๋‹ค์‹œํ”ผ `addEventListener`๊ฐ€ ์ธ์ˆ˜๋กœ ๊ฐ์ฒด ํ˜•ํƒœ์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฐ›์œผ๋ฉด ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ `obj.handleEvent(event)`๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค: +ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run -<button id="elem">Click me</button> +<button id="elem">ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.</button> <script> class Menu { handleEvent(event) { switch(event.type) { case 'mousedown': - elem.innerHTML = "Mouse button pressed"; + elem.innerHTML = "๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์Šต๋‹ˆ๋‹ค."; break; case 'mouseup': - elem.innerHTML += "...and released."; + elem.innerHTML += " ๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํŠผ์„ ๋—์Šต๋‹ˆ๋‹ค."; break; } } @@ -418,12 +401,12 @@ As we can see, when `addEventListener` receives an object as the handler, it cal </script> ``` -์œ„ ์˜ˆ์ œ์—์„  ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ๋‘ ๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌ(handle)ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์˜ํ•  ๊ฒƒ์€ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ• ๋‹นํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์ œ์—์„œ `menu` ๊ฐ์ฒด๋Š” ์˜ค์ง `mousedown` ์™€ `mouseup`์ด๋ฒคํŠธ์—๋งŒ ์‘๋‹ตํ•˜๊ณ , ๋‹ค๋ฅธ ํƒ€์ž…์˜ ์ด๋ฒคํŠธ์—๋Š” ์‘๋‹ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„  ํ•˜๋‚˜์˜ ๊ฐ์ฒด์—์„œ ๋‘ ๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ฃผ์˜ํ•  ์ ์€ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์š”์†Œ์— ํƒ€์ž…์„ ์ •ํ™•ํžˆ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ `menu` ๊ฐ์ฒด๋Š” ์˜ค์ง `mousedown` ์™€ `mouseup`์ด๋ฒคํŠธ์—๋งŒ ์‘๋‹ตํ•˜๊ณ , ๋‹ค๋ฅธ ํƒ€์ž…์˜ ์ด๋ฒคํŠธ์—๋Š” ์‘๋‹ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -`handleEvent` ๋ฉ”์„œ๋“œ๊ฐ€ ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ `handleEvent` ์—์„œ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ : +`handleEvent` ๋ฉ”์„œ๋“œ๊ฐ€ ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ `handleEvent` ์—์„œ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ , ```html run -<button id="elem">Click me</button> +<button id="elem">ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.</button> <script> class Menu { @@ -434,11 +417,11 @@ As we can see, when `addEventListener` receives an object as the handler, it cal } onMousedown() { - elem.innerHTML = "Mouse button pressed"; + elem.innerHTML = "๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์Šต๋‹ˆ๋‹ค."; } onMouseup() { - elem.innerHTML += "...and released."; + elem.innerHTML += " ๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํŠผ์„ ๋—์Šต๋‹ˆ๋‹ค."; } } @@ -448,22 +431,22 @@ As we can see, when `addEventListener` receives an object as the handler, it cal </script> ``` -์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌ๋˜์–ด์„œ, ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ์šฉ์ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ์›ํ™œํ•ด์กŒ์Šต๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1. HTML ์†์„ฑ: `onclick="..."`. 2. DOM ํ”„๋กœํผํ‹ฐ: `elem.onclick = function`. -3. ๋ฉ”์„œ๋“œ: `elem.addEventListener(event, handler[, phase])` ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , `removeEventListener` ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐ. +3. ๋ฉ”์„œ๋“œ: `elem.addEventListener(event, handler[, phase])`๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , `removeEventListener` ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•จ -HTML ์†์„ฑ์„ ์ด์šฉํ•œ ํ• ๋‹น์€ ์ž์ฃผ ์“ฐ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HTML ํƒœ๊ทธ ์ค‘๊ฐ„์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋“ค์–ด๊ฐ€์žˆ์œผ๋ฉด ์–ด์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ธด ์ฝ”๋“œ๋ฅผ ๋ผ์›Œ ๋„ฃ๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ ๋„ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. +HTML ์†์„ฑ์„ ์ด์šฉํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น์€ ์ž์ฃผ ์“ฐ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HTML ํƒœ๊ทธ ์ค‘๊ฐ„์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ์œผ๋ฉด ์–ด์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ธด ์ฝ”๋“œ๋ฅผ ๋ผ์›Œ ๋„ฃ๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ ๋„ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. -DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„, ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋‹ค๋ฃจ์ง„ ์•Š์„ ๊ฒ๋‹ˆ๋‹ค. +DOM ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ƒํ™ฉ์—์„œ ์ด๋Ÿฐ ์ œ์•ฝ์ด ํฐ ๋‹จ์ ์ด ๋˜์ง„ ์•Š์ง€๋งŒ์š”. -๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ€์žฅ ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๊ฐ€์žฅ ๊น๋‹ˆ๋‹ค. `transtionend` ์™€ `DOMContentLoaded`(์ถ”ํ›„ ๋‹ค๋ฃฐ ์˜ˆ์ •)๊ฐ™์€ ์ด๋ฒคํŠธ๋Š” ์ด ๋ฐฉ๋ฒ•์œผ๋กœ๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `addEventListener`๋Š” ๊ฐ์ฒด๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด `handleEvent`๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ€์žฅ ์œ ์—ฐํ•˜์ง€๋งŒ, ์ฝ”๋“œ๋Š” ๊ฐ€์žฅ ๊น๋‹ˆ๋‹ค. `transitionend`์™€ `DOMContentLoaded`(์ถ”ํ›„ ๋‹ค๋ฃฐ ์˜ˆ์ •)๊ฐ™์€ ์ผ๋ถ€ ์ด๋ฒคํŠธ๋Š” ์ด ๋ฐฉ๋ฒ•์œผ๋กœ๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `addEventListener`๋Š” ๊ฐ์ฒด ํ˜•ํƒœ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—” ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๊ฐ์ฒด ์•ˆ์— ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ์ธ `handleEvent`๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋˜, ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ์ด๋ฒคํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋˜, ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ์ด๋ฒคํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๊ฐ์ฒด๋Š” ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ ์ฃผ์ œ์—์„œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์ „๋ฐ˜์ ์ธ ๋‚ด์šฉ๊ณผ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +๋‹ค์Œ ์ฃผ์ œ์—์„œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์ „๋ฐ˜์ ์ธ ๋‚ด์šฉ๊ณผ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index aff4400665..9a544d459c 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -1,12 +1,12 @@ # ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง -๋จผ์ € ์ฝ”๋“œ๋ถ€ํ„ฐ ์‚ดํŽด๋ด…์‹œ๋‹ค. +๋จผ์ € ์˜ˆ์‹œ๋ถ€ํ„ฐ ์‚ดํŽด๋ด…์‹œ๋‹ค. -์•„๋ž˜ ํ•ธ๋“ค๋Ÿฌ๋Š” `<div>`์— ํ• ๋‹น๋˜์–ด ์žˆ์ง€๋งŒ, `<em>` ์ด๋‚˜ `<code>`๊ฐ™์€ ์ค‘์ฒฉํƒœ๊ทธ(nested tag)๋ฅผ ํด๋ฆญํ•ด๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค: +์•„๋ž˜ ํ•ธ๋“ค๋Ÿฌ๋Š” `<div>`์— ํ• ๋‹น๋˜์–ด ์žˆ์ง€๋งŒ, `<em>` ์ด๋‚˜ `<code>`๊ฐ™์€ ์ค‘์ฒฉ ํƒœ๊ทธ๋ฅผ ํด๋ฆญํ•ด๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```html autorun height=60 -<div onclick="alert('The handler!')"> - <em>If you click on <code>EM</code>, the handler on <code>DIV</code> runs.</em> +<div onclick="alert('div์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ!')"> + <em><code>EM</code>์„ ํด๋ฆญํ–ˆ๋Š”๋ฐ๋„ <code>DIV</code>์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.</em> </div> ``` @@ -14,11 +14,11 @@ ## ๋ฒ„๋ธ”๋ง -๋ฒ„๋ธ”๋ง ์›๋ฆฌ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. +๋ฒ„๋ธ”๋ง(bubbling)์˜ ์›๋ฆฌ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. -**ํ•œ ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์ด ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ ๊ทธ ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๊ณ , ์ด ๊ณผ์ •์ด ๋ฐ˜๋ณต๋˜๋ฉด์„œ ๊ฐ€์žฅ ์ตœ์ƒ๋‹จ์˜ ์กฐ์ƒ ์š”์†Œ๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๊ฐ ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.** +**ํ•œ ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์ด ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๊ณ , ์ด์–ด์„œ ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ตœ์ƒ๋‹จ์˜ ์กฐ์ƒ ์š”์†Œ๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ์ด ๊ณผ์ •์ด ๋ฐ˜๋ณต๋˜๋ฉด์„œ ์š”์†Œ ๊ฐ๊ฐ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.** -3๊ฐœ์˜ ์š”์†Œ๊ฐ€ ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ `FORM > DIV > P`๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์š”์†Œ๋งˆ๋‹ค ๊ฐ์ž์˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค: +3๊ฐœ์˜ ์š”์†Œ๊ฐ€ `FORM > DIV > P` ํ˜•ํƒœ๋กœ ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์š”์†Œ ๊ฐ๊ฐ์— ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ```html run autorun <style> @@ -35,43 +35,43 @@ </form> ``` -๊ฐ€์žฅ ์•ˆ์ชฝ์˜ `<p>`๋ฅผ ํด๋ฆญํ•˜๋ฉด : +๊ฐ€์žฅ ์•ˆ์ชฝ์˜ `<p>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ˆœ์„œ๋Œ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์ด ๋ฒŒ์–ด์ง‘๋‹ˆ๋‹ค. 1. `<p>`์— ํ• ๋‹น๋œ `onclick` ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -2. ๊ทธ๋‹ค์Œ์€ ๋ฐ”๊นฅ์˜ `<div>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -3. ๋‹ค์Œ์€ ๊ทธ ๋ฐ”๊นฅ์˜ `<form>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -4. ํŠธ๋ฆฌ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ `document` ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€, ๊ฐ ์š”์†Œ์— ํ• ๋‹น๋œ `onclick` ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +2. ๋ฐ”๊นฅ์˜ `<div>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +3. ๊ทธ ๋ฐ”๊นฅ์˜ `<form>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +4. `document` ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€, ๊ฐ ์š”์†Œ์— ํ• ๋‹น๋œ `onclick` ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ![](event-order-bubbling.svg) -์ด๋Ÿฐ ๋™์ž‘ ๋ฐฉ์‹ ๋•Œ๋ฌธ์— `<p>` ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด 3๊ฐœ์˜ alert ์ฐฝ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๊ฒƒ ์ž…๋‹ˆ๋‹ค. `p` -> `div` -> `form` ์ˆœ์„œ๋กœ ๋ง์ด์ฃ . +์ด๋Ÿฐ ๋™์ž‘ ๋ฐฉ์‹ ๋•Œ๋ฌธ์— `<p>` ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด `p` -> `div` -> `form` ์ˆœ์„œ๋กœ 3๊ฐœ์˜ ์–ผ๋Ÿฟ ์ฐฝ์ด ๋œจ๋Š”๊ฒƒ์ด์ฃ . -์ด๋Ÿฐ ํ๋ฆ„์„ "์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง(bubbling)"์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ์ œ์ผ ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์š”์†Œ์—์„œ ์‹œ์ž‘ํ•ด ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ํ๋ฅด๋Š” ๋ชจ์–‘์ด ๋งˆ์น˜ ๋ฌผ์† ๊ฑฐํ’ˆ(bubble)๊ณผ ๋‹ฎ์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฐ ํ๋ฆ„์„ '์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง'์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ์ œ์ผ ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์š”์†Œ์—์„œ ์‹œ์ž‘ํ•ด ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ์–‘์ด ๋งˆ์น˜ ๋ฌผ์† ๊ฑฐํ’ˆ(bubble)๊ณผ ๋‹ฎ์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ```warn header="*๊ฑฐ์˜* ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง ๋ฉ๋‹ˆ๋‹ค." -์œ„ ๋ฌธ์žฅ์—์„œ ํ‚ค์›Œ๋“œ๋Š” "๊ฑฐ์˜" ์ž…๋‹ˆ๋‹ค. +ํ‚ค์›Œ๋“œ๋Š” '๊ฑฐ์˜' ์ž…๋‹ˆ๋‹ค. -`focus` ์ด๋ฒคํŠธ์™€ ๊ฐ™์ด, ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š๋Š” ๋ช‡ ๊ฐ€์ง€ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด๋ฒคํŠธ๊ฐ€ ๋งŽ์€๊ฑด ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„ ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง ๋ฉ๋‹ˆ๋‹ค. +`focus` ์ด๋ฒคํŠธ์™€ ๊ฐ™์ด ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š๋Š” ์ด๋ฒคํŠธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š๋Š” ์ด๋ฒคํŠธ์˜ ์ข…๋ฅ˜์— ๋Œ€ํ•ด์„  ์กฐ๊ธˆ ํ›„์— ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋ฅผ ์ œ์™ธํ•˜๊ณค ๋Œ€๋ถ€๋ถ„์˜ ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง ๋ฉ๋‹ˆ๋‹ค. ``` ## event.target ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๋“ฑ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์š”์†Œ๋Š” *ํƒ€๊นƒ(target)* ์š”์†Œ๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ณ , `event.target`์œผ๋กœ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** +**์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์š”์†Œ๋Š” *ํƒ€๊นƒ(target)* ์š”์†Œ๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ณ , `event.target`์„ ์‚ฌ์šฉํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** -`this` (=`event.currentTarget`) ์™€๋Š” ๋‹ค๋ฅด๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: +`event.target`๊ณผ `this`(=`event.currentTarget`)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -- `event.target` -- ์€ ์‹ค์ œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ "ํƒ€๊นƒ" ์š”์†Œ์ด๊ณ , ๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚˜๋„ ๋ณ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- `this` -- ๋Š” "ํ˜„์žฌ(current)" ์š”์†Œ๋กœ, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋œ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. +- `event.target`์€ ์‹ค์ œ ์ด๋ฒคํŠธ๊ฐ€ ์‹œ์ž‘๋œ 'ํƒ€๊นƒ' ์š”์†Œ์ž…๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง์ด ์ง„ํ–‰๋˜์–ด๋„ ๋ณ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- `this`๋Š” 'ํ˜„์žฌ' ์š”์†Œ๋กœ, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋œ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. -์˜ˆ์‹œ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋Š” `form.onclick` ํ•˜๋‚˜๋ฐ–์— ์—†๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ form ์•ˆ์˜ ๋ชจ๋“  ์š”์†Œ์— ์žˆ๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ "์žก์•„๋‚ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(catch)". ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ๋“  ์ƒ๊ด€์—†์ด, `<form>`์š”์†Œ๊นŒ์ง€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง ๋˜์–ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ํ•ธ๋“ค๋Ÿฌ๋Š” `form.onclick` ํ•˜๋‚˜๋ฐ–์— ์—†์ง€๋งŒ ์ด ํ•ธ๋“ค๋Ÿฌ์—์„œ ํผ ์•ˆ์˜ ๋ชจ๋“  ์š”์†Œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ '์žก์•„๋‚ด๊ณ (catch)' ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ๋“  ์ƒ๊ด€์—†์ด `<form>` ์š”์†Œ๊นŒ์ง€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง ๋˜์–ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -`form.onclick` ํ•ธ๋“ค๋Ÿฌ์—์„œ: +`form.onclick` ํ•ธ๋“ค๋Ÿฌ ๋‚ด์˜ `this`์™€ `event.target`์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `this` (`=event.currentTarget`)๋Š” `<form>` ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. `<form>` ์š”์†Œ์— ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -- `event.target` ์€ form ์•ˆ์ชฝ์— ์žˆ๋Š” ์‹ค์ œ ํด๋ฆญํ•œ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. +- `this`(`event.currentTarget`) -- `<form>` ์š”์†Œ์— ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— `<form>` ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +- `event.target` -- ํผ ์•ˆ์ชฝ์— ์‹ค์ œ ํด๋ฆญํ•œ ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค: +์ง์ ‘ ํ™•์ธํ•ด ๋ด…์‹œ๋‹ค. [codetabs height=220 src="bubble-target"] @@ -79,80 +79,80 @@ ## ๋ฒ„๋ธ”๋ง ์ค‘๋‹จํ•˜๊ธฐ -์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ ํƒ€๊นƒ ์ด๋ฒคํŠธ์—์„œ ์‹œ์ž‘ํ•ด์„œ `<html>` ์š”์†Œ๋ฅผ ๊ฑฐ์ณ `document` ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๊ฐ ๋…ธ๋“œ์—์„œ ๋ชจ๋‘ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” `window` ๊ฐ์ฒด๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ ํƒ€๊นƒ ์ด๋ฒคํŠธ์—์„œ ์‹œ์ž‘ํ•ด์„œ `<html>` ์š”์†Œ๋ฅผ ๊ฑฐ์ณ `document` ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๊ฐ ๋…ธ๋“œ์—์„œ ๋ชจ๋‘ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” `window` ๊ฐ์ฒด๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋„ ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ ์ด๋ฒคํŠธ๋ฅผ ์™„์ „ํžˆ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚œ ํ›„ ๋ฒ„๋ธ”๋ง์„ ์ค‘๋‹จํ•˜๋„๋ก ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ๋ช…๋ นํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฐ๋ฐ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์™„์ „ํžˆ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚œ ํ›„ ๋ฒ„๋ธ”๋ง์„ ์ค‘๋‹จํ•˜๋„๋ก ๋ช…๋ นํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ์ธ `event.stopPropagation()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `<button>`์„ ํด๋ฆญํ•ด๋„ `body.onclick`์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `<button>`์„ ํด๋ฆญํ•ด๋„ `body.onclick`์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```html run autorun height=60 -<body onclick="alert(`the bubbling doesn't reach here`)"> - <button onclick="event.stopPropagation()">Click me</button> +<body onclick="alert(`๋ฒ„๋ธ”๋ง์€ ์—ฌ๊ธฐ๊นŒ์ง€ ๋„๋‹ฌํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.`)"> + <button onclick="event.stopPropagation()">ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.</button> </body> ``` ```smart header="event.stopImmediatePropagation()" -ํŠน์ • ์š”์†Œ์˜ ์ด๋ฒคํŠธ์— ๋ณต์ˆ˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ๊ณ , ํ•ธ๋“ค๋Ÿฌ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถ”๋”๋ผ๋„ ๋‚˜๋จธ์ง€ ํ•ธ๋“ค๋Ÿฌ๋Š” ์—ฌ์ „ํžˆ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +ํ•œ ์š”์†Œ์˜ ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ธ ์ƒํ™ฉ์—์„œ, ํ•ธ๋“ค๋Ÿฌ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถ”๋”๋ผ๋„ ๋‚˜๋จธ์ง€ ํ•ธ๋“ค๋Ÿฌ๋Š” ์—ฌ์ „ํžˆ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -`event.stopPropagation()`์€ ์ด๋ฒคํŠธ๊ฐ€ ์ƒ์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๊ฑด ๋ง‰์ง€๋งŒ, ํ˜„์žฌ ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๊ฑด ๋ง‰์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. +`event.stopPropagation()`์€ ์œ„์ชฝ์œผ๋กœ ์ผ์–ด๋‚˜๋Š” ๋ฒ„๋ธ”๋ง์€ ๋ง‰์•„์ฃผ์ง€๋งŒ, ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ๋“ค์ด ๋™์ž‘ํ•˜๋Š” ๊ฑด ๋ง‰์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. -๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถ”๊ณ , ํ˜„์žฌ ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ์˜ ๋™์ž‘๋„ ๋ง‰์œผ๋ ค๋ฉด, `event.stopImmediatePropagation()`์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถ”๊ณ , ์š”์†Œ์— ํ• ๋‹น๋œ ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ์˜ ๋™์ž‘๋„ ๋ง‰์œผ๋ ค๋ฉด `event.stopImmediatePropagation()`์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ์— ํ• ๋‹น๋œ ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ ๋ชจ๋‘๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` ```warn header="๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณค ๋ฒ„๋ธ”๋ง์„ ๋ง‰์ง€ ๋งˆ์„ธ์š”!" -๋ฒ„๋ธ”๋ง์€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง์„ ๊ผญ ๋ฉˆ์ถฐ์•ผ ํ•˜๋Š” ๋ช…๋ฐฑํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด ๋ฒ„๋ธ”๋ง์„ ๋ง‰์ง€ ๋งˆ์„ธ์š”. ๊ตฌ์กฐ์ ์œผ๋กœ ์ž˜ ์ƒ๊ฐํ•˜๊ณ  ์ง„์งœ ๋ฉˆ์ถฐ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—๋งŒ ๋ง‰์œผ์„ธ์š”. +๋ฒ„๋ธ”๋ง์€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง์„ ๊ผญ ๋ฉˆ์ถฐ์•ผ ํ•˜๋Š” ๋ช…๋ฐฑํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด ๋ฒ„๋ธ”๋ง์„ ๋ง‰์ง€ ๋งˆ์„ธ์š”. ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ž˜ ๊ณ ๋ คํ•ด ์ง„์งœ ๋ง‰์•„์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋งŒ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์œผ์„ธ์š”. -`event.stopPropagation()`์€ ์ถ”ํ›„์— ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์œ„ํ—˜ ์ƒํ™ฉ์„ ๋งŒ๋“ค์–ด๋‚ผ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +`event.stopPropagation()`์€ ์ถ”ํ›„์— ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด: +๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ• ๋งŒํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. -1. ์ค‘์ฒฉ ๋ฉ”๋‰ด๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค. ๊ฐ ๋ถ€๋ฉ”๋‰ด์˜ ํ•ด๋‹น ์š”์†Œ์—์„  ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒ์œ„ ๋ฉ”๋‰ด์˜ ํด๋ฆญ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋„๋ก `stopPropagation`์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. -2. ์‚ฌ์šฉ์ž์˜ ํ–‰๋™ ํŒจํ„ด(์‚ฌ๋žŒ๋“ค์ด ์–ด๋””์„œ ํด๋ฆญ์„ ํ•˜๋Š”์ง€) ๋ถ„์„์„ ๋ชฉ์ ์œผ๋กœ, window์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๋ชจ๋‘ ๊ฐ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ถ„์„์„ ๋„์™€์ฃผ๋Š” ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ถ„์„ ์‹œ์Šคํ…œ์˜ ์ฝ”๋“œ๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด `document.addEventListener('click'โ€ฆ)`์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -3. `stopPropagation`๋กœ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„๋†“์€ ์˜์—ญ์—์„  ์ด ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ„์„ ์‹œ์Šคํ…œ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ˆํƒ€๊น๊ฒŒ๋„ ์ด ์˜์—ญ์€ "์ฃฝ์€ ์˜์—ญ(dead zone)"์ด ๋˜์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. +1. ์ค‘์ฒฉ ๋ฉ”๋‰ด๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค. ๊ฐ ์„œ๋ธŒ๋ฉ”๋‰ด(submenu)์— ํ•ด๋‹นํ•˜๋Š” ์š”์†Œ์—์„œ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๊ณ , ์ƒ์œ„ ๋ฉ”๋‰ด์˜ ํด๋ฆญ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋„๋ก `stopPropagation`์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. +2. ์‚ฌ๋žŒ๋“ค์ด ํŽ˜์ด์ง€์—์„œ ์–ด๋””๋ฅผ ํด๋ฆญํ–ˆ๋Š”์ง€ ๋“ฑ์˜ ํ–‰๋™ ํŒจํ„ด์„ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด, window๋‚ด์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ ์ „๋ถ€๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ถ„์„ ์‹œ์Šคํ…œ์€ ๊ทธ๋ ‡๊ฒŒ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ถ„์„ ์‹œ์Šคํ…œ์˜ ์ฝ”๋“œ๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด `document.addEventListener('click'โ€ฆ)`์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +3. `stopPropagation`๋กœ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„๋†“์€ ์˜์—ญ์—์„  ๋ถ„์„ ์‹œ์Šคํ…œ์˜ ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ„์„์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ˆํƒ€๊น๊ฒŒ๋„ `stopPropagation`์„ ์‚ฌ์šฉํ•œ ์˜์—ญ์€ '์ฃฝ์€ ์˜์—ญ(dead zone)'์ด ๋˜์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. -์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง์„ ์ง„์งœ ๋ง‰์•„์•ผ ํ•œ๋‹ค๋ฉด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ถ”ํ›„์— ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ์˜ `์ด๋ฒคํŠธ(event)` ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ฉด, ์•„๋ž˜์ชฝ์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€๋ฅผ ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ด ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์•ผ ํ•ด๊ฒฐ๋˜๋Š” ๋ฌธ์ œ๋ผ๋ฉด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ๋“ฑ์„ ์‚ฌ์šฉํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์ถ”ํ›„์— ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ์˜ `event` ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ฉด, ์•„๋ž˜์ชฝ์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€๋ฅผ ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ด ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` ## ์บก์ฒ˜๋ง -์ด๋ฒคํŠธ์—” ๋ฒ„๋ธ”๋ง ์ด์™ธ์—๋„ "์บก์ฒ˜๋ง(Capturing)" ์ด๋ผ๋Š” ํ๋ฆ„์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์ž์ฃผ ์“ฐ์ด์ง„ ์•Š์ง€๋งŒ, ์ข…์ข… ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์•Œ์•„๋ด…์‹œ๋‹ค. +์ด๋ฒคํŠธ์—” ๋ฒ„๋ธ”๋ง ์ด์™ธ์—๋„ '์บก์ฒ˜๋ง(capturing)' ์ด๋ผ๋Š” ํ๋ฆ„์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์ž์ฃผ ์“ฐ์ด์ง„ ์•Š์ง€๋งŒ, ์ข…์ข… ์œ ์šฉํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์•Œ์•„๋ด…์‹œ๋‹ค. -ํ‘œ์ค€ [DOM ์ด๋ฒคํŠธ(Events)](http://www.w3.org/TR/DOM-Level-3-Events/)์—์„œ ์ •์˜ํ•œ ์ด๋ฒคํŠธ ํ๋ฆ„์—” 3๊ฐ€์ง€ ๋‹จ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ‘œ์ค€ [DOM ์ด๋ฒคํŠธ](http://www.w3.org/TR/DOM-Level-3-Events/)์—์„œ ์ •์˜ํ•œ ์ด๋ฒคํŠธ ํ๋ฆ„์—” 3๊ฐ€์ง€ ๋‹จ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -1. ์บก์ฒ˜๋ง ๋‹จ๊ณ„(Capturing phase) -- ์ด๋ฒคํŠธ๊ฐ€ ํ•˜์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ. -2. ํƒ€๊นƒ ๋‹จ๊ณ„(Target phase) -- ์ด๋ฒคํŠธ๊ฐ€ ์‹ค์ œ ํƒ€๊นƒ ์š”์†Œ์— ์ „๋‹ฌ๋จ. -3. ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„(Bubbling phase) -- ์ด๋ฒคํŠธ๊ฐ€ ์ƒ์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ. +1. ์บก์ฒ˜๋ง ๋‹จ๊ณ„ -- ์ด๋ฒคํŠธ๊ฐ€ ํ•˜์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๋‹จ๊ณ„ +2. ํƒ€๊นƒ ๋‹จ๊ณ„ -- ์ด๋ฒคํŠธ๊ฐ€ ์‹ค์ œ ํƒ€๊นƒ ์š”์†Œ์— ์ „๋‹ฌ๋˜๋Š” ๋‹จ๊ณ„ +3. ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„ -- ์ด๋ฒคํŠธ๊ฐ€ ์ƒ์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๋‹จ๊ณ„ -ํ…Œ์ด๋ธ” ์•ˆ์˜ `<td>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ํ๋ฅด๋Š”์ง€ ์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๊ณ  ์ดํ•ดํ•ด ๋ด…์‹œ๋‹ค: +ํ…Œ์ด๋ธ” ์•ˆ์˜ `<td>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ํ๋ฅด๋Š”์ง€ ์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๊ณ  ์ดํ•ดํ•ด ๋ด…์‹œ๋‹ค. ![](eventflow.svg) -`<td>` ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์ตœ์ƒ์œ„ ์กฐ์ƒ์—์„œ ์‹œ์ž‘ํ•ด ์•„๋ž˜๋กœ ์ „ํŒŒ๋˜๊ณ (์บก์ฒ˜๋ง ๋‹จ๊ณ„), ์ด๋ฒคํŠธ๊ฐ€ ํƒ€๊นƒ ์š”์†Œ์— ๋„์ฐฉํ•ด ์‹คํ–‰๋œ ํ›„(ํƒ€๊นƒ ๋‹จ๊ณ„), ๋‹ค์‹œ ์œ„๋กœ ์ „ํŒŒ๋ฉ๋‹ˆ๋‹ค(๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„). ์ด๋Ÿฐ ๊ณผ์ •์„ ํ†ตํ•ด ์š”์†Œ์— ํ• ๋‹น๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +`<td>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์ตœ์ƒ์œ„ ์กฐ์ƒ์—์„œ ์‹œ์ž‘ํ•ด ์•„๋ž˜๋กœ ์ „ํŒŒ๋˜๊ณ (์บก์ฒ˜๋ง ๋‹จ๊ณ„), ์ด๋ฒคํŠธ๊ฐ€ ํƒ€๊นƒ ์š”์†Œ์— ๋„์ฐฉํ•ด ์‹คํ–‰๋œ ํ›„(ํƒ€๊นƒ ๋‹จ๊ณ„), ๋‹ค์‹œ ์œ„๋กœ ์ „ํŒŒ๋ฉ๋‹ˆ๋‹ค(๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„). ์ด๋Ÿฐ ๊ณผ์ •์„ ํ†ตํ•ด ์š”์†Œ์— ํ• ๋‹น๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -**์บก์ฒ˜๋ง ๋‹จ๊ณ„๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ฃผ๋กœ ๋ฒ„๋ธ”๋ง๋งŒ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์บก์ฒ˜๋ง์— ๊ด€ํ•œ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†์„ ๊ฒ๋‹ˆ๋‹ค.** +**์บก์ฒ˜๋ง ๋‹จ๊ณ„๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ด์ „๊นŒ์ง„ ์ฃผ๋กœ ๋ฒ„๋ธ”๋ง๋งŒ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์บก์ฒ˜๋ง์— ๊ด€ํ•œ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†์„ ๊ฒ๋‹ˆ๋‹ค.** -`on<event>`-ํ”„๋กœํผํ‹ฐ, HTML ์†์„ฑ, ์ธ์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ธ `addEventListener(event, handler)`์„ ์ด์šฉํ•ด ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ์บก์ฒ˜๋ง์— ๋Œ€ํ•ด ์ „ํ˜€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ํ•ธ๋“ค๋Ÿฌ๋“ค์€ ๋‘ ๋ฒˆ์งธ ํ˜น์€ ์„ธ ๋ฒˆ์งธ ๋‹จ๊ณ„์˜ ์ด๋ฒคํŠธ ํ๋ฆ„(ํƒ€๊นƒ ๋‹จ๊ณ„์™€ ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„)์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +`on<event>` ํ”„๋กœํผํ‹ฐ๋‚˜ HTML ์†์„ฑ, `addEventListener(event, handler)`๋ฅผ ์ด์šฉํ•ด ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ์บก์ฒ˜๋ง์— ๋Œ€ํ•ด ์ „ํ˜€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ํ•ธ๋“ค๋Ÿฌ๋“ค์€ ๋‘ ๋ฒˆ์งธ ํ˜น์€ ์„ธ ๋ฒˆ์งธ ๋‹จ๊ณ„์˜ ์ด๋ฒคํŠธ ํ๋ฆ„(ํƒ€๊นƒ ๋‹จ๊ณ„์™€ ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„)์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -์บก์ฒ˜๋ง ๋‹จ๊ณ„์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์žก์•„๋‚ด๋ ค๋ฉด `addEventListener`์˜ `capture` ์˜ต์…˜์„ `true`๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: +์บก์ฒ˜๋ง ๋‹จ๊ณ„์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์žก์•„๋‚ด๋ ค๋ฉด `addEventListener`์˜ `capture` ์˜ต์…˜์„ `true`๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js elem.addEventListener(..., {capture: true}) -// ์•„๋‹ˆ๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด {capture: true} ๋Œ€์‹ , true๋ฅผ ์จ์ค˜๋„ ๋ฉ๋‹ˆ๋‹ค. +// ์•„๋‹ˆ๋ฉด, ์•„๋ž˜ ๊ฐ™์ด {capture: true} ๋Œ€์‹ , true๋ฅผ ์จ์ค˜๋„ ๋ฉ๋‹ˆ๋‹ค. elem.addEventListener(..., true) ``` -`capture` ์˜ต์…˜์€ 2๊ฐ€์ง€ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +`capture` ์˜ต์…˜์€ ๋‘ ๊ฐ€์ง€ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- `false`(default ๊ฐ’)์ธ ๊ฒฝ์šฐ, ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- `true`์ธ ๊ฒฝ์šฐ, ํ•ธ๋“ค๋Ÿฌ๋Š” ์บก์ฒ˜๋ง ๋‹จ๊ณ„์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +- `false`์ด๋ฉด(default ๊ฐ’) ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +- `true`์ด๋ฉด ํ•ธ๋“ค๋Ÿฌ๋Š” ์บก์ฒ˜๋ง ๋‹จ๊ณ„์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -๊ณต์‹์ ์œผ๋ก  ์ด 3๊ฐœ์˜ ์ด๋ฒคํŠธ ํ๋ฆ„์ด ์žˆ์ง€๋งŒ, ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„("ํƒ€๊นƒ ๋‹จ๊ณ„": ์ด๋ฒคํŠธ๊ฐ€ ์‹ค์ œ ํƒ€๊นƒ ์š”์†Œ์— ์ „๋‹ฌ๋˜๋Š” ๋‹จ๊ณ„)๋Š” ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์˜ ํ•ธ๋“ค๋Ÿฌ๋Š” ํƒ€๊นƒ๋‹จ๊ณ„์—์„œ ๋ชจ๋‘ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +๊ณต์‹์ ์œผ๋ก  ์ด 3๊ฐœ์˜ ์ด๋ฒคํŠธ ํ๋ฆ„์ด ์žˆ์ง€๋งŒ, ์ด๋ฒคํŠธ๊ฐ€ ์‹ค์ œ ํƒ€๊นƒ ์š”์†Œ์— ์ „๋‹ฌ๋˜๋Š” ๋‹จ๊ณ„์ธ 'ํƒ€๊นƒ ๋‹จ๊ณ„'(๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„)๋Š” ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์˜ ํ•ธ๋“ค๋Ÿฌ๋Š” ํƒ€๊นƒ ๋‹จ๊ณ„์—์„œ ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค. ```html run autorun height=140 edit <style> @@ -170,31 +170,31 @@ elem.addEventListener(..., true) <script> for(let elem of document.querySelectorAll('*')) { - elem.addEventListener("click", e => alert(`Capturing: ${elem.tagName}`), true); - elem.addEventListener("click", e => alert(`Bubbling: ${elem.tagName}`)); + elem.addEventListener("click", e => alert(`์บก์ณ๋ง: ${elem.tagName}`), true); + elem.addEventListener("click", e => alert(`๋ฒ„๋ธ”๋ง: ${elem.tagName}`)); } </script> ``` -์ด ์ฝ”๋“œ๋Š” ๋ฌธ์„œ ๋‚ด์˜ "๋ชจ๋“ " ์š”์†Œ์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด์„œ ์–ด๋–ค ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ๋Š” ๋ฌธ์„œ ๋‚ด ์š”์†Œ '์ „์ฒด'์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด์„œ ์–ด๋–ค ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. -`<p>` ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค: +`<p>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. 1. `HTML` -> `BODY` -> `FORM` -> `DIV` (์บก์ฒ˜๋ง ๋‹จ๊ณ„, ์ฒซ ๋ฒˆ์งธ ๋ฆฌ์Šค๋„ˆ) -2. `P (ํƒ€๊นƒ ๋‹จ๊ณ„, capturing๊ณผ bubbling ๋‘˜ ๋‹ค์— ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.) +2. `P` (ํƒ€๊นƒ ๋‹จ๊ณ„, ์บก์ณ๋ง๊ณผ ๋ฒ„๋ธ”๋ง ๋‘˜ ๋‹ค์— ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.) 3. `DIV` -> `FORM` -> `BODY` -> `HTML` (๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„, ๋‘ ๋ฒˆ์งธ ๋ฆฌ์Šค๋„ˆ) -`event.eventPhase` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋ฉด ํ˜„์žฌ ๋ฐœ์ƒ ์ค‘์ธ ์ด๋ฒคํŠธ ํ๋ฆ„์˜ ๋‹จ๊ณ„๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์—ญ์ฃผ: ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •์ˆซ๊ฐ’์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ ํ๋ฆ„์˜ ํ˜„์žฌ ์‹คํ–‰ ๋‹จ๊ณ„๋ฅผ ๊ตฌ๋ถ„ํ•จ). ํ•˜์ง€๋งŒ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ํ๋ฆ„ ๋‹จ๊ณ„๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ”„๋กœํผํ‹ฐ๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +`event.eventPhase` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋ฉด ํ˜„์žฌ ๋ฐœ์ƒ ์ค‘์ธ ์ด๋ฒคํŠธ ํ๋ฆ„์˜ ๋‹จ๊ณ„๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ์ •์ˆซ๊ฐ’์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ ํ๋ฆ„์˜ ํ˜„์žฌ ์‹คํ–‰ ๋‹จ๊ณ„๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์ฃ . ํ•˜์ง€๋งŒ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ํ๋ฆ„ ๋‹จ๊ณ„๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ”„๋กœํผํ‹ฐ๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -```smart header="ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•  ๋•, `removeEventListener`๊ฐ€ ๊ฐ™์€ ๋‹จ๊ณ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค" +```smart header="ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•  ๋•Œ `removeEventListener`๊ฐ€ ๊ฐ™์€ ๋‹จ๊ณ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค." `addEventListener(..., true)`๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด ์คฌ๋‹ค๋ฉด, ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์šธ ๋•Œ, `removeEventListener(..., true)`๋ฅผ ์‚ฌ์šฉํ•ด ์ง€์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋‹จ๊ณ„์— ์žˆ์–ด์•ผ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ง€์›Œ์ง‘๋‹ˆ๋‹ค. ``` -````smart header="Listeners on same element and same phase run in their set order" -If we have multiple event handlers on the same phase, assigned to the same element with `addEventListener`, they run in the same order as they are created: +````smart header="๊ฐ™์€ ์š”์†Œ์™€ ๊ฐ™์€ ๋‹จ๊ณ„์— ์„ค์ •ํ•œ ๋ฆฌ์Šค๋„ˆ๋Š” ์„ค์ •ํ•œ ์ˆœ์„œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค." +ํŠน์ • ์š”์†Œ์— `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด ํ•œ ๋‹จ๊ณ„์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์„ค์ •ํ–ˆ๋‹ค๋ฉด ์ด ํ•ธ๋“ค๋Ÿฌ๋“ค์€ ์„ค์ •ํ•œ ์ˆœ์„œ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```js -elem.addEventListener("click", e => alert(1)); // guaranteed to trigger first +elem.addEventListener("click", e => alert(1)); // ์ฒซ ๋ฒˆ์งธ๋กœ ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. elem.addEventListener("click", e => alert(2)); ``` ```` @@ -202,24 +202,24 @@ elem.addEventListener("click", e => alert(2)); ## ์š”์•ฝ -์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์š”์†Œ๊ฐ€ "ํƒ€๊นƒ ์š”์†Œ(`event.target`)"๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฐ€์žฅ ์•ˆ์ชฝ ์š”์†Œ๊ฐ€ 'ํƒ€๊นƒ ์š”์†Œ(`event.target`)'๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -- ์ดํ›„ ์ด๋ฒคํŠธ๋Š” document์—์„œ ์‹œ์ž‘ํ•ด DOM ํŠธ๋ฆฌ๋ฅผ ๋”ฐ๋ผ `event.target`๊นŒ์ง€ ๋‚ด๋ ค๊ฐ‘๋‹ˆ๋‹ค. ์ด๋•Œ, ์š”์†Œ์— `addEventListener(...., true)`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค(`addEventListener(...., true)`์˜ `true`๋Š” `{capture: true}`์˜ ์ค„์ž„์ž…๋‹ˆ๋‹ค). -- ํƒ€๊นƒ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -- ์ด๋ฒคํŠธ๊ฐ€ `event.target`๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ๋‹ค์‹œ ์ตœ์ƒ์œ„ ๋…ธ๋“œ๊นŒ์ง€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, `on<event>`, ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์—†๊ฑฐ๋‚˜ `false`์ธ `addEventListener`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +- ์ด๋ฒคํŠธ๋Š” document์—์„œ ์‹œ์ž‘ํ•ด DOM ํŠธ๋ฆฌ๋ฅผ ๋”ฐ๋ผ `event.target`๊นŒ์ง€ ๋‚ด๋ ค๊ฐ‘๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๋Š” ํŠธ๋ฆฌ๋ฅผ ๋”ฐ๋ผ ๋‚ด๋ ค๊ฐ€๋ฉด์„œ `addEventListener(..., true)`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋™์ž‘์‹œํ‚ต๋‹ˆ๋‹ค. `addEventListener(..., true)`์˜ `true`๋Š” `{capture: true}`์˜ ์ถ•์•ฝํ˜•์ž…๋‹ˆ๋‹ค. +- ์ดํ›„ ํƒ€๊นƒ ์š”์†Œ์— ์„ค์ •๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +- ์ดํ›„์—” ์ด๋ฒคํŠธ๊ฐ€ `event.target`๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ๋‹ค์‹œ ์ตœ์ƒ์œ„ ๋…ธ๋“œ๊นŒ์ง€ ์ „๋‹ฌ๋˜๋ฉด์„œ ๊ฐ ์š”์†Œ์— `on<event>`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์™€ `addEventListener`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋™์ž‘์‹œํ‚ต๋‹ˆ๋‹ค. `addEventListener`๋กœ ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ ์ค‘, ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์—†๊ฑฐ๋‚˜ `false`, `{capture: false}`์ธ ํ•ธ๋“ค๋Ÿฌ๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -๊ฐ ํ•ธ๋“ค๋Ÿฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ `์ด๋ฒคํŠธ` ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๊ฐ ํ•ธ๋“ค๋Ÿฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ `event` ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - `event.target` -- ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์š”์†Œ - `event.currentTarget` (=`this`) -- ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋ง ํ•˜๋Š” ํ˜„์žฌ ์š”์†Œ (ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹ค์ œ ํ• ๋‹น๋œ ์š”์†Œ) -- `event.eventPhase` -- ํ˜„์žฌ ์ด๋ฒคํŠธ ํ๋ฆ„ ๋‹จ๊ณ„ (์บก์ฒ˜๋ง=1, ํƒ€๊นƒ=2, ๋ฒ„๋ธ”๋ง=3). +- `event.eventPhase` -- ํ˜„์žฌ ์ด๋ฒคํŠธ ํ๋ฆ„ ๋‹จ๊ณ„(์บก์ฒ˜๋ง=1, ํƒ€๊นƒ=2, ๋ฒ„๋ธ”๋ง=3) -ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.stopPropagation()`์„ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ ์บก์ฒ˜๋ง์ด๋‚˜ ๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถ”๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ƒ์œ„ ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์“ฐ์ผ์ง€ ํ™•์‹ค์น˜ ์•Š๋”๋ผ๋„, ์ถ”ํ›„์— ๋ฒ„๋ธ”๋ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.stopPropagation()`์„ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ๋ฉˆ์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ƒ์œ„ ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์“ฐ์ผ์ง€ ํ™•์‹ค์น˜ ์•Š๋”๋ผ๋„, ์ถ”ํ›„์— ๋ฒ„๋ธ”๋ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์บก์ฒ˜๋ง ๋‹จ๊ณ„๋Š” ๊ฑฐ์˜ ์“ฐ์ด์ง€ ์•Š๊ณ , ์ฃผ๋กœ ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์˜ ์ด๋ฒคํŠธ๋งŒ ๋‹ค๋ค„์ง‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋œ ๋ฐ๋Š” ๋…ผ๋ฆฌ์  ๋ฐฐ๊ฒฝ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -ํ˜„์‹ค์—์„œ ์‚ฌ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ง€์—ญ ๊ฒฝ์ฐฐ์ด ๋จผ์ € ์‚ฌ๊ณ ๋ฅผ ์กฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ง€์—ญ์— ๋Œ€ํ•ด ๊ฐ€์žฅ ์ž˜ ์•„๋Š” ๊ธฐ๊ด€์€ ์ง€์—ญ ๊ฒฝ์ฐฐ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€์ ์ธ ์กฐ์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ทธ ์ดํ›„์— ์ƒ์œ„ ๊ธฐ๊ด€์ด ์‚ฌ๊ฑด์„ ๋„˜๊ฒจ๋ฐ›์Šต๋‹ˆ๋‹ค. +ํ˜„์‹ค์—์„œ ์‚ฌ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ง€์—ญ ๊ฒฝ์ฐฐ์ด ๋จผ์ € ์‚ฌ๊ณ ๋ฅผ ์กฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ง€์—ญ์— ๋Œ€ํ•ด ๊ฐ€์žฅ ์ž˜ ์•„๋Š” ๊ธฐ๊ด€์€ ์ง€์—ญ ๊ฒฝ์ฐฐ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์กฐ์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ทธ ์ดํ›„์— ์ƒ์œ„ ๊ธฐ๊ด€์ด ์‚ฌ๊ฑด์„ ๋„˜๊ฒจ๋ฐ›์Šต๋‹ˆ๋‹ค. -์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋„ ์ด์™€ ๊ฐ™์€ ๋…ผ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ทธ ์š”์†Œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์‚ฌํ•ญ๊ณผ ๋ฌด์Šจ ์ผ์„ ํ•ด์•ผ ํ• ์ง€๋„ ๊ฐ€์žฅ ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • `<td>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ทธ `<td>`์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `<td>`๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ ๊ฐ€์žฅ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `<td>`๋ฅผ ๋‹ค๋ฃฐ ๊ธฐํšŒ๋ฅผ ์ด ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ๊ฐ€์žฅ ๋จผ์ € ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋„ ์ด์™€ ๊ฐ™์€ ๋…ผ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ทธ ์š”์†Œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์‚ฌํ•ญ๊ณผ ๋ฌด์Šจ ์ผ์„ ํ•ด์•ผ ํ• ์ง€ ๊ฐ€์žฅ ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. `<td>`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” `<td>`์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `<td>`๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ ๊ฐ€์žฅ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `<td>`๋ฅผ ๋‹ค๋ฃฐ ๊ธฐํšŒ๋ฅผ ์ด ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ๊ฐ€์žฅ ๋จผ์ € ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง์€ "์ด๋ฒคํŠธ ์œ„์ž„(event delegation)"์˜ ํ† ๋Œ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์œ„์ž„์€ ๊ฐ•๋ ฅํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ด๋ฅผ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง์€ '์ด๋ฒคํŠธ ์œ„์ž„(event delegation)'์˜ ํ† ๋Œ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์œ„์ž„์€ ๊ฐ•๋ ฅํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ด๋ฅผ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/index.html b/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/index.html index 8313ec29fe..27ec11362e 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/index.html +++ b/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/index.html @@ -7,7 +7,7 @@ </head> <body> - A click shows both <code>event.target</code> and <code>this</code> to compare: + ํด๋ฆญํ•˜๋ฉด <code>event.target</code>๊ณผ <code>this</code>์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <form id="form">FORM <div>DIV diff --git a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg index 580022a9fb..b62d990890 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg +++ b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="353" height="216" viewBox="0 0 353 216"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="event-order-bubbling.svg"><path id="Rectangle-210" fill="#FFDE99" d="M159.488 140L174 186H60l14.512-46z"/><path id="Rectangle-209" stroke="#CFCE95" stroke-width="18" d="M173.634 81H59.366l-16.09 51h146.447l-16.09-51z"/><path id="Rectangle-208" stroke="#99C0C3" stroke-width="18" d="M193.014 29H39.986l-22.71 72h198.448l-22.71-72z"/><path id="Fill-46" fill="#5A4739" d="M121.5 141v13.816a4.5 4.5 0 01-8.994.212l-.005-.212V141h8.998zm0-31v13h-9v-13h9zm-1.327-88.347l.189.178 17.64 17.64a4.5 4.5 0 01-6.196 6.524l-.168-.16L121.5 35.698V92h-9V35.7l-10.138 10.136a4.5 4.5 0 01-6.523-6.196l.16-.168 17.639-17.64a4.477 4.477 0 013.363-1.3 4.478 4.478 0 013.172 1.122z"/><text id="1" fill="#5A4739" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="210" y="105">1</tspan></text><text id="2" fill="#5A4739" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="185" y="136">2</tspan></text><text id="3" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="157" y="181">3</tspan></text><text id="Most-deeply-nested-e" fill="#8A704D" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold"><tspan x="233.48" y="175">Most deeply</tspan> <tspan x="221.306" y="194">nested element</tspan></text><path id="Line-30" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M179.5 177.5h30"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="353" height="216" viewBox="0 0 353 216"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="event-order-bubbling.svg"><path id="Rectangle-210" fill="#DBAF88" d="M159.488 140L174 186H60l14.512-46z"/><path id="Rectangle-209" stroke="#91C2A3" stroke-width="18" d="M173.634 81l16.09 51H43.276l16.09-51h114.267z"/><path id="Rectangle-208" stroke="#EFA39F" stroke-width="18" d="M39.986 29h153.028l22.71 72H17.276l22.71-72z"/><path id="Fill-46" fill="#166388" d="M121.5 141v13.816a4.5 4.5 0 11-9 0V141h9zm0-31v13h-9v-13h9zM117 20.53a4.471 4.471 0 013.362 1.3l17.64 17.64a4.5 4.5 0 01-6.364 6.364L121.5 35.698V92h-9V35.7l-10.138 10.136a4.5 4.5 0 11-6.363-6.364l17.639-17.64a4.477 4.477 0 013.363-1.3z"/><text id="1" fill="#643B0C" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="210" y="105">1</tspan></text><text id="2" fill="#643B0C" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="185" y="136">2</tspan></text><text id="3" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="157" y="181">3</tspan></text><text id="Most-deeply-nested-e" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold"><tspan x="233.48" y="175">Most deeply</tspan> <tspan x="221.306" y="194">nested element</tspan></text><path id="Line-30" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M179.5 177.5h30"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/02-bubbling-and-capturing/eventflow.svg b/2-ui/2-events/02-bubbling-and-capturing/eventflow.svg index e7db9bff7b..566064cd6b 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/eventflow.svg +++ b/2-ui/2-events/02-bubbling-and-capturing/eventflow.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="641" height="633" viewBox="0 0 641 633"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="eventflow.svg"><g id="eventflow" transform="translate(22 28)"><g id="nodes"><g id="Window-node" transform="translate(224.685)"><g id="Group"><path id="Rectangle-path" fill="#DCDCDC" stroke="#000" d="M0 0h134.427v34.567H0z"/><text id="Window" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="39.368" y="21.913">Window</tspan></text></g></g><g id="document-node" transform="translate(234.287 60.493)"><g id="Group"><path id="Rectangle-path" fill="#DCDCDC" stroke="#000" d="M0 0h115.223v34.567H0z"/><text id="Document" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="22.084" y="21.913">Document</tspan></text></g></g><g id="html-node" transform="translate(243.889 120.985)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<html>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><html></tspan></text></g><g id="body-node" transform="translate(243.889 181.478)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<body>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><body></tspan></text></g><g id="table-node" transform="translate(243.889 241.97)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<table>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><table></tspan></text></g><g id="tbody-node" transform="translate(243.889 302.463)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<tbody>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="19.204" y="21.913"><tbody></tspan></text></g><g id="tr_1-node" transform="translate(80.656 380.239)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<tr>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="35.527" y="21.913"><tr></tspan></text></g><g id="tr_2-node" transform="translate(426.325 380.239)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<tr>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><tr></tspan></text></g><g id="tr_1_td_1-node" transform="translate(13.443 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<td>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="31.686" y="21.913"><td></tspan></text></g><g id="tr_1_td_1_text-node" transform="translate(0 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#4682B4" stroke="#000" rx="61.452" ry="30.246"/><text id="Shady-Grove" fill="#FFF" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="19.204" y="34.604">Shady Grove</tspan></text></g><g id="tr_1_td_2-node" transform="translate(147.87 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<td>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><td></tspan></text></g><g id="tr_1_td_2_text-node" transform="translate(134.427 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#4682B4" stroke="#000" rx="61.452" ry="30.246"/><text id="Aeolian" fill="#FFF" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="36.967" y="34.604">Aeolian</tspan></text></g><g id="tr_2_td_1-node" transform="translate(359.111 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#00F" stroke="#000" rx="5"/><text id="<td>" fill="#FFF" font-family="PTMono-Regular, PT Mono" font-size="15.555" font-weight="normal"><tspan x="27.846" y="22.37"><td></tspan></text></g><g id="tr_2_td_1_text-node" transform="translate(345.669 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#4682B4" stroke="#000" rx="61.452" ry="30.246"/><g id="Group" fill="#FFF" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal" transform="translate(12.482 14.555)"><text id="Over-the-River,"><tspan x=".48" y="14">Over the River,</tspan></text><text id="Charlie"><tspan x="25.925" y="31.284">Charlie</tspan></text></g></g><g id="tr_2_td_2-node" transform="translate(493.538 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#87CEFA" stroke="#000" rx="5"/><text id="<td>" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><td></tspan></text></g><g id="tr_2_td_2_text-node" transform="translate(480.096 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#4682B4" stroke="#000" rx="61.452" ry="30.246"/><text id="Dorian" fill="#FFF" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="39.848" y="34.604">Dorian</tspan></text></g></g><g id="edges" stroke="#000" stroke-width="2" transform="translate(61.452 34.567)"><path id="window-document" fill="#000" d="M230.446 0v19.876"/><path id="document-html" fill="#000" d="M230.446 60.493v19.876"/><path id="html-body" fill="#000" d="M230.446 120.985v19.876"/><path id="body-table" fill="#000" d="M230.446 181.478v19.876"/><path id="table-tbody" fill="#000" d="M230.446 241.97v19.876"/><path id="tbody-tr_1" d="M230.446 302.463c0 11.522-16.003 17.283-48.01 17.283H86.417c-12.802 0-19.204 6.626-19.204 19.876"/><path id="tbody-tr_2" d="M230.446 302.463c0 11.522 22.404 17.283 67.213 17.283h96.02c12.802 0 19.203 6.626 19.203 19.876"/><path id="tr_1-tr_2_td_1" d="M67.213 380.239c0 11.522-6.4 17.283-19.203 17.283H19.204C6.4 397.522 0 404.148 0 417.4"/><path id="tr_1-tr_2_td_2" d="M67.213 380.239c0 11.522 6.402 17.283 19.204 17.283h28.806c12.802 0 19.204 6.626 19.204 19.877"/><path id="tr_2-tr_2_td_1" d="M412.882 380.239c0 11.522-6.401 17.283-19.204 17.283h-28.805c-12.803 0-19.204 6.626-19.204 19.877"/><path id="tr_2-tr_2_td_2" d="M412.882 380.239c0 11.522 12.803 17.283 38.408 17.283h9.602c12.802 0 19.204 6.626 19.204 19.877"/><path id="tr_1_td_1-text" fill="#000" d="M0 458.015v19.876"/><path id="tr_1_td_2-text" fill="#000" d="M134.427 458.015v19.876"/><path id="tr_2_td_1-text" fill="#000" d="M345.669 458.015v19.876"/><path id="tr_2_td_2-text" fill="#000" d="M482.016 458.015v19.876"/></g><g id="event-flow" transform="translate(103.7 14.691)"><g id="target_phase" transform="translate(186.277 443.324)"><text id="Target" fill="#00F" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x=".96" y="34.148">Target</tspan></text><text id="Phase" fill="#00F" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x=".48" y="51.431">Phase</tspan></text><text id="(2)" fill="#00F" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="15.843" y="68.715">(2)</tspan></text><rect id="Rectangle-path" width="96.019" height="34.567" x="69.134" y="0" stroke="#000" stroke-width="5" rx="5"/></g><g id="capture_phase"><text id="Capture" fill="red" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="0" y="166.367">Capture</tspan></text><text id="Phase" fill="red" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="7.201" y="183.651">Phase</tspan></text><text id="(1)" fill="red" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="22.564" y="200.934">(1)</tspan></text><path id="capture_phase_arrow" stroke="red" stroke-width="3" d="M116.183.864c-38.408-2.592-38.408 40.617 2.88 49.258"/><g id="capture_phase_arrow-link" stroke="red" stroke-width="3" transform="translate(92.178 60.493)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="red" stroke-width="3" transform="translate(96.98 120.985)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="red" stroke-width="3" transform="translate(96.98 181.478)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="red" stroke-width="3" transform="translate(96.98 241.97)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><path id="capture_phase_arrow2" stroke="red" stroke-width="3" d="M125.785 303.327c-38.408-2.593-38.408 82.097 175.715 69.134"/><path id="capture_phase_arrow3" stroke="red" stroke-width="3" d="M301.5 385.424c-94.099-2.593-94.099 51.85-62.412 64.813"/></g><g id="bubble_phase" transform="translate(250.61 12.963)"><text id="Bubbling" fill="green" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="72.975" y="239.822">Bubbling</tspan></text><text id="Phase" fill="green" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="83.057" y="257.106">Phase</tspan></text><text id="(3)" fill="green" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="98.42" y="274.39">(3)</tspan></text><path id="bubble_phase_arrow3" stroke="green" stroke-width="3" d="M112.342 437.275c132.507-56.172 132.507-67.406 67.214-64.814"/><path id="bubble_phase_arrow2" stroke="green" stroke-width="3" d="M182.436 358.634c38.408-8.641 38.408-50.986-180.516-59.628"/><path id="bubble_phase_arrow" stroke="green" stroke-width="3" d="M0 287.772c38.408-2.593 38.408-37.16 0-45.802"/><g id="bubble_phase_arrow-link" stroke="green" stroke-width="3" transform="translate(0 181.478)"><path id="bubble_phase_arrow" d="M0 45.801C38.408 43.21 38.408 8.641 0 0"/></g><g id="bubble_phase_arrow-link" stroke="green" stroke-width="3" transform="translate(0 120.985)"><path id="bubble_phase_arrow" d="M0 45.801C38.408 43.21 38.408 8.641 0 0"/></g><path id="bubble_phase_arrow4" stroke="green" stroke-width="3" d="M0 106.294c48.01-2.593 48.01-37.16 9.602-45.801"/><path id="bubble_phase_arrow" stroke="green" stroke-width="3" d="M9.602 45.801C57.612 43.21 57.612 8.641 19.204 0"/></g></g></g></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="641" height="633" viewBox="0 0 641 633"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="eventflow" transform="translate(22 28)"><g id="nodes"><g id="Group" transform="translate(224.685)"><path id="Rectangle-path" fill="#D1CFCD" stroke="#181717" d="M0 0h134.427v34.567H0z"/><text id="Window" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="39.368" y="21.913">Window</tspan></text></g><g id="Group" transform="translate(234.287 60.493)"><path id="Rectangle-path" fill="#D1CFCD" stroke="#181717" d="M0 0h115.223v34.567H0z"/><text id="Document" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="22.084" y="21.913">Document</tspan></text></g><g id="html-node" transform="translate(243.889 120.985)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<html>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><html></tspan></text></g><g id="body-node" transform="translate(243.889 181.478)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<body>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><body></tspan></text></g><g id="table-node" transform="translate(243.889 241.97)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<table>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="23.045" y="21.913"><table></tspan></text></g><g id="tbody-node" transform="translate(243.889 302.463)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<tbody>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="19.204" y="21.913"><tbody></tspan></text></g><g id="tr_1-node" transform="translate(80.656 380.239)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<tr>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="35.527" y="21.913"><tr></tspan></text></g><g id="tr_2-node" transform="translate(426.325 380.239)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<tr>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><tr></tspan></text></g><g id="tr_1_td_1-node" transform="translate(13.443 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<td>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="31.686" y="21.913"><td></tspan></text></g><g id="tr_1_td_1_text-node" transform="translate(0 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#1C85B5" stroke="#181717" rx="61.452" ry="30.246"/><text id="Shady-Grove" fill="#FFF" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="19.204" y="34.604">Shady Grove</tspan></text></g><g id="tr_1_td_2-node" transform="translate(147.87 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<td>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><td></tspan></text></g><g id="tr_1_td_2_text-node" transform="translate(134.427 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#1C85B5" stroke="#181717" rx="61.452" ry="30.246"/><text id="Aeolian" fill="#FFF" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="36.967" y="34.604">Aeolian</tspan></text></g><g id="tr_2_td_1-node" transform="translate(359.111 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#FFF" stroke="#181717" rx="5"/><text id="<td>" fill="#C06334" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="15.555" font-weight="normal"><tspan x="27.846" y="22.37"><td></tspan></text></g><g id="tr_2_td_1_text-node" transform="translate(345.669 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#1C85B5" stroke="#181717" rx="61.452" ry="30.246"/><g id="Group" fill="#FFF" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal" transform="translate(12.482 14.555)"><text id="Over-the-River,"><tspan x=".48" y="14">Over the River,</tspan></text><text id="Charlie"><tspan x="25.925" y="31.284">Charlie</tspan></text></g></g><g id="tr_2_td_2-node" transform="translate(493.538 458.015)"><rect id="Rectangle-path" width="96.019" height="34.567" x="0" y="0" fill="#C9DCEA" stroke="#181717" rx="5"/><text id="<td>" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="15.555" font-weight="normal"><tspan x="33.607" y="21.913"><td></tspan></text></g><g id="tr_2_td_2_text-node" transform="translate(480.096 518.507)"><ellipse id="Oval" cx="61.452" cy="30.246" fill="#1C85B5" stroke="#181717" rx="61.452" ry="30.246"/><text id="Dorian" fill="#FFF" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="12.963" font-weight="normal"><tspan x="39.848" y="34.604">Dorian</tspan></text></g></g><g id="edges" stroke="#7E7C7B" stroke-width="2" transform="translate(61.452 34.567)"><path id="window-document" fill="#7E7C7B" d="M230.446 0v19.876"/><path id="document-html" fill="#7E7C7B" d="M230.446 60.493v19.876"/><path id="html-body" fill="#7E7C7B" d="M230.446 120.985v19.876"/><path id="body-table" fill="#7E7C7B" d="M230.446 181.478v19.876"/><path id="table-tbody" fill="#7E7C7B" d="M230.446 241.97v19.876"/><path id="tbody-tr_1" d="M230.446 302.463c0 11.522-16.003 17.283-48.01 17.283H86.417c-12.802 0-19.204 6.626-19.204 19.876"/><path id="tbody-tr_2" d="M230.446 302.463c0 11.522 22.404 17.283 67.213 17.283h96.02c12.802 0 19.203 6.626 19.203 19.876"/><path id="tr_1-tr_2_td_1" d="M67.213 380.239c0 11.522-6.4 17.283-19.203 17.283H19.204C6.4 397.522 0 404.148 0 417.4"/><path id="tr_1-tr_2_td_2" d="M67.213 380.239c0 11.522 6.402 17.283 19.204 17.283h28.806c12.802 0 19.204 6.626 19.204 19.877"/><path id="tr_2-tr_2_td_1" d="M412.882 380.239c0 11.522-6.401 17.283-19.204 17.283h-28.805c-12.803 0-19.204 6.626-19.204 19.877"/><path id="tr_2-tr_2_td_2" d="M412.882 380.239c0 11.522 12.803 17.283 38.408 17.283h9.602c12.802 0 19.204 6.626 19.204 19.877"/><path id="tr_1_td_1-text" fill="#7E7C7B" d="M0 458.015v19.876"/><path id="tr_1_td_2-text" fill="#7E7C7B" d="M134.427 458.015v19.876"/><path id="tr_2_td_1-text" fill="#7E7C7B" d="M345.669 458.015v19.876"/><path id="tr_2_td_2-text" fill="#7E7C7B" d="M482.016 458.015v19.876"/></g><g id="event-flow" transform="translate(103.7 15.443)"><g id="target_phase" transform="translate(186.757 442.572)"><text id="Target" fill="#C06334" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x=".48" y="34.148">Target</tspan></text><text id="Phase" fill="#C06334" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="0" y="51.431">Phase</tspan></text><text id="(2)" fill="#C06334" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="15.363" y="68.715">(2)</tspan></text><rect id="Rectangle-path" width="96.019" height="34.567" x="68.654" y="0" stroke="#C06334" stroke-width="4" rx="5"/></g><g id="capture_phase"><text id="Capture" fill="#D35155" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="0" y="165.615">Capture</tspan></text><text id="Phase" fill="#D35155" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="7.201" y="182.899">Phase</tspan></text><text id="(1)" fill="#D35155" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="22.564" y="200.182">(1)</tspan></text><path id="capture_phase_arrow" stroke="#D35155" stroke-width="3" d="M116.183.112c-38.408-2.593-38.408 40.616 2.88 49.258"/><g id="capture_phase_arrow-link" stroke="#D35155" stroke-width="3" transform="translate(92.178 59.74)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="#D35155" stroke-width="3" transform="translate(96.98 120.233)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="#D35155" stroke-width="3" transform="translate(96.98 180.725)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><g id="capture_phase_arrow-link" stroke="#D35155" stroke-width="3" transform="translate(96.98 241.218)"><path id="capture_phase_arrow" d="M28.806.864c-38.408-2.592-38.408 40.617 2.88 49.258"/></g><path id="capture_phase_arrow2" stroke="#D35155" stroke-width="3" d="M125.785 302.575c-38.408-2.593-38.408 82.097 175.715 69.134"/><path id="capture_phase_arrow3" stroke="#D35155" stroke-width="3" d="M301.5 384.672c-94.099-2.593-94.099 51.85-62.412 64.813"/></g><g id="bubble_phase" transform="translate(250.61 12.21)"><text id="Bubbling" fill="#478964" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="72.975" y="239.822">Bubbling</tspan></text><text id="Phase" fill="#478964" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="83.057" y="257.106">Phase</tspan></text><text id="(3)" fill="#478964" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="17.284" font-weight="normal"><tspan x="98.42" y="274.39">(3)</tspan></text><path id="bubble_phase_arrow3" stroke="#478964" stroke-width="3" d="M112.342 437.275c132.507-56.172 132.507-67.406 67.214-64.814"/><path id="bubble_phase_arrow2" stroke="#478964" stroke-width="3" d="M182.436 358.634c38.408-8.641 38.408-50.986-180.516-59.628"/><path id="bubble_phase_arrow" stroke="#478964" stroke-width="3" d="M0 287.772c38.408-2.593 38.408-37.16 0-45.802"/><g id="bubble_phase_arrow-link" stroke="#478964" stroke-width="3" transform="translate(0 181.478)"><path id="bubble_phase_arrow" d="M0 45.801C38.408 43.21 38.408 8.641 0 0"/></g><g id="bubble_phase_arrow-link" stroke="#478964" stroke-width="3" transform="translate(0 120.985)"><path id="bubble_phase_arrow" d="M0 45.801C38.408 43.21 38.408 8.641 0 0"/></g><path id="bubble_phase_arrow4" stroke="#478964" stroke-width="3" d="M0 106.294c48.01-2.593 48.01-37.16 9.602-45.801"/><path id="bubble_phase_arrow" stroke="#478964" stroke-width="3" d="M9.602 45.801C57.612 43.21 57.612 8.641 19.204 0"/></g></g></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/source.view/index.html b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/source.view/index.html index 8a9ed9a09b..0e9dcf1e6b 100644 --- a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/source.view/index.html +++ b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/source.view/index.html @@ -28,7 +28,7 @@ <h3>Cat</h3> </div> <script> - // ...your code... + // ...์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”... </script> </body> diff --git a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md index 62c0a8ab00..9e09f382f7 100644 --- a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md +++ b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md @@ -2,12 +2,12 @@ importance: 5 --- -# Hide messages with delegation +# ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•ด์„œ ๋ฉ”์‹œ์ง€ ์ˆจ๊ธฐ๊ธฐ -There's a list of messages with removal buttons `[x]`. Make the buttons work. +๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก์ด ์žˆ๊ณ  ๊ฐ ๋ฉ”์‹œ์ง€์—” ์‚ญ์ œ ๋ฒ„ํŠผ(`[x]`)์ด ์žˆ์Šต๋‹ˆ๋‹ค. -Like this: +์˜ˆ์‹œ: [iframe src="solution" height=420] -P.S. Should be only one event listener on the container, use event delegation. +P.S. ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•ด์„œ ๋‹จ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋งŒ์œผ๋กœ๋„ ์‚ญ์ œ ๋ฒ„ํŠผ์ด ๋™์ž‘ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด๋ณด์„ธ์š”. diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md index 09c14a08c1..7ff4d0a5ee 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md @@ -1,4 +1,4 @@ -The solution has two parts. +ํ•ด๋‹ต์€ ๋‘ ํŒŒํŠธ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. -1. Wrap every tree node title into `<span>`. Then we can CSS-style them on `:hover` and handle clicks exactly on text, because `<span>` width is exactly the text width (unlike without it). -2. Set a handler to the `tree` root node and handle clicks on that `<span>` titles. +1. ํŠธ๋ฆฌ์— ์žˆ๋Š” ๋ชจ๋“  ํ…์ŠคํŠธ๋ฅผ `<span>`์ด ๊ฐ์‹ธ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด CSS `:hover`๋ฅผ ์‚ฌ์šฉํ•ด ๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์‹œ ๊ธ€์”จ๋ฅผ ๊ตด๊ฒŒ ํ•ด์ฃผ๋Š” ํšจ๊ณผ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ณ  `<span>`์ด ์ฐจ์ง€ํ•˜๋Š” ๋„ˆ๋น„๊ฐ€ ํ…์ŠคํŠธ์˜ ๋„ˆ๋น„์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…์ŠคํŠธ์—๋งŒ ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋™์ž‘ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +2. ๋ฃจํŠธ ๋…ธ๋“œ์ธ `tree`์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ `<span>`์œผ๋กœ ๊ฐ์‹ผ ํ…์ŠคํŠธ์—๋งŒ ๋™์ž‘ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.view/index.html b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.view/index.html index 0e85e457e5..b7e2ee8547 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.view/index.html +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.view/index.html @@ -54,15 +54,14 @@ </ul> <script> - // move all text into <span> - // they occupy exactly the place necessary for the text, + // ํ…์ŠคํŠธ ์ „๋ถ€๋ฅผ <span>์ด ๊ฐ์‹ธ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. for (let li of tree.querySelectorAll('li')) { let span = document.createElement('span'); li.prepend(span); - span.append(span.nextSibling); // move the text node into span + span.append(span.nextSibling); // ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ span ์•ˆ์œผ๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค. } - // catch clicks on whole tree + // ํŠธ๋ฆฌ ์ „์ฒด์˜ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. tree.onclick = function(event) { if (event.target.tagName != 'SPAN') { @@ -70,7 +69,7 @@ } let childrenContainer = event.target.parentNode.querySelector('ul'); - if (!childrenContainer) return; // no children + if (!childrenContainer) return; // ์ž์† ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ childrenContainer.hidden = !childrenContainer.hidden; } diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/source.view/index.html b/2-ui/2-events/03-event-delegation/2-sliding-tree/source.view/index.html index 8572517f24..a4e0eafd9c 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/source.view/index.html +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/source.view/index.html @@ -42,5 +42,9 @@ </li> </ul> + <script> + // ...์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”... + </script> + </body> </html> diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md b/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md index bdcf2a510b..3aa79e4d5c 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md @@ -2,13 +2,14 @@ importance: 5 --- -# Tree menu +# ํŠธ๋ฆฌ ๋ฉ”๋‰ด ๊ตฌํ˜„ํ•˜๊ธฐ -Create a tree that shows/hides node children on click: +๋…ธ๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ž์† ๋…ธ๋“œ๊ฐ€ ๋ณด์ด๊ฑฐ๋‚˜ ์ˆจ๊ฒจ์ง€๋Š” ํŠธ๋ฆฌ ๋ฉ”๋‰ด๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์„ธ์š”. [iframe border=1 src="solution"] -Requirements: +๊ตฌ์ฒด์ ์ธ ์š”๊ตฌ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- Only one event handler (use delegation) -- A click outside the node title (on an empty space) should not do anything. +- ๋‹จ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ(์ด๋ฒคํŠธ ์œ„์ž„ ์‚ฌ์šฉํ•˜๊ธฐ) + +- ๋…ธ๋“œ(ํ…์ŠคํŠธ) ๋ฐ”๊นฅ(๋นˆ ๊ณณ)์„ ํด๋ฆญํ•˜๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/03-event-delegation/3-sortable-table/solution.view/index.html b/2-ui/2-events/03-event-delegation/3-sortable-table/solution.view/index.html index d5d2d640ba..0dce1642c0 100644 --- a/2-ui/2-events/03-event-delegation/3-sortable-table/solution.view/index.html +++ b/2-ui/2-events/03-event-delegation/3-sortable-table/solution.view/index.html @@ -25,30 +25,30 @@ <table id="grid"> <thead> <tr> - <th data-type="number">Age</th> - <th data-type="string">Name</th> + <th data-type="number">๋‚˜์ด</th> + <th data-type="string">์ด๋ฆ„</th> </tr> </thead> <tbody> <tr> <td>5</td> - <td>John</td> + <td>์ผ๋ฆฌ์•ผ</td> </tr> <tr> <td>2</td> - <td>Pete</td> + <td>๋ณด๋ผ</td> </tr> <tr> <td>12</td> - <td>Ann</td> + <td>ํ˜ธ์ง„</td> </tr> <tr> <td>9</td> - <td>Eugene</td> + <td>์ง€๋ฏผ</td> </tr> <tr> <td>1</td> - <td>Ilya</td> + <td>์žฌ์ธ</td> </tr> </tbody> </table> @@ -59,10 +59,10 @@ if (e.target.tagName != 'TH') return; let th = e.target; - // if TH, then sort - // cellIndex is the number of th: - // 0 for the first column - // 1 for the second column, etc + // ํด๋ฆญํ•œ ์š”์†Œ๊ฐ€ TH๋ผ๋ฉด ์ •๋ ฌ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + // cellIndex๋Š” ๋ช‡ ๋ฒˆ์งธ ์—ด์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธ๋ฑ์Šค ๊ฐ’์ž…๋‹ˆ๋‹ค. + // ์ฒซ ๋ฒˆ์งธ ์—ด์ด๋ผ๋ฉด 0, + // ๋‘ ๋ฒˆ์งธ ์—ด์ด๋ผ๋ฉด 1์ด ๋ฉ๋‹ˆ๋‹ค. sortGrid(th.cellIndex, th.dataset.type); }; @@ -71,7 +71,7 @@ let rowsArray = Array.from(tbody.rows); - // compare(a, b) compares two rows, need for sorting + // ๋ณ€์ˆ˜ compare์— ํ• ๋‹นํ•  ํ•จ์ˆ˜ compare(a, b)๋Š” ๋‘ ํ–‰์„ ๋น„๊ตํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ์ •๋ ฌ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. let compare; switch (type) { @@ -87,7 +87,7 @@ break; } - // sort + // ํ•ด๋‹น ์—ด์„ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค. rowsArray.sort(compare); tbody.append(...rowsArray); diff --git a/2-ui/2-events/03-event-delegation/3-sortable-table/source.view/index.html b/2-ui/2-events/03-event-delegation/3-sortable-table/source.view/index.html index 8fac06246f..dcc8bbc14c 100644 --- a/2-ui/2-events/03-event-delegation/3-sortable-table/source.view/index.html +++ b/2-ui/2-events/03-event-delegation/3-sortable-table/source.view/index.html @@ -25,36 +25,36 @@ <table id="grid"> <thead> <tr> - <th data-type="number">Age</th> - <th data-type="string">Name</th> + <th data-type="number">๋‚˜์ด</th> + <th data-type="string">์ด๋ฆ„</th> </tr> </thead> <tbody> <tr> <td>5</td> - <td>John</td> + <td>์ผ๋ฆฌ์•ผ</td> </tr> <tr> <td>2</td> - <td>Pete</td> + <td>๋ณด๋ผ</td> </tr> <tr> <td>12</td> - <td>Ann</td> + <td>ํ˜ธ์ง„</td> </tr> <tr> <td>9</td> - <td>Eugene</td> + <td>๋ฏผ์ง€</td> </tr> <tr> <td>1</td> - <td>Ilya</td> + <td>ํ˜ธ์„</td> </tr> </tbody> </table> <script> - // ...your code... + // ...์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”... </script> </body> diff --git a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md index ec85a473c8..c0290a0a59 100644 --- a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md +++ b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md @@ -2,42 +2,42 @@ importance: 4 --- -# Sortable table +# ์ •๋ ฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํ‘œ -Make the table sortable: clicks on `<th>` elements should sort it by corresponding column. +์—ด ์ œ๋ชฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์š”์†Œ์ธ `<th>`๋ฅผ ํด๋ฆญํ•˜๋ฉด ์—ด ์ „์ฒด๊ฐ€ ์ •๋ ฌ๋˜๋Š” ํ‘œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. -Each `<th>` has the type in the attribute, like this: +๋ชจ๋“  `<th>` ์†์„ฑ์—” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ์ดํ„ฐ์˜ ํƒ€์ž…์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ```html <table id="grid"> <thead> <tr> *!* - <th data-type="number">Age</th> - <th data-type="string">Name</th> + <th data-type="number">๋‚˜์ด</th> + <th data-type="string">์ด๋ฆ„</th> */!* </tr> </thead> <tbody> <tr> <td>5</td> - <td>John</td> + <td>์ผ๋ฆฌ์•ผ</td> </tr> <tr> <td>10</td> - <td>Ann</td> + <td>๋ณด๋ผ</td> </tr> ... </tbody> </table> ``` -In the example above the first column has numbers, and the second one -- strings. The sorting function should handle sort according to the type. +์œ„ ์˜ˆ์‹œ์—์„  ์ฒซ ๋ฒˆ์งธ ์—ด์—” ์ˆซ์ž๊ฐ€, ๋‘ ๋ฒˆ์งธ ์—ด์—” ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ๊ตฌํ˜„ํ•  ์ •๋ ฌ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ๋งž๊ฒŒ ์ •๋ ฌ์„ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Only `"string"` and `"number"` types should be supported. +์ด ๋ฌธ์ œ์—์„  `'์ˆซ์ž'`์™€ `'๋ฌธ์ž์—ด'` ํƒ€์ž…๋งŒ ๋‹ค๋ฃฌ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -The working example: +์ œ๋Œ€๋กœ ํ•ด๋‹ต์„ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [iframe border=1 src="solution" height=190] -P.S. The table can be big, with any number of rows and columns. +P.S. ํ‘œ ํฌ๊ธฐ๋Š” ์˜ˆ์‹œ๋ณด๋‹ค ํ›จ์”ฌ ํด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ด์ด๋‚˜ ํ–‰์ด ๋” ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ๋‹ต์„ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”. diff --git a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/solution.view/index.html b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/solution.view/index.html index 1ef37cdc90..f80f6f870f 100644 --- a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/solution.view/index.html +++ b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/solution.view/index.html @@ -6,7 +6,7 @@ <style> body { height: 2000px; - /* make body scrollable, the tooltip should work after the scroll */ + /* body ๋†’์ด๋ฅผ ์ผ๋ถ€๋Ÿฌ ํ‚ค์›Œ์„œ ์Šคํฌ๋กค์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค ์œ„์น˜์— ์ƒ๊ด€์—†์ด ์š”๊ตฌ์‚ฌํ•ญ๋Œ€๋กœ ํˆดํŒ์ด ๋‚˜ํƒ€๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.*/ } .tooltip { @@ -25,13 +25,13 @@ <body> - <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p> - <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p> + <p>๋™ํ•ด๋ฌผ๊ณผ ๋ฐฑ๋‘์‚ฐ์ด ๋งˆ๋ฅด๊ณ  ๋‹ณ๋„๋ก ํ•˜๋А๋‹˜์ด ๋ณด์šฐํ•˜์‚ฌ ์šฐ๋ฆฌ๋‚˜๋ผ ๋งŒ์„ธ</p> + <p>๋ฌด๊ถํ™” ์‚ผ์ฒœ๋ฆฌ ํ™”๋ ค๊ฐ•์‚ฐ ๋Œ€ํ•œ์‚ฌ๋žŒ ๋Œ€ํ•œ์œผ๋กœ ๊ธธ์ด ๋ณด์ „ํ•˜์„ธ</p> - <button data-tooltip="the tooltip is longer than the element">Short button</button> - <button data-tooltip="HTML<br>tooltip">One more button</button> + <button data-tooltip="๋ฒ„ํŠผ ์š”์†Œ ๊ธธ์ด๋ณด๋‹ค ํˆดํŒ ๊ธธ์ด๊ฐ€ ํ›จ์”ฌ ๊ธฐ๋„ค์š”.">์งง์€ ๋ฒ„ํŠผ</button> + <button data-tooltip="๋‘ ์ค„์งœ๋ฆฌ<br>ํˆดํŒ">...๋˜ ๋‹ค๋ฅธ ๋ฒ„ํŠผ...</button> - <p>Scroll the page to make buttons appear on the top, check if the tooltips show up correctly.</p> + <p>๋ฒ„ํŠผ์ด ํ™”๋ฉด ๋งจ ์œ„์ชฝ์— ์œ„์น˜ํ•˜๋„๋ก ์Šคํฌ๋กค์„ ์›€์ง์—ฌ๋ณด๊ณ , ๊ทธ ์ƒํƒœ์—์„œ ํˆดํŒ์ด ์ œ๋Œ€๋กœ ๋ฒ„ํŠผ ์•„๋ž˜์— ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์„ธ์š”.</p> <script> @@ -40,25 +40,25 @@ document.onmouseover = function(event) { let target = event.target; - // if we have tooltip HTML... + // data-tooltip ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ let tooltipHtml = target.dataset.tooltip; if (!tooltipHtml) return; - // ...create the tooltip element + // ํˆดํŒ ์š”์†Œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. tooltipElem = document.createElement('div'); tooltipElem.className = 'tooltip'; tooltipElem.innerHTML = tooltipHtml; document.body.append(tooltipElem); - // position it above the annotated element (top-center) + // ํˆดํŒ ์š”์†Œ๋ฅผ data-tooltip ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ ์œ„, ๊ฐ€์šด๋ฐ์— ์œ„์น˜์‹œํ‚ต๋‹ˆ๋‹ค. let coords = target.getBoundingClientRect(); let left = coords.left + (target.offsetWidth - tooltipElem.offsetWidth) / 2; - if (left < 0) left = 0; // don't cross the left window edge + if (left < 0) left = 0; // ํˆดํŒ์ด ์ฐฝ ์™ผ์ชฝ ๊ฐ€์žฅ์ž๋ฆฌ๋ฅผ ๋„˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. let top = coords.top - tooltipElem.offsetHeight - 5; - if (top < 0) { // if crossing the top window edge, show below instead + if (top < 0) { // ํˆดํŒ์ด ์ฐฝ ์œ„๋กœ ๋„˜์น˜๋ฉด ์š”์†Œ ์•„๋ž˜์— ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. top = coords.top + target.offsetHeight + 5; } diff --git a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/source.view/index.html b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/source.view/index.html index add3b21442..ce76327aab 100644 --- a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/source.view/index.html +++ b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/source.view/index.html @@ -6,11 +6,11 @@ <style> body { height: 2000px; - /* make body scrollable, the tooltip should work after the scroll */ + /* body ๋†’์ด๋ฅผ ์ผ๋ถ€๋Ÿฌ ํ‚ค์›Œ์„œ ์Šคํฌ๋กค์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค ์œ„์น˜์— ์ƒ๊ด€์—†์ด ์š”๊ตฌ์‚ฌํ•ญ๋Œ€๋กœ ํˆดํŒ์ด ๋‚˜ํƒ€๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.*/ } .tooltip { - /* some styles for the tooltip, you can use your own instead */ + /* ํˆดํŒ์„ ๊พธ๋ฉฐ์ฃผ๊ธฐ ์œ„ํ•œ CSS์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์›ํ•˜๋ฉด ์ˆ˜์ •ํ•ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. */ position: fixed; padding: 10px 20px; border: 1px solid #b3c9ce; @@ -26,17 +26,17 @@ <body> - <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p> - <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p> + <p>๋™ํ•ด๋ฌผ๊ณผ ๋ฐฑ๋‘์‚ฐ์ด ๋งˆ๋ฅด๊ณ  ๋‹ณ๋„๋ก ํ•˜๋А๋‹˜์ด ๋ณด์šฐํ•˜์‚ฌ ์šฐ๋ฆฌ๋‚˜๋ผ ๋งŒ์„ธ</p> + <p>๋ฌด๊ถํ™” ์‚ผ์ฒœ๋ฆฌ ํ™”๋ ค๊ฐ•์‚ฐ ๋Œ€ํ•œ์‚ฌ๋žŒ ๋Œ€ํ•œ์œผ๋กœ ๊ธธ์ด ๋ณด์ „ํ•˜์„ธ</p> - <button data-tooltip="the tooltip is longer than the element">Short button</button> - <button data-tooltip="HTML<br>tooltip">One more button</button> + <button data-tooltip="๋ฒ„ํŠผ ์š”์†Œ ๊ธธ์ด๋ณด๋‹ค ํˆดํŒ ๊ธธ์ด๊ฐ€ ํ›จ์”ฌ ๊ธฐ๋„ค์š”.">์งง์€ ๋ฒ„ํŠผ</button> + <button data-tooltip="๋‘ ์ค„์งœ๋ฆฌ<br>ํˆดํŒ">...๋˜ ๋‹ค๋ฅธ ๋ฒ„ํŠผ...</button> - <p>Scroll the page to make buttons appear on the top, check if the tooltips show up correctly.</p> + <p>๋ฒ„ํŠผ์ด ํ™”๋ฉด ๋งจ ์œ„์ชฝ์— ์œ„์น˜ํ•˜๋„๋ก ์Šคํฌ๋กค์„ ์›€์ง์—ฌ๋ณด๊ณ , ๊ทธ ์ƒํƒœ์—์„œ ํˆดํŒ์ด ์ œ๋Œ€๋กœ ๋ฒ„ํŠผ ์•„๋ž˜์— ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์„ธ์š”.</p> <script> - // ...your code... + // ...์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”... </script> </body> diff --git a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md index 73102a92b9..f61c178636 100644 --- a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md +++ b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md @@ -2,35 +2,37 @@ importance: 5 --- -# Tooltip behavior +# ํˆดํŒ ๋ณด์—ฌ์ฃผ๊ธฐ -Create JS-code for the tooltip behavior. +ํˆดํŒ(tooltip)์„ ๋ณด์—ฌ์ฃผ๋Š” JS ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค. -When a mouse comes over an element with `data-tooltip`, the tooltip should appear over it, and when it's gone then hide. +`data-tooltip` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ์— ๋งˆ์šฐ์Šค๋ฅผ ๊ฐ€์ ธ๋‹ค ๋Œ€๋ฉด ํˆดํŒ์ด ๋ณด์—ฌ์•ผ ํ•˜๊ณ , ๋งˆ์šฐ์Šค ์ปค์„œ๊ฐ€ ์š”์†Œ์—์„œ ๋– ๋‚˜๋ฉด ํˆดํŒ์ด ์‚ฌ๋ผ์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -An example of annotated HTML: +`data-tooltip` ์†์„ฑ์€ ๋‹ค์Œ HTML์ฒ˜๋Ÿผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html -<button data-tooltip="the tooltip is longer than the element">Short button</button> -<button data-tooltip="HTML<br>tooltip">One more button</button> +<button data-tooltip="๋ฒ„ํŠผ ์š”์†Œ ๊ธธ์ด๋ณด๋‹ค ํˆดํŒ ๊ธธ์ด๊ฐ€ ํ›จ์”ฌ ๊ธฐ๋„ค์š”.">์งง์€ ๋ฒ„ํŠผ</button> +<button data-tooltip="๋‘ ์ค„์งœ๋ฆฌ<br>ํˆดํŒ">...๋˜ ๋‹ค๋ฅธ ๋ฒ„ํŠผ...</button> ``` -Should work like this: +๋‹ต์„ ์ž˜ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด ์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [iframe src="solution" height=200 border=1] -In this task we assume that all elements with `data-tooltip` have only text inside. No nested tags (yet). +`data-tooltip`์ด ์žˆ๋Š” ์š”์†Œ์—” ํ…์ŠคํŠธ๋งŒ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์š”์†Œ ์•ˆ์— ๋‹ค๋ฅธ ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ์ƒ๊ฐํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ•ฉ์‹œ๋‹ค. -Details: +์ž์„ธํ•œ ์š”๊ตฌ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- The tooltip should not cross window edges. Normally it should be above the element, but if the element is at the page top and there's no space for the tooltip, then below it. -- The tooltip is given in the `data-tooltip` attribute. It can be arbitrary HTML. +- ํˆดํŒ๊ณผ ์š”์†Œ์˜ ๊ฐ„๊ฒฉ์€ `5px`์ž…๋‹ˆ๋‹ค. +- ๊ฐ€๋Šฅํ•˜๋ฉด ํˆดํŒ์€ ์š”์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ค‘์•™์— ์žˆ๋„๋ก ํ•ฉ์‹œ๋‹ค. +- ํˆดํŒ์€ ์ฐฝ ํฌ๊ธฐ๋ณด๋‹ค ์ปค์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ๋ผ๋ฉด ํˆดํŒ์€ ์š”์†Œ ์œ„์— ์žˆ์„ ํ…๋ฐ, ์š”์†Œ๊ฐ€ ์ฐฝ ๋งจ ์œ„์— ์žˆ์–ด์„œ ํˆดํŒ์„ ๋ณด์—ฌ์ค„ ๊ณต๊ฐ„์ด ์—†๋‹ค๋ฉด ํˆดํŒ์€ ์š”์†Œ ์•„๋ž˜์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. +- ํˆดํŒ์•ˆ์— ๋„์šธ ์ฝ˜ํ…์ธ ๋Š” `data-tooltip` ์†์„ฑ์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์†์„ฑ๊ฐ’์€ HTML์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -You'll need two events here: -- `mouseover` triggers when a pointer comes over an element. -- `mouseout` triggers when a pointer leaves an element. +์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ด๋ฒคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +- `mouseover` -- ์š”์†Œ ์•ˆ์œผ๋กœ ํฌ์ธํ„ฐ๊ฐ€ ์ด๋™ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ +- `mouseout`-- ์š”์†Œ ๋ฐ–์œผ๋กœ ํฌ์ธํ„ฐ๊ฐ€ ์ด๋™ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ -Please use event delegation: set up two handlers on `document` to track all "overs" and "outs" from elements with `data-tooltip` and manage tooltips from there. +์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•ด์„œ ๋‘ ๊ฐœ์˜ ํ•ธ๋“ค๋Ÿฌ๋งŒ์œผ๋กœ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์„ธ์š”. `document`์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•ด `data-tooltip` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ ์•ˆ์ด๋‚˜ ๋ฐ–์œผ๋กœ ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๊ฐ€ ์ด๋™ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ชจ๋‘ ๊ฐ์ง€ํ•˜๊ณ  ๋‘ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ํˆดํŒ์„ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ๊ฐ์ถ”์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -After the behavior is implemented, even people unfamiliar with JavaScript can add annotated elements. +์ด๋ ‡๊ฒŒ ํˆดํŒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด ๋†“์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋„ ์›ํ•˜๋Š” ์š”์†Œ์— ์‰ฝ๊ฒŒ ํˆดํŒ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. -P.S. Only one tooltip may show up at a time. +P.S. ํ•œ ๋ฒˆ์— ํ•œ ๊ฐœ์˜ ํˆดํŒ ๋งŒ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md index 33a2e42b7b..b223591eb8 100644 --- a/2-ui/2-events/03-event-delegation/article.md +++ b/2-ui/2-events/03-event-delegation/article.md @@ -3,17 +3,17 @@ ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง์„ ํ™œ์šฉํ•˜๋ฉด ๊ฐ•๋ ฅํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ํŒจํ„ด์ธ *์ด๋ฒคํŠธ ์œ„์ž„(event delegation)* ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋ฒคํŠธ ์œ„์ž„์€ ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ๋‹ค๋ค„์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ์š”์†Œ๋งˆ๋‹ค ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ , ์š”์†Œ์˜ ๊ณตํ†ต ์กฐ์ƒ์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋‹จ ํ•˜๋‚˜๋งŒ ํ• ๋‹นํ•ด๋„ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ์œ„์ž„์€ ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ๋‹ค๋ค„์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ๋งˆ๋‹ค ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ , ์š”์†Œ์˜ ๊ณตํ†ต ์กฐ์ƒ์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋‹จ ํ•˜๋‚˜๋งŒ ํ• ๋‹นํ•ด๋„ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ณตํ†ต ์กฐ์ƒ์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.target`์„ ์ด์šฉํ•˜๋ฉด, ์‹ค์ œ ์–ด๋””์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค. +๊ณตํ†ต ์กฐ์ƒ์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.target`์„ ์ด์šฉํ•˜๋ฉด ์‹ค์ œ ์–ด๋””์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค. -์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ๋‹ค์Œ์€ ๊ณ ๋Œ€ ์ค‘๊ตญ ์ฒ ํ•™๊ณผ ๊ด€๋ จ๋œ [ํŒ”๊ด˜๋„(Ba-Gua diagram)](http://en.wikipedia.org/wiki/Ba_gua) ์ž…๋‹ˆ๋‹ค. +์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ๋‹ค์Œ์€ ๊ณ ๋Œ€ ์ค‘๊ตญ ์ฒ ํ•™์—์„œ ์œ ๋ž˜ํ•œ [ํŒ”๊ด˜๋„(Ba-Gua diagram)](http://en.wikipedia.org/wiki/Ba_gua) ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆผ์„ ๋ณด์‹œ์ฃ . [iframe height=350 src="bagua" edit link] -HTML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: +HTML์€ ๋Œ€๋žต ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```html <table> @@ -21,54 +21,54 @@ HTML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: <th colspan="3"><em>Bagua</em> Chart: Direction, Element, Color, Meaning</th> </tr> <tr> - <td>...<strong>Northwest</strong>...</td> - <td>...</td> - <td>...</td> + <td class="nw"><strong>Northwest</strong><br>Metal<br>Silver<br>Elders</td> + <td class="n">...</td> + <td class="ne">...</td> </tr> <tr>...2 more lines of this kind...</tr> <tr>...2 more lines of this kind...</tr> </table> ``` -์ง€๊ธˆ ๋ณด๋Š” ํ‘œ์—๋Š” 9๊ฐœ์˜ ์นธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์นธ์ด 99๊ฐœ์ด๋“  9999๊ฐœ์ด๋“  ์ƒ๊ด€์—†์ด ์ด๋ฒคํŠธ ์œ„์ž„์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ง€๊ธˆ ๋ณด๋Š” ํ‘œ์—๋Š” 9๊ฐœ์˜ ์นธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์นธ์ด 99๊ฐœ์ด๋“  9,999๊ฐœ์ด๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. -**์šฐ๋ฆฌ๊ฐ€ ํ•  ์ž‘์—…์€ `<td>`๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, ๊ทธ ์นธ์„ ๊ฐ•์กฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.** +**์ง€๊ธˆ ํ•ด์•ผ ํ•  ์ž‘์—…์€ `<td>`๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, ๊ทธ ์นธ์„ ๊ฐ•์กฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.** -์ด๋ฅผ ์œ„ํ•ด ๊ฐ `<td>`๋งˆ๋‹ค `onclick` ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋Œ€์‹ , `<table>` ์š”์†Œ์— "๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์žก์•„๋‚ด๋Š”(catch-all)" ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +๊ฐ `<td>`๋งˆ๋‹ค `onclick` ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋Œ€์‹ , '๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์žก์•„๋‚ด๋Š”' ํ•ธ๋“ค๋Ÿฌ๋ฅผ `<table>` ์š”์†Œ์— ํ• ๋‹นํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -์ด ํ•ธ๋“ค๋Ÿฌ๋Š” `event.target`์„ ์ด์šฉํ•ด ์–ด๋–ค ์š”์†Œ๊ฐ€ ํด๋ฆญ ๋˜์—ˆ๋Š”์ง€ ๊ฐ์ง€ํ•˜๊ณ , ํ•ด๋‹น ์นธ์„ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. +`<table>` ์š”์†Œ์— ํ• ๋‹นํ•˜๊ฒŒ ๋  ํ•ธ๋“ค๋Ÿฌ๋Š” `event.target`์„ ์ด์šฉํ•ด ์–ด๋–ค ์š”์†Œ๊ฐ€ ํด๋ฆญ ๋˜์—ˆ๋Š”์ง€ ๊ฐ์ง€ํ•˜๊ณ , ํ•ด๋‹น ์นธ์„ ๊ฐ•์กฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค: +์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let selectedTd; *!* table.onclick = function(event) { - let target = event.target; // ํด๋ฆญ์ด ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ๋‚˜? + let target = event.target; // ํด๋ฆญ์ด ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ์„๊นŒ์š”? - if (target.tagName != 'TD') return; // TD์—์„œ ๋ฐœ์ƒํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด? ์•„๋ฌด ์ž‘์—…๋„ ์•ˆ ํ•จ + if (target.tagName != 'TD') return; // TD์—์„œ ๋ฐœ์ƒํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ฌด ์ž‘์—…๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค, - highlight(target); // ๊ฐ•์กฐํ•ด์คŒ + highlight(target); // ๊ฐ•์กฐ ํ•จ }; */!* function highlight(td) { - if (selectedTd) { // ๊ฐ•์กฐ๋œ ์นธ์„ ์›์ƒํƒœ๋กœ ๋ฐ”๊ฟ”์คŒ + if (selectedTd) { // ์ด๋ฏธ ๊ฐ•์กฐ๋˜์–ด์žˆ๋Š” ์นธ์ด ์žˆ๋‹ค๋ฉด ์›์ƒํƒœ๋กœ ๋ฐ”๊ฟ”์คŒ selectedTd.classList.remove('highlight'); } selectedTd = td; - selectedTd.classList.add('highlight'); // ์ƒˆ๋กœ์šด td๋ฅผ ๊ฐ•์กฐํ•ด์คŒ + selectedTd.classList.add('highlight'); // ์ƒˆ๋กœ์šด td๋ฅผ ๊ฐ•์กฐ ํ•จ } ``` -์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ํ…Œ์ด๋ธ” ๋‚ด์˜ ์นธ ๊ฐœ์ˆ˜๋Š” ๊ณ ๋ฏผ๊ฑฐ๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ•์กฐ๊ธฐ๋Šฅ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋”๋ผ๋„ `<td>`๋ฅผ ์–ธ์ œ๋ผ๋„ ๋„ฃ๊ณ  ๋บ„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ํ…Œ์ด๋ธ” ๋‚ด ์นธ์˜ ๊ฐœ์ˆ˜๋Š” ๊ณ ๋ฏผ๊ฑฐ๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ•์กฐ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•˜๋ฉด์„œ `<td>`๋ฅผ ์–ธ์ œ๋ผ๋„ ๋„ฃ๊ณ  ๋บ„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ, ๋‹จ์ ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ ๋‹จ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -์œ„์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•˜๋ฉด ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ `<td>`๊ฐ€ ์•„๋‹Œ ๊ทธ ์•ˆ์— ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๋ฉด ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ `<td>`๊ฐ€ ์•„๋‹Œ `<td>` ์•ˆ์—์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์œ„ ํŒ”๊ด˜๋„์˜ HTML์„ ์‚ดํŽด๋ด…์‹œ๋‹ค. `<td>`์•ˆ์— `<strong>`์ด ์ค‘์ฒฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +ํŒ”๊ด˜๋„์˜ HTML์„ ์‚ดํŽด๋ด…์‹œ๋‹ค. `<td>`์•ˆ์— ์ค‘์ฒฉ ํƒœ๊ทธ `<strong>`์ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html <td> @@ -79,13 +79,13 @@ function highlight(td) { </td> ``` - `<strong>`์„ ํด๋ฆญํ•˜๊ฒŒ ๋˜๋ฉด ์ด ์š”์†Œ๊ฐ€ ์ด๋ฒคํŠธ์˜ ํƒ€๊นƒ์ด ๋ฉ๋‹ˆ๋‹ค. `event.target`์— ์ด ์š”์†Œ๊ฐ€ ์ €์žฅ๋˜๊ณ , ์›ํ•˜๋Š” ๊ฐ•์กฐ ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + `<strong>`์„ ํด๋ฆญํ•˜๋ฉด `event.target`์— `<strong>`์— ํ•ด๋‹นํ•˜๋Š” ์š”์†Œ๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ![](bagua-bubble.svg) -๋”ฐ๋ผ์„œ `table.onclick`ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.target`์„ ์ด์šฉํ•ด ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ `<td>`์•ˆ์ชฝ์—์„œ ์ผ์–ด๋‚ฌ๋Š”์ง€, ์•„๋‹Œ์ง€๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ `table.onclick` ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.target`์„ ์ด์šฉํ•ด ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ `<td>`์•ˆ์ชฝ์—์„œ ์ผ์–ด๋‚ฌ๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜๋Š” ๊ธฐ๋Šฅ์ด ์ข€ ๋” ํ–ฅ์ƒํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค: +๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js table.onclick = function(event) { @@ -100,32 +100,32 @@ table.onclick = function(event) { ``` ์„ค๋ช…: -1. `elem.closest(selector)` ๋ฉ”์„œ๋“œ๋Š” elem์˜ ์ƒ์œ„ ์š”์†Œ ์ค‘ selector์™€ ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ทผ์ ‘ํ•œ ์กฐ์ƒ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„  ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<td>` ์š”์†Œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. -2. ๋งŒ์•ฝ `event.target`์ด `<td>`์•ˆ์— ์žˆ์ง€ ์•Š์œผ๋ฉด, ๋ฐ˜ํ™˜ ๊ฐ’์€ `null`์ด ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์•„๋ฌด ์ž‘์—…๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -3. ์ค‘์ฒฉ ํ…Œ์ด๋ธ”์ด ์žˆ๋Š” ๊ฒฝ์šฐ, `event.target`์€ ํ˜„์žฌ ํ…Œ์ด๋ธ” ๋ฐ”๊นฅ์— ์žˆ๋Š” `<td>`์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด, `<td>`๊ฐ€ ํŒ”๊ด˜๋„ ์•ˆ์— ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. +1. `elem.closest(selector)` ๋ฉ”์„œ๋“œ๋Š” `elem`์˜ ์ƒ์œ„ ์š”์†Œ ์ค‘ `selector`์™€ ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ทผ์ ‘ํ•œ ์กฐ์ƒ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„  ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<td>` ์š”์†Œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. +2. `event.target`์ด `<td>`์•ˆ์— ์žˆ์ง€ ์•Š์œผ๋ฉด ๊ทธ ์ฆ‰์‹œ `null`์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์•„๋ฌด ์ž‘์—…๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +3. ์ค‘์ฒฉ ํ…Œ์ด๋ธ”์ด ์žˆ๋Š” ๊ฒฝ์šฐ `event.target`์€ ํ˜„์žฌ ํ…Œ์ด๋ธ” ๋ฐ”๊นฅ์— ์žˆ๋Š” `<td>`๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด `<td>`๊ฐ€ ํŒ”๊ด˜๋„ ์•ˆ์— ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 4. ์ด์ œ ์ง„์งœ td๋ฅผ ๊ฐ•์กฐํ•ด ์ค๋‹ˆ๋‹ค. -As the result, we have a fast, efficient highlighting code, that doesn't care about the total number of `<td>` in the table. +์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด `<td>`์˜ ๊ฐœ์ˆ˜์— ์ƒ๊ด€์—†์ด ์›ํ•˜๋Š” `<td>`๋ฅผ ๊ฐ•์กฐํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## ์ด๋ฒคํŠธ ์œ„์ž„ ํ™œ์šฉ: ๋งˆํฌ์—… ๋‚ด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ์ตœ์ ํ™” +## ์ด๋ฒคํŠธ ์œ„์ž„ ํ™œ์šฉํ•˜๊ธฐ -There are other uses for event delegation. +์ด๋ฒคํŠธ ์œ„์ž„์„ ๋‹ค๋ฅธ ์‹์œผ๋กœ๋„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Let's say, we want to make a menu with buttons "Save", "Load", "Search" and so on. And there's an object with methods `save`, `load`, `search`... How to match them? +'์ €์žฅํ•˜๊ธฐ', '๋ถˆ๋Ÿฌ์˜ค๊ธฐ', '๊ฒ€์ƒ‰ํ•˜๊ธฐ' ๋“ฑ์˜ ๋ฒ„ํŠผ์ด ์žˆ๋Š” ๋ฉ”๋‰ด๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ๊ฐ ๋ฒ„ํŠผ์˜ ๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ๋ฉ”์„œ๋“œ `save`, `load`, `search`๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋„ ์ด๋ฏธ ๊ตฌํ˜„ํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ ๋ฒ„ํŠผ๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? -์ฒ˜์Œ์—” ๋ฒ„ํŠผ ๊ฐ๊ฐ์— ๋…๋ฆฝ๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ ค๊ณ  ํ•  ๊ฒ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋” ์šฐ์•„ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋‰ด ์ „์ฒด์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ•˜๋‚˜ ํ• ๋‹นํ•ด์ฃผ๊ณ , ๊ฐ ๋ฒ„ํŠผ์˜ `data-action` ์†์„ฑ์— ํ˜ธ์ถœํ•  ๋ฉ”์„œ๋“œ๋ฅผ ํ• ๋‹นํ•ด ์ฃผ๋Š” ๋ฐฉ๋ฒ• ๋ง์ด์ฃ : +๊ฐ€์žฅ ๋จผ์ € ๋ฒ„ํŠผ ๊ฐ๊ฐ์— ๋…๋ฆฝ๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋– ์˜ค๋ฅผ ๊ฒ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋” ์šฐ์•„ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋‰ด ์ „์ฒด์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๊ฐ ๋ฒ„ํŠผ์˜ `data-action` ์†์„ฑ์— ํ˜ธ์ถœํ•  ๋ฉ”์„œ๋“œ๋ฅผ ํ• ๋‹นํ•ด ์ฃผ๋Š” ๋ฐฉ๋ฒ• ๋ง์ด์ฃ . ```html -<button *!*data-action="save"*/!*>Click to Save</button> +<button *!*data-action="save"*/!*>์ €์žฅํ•˜๊ธฐ</button> ``` -ํ•ธ๋“ค๋Ÿฌ๋Š” ์†์„ฑ๊ฐ’์„ ์ฝ๊ณ  ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด ๋ด…์‹œ๋‹ค: +ํ•ธ๋“ค๋Ÿฌ๋Š” ์†์„ฑ๊ฐ’์„ ์ฝ๊ณ  ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๊ฒ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•ด๋ด…์‹œ๋‹ค. -```html autorun height=60 run +```html autorun height=60 run untrusted <div id="menu"> - <button data-action="save">Save</button> - <button data-action="load">Load</button> - <button data-action="search">Search</button> + <button data-action="save">์ €์žฅํ•˜๊ธฐ</button> + <button data-action="load">๋ถˆ๋Ÿฌ์˜ค๊ธฐ</button> + <button data-action="search">๊ฒ€์ƒ‰ํ•˜๊ธฐ</button> </div> <script> @@ -136,15 +136,15 @@ Let's say, we want to make a menu with buttons "Save", "Load", "Search" and so o } save() { - alert('saving'); + alert('์ €์žฅํ•˜๊ธฐ'); } load() { - alert('loading'); + alert('๋ถˆ๋Ÿฌ์˜ค๊ธฐ'); } search() { - alert('searching'); + alert('๊ฒ€์ƒ‰ํ•˜๊ธฐ'); } onClick(event) { @@ -161,37 +161,37 @@ Let's say, we want to make a menu with buttons "Save", "Load", "Search" and so o </script> ``` -`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์˜ `this.onClick`์€ `this`์— bind ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด `this`๋Š” `Menu` ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ , DOM ์š”์†Œ(`elem`)๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. . `this[action]`์€ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋ฐ”๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. +`(*)`๋กœ ํ‘œ์‹œํ•œ ์ค„์˜ `this.onClick`์€ `this`์— ๋ฐ”์ธ๋”ฉํ–ˆ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด `this`๋Š” `Menu` ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ DOM ์š”์†Œ(`elem`)๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด `this[action]`์—์„œ ์›ํ•˜๋Š” ๊ฒƒ์„ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. -์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์–ด๋–ค ์ด์ ์ด ์žˆ์„๊นŒ์š”? ์•„๋ž˜์™€ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์‹์œผ๋กœ ์ด๋ฒคํŠธ ์œ„์ž„์„ ํ™œ์šฉํ•˜๋ฉด ์–ด๋–ค ์ด์ ์ด ์žˆ์„๊นŒ์š”? ์•„๋ž˜์™€ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```compare -+ ๊ฐ ๋ฒ„ํŠผ๋งˆ๋‹ค ํ•ธ๋“ค๋Ÿฌ ํ• ๋‹น์„ ์œ„ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง‘๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , ๋งˆํฌ์—…์— ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ์จ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -+ HTML ๊ตฌ์กฐ๋Š” ์œ ์—ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์–ธ์ œ๋“ ์ง€ ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ++ ๋ฒ„ํŠผ๋งˆ๋‹ค ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง‘๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  HTML์— ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ์จ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ++ ์–ธ์ œ๋“ ์ง€ ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์–ด HTML ๊ตฌ์กฐ๊ฐ€ ์œ ์—ฐํ•ด์ง‘๋‹ˆ๋‹ค. ``` `.action-save`, `.action-load` ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, `data-action` ์†์„ฑ์ด ์ข€ ๋” ์˜๋ฏธ๋ก ์ ์œผ๋กœ ๋‚ซ์Šต๋‹ˆ๋‹ค. CSS ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -## "ํ–‰๋™" ํŒจํ„ด +## 'ํ–‰๋™' ํŒจํ„ด -์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜์—ฌ *์„ ์–ธ์  ๋ฐฉ์‹์œผ๋กœ* ์š”์†Œ์— "ํ–‰๋™(behavior)"์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ๋Š” ํŠน๋ณ„ํ•œ ์†์„ฑ๊ณผ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ์œ„์ž„์€ ์š”์†Œ์— *์„ ์–ธ์  ๋ฐฉ์‹์œผ๋กœ* 'ํ–‰๋™(behavior)'์„ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ๋Š” ํŠน๋ณ„ํ•œ ์†์„ฑ๊ณผ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์ ˆ์ฐจ๋ฅผ ํ†ตํ•ด ์ด ํŒจํ„ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -1. We add a custom attribute to an element that describes its behavior. -2. document ์ „์ฒด๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. 1์—์„œ ์ถ”๊ฐ€ํ•œ ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋ง์ด์ฃ . +ํ–‰๋™ ํŒจํ„ด์€ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. +1. ์š”์†Œ์˜ ํ–‰๋™์„ ์„ค๋ช…ํ•˜๋Š” ์ปค์Šคํ…€ ์†์„ฑ์„ ์š”์†Œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. +2. ๋ฌธ์„œ ์ „์ฒด๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. 1์—์„œ ์ถ”๊ฐ€ํ•œ ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. -### Behavior: Counter +### ์นด์šดํ„ฐ ๊ตฌํ˜„ํ•˜๊ธฐ -`data-counter`๋ฅผ ์‚ฌ์šฉํ•ด ์š”์†Œ์— ํ–‰๋™์„ ๋”ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. "ํด๋ฆญ ์‹œ ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€"ํ•˜๋Š” ๋ฒ„ํŠผ์„ ๋งŒ๋“œ๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค: +๋ฒ„ํŠผ์„ 'ํด๋ฆญํ•˜๋ฉด ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€'ํ•˜๋Š” ํ–‰๋™์„ ๋ถ€์—ฌํ•ด์ฃผ๋Š” ์†์„ฑ์ธ `data-counter`๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run autorun height=60 -Counter: <input type="button" value="1" data-counter> -One more counter: <input type="button" value="2" data-counter> +์ฒซ ๋ฒˆ์งธ ์นด์šดํ„ฐ: <input type="button" value="1" data-counter> +๋‘ ๋ฒˆ์งธ ์นด์šดํ„ฐ: <input type="button" value="2" data-counter> <script> document.addEventListener('click', function(event) { - if (event.target.dataset.counter != undefined) { // ์†์„ฑ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ... + if (event.target.dataset.counter != undefined) { // ์†์„ฑ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ event.target.value++; } @@ -199,27 +199,27 @@ One more counter: <input type="button" value="2" data-counter> </script> ``` -๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ง‘์ค‘ํ•ด์•ผ ํ•  ๊ฒƒ์€ ๋ฒ„ํŠผ์ด ์•„๋‹ˆ๊ณ , ์ ‘๊ทผ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. +๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ ์ง‘์ค‘ํ•ด์•ผ ํ•  ๊ฒƒ์€ ๋ฒ„ํŠผ์ด ์•„๋‹ˆ๊ณ  ์ ‘๊ทผ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. -`data-counter` ์†์„ฑ์€ ์›ํ•˜๋Š” ๋งŒํผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค HTML์— ๋”ํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ์š”. ์—ฌ๊ธฐ์„  ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜์—ฌ HTML์„ "ํ™•์žฅ"ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ–‰๋™์„ ์„ ์–ธํ•ด์ฃผ๋Š” ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์„œ ๋ง์ด์ฃ . +`data-counter` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ๋Š” ์›ํ•˜๋Š” ๋งŒํผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค HTML์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋˜๋‹ˆ๊นŒ์š”. ์˜ˆ์‹œ์—์„  ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํ–‰๋™์„ ์„ ์–ธํ•ด์ฃผ๋Š” ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์„œ HTML์„ 'ํ™•์žฅ'ํ•˜์˜€์Šต๋‹ˆ๋‹ค. -```warn header="document ์ˆ˜์ค€์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค ๋• ํ•ญ์ƒ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”" -`document` ๊ฐ์ฒด์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ๋•, `document.onclick`๋ฅผ ์‚ฌ์šฉํ•ด์„  ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋ฌด์กฐ๊ฑด `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `document.onclick`์€ ์ถฉ๋Œ์„ ์ผ์œผํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด์ „์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ๊ฒƒ ๊ฐ™์ด ๋ง์ด์ฃ  ๋ง์ด์ฃ . +```warn header="๋ฌธ์„œ ๋ ˆ๋ฒจ์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค ๋• ํ•ญ์ƒ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”." +`document` ๊ฐ์ฒด์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ๋•Œ๋Š” `document.onclick`๋ฅผ ์‚ฌ์šฉํ•ด์„  ์•ˆ ๋ฉ๋‹ˆ๋‹ค. `document.onclick`์€ ์ถฉ๋Œ์„ ์ผ์œผํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `document.onclick`์€ ์ƒˆ๋กœ์šด ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด์ „์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ฝ”๋“œ ๊ณณ๊ณณ์—์„œ `document`์— ๋‹ค์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋Š” ์ž์—ฐ์Šค๋Ÿฌ์šด ์ผ์ž…๋‹ˆ๋‹ค. +์ฝ”๋“œ ๊ณณ๊ณณ์—์„œ `document`์— ๋‹ค์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋Š” ์ž์—ฐ์Šค๋Ÿฌ์šด ์ผ์ž…๋‹ˆ๋‹ค. ``` -### Behavior: Toggler +### ํ† ๊ธ€๋Ÿฌ ๊ตฌํ˜„ํ•˜๊ธฐ -One more example of behavior. `data-toggle-id` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด, ์†์„ฑ๊ฐ’์„ `id`๋กœ ๊ฐ€์ง„ ์š”์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฑฐ๋‚˜ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +ํ–‰๋™ ํŒจํ„ด์— ๊ด€ํ•œ ์˜ˆ์‹œ๋ฅผ ํ•˜๋‚˜ ๋” ์‚ดํŽด๋ด…์‹œ๋‹ค. ์ด๋ฒˆ์—” `data-toggle-id` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์†์„ฑ๊ฐ’์ด `id`์ธ ์š”์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฑฐ๋‚˜ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```html autorun run height=60 <button *!*data-toggle-id="subscribe-mail"*/!*> - Show the subscription form + ๊ตฌ๋… ํผ ๋ณด์—ฌ์ฃผ๊ธฐ </button> <form id="subscribe-mail" hidden> - Your mail: <input type="email"> + ๋ฉ”์ผ ์ฃผ์†Œ: <input type="email"> </form> <script> @@ -236,37 +236,37 @@ One more example of behavior. `data-toggle-id` ์†์„ฑ์ด ์žˆ๋Š” ์š”์†Œ๋ฅผ ํด๋ฆญ </script> ``` -์š”์†Œ์— ํ† ๊ธ€๊ธฐ๋Šฅ์„ ๋”ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•ฉ์‹œ๋‹ค. `data-toggle-id` ์†์„ฑ๋งŒ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์š”์†Œ์— ํ† ๊ธ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•ฉ์‹œ๋‹ค. ํƒœ๊ทธ์— `data-toggle-id` ์†์„ฑ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์š”์†Œ๋ฅผ ํ† ๊ธ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๋ชจ๋“  ์š”์†Œ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์“ฐ์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. "ํ–‰๋™"์„ ์„ ์–ธํ•ด ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. document ์ˆ˜์ค€์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋Š” ํŽ˜์ด์ง€ ๋‚ด์˜ ๋ชจ๋“  ์š”์†Œ์— ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +ํ–‰๋™ ํŒจํ„ด์„ ์‘์šฉํ•˜๋ฉด ํ† ๊ธ€ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์š”์†Œ ์ „์ฒด์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด ์ฃผ์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 'ํ–‰๋™'์„ ์„ ์–ธํ•ด ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋ ˆ๋ฒจ์— ์ ์ ˆํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ํŽ˜์ด์ง€ ๋‚ด ๋ชจ๋“  ์š”์†Œ์— ํ–‰๋™์„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ–‰๋™์„ ์กฐํ•ฉํ•ด ํ•œ ์š”์†Œ์— ์ ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +ํ•œ ์š”์†Œ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ–‰๋™์„ ์กฐํ•ฉํ•ด ์ ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ "ํ–‰๋™" ํŒจํ„ด์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ ๋Œ€์•ˆ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ 'ํ–‰๋™' ํŒจํ„ด์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฏธ๋‹ˆ ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ ๋Œ€์•ˆ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์š”์•ฝ -์ด๋ฒคํŠธ ์œ„์ž„์€ ๋ฉ‹์ง‘๋‹ˆ๋‹ค! DOM ์ด๋ฒคํŠธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ฃผ ์œ ์šฉํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ์œ„์ž„์€ ์ƒ๋‹นํžˆ ๋ฉ‹์ง„ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. DOM ์ด๋ฒคํŠธ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ฃผ ์œ ์šฉํ•œ ํŒจํ„ด์ด์ฃ , -์œ ์‚ฌํ•œ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์˜ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋‹ค๋ฃจ๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ผญ ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ์•„๋‹™๋‹ˆ๋‹ค. +์ด๋ฒคํŠธ ์œ„์ž„์€ ์œ ์‚ฌํ•œ ์š”์†Œ์— ๋™์ผํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ ์šฉํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๊ผญ ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. -๋‹ค์Œ๊ณผ ๊ฐ™์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค: +์ด๋ฒคํŠธ ์œ„์ž„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. 1. ์ปจํ…Œ์ด๋„ˆ์— ํ•˜๋‚˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. 2. ํ•ธ๋“ค๋Ÿฌ์˜ `event.target`์„ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ๊ฐ€ ์–ด๋””์ธ์ง€ ์•Œ์•„๋ƒ…๋‹ˆ๋‹ค. -3. ์›ํ•˜๋Š” ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ™•์ธ๋˜๋ฉด, ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋ง ํ•ฉ๋‹ˆ๋‹ค. +3. ์›ํ•˜๋Š” ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ™•์ธ๋˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค. -์žฅ์ : +์ด๋ฒคํŠธ ์œ„์ž„์˜ ์žฅ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```compare -+ ๋‹จ์ˆœํ•œ ์ดˆ๊ธฐํ™”์™€ ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ: ๋งŽ์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -+ ์ ์€ ์ฝ”๋“œ: ์š”์†Œ๋ฅผ ๋”ํ•˜๊ฑฐ๋‚˜ ๋บ„ ๋•Œ, ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -+ DOM ์ˆ˜์ •: `innerHTML`์ด๋‚˜ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋กœ ์š”์†Œ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋”ํ•˜๊ฑฐ๋‚˜ ๋บ„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ++ ๋งŽ์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐํ™”๊ฐ€ ๋‹จ์ˆœํ•ด์ง€๊ณ  ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค. ++ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ๋•Œ ํ•ด๋‹น ์š”์†Œ์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ์งง์•„์ง‘๋‹ˆ๋‹ค. ++ `innerHTML`์ด๋‚˜ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋กœ ์š”์†Œ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋”ํ•˜๊ฑฐ๋‚˜ ๋บ„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— DOM ์ˆ˜์ •์ด ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ``` -์ด๋ฒคํŠธ ์œ„์ž„์—๋„ ๋ฌผ๋ก  ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค: +์ด๋ฒคํŠธ ์œ„์ž„์—๋„ ๋ฌผ๋ก  ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```compare -- ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ์ด๋ฒคํŠธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ๋ฒ„๋ธ”๋ง ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ , ๋‚ฎ์€ ๋ ˆ๋ฒจ์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—” `event.stopPropagation()`๋ฅผ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -- CPU ์ž‘์—… ๋ถ€ํ•˜๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ ์ˆ˜์ค€์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ชจ๋“  ํ•˜์œ„ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์‘๋‹ตํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ์ด๋ฒคํŠธ์ด๋“  ์•„๋‹ˆ๋“  ์ƒ๊ด€์—†์ด ๋ง์ด์ฃ . +- ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ๋ฒ„๋ธ”๋ง ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ฎ์€ ๋ ˆ๋ฒจ์— ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—” `event.stopPropagation()`๋ฅผ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +- ์ปจํ…Œ์ด๋„ˆ ์ˆ˜์ค€์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‘๋‹ตํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ์ด๋ฒคํŠธ์ด๋“  ์•„๋‹ˆ๋“  ์ƒ๊ด€์—†์ด ๋ชจ๋“  ํ•˜์œ„ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•ด์•ผ ํ•˜๋ฏ€๋กœ CPU ์ž‘์—… ๋ถ€ํ•˜๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ๋ถ€ํ•˜๋Š” ๋ฌด์‹œํ• ๋งŒํ•œ ์ˆ˜์ค€์ด๋ฏ€๋กœ ์‹ค์ œ๋กœ๋Š” ์ž˜ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` diff --git a/2-ui/2-events/03-event-delegation/bagua-bubble.svg b/2-ui/2-events/03-event-delegation/bagua-bubble.svg index b770f8c55c..c4cd1ee1e2 100644 --- a/2-ui/2-events/03-event-delegation/bagua-bubble.svg +++ b/2-ui/2-events/03-event-delegation/bagua-bubble.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="369" height="216" viewBox="0 0 369 216"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="bagua-bubble.svg"><path id="Rectangle-210" fill="#FFDE99" d="M202.488 140L217 186H103l14.512-46z"/><path id="Rectangle-209" stroke="#CFCE95" stroke-width="18" d="M216.634 81H102.366l-16.09 51h146.447l-16.09-51z"/><path id="Rectangle-208" stroke="#99C0C3" stroke-width="18" d="M236.014 29H82.986l-22.71 72h198.448l-22.71-72z"/><path id="Fill-46" fill="#5A4739" d="M164.5 141v13.816a4.5 4.5 0 01-8.994.212l-.005-.212V141h8.998zm0-31v13h-9v-13h9zm-1.327-88.347l.189.178 17.64 17.64a4.5 4.5 0 01-6.196 6.524l-.168-.16L164.5 35.698V92h-9V35.7l-10.138 10.136a4.5 4.5 0 01-6.523-6.196l.16-.168 17.639-17.64a4.477 4.477 0 013.363-1.3 4.478 4.478 0 013.172 1.122z"/><text id="<table>" fill="#99C0C3" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="9" y="30"><table></tspan></text><text id="<td>" fill="#CFCE95" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="36" y="136"><td></tspan></text><text id="<strong>" fill="#E8C48E" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="35" y="181"><strong></tspan></text><text id="event.target" fill="#8A704D" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold"><tspan x="271.746" y="181">event.target</tspan></text><path id="Line-30" stroke="#EE6B47" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M229.5 177.5h30"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="369" height="216" viewBox="0 0 369 216"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:'PT Mono';font-weight:700;font-style:normal;src:local('PT MonoBold'),url(/font/PTMonoBold.woff2) format('woff2'),url(/font/PTMonoBold.woff) format('woff'),url(/font/PTMonoBold.ttf) format('truetype')}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="bagua-bubble.svg"><path id="Rectangle-210" fill="#DBAF88" d="M202.488 140L217 186H103l14.512-46z"/><path id="Rectangle-209" stroke="#91C2A3" stroke-width="18" d="M216.634 81l16.09 51H86.276l16.09-51h114.267z"/><path id="Rectangle-208" stroke="#EFA39F" stroke-width="18" d="M82.986 29h153.028l22.71 72H60.276l22.71-72z"/><path id="Fill-46" fill="#166388" d="M164.5 141v13.816a4.5 4.5 0 11-9 0V141h9zm0-31v13h-9v-13h9zM160 20.53a4.471 4.471 0 013.362 1.3l17.64 17.64a4.5 4.5 0 01-6.364 6.364L164.5 35.698V92h-9V35.7l-10.138 10.136a4.5 4.5 0 11-6.363-6.364l17.639-17.64a4.477 4.477 0 013.363-1.3z"/><text id="<table>" fill="#D35155" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="9" y="30"><table></tspan></text><text id="<td>" fill="#478964" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="36" y="136"><td></tspan></text><text id="<strong>" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="35" y="181"><strong></tspan></text><text id="event.target" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold"><tspan x="271.537" y="181">event.target</tspan></text><path id="Line-30" stroke="#C06334" stroke-dasharray="3,6" stroke-linecap="square" stroke-width="2" d="M229.5 177.5h30"/></g></g></svg> \ No newline at end of file diff --git a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md index 2862e60063..fefda6c633 100644 --- a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md +++ b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md @@ -1,16 +1,16 @@ -When the browser reads the `on*` attribute like `onclick`, it creates the handler from its content. +๋ธŒ๋ผ์šฐ์ €๋Š” `onclick` ๊ฐ™์€ `on*` ์†์„ฑ์„ ์ฝ์„ ๋•Œ, ์†์„ฑ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์™€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. -For `onclick="handler()"` the function will be: +๋”ฐ๋ผ์„œ `onclick="handler()"`์˜ ๊ฒฝ์šฐ ์ƒ์„ฑ๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js function(event) { - handler() // the content of onclick + handler() // onclick ์†์„ฑ์— ํ• ๋‹น๋œ ๊ฐ’์ด ๊ทธ๋Œ€๋กœ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์ด ๋ฉ๋‹ˆ๋‹ค. } ``` -Now we can see that the value returned by `handler()` is not used and does not affect the result. +๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ๋ณด๋ฉด ํ•จ์ˆ˜ `handler`๋ฅผ ๊ด„ํ˜ธ๋ฅผ ๋ถ™์—ฌ์„œ ํ˜ธ์ถœํ•˜๊ธฐ๋งŒ ํ–ˆ์ง€, ํ˜ธ์ถœ์‹œ ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ๊ทธ ์–ด๋””์—์„œ๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ฌด๋Ÿฐ ๋ณ€ํ™”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -The fix is simple: +์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋งํฌ๋กœ ์ด๋™ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```html run <script> @@ -20,10 +20,10 @@ The fix is simple: } </script> -<a href="http://w3.org" onclick="*!*return handler()*/!*">w3.org</a> +<a href="https://w3.org" onclick="*!*return handler()*/!*">w3.org</a> ``` -Also we can use `event.preventDefault()`, like this: +์ด ์™ธ์—๋„ `event.preventDefault()`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run <script> @@ -35,5 +35,5 @@ Also we can use `event.preventDefault()`, like this: */!* </script> -<a href="http://w3.org" onclick="*!*handler(event)*/!*">w3.org</a> +<a href="https://w3.org" onclick="*!*handler(event)*/!*">w3.org</a> ``` diff --git a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md index 8fa4fb29a9..6ed551e64c 100644 --- a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md +++ b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md @@ -2,9 +2,9 @@ importance: 3 --- -# Why "return false" doesn't work? +# ์™œ 'return false'๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์„๊นŒ์š” -Why in the code below `return false` doesn't work at all? +์•„๋ž˜์˜ ์ฝ”๋“œ์—์„œ `return false`๋Š” ์™œ ์ „ํ˜€ ์ž‘๋™ํ•˜์ง€ ์•Š์„๊นŒ์š”? ```html autorun run <script> @@ -14,9 +14,9 @@ Why in the code below `return false` doesn't work at all? } </script> -<a href="http://w3.org" onclick="handler()">the browser will go to w3.org</a> +<a href="https://w3.org" onclick="handler()">๋ธŒ๋ผ์šฐ์ €๊ฐ€ w3.org๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.</a> ``` -The browser follows the URL on click, but we don't want it. +๋ธŒ๋ผ์šฐ์ €์—์„œ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น URL๋กœ ์ด๋™ํ•˜๋Š”๋ฐ, ์ด ๊ธฐ๋ณธ๋™์ž‘์„ ์ทจ์†Œํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. -How to fix? +์–ด๋–ป๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋ ๊นŒ์š”? diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md index 25079cb8d4..1d05294c52 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md @@ -1,5 +1,5 @@ -That's a great use of the event delegation pattern. +์ด ๋ฌธ์ œ๋Š” ์ด๋ฒคํŠธ ์œ„์ž„ ํŒจํ„ด์„ ์ž˜ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. -In real life instead of asking we can send a "logging" request to the server that saves the information about where the visitor left. Or we can load the content and show it right in the page (if allowable). +์‚ฌ์šฉ์ž์—๊ฒŒ ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ ๋– ๋‚  ๊ฒƒ์ธ์ง€ ๋ฌผ์–ด๋ณด๋Š” ๋Œ€์‹ , ๋ฐฉ๋ฌธ์ž๊ฐ€ ๋– ๋‚œ ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๋Š” ์„œ๋ฒ„์— 'logging' ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋‚ด์šฉ์„ ๋ถˆ๋Ÿฌ์™€์„œ ํ˜„์žฌ ํŽ˜์ด์ง€์— ๋ฐ”๋กœ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -All we need is to catch the `contents.onclick` and use `confirm` to ask the user. A good idea would be to use `link.getAttribute('href')` instead of `link.href` for the URL. See the solution for details. +๊ทธ๋Ÿฌ๋‹ˆ๊นŒ `contents.onclick`๋ฅผ ์žก์•„๋‚ธ ๋‹ค์Œ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌผ์–ด๋ณด๊ธฐ ์œ„ํ•ด `confirm`์„ ์‚ฌ์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. URL์— `link.href` ๋Œ€์‹  `link.getAttribute('href')`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์ƒŒ๋“œ๋ฐ•์Šค์˜ ํ•ด๋‹ต์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”. diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html index 90aecd9dc7..51ac0838be 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html @@ -16,7 +16,7 @@ <fieldset id="contents"> <legend>#contents</legend> <p> - How about to read <a href="http://wikipedia.org">Wikipedia</a> or visit <a href="http://w3.org"><i>W3.org</i></a> and learn about modern standards? + How about to read <a href="https://wikipedia.org">Wikipedia</a> or visit <a href="https://w3.org"><i>W3.org</i></a> and learn about modern standards? </p> </fieldset> diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html index b88834c96f..f0c9343919 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html @@ -16,7 +16,7 @@ <fieldset id="contents"> <legend>#contents</legend> <p> - How about to read <a href="http://wikipedia.org">Wikipedia</a> or visit <a href="http://w3.org"><i>W3.org</i></a> and learn about modern standards? + How about to read <a href="https://wikipedia.org">Wikipedia</a> or visit <a href="https://w3.org"><i>W3.org</i></a> and learn about modern standards? </p> </fieldset> diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md index 6439376bf8..f24e9a14e0 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md @@ -2,15 +2,15 @@ importance: 5 --- -# Catch links in the element +# ์š”์†Œ ์•ˆ ๋งํฌ ์žก์•„๋‚ด๊ธฐ -Make all links inside the element with `id="contents"` ask the user if they really want to leave. And if they don't then don't follow. +์‚ฌ์šฉ์ž๊ฐ€ `id`๊ฐ€ `contents`์ธ ์š”์†Œ ์•ˆ์— ์žˆ๋Š” ๋งํฌ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ •๋ง ์‚ฌ์ดํŠธ๋ฅผ ๋– ๋‚˜ ํ•ด๋‹น ๋งํฌ๋กœ ๊ฐˆ์ง€๋ฅผ ๋ฌผ์–ด๋ณด๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ ๋– ๋‚˜์ง€ ์•Š๊ฒ ๋‹ค๊ณ  ํ•˜๋ฉด, ์‚ฌ์ดํŠธ์— ๋‚จ์•„์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Like this: +์˜ˆ์‹œ: [iframe height=100 border=1 src="solution"] -Details: +์ฃผ์˜์‚ฌํ•ญ: -- HTML inside the element may be loaded or regenerated dynamically at any time, so we can't find all links and put handlers on them. Use the event delegation. -- The content may have nested tags. Inside links too, like `<a href=".."><i>...</i></a>`. +- ์š”์†Œ ์•ˆ HTML์€ ์–ธ์ œ๋“ ์ง€ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋˜๊ฑฐ๋‚˜ ์žฌ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ๋งํฌ๋ฅผ ์ฐพ์•„ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•ด ๋‹ต์•ˆ์„ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”. +- `id`๊ฐ€ `contents`์ธ ์š”์†Œ ์•ˆ์—๋Š” ์ค‘์ฒฉ ํƒœ๊ทธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ ์•ˆ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `<a href=".."><i>...</i></a>` ์ด๋ ‡๊ฒŒ ์ค‘์ฒฉ ํƒœ๊ทธ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md index 5ff60b5c08..9fea970b56 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md @@ -1 +1 @@ -The solution is to assign the handler to the container and track clicks. If a click is on the `<a>` link, then change `src` of `#largeImg` to the `href` of the thumbnail. +์ƒ์œ„ ์š”์†Œ์— ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋ฉด ์–ด๋–ค ์ด๋ฏธ์ง€๋ฅผ ํด๋ฆญํ–ˆ๋Š”์ง€ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ `<a>` ๋งํฌ๋ฅผ ํด๋ฆญํ•œ ๊ฒฝ์šฐ, `#largeImg`์˜ `src` ๊ฐ’์„ ์„ฌ๋„ค์ผ์˜ `href`๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md b/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md index f7571cc80c..477a05de41 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md @@ -2,12 +2,12 @@ importance: 5 --- -# Image gallery +# ์ด๋ฏธ์ง€ ๊ฐค๋Ÿฌ๋ฆฌ -Create an image gallery where the main image changes by the click on a thumbnail. +์„ฌ๋„ค์ผ(thumbnail)์„ ํด๋ฆญํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ด๋ฏธ์ง€ ๊ฐค๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. -Like this: +์˜ˆ์‹œ: [iframe src="solution" height=600] -P.S. Use event delegation. +P.S. ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md index 55e4e99771..bb2903bd7e 100644 --- a/2-ui/2-events/04-default-browser-action/article.md +++ b/2-ui/2-events/04-default-browser-action/article.md @@ -1,43 +1,43 @@ -# ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘(browser default action) +# ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘ -Many events automatically lead to certain actions performed by the browser. +์ƒ๋‹น์ˆ˜ ์ด๋ฒคํŠธ๋Š” ๋ฐœ์ƒ ์ฆ‰์‹œ ๋ธŒ๋ผ์šฐ์ €์— ์˜ํ•ด ํŠน์ • ๋™์ž‘์„ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. -์˜ˆ: +์˜ˆ์‹œ: -- A click on a link - initiates navigation to its URL. -- A click on a form submit button - initiates its submission to the server. -- Pressing a mouse button over a text and moving it - selects the text. +- ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น URL๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. +- ํผ ์ „์†ก ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์„œ๋ฒ„์— ํผ์ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. +- ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ์ฑ„๋กœ ๊ธ€์ž ์œ„์—์„œ ์ปค์„œ๋ฅผ ์›€์ง์ด๋ฉด ๊ธ€์ž๊ฐ€ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. -If we handle an event in JavaScript, we may not want the corresponding browser action to happen, to implement another behavior instead. +๊ทธ๋Ÿฐ๋ฐ ์–ด๋–จ ๋•Œ๋Š” ์ด๋Ÿฐ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘ ๋Œ€์‹ ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ ๋™์ž‘์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. -## ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘ ์ทจ์†Œํ•˜๊ธฐ +## ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘ ๋ง‰๊ธฐ -๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ด๋ฒคํŠธ์˜ ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- The main way is to use the `event` object. There's a method `event.preventDefault()`. -- If the handler is assigned using `on<event>` (not by `addEventListener`), then returning `false` also works the same. +- ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ `event` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋•Œ `event` ๊ฐ์ฒด์— ๊ตฌํ˜„๋œ `event.preventDefault()` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +- ํ•ธ๋“ค๋Ÿฌ๊ฐ€ `addEventListener`๊ฐ€ ์•„๋‹Œ `on<event>`๋ฅผ ์‚ฌ์šฉํ•ด ํ• ๋‹น๋˜์—ˆ๋‹ค๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -In this HTML a click on a link doesn't lead to navigation, browser doesn't do anything: +์•„๋ž˜ HTML์—์„  ๋งํฌ๋ฅผ ํด๋ฆญํ•ด๋„ ํ•ด๋‹น URL๋กœ ์ด๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```html autorun height=60 no-beautify -<a href="/" onclick="return false">Click here</a> -or -<a href="/" onclick="event.preventDefault()">here</a> +<a href="/" onclick="return false">์ด๊ณณ</a> +์ด๋‚˜ +<a href="/" onclick="event.preventDefault()">์ด๊ณณ์„</a> ํด๋ฆญํ•ด์ฃผ์„ธ์š”. ``` -In the next example we'll use this technique to create a JavaScript-powered menu. +๋‹ค์Œ ์˜ˆ์‹œ์—์„  ์—ฌ๊ธฐ์„œ ๋ฐฐ์šด ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ”๋‰ด๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -```warn header="Returning `false` from a handler is an exception" -The value returned by an event handler is usually ignored. +```warn header="ํ•ธ๋“ค๋Ÿฌ์—์„œ `false`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์˜ˆ์™ธ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค." +์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ๋Œ€๊ฐœ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. -The only exception is `return false` from a handler assigned using `on<event>`. +ํ•˜๋‚˜์˜ ์˜ˆ์™ธ์‚ฌํ•ญ์ด ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ `on<event>`๋ฅผ ์‚ฌ์šฉํ•ด ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—์„œ `false`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -In all other cases, `return` value is ignored. In particular, there's no sense in returning `true`. +์ด ์™ธ์˜ ๊ฐ’๋“ค์€ `return` ๋˜์–ด๋„ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. `true` ์—ญ์‹œ ๋ฌด์‹œ๋˜์ฃ . ``` -### ์˜ˆ์ œ: ๋ฉ”๋‰ด +### ๋ฉ”๋‰ด ๊ตฌํ˜„ํ•˜๊ธฐ -์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์ดํŠธ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค: +์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”๋‰ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ฒ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ```html <ul id="menu" class="menu"> @@ -47,62 +47,62 @@ In all other cases, `return` value is ignored. In particular, there's no sense i </ul> ``` -์•ฝ๊ฐ„์˜ CSS๋ฅผ ๊ฐ€๋ฏธํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ๊พธ๋ฉฐ๋ณด์•˜์Šต๋‹ˆ๋‹ค: +์•ฝ๊ฐ„์˜ CSS๋ฅผ ๊ฐ€๋ฏธํ•ด ๋ฉ”๋‰ด๋ฅผ ๊พธ๋ฏธ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. [iframe height=70 src="menu" link edit] -Menu items are implemented as HTML-links `<a>`, not buttons `<button>`. There are several reasons to do so, for instance: +๊ฐ ํ•ญ๋ชฉ์€ `<button>` ํƒœ๊ทธ๊ฐ€ ์•„๋‹Œ ๋งํฌ๋ฅผ ๋งŒ๋“ค ๋•Œ ์“ฐ์ด๋Š” `<a>` ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค์–ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•œ๋ฐ๋Š” ์—ฌ๋Ÿฌ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -- ๋งŽ์€ ์‚ฌ๋žŒ์ด "๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ํด๋ฆญ" ํ›„ "์ƒˆ ์ฐฝ์—์„œ ์—ด๊ธฐ"๋ฅผ ํ†ตํ•ด ๋งํฌ๋ฅผ ์—ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `<button>` ์ด๋‚˜ `<span>`์„ ์“ฐ๋ฉด ์ด ๊ธฐ๋Šฅ์„ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +- ๋งŽ์€ ์‚ฌ๋žŒ์ด '๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญ'ํ•œ ํ›„ '์ƒˆ ์ฐฝ์—์„œ ์—ด๊ธฐ'๋ฅผ ํด๋ฆญํ•ด ๋งํฌ๋ฅผ ์—ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. `<button>` ์ด๋‚˜ `<span>`์„ ์“ฐ๋ฉด ์ด ๊ธฐ๋Šฅ์„ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - ๊ฒ€์ƒ‰ ์—”์ง„์€ ์ธ๋ฑ์‹ฑ(์ƒ‰์ธ)์„ ํ•˜๋Š” ๋™์•ˆ `<a href="...">` ๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ‘๋‹ˆ๋‹ค. -์ด๋Ÿฐ ์ด์œ ๋กœ `<a>`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์˜๋„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์—, ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด๋Ÿฐ ์ด์œ ๋กœ `<a>`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์˜๋„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋กœ ํ–ˆ์œผ๋ฏ€๋กœ ์‹ค์ œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ : +์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . ```js menu.onclick = function(event) { if (event.target.nodeName != 'A') return; let href = event.target.getAttribute('href'); - alert( href ); // ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ฑฐ๋‚˜, UI๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค๊ฑฐ๋‚˜ ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—… + alert( href ); // ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ฑฐ๋‚˜, UI๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค๊ฑฐ๋‚˜ ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์ด ์—ฌ๊ธฐ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. *!* - return false; // ๋ธŒ๋ผ์šฐ์ € ๋™์ž‘ ์ทจ์†Œ(URL๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š์Œ) + return false; // ๋ธŒ๋ผ์šฐ์ € ๋™์ž‘์„ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค(URL๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š์Œ). */!* }; ``` -If we omit `return false`, then after our code executes the browser will do its "default action" -- navigating to the URL in `href`. And we don't need that here, as we're handling the click by ourselves. +๋งจ ์•„๋žซ์ค„ `return false`๋ฅผ ์ƒ๋žตํ•˜๋ฉด ์˜ˆ์‹œ์—์„œ ๋งŒ๋“  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜์—ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ €๋Š” '๊ธฐ๋ณธ ๋™์ž‘'์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. `href`์— ์ง€์ •ํ•œ URL๋กœ ์ด๋™ํ•˜์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฑด ํŽ˜์ด์ง€ ์ด๋™์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œ์‹œํ‚ค๊ณ  ์›ํ•˜๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. -By the way, using event delegation here makes our menu very flexible. We can add nested lists and style them using CSS to "slide down". +ํ•œํŽธ, ์—ฌ๊ธฐ์„œ๋„ ์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์œ ์—ฐํ•ด์ง‘๋‹ˆ๋‹ค. ์ค‘์ฒฉ ๋ฉ”๋‰ด๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ณ  ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ค‘์ฒฉ ๋ฉ”๋‰ด๊ฐ€ '์Šค๋ฅด๋ฅต' ๋‚˜ํƒ€๋‚˜๋„๋ก CSS๋ฅผ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -````smart header="Follow-up events" -Certain events flow one into another. If we prevent the first event, there will be no second. +````smart header="ํ›„์† ์ด๋ฒคํŠธ" +์–ด๋–ค ์ด๋ฒคํŠธ๋“ค์€ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด๋ฒคํŠธ๋“ค์€ ์ฒซ ๋ฒˆ์งธ ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์œผ๋ฉด ๋‘ ๋ฒˆ์งธ ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. `<input>` ํ•„๋“œ์˜ `mousedown` ์ด๋ฒคํŠธ๋Š” `focus` ์ด๋ฒคํŠธ๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `mousedown`๋ฅผ ๋ง‰์œผ๋ฉด ํฌ์ปค์‹ฑ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +`<input>` ํ•„๋“œ์˜ `mousedown` ์ด๋ฒคํŠธ๋Š” `focus` ์ด๋ฒคํŠธ๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `mousedown`๋ฅผ ๋ง‰์œผ๋ฉด ํฌ์ปค์‹ฑ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š์ฃ . -Try to click on the first `<input>` below -- the `focus` event happens. But if you click the second one, there's no focus. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ์ฒซ ๋ฒˆ์งธ `<input>`์„ ํด๋ฆญํ•ด๋ด…์‹œ๋‹ค. `focus` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‘ ๋ฒˆ์งธ `<input>`๋Š” ํด๋ฆญํ•ด๋„ `focus` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```html run autorun -<input value="Focus works" onfocus="this.value=''"> -<input *!*onmousedown="return false"*/!* onfocus="this.value=''" value="Click me"> +<input value="focus๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค," onfocus="this.value=''"> +<input *!*onmousedown="return false"*/!* onfocus="this.value=''" value="ํด๋ฆญํ•ด ์ฃผ์„ธ์š”."> ``` -That's because the browser action is canceled on `mousedown`. The focusing is still possible if we use another way to enter the input. For instance, the `key:Tab` key to switch from the 1st input into the 2nd. But not with the mouse click any more. +๋‘ ๋ฒˆ์งธ `<input>`์—์„œ `focus` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” `mousedown` ์ด๋ฒคํŠธ์˜ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์ด ์ทจ์†Œ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด `focus` ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ `<input>`์— ํฌ์ปค์Šคํ•œ ์ƒํƒœ์—์„œ `key:Tab` ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ํฌ์ปค์Šค๊ฐ€ ๋‘ ๋ฒˆ์งธ `<input>`์œผ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ```` -## addEventListener์˜ "passive" ์˜ต์…˜ +## addEventListener์˜ 'passive' ์˜ต์…˜ -`addEventListener`์˜ ์˜ต์…˜์— `passive: true`๋ฅผ ์„ค์ •ํ•˜๋ฉด, `preventDefault()`๋ฅผ ์ด์šฉํ•ด ์Šคํฌ๋กค ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์ง€ ์•Š๊ฒ ๋‹ค๊ณ  ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ธ์‹์‹œํ‚ต๋‹ˆ๋‹ค. +`addEventListener`์˜ `passive: true` ์˜ต์…˜์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ `preventDefault()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ฒ ๋‹ค๊ณ  ์•Œ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ์™œ ํ•„์š”ํ•œ ๊ฑธ๊นŒ์š”? +์ด ์˜ต์…˜์€ ์™œ ํ•„์š”ํ•œ ๊ฑธ๊นŒ์š”? -๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์—๋Š” (์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋ฆฐ์— ์†๊ฐ€๋ฝ์„ ๋Œ€๊ณ  ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” )`touchmove`์™€ ๊ฐ™์€ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด๋ฒคํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์Šคํฌ๋กค๋ง(scrolling)์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ธ๋“ค๋Ÿฌ์˜ `preventDefault()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ๋™์ž‘์ธ ์Šคํฌ๋กค๋ง์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋ฆฐ์— ์†๊ฐ€๋ฝ์„ ๋Œ€๊ณ  ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” `touchmove`์™€ ๊ฐ™์€ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด๋ฒคํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์Šคํฌ๋กค๋ง(scrolling)์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ•ธ๋“ค๋Ÿฌ์˜ `preventDefault()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋กค๋ง์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋กค๋ง์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ, ๋จผ์ € ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, ์ด๋•Œ `preventDefault`๊ฐ€ ์–ด๋””์—์„œ๋„ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด, ๊ทธ์ œ์•ผ ์Šคํฌ๋กค๋ง์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋ถˆํ•„์š”ํ•œ ์ง€์—ฐ์ด ์ƒ๊ธฐ๊ณ , UI๊ฐ€ "๋œ๋œ ๋–จ๋ฆฌ๋Š”" ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํฌ๋กค๋ง์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ ๋จผ์ € ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, ์ด๋•Œ `preventDefault`๊ฐ€ ์–ด๋””์—์„œ๋„ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด, ๊ทธ์ œ์•ผ ์Šคํฌ๋กค๋ง์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋ถˆํ•„์š”ํ•œ ์ง€์—ฐ์ด ์ƒ๊ธฐ๊ณ , ํ™”๋ฉด์ด '๋œ๋œ ๋–จ๋ฆฌ๋Š”' ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -`passive: true` ์˜ต์…˜์€ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์Šคํฌ๋กค๋ง์„ ์ทจ์†Œํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ตœ๋Œ€ํ•œ ์ž์—ฐ์Šค๋Ÿฌ์šด ๋™์ž‘์œผ๋กœ ์Šคํฌ๋กค๋ง ๋˜๊ณ , ์ด๋ฒคํŠธ๋Š” ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. +`passive: true` ์˜ต์…˜์€ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์Šคํฌ๋กค๋ง์„ ์ทจ์†Œํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ํ™”๋ฉด์„ ์ตœ๋Œ€ํ•œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์Šคํฌ๋กค๋ง ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ์ด๋ฒคํŠธ๋Š” ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. Firefox, Chrome ๊ฐ™์€ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ `touchstart` ์™€ `touchmove` ์ด๋ฒคํŠธ์˜ `passive` ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด `true`์ž…๋‹ˆ๋‹ค. @@ -111,52 +111,52 @@ Firefox, Chrome ๊ฐ™์€ ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ `touchstart` ์™€ `touchmove` ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰์€ ๊ฒฝ์šฐ๋Š” `event.defaultPrevented` ๊ฐ’์ด `true` ์ด๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” `false` ์ž…๋‹ˆ๋‹ค. -์ด๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํฅ๋ฏธ๋กœ์šด ์œ ์Šค ์ผ€์ด์Šค(use case)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฅผ ์ด์šฉํ•œ ํฅ๋ฏธ๋กœ์šด ์œ ์Šค ์ผ€์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -<info:bubbling-and-capturing> ์ฑ•ํ„ฐ์˜ `event.stopPropagation()`๋ฅผ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”? ์—ฌ๊ธฐ์„œ ๋ฒ„๋ธ”๋ง์„ ๋ง‰๋Š” ๊ฒŒ ์™œ ๋‚˜์œ์ง€ ์ด์•ผ๊ธฐํ•œ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. +<info:bubbling-and-capturing> ์ฑ•ํ„ฐ์—์„œ ๋ฐฐ์šด `event.stopPropagation()`๋ฅผ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”? ์—ฌ๊ธฐ์„œ ๋ฒ„๋ธ”๋ง์„ ๋ง‰๋Š” ๊ฒŒ ์™œ ๋‚˜์œ์ง€ ์ด์•ผ๊ธฐํ•œ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -Sometimes we can use `event.defaultPrevented` instead, to signal other event handlers that the event was handled. +๊ฐ€๋”์€ `event.stopPropagation()`๋Œ€์‹ ์— `event.defaultPrevented`๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ๊ฐ€ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌ๋˜์—ˆ๋‹ค๊ณ  ๋‹ค๋ฅธ ์ด๋ฒคํŠธ์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -Let's see a practical example. +์‹ค์ œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ด ๋ง์„ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค. -`์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด(contextmenu)`๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œจ์ฃ . ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ๋Œ€์‹  ๋‹ค๋ฅธ ๊ฑธ ๋„์šธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ : +๋ธŒ๋ผ์šฐ์ €์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด `contextmenu`๋ผ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œจ์ฃ . ๊ทธ๋Ÿฐ๋ฐ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ๋Œ€์‹  ๋‹ค๋ฅธ ๊ฑธ ๋„์šธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ . ```html autorun height=50 no-beautify run -<button>Right-click shows browser context menu</button> +<button>๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œน๋‹ˆ๋‹ค.</button> -<button *!*oncontextmenu="alert('Draw our menu'); return false"*/!*> - Right-click shows our context menu +<button *!*oncontextmenu="alert('์ปค์Šคํ…€ ๋ฉ”๋‰ด๊ฐ€ ๋œจ๋„ค์š”!'); return false"*/!*> + ์—ฌ๊ธฐ์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด๋ณด์„ธ์š”. </button> ``` -Now, in addition to that context menu we'd like to implement document-wide context menu. +์ด๋ ‡๊ฒŒ ๋ฒ„ํŠผ์—์„œ๋งŒ ์ž์ฒด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๋ฅผ ๋„์šฐ๋Š” ๋Œ€์‹ , ๋ฌธ์„œ ๋ ˆ๋ฒจ์—์„œ๋„ ์ž์ฒด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๋ฅผ ๋œจ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Upon right click, the closest context menu should show up. +๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ```html autorun height=80 no-beautify run -<p>Right-click here for the document context menu</p> -<button id="elem">Right-click here for the button context menu</button> +<p>๋ฌธ์„œ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด</p> +<button id="elem">๋ฒ„ํŠผ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด</button> <script> elem.oncontextmenu = function(event) { event.preventDefault(); - alert("Button context menu"); + alert("๋ฒ„ํŠผ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; document.oncontextmenu = function(event) { event.preventDefault(); - alert("Document context menu"); + alert("๋ฌธ์„œ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; </script> ``` -`elem`์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋‘ ๊ฐœ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œจ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค: ๋ฒ„ํŠผ ๋ ˆ๋ฒจ์˜ ๋ฉ”๋‰ด์™€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์„œ ๋ ˆ๋ฒจ์˜ ๋ฉ”๋‰ด๊ฐ€ ๋œจ์ฃ . +๊ทธ๋Ÿฐ๋ฐ ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๋ฉด `elem`์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋‘ ๊ฐœ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œจ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋˜๋ฉด์„œ ๋ฒ„ํŠผ ๋ ˆ๋ฒจ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์™€ ๋ฌธ์„œ ๋ ˆ๋ฒจ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋œจ๋Š” ๊ฒƒ์ด์ฃ . -How to fix it? One of solutions is to think like: "When we handle right-click in the button handler, let's stop its bubbling" and use `event.stopPropagation()`: +์–ด๋–ป๊ฒŒ ์ด ๋ฌธ์ œ๋ฅผ ๊ณ ์น  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๊ฐ€์žฅ ๋จผ์ € ๋– ์˜ค๋ฅด๋Š” ์ƒ๊ฐ์€ "๋ฒ„ํŠผ์— ๊ตฌํ˜„๋œ ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚˜๋ฉด ๋ฒ„๋ธ”๋ง์ด ๋ฉˆ์ถ”๋„๋ก ํ•˜์ž"์ผ ๊ฒ๋‹ˆ๋‹ค. ์ด๋•Œ `event.stopPropagation()`์„ ์‚ฌ์šฉํ•˜๊ฒ ์ฃ . ```html autorun height=80 no-beautify run -<p>Right-click for the document menu</p> -<button id="elem">Right-click for the button menu (fixed with event.stopPropagation)</button> +<p>๋ฌธ์„œ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด</p> +<button id="elem">๋ฒ„ํŠผ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด(event.stopPropagation๋ฅผ ์‚ฌ์šฉํ•ด ๋ฒ„๊ทธ ์ˆ˜์ •)</button> <script> elem.oncontextmenu = function(event) { @@ -164,29 +164,29 @@ How to fix it? One of solutions is to think like: "When we handle right-click in *!* event.stopPropagation(); */!* - alert("Button context menu"); + alert("๋ฒ„ํŠผ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; document.oncontextmenu = function(event) { event.preventDefault(); - alert("Document context menu"); + alert("๋ฌธ์„œ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; </script> ``` -์ด์ œ ์˜๋„ํ•œ ๋Œ€๋กœ ๋ฒ„ํŠผ ๋ ˆ๋ฒจ์˜ ๋ฉ”๋‰ด๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์— ๋Œ€ํ•œ ๋Œ€๊ฐ€๊ฐ€ ๋„ˆ๋ฌด ํฝ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ ๋”๋Š” ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ†ต๊ณ„ ์ž๋ฃŒ ์ˆ˜์ง‘์„ ์œ„ํ•œ ์นด์šดํ„ฐ ๋“ฑ์ด ๋™์ž‘ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฑฐ์ฃ . ํ˜„๋ช…ํ•˜์ง€ ๋ชปํ•œ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค. +์ด์ œ ์˜๋„ํ•œ ๋Œ€๋กœ ๋ฒ„ํŠผ์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฒ„ํŠผ ๋ ˆ๋ฒจ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๋งŒ ๋œน๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์— ๋Œ€ํ•œ ๋Œ€๊ฐ€๊ฐ€ ๋„ˆ๋ฌด ํฝ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋”๋Š” ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ†ต๊ณ„ ์ž๋ฃŒ ์ˆ˜์ง‘์„ ์œ„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ๋ชปํ•˜์ฃ . ํ˜„๋ช…ํ•˜์ง€ ๋ชปํ•œ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค. -`document`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ์—์„œ ๊ธฐ๋ณธ ๋™์ž‘์ด ๋ง‰ํ˜€์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฉด ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋™์ž‘์ด ๋ง‰ํ˜€์žˆ๋Š”๋ฐ ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋งํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ์ด์— ๋ฐ˜์‘ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ฉด ๋˜๋Š” ๊ฑฐ์ฃ . +`event.stopPropagation()`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๋Œ€์‹ ์— `document` ํ•ธ๋“ค๋Ÿฌ์—์„œ ๊ธฐ๋ณธ ๋™์ž‘์ด ๋ง‰ํ˜€์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋™์ž‘์ด ๋ง‰ํ˜€์žˆ๋Š”๋ฐ ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋งํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ์ด์— ๋ฐ˜์‘ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ฉด ๋˜์ฃ . ```html autorun height=80 no-beautify run -<p>Right-click for the document menu (added a check for event.defaultPrevented)</p> -<button id="elem">Right-click for the button menu</button> +<p>๋ฌธ์„œ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด(event.defaultPrevented๋ฅผ ํ™•์ธํ•จ)</p> +<button id="elem">๋ฒ„ํŠผ ๋ ˆ๋ฒจ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด</button> <script> elem.oncontextmenu = function(event) { event.preventDefault(); - alert("Button context menu"); + alert("๋ฒ„ํŠผ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; document.oncontextmenu = function(event) { @@ -195,50 +195,50 @@ How to fix it? One of solutions is to think like: "When we handle right-click in */!* event.preventDefault(); - alert("Document context menu"); + alert("๋ฌธ์„œ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด"); }; </script> ``` -์ด์ œ ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ ์š”์†Œ๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๊ณ , ์š”์†Œ๋งˆ๋‹ค ๊ฐ๊ฐ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์ด์   ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ `contextmenu` ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.defaultPrevented`๋ฅผ ํ™•์ธํ•ด์„œ ๋ง์ด์ฃ . +์ด์ œ ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ ์š”์†Œ๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๊ณ , ์š”์†Œ๋งˆ๋‹ค ๊ฐ๊ฐ์˜ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์ด์   ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•  ๊ฒ๋‹ˆ๋‹ค. ๊ฐ `contextmenu` ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.defaultPrevented`๋ฅผ ํ™•์ธํ•˜๋ฉด ๋˜์ฃ . -```smart header="event.stopPropagation()์™€ event.preventDefault()" -์œ„ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ๋ณด์•˜๋“ฏ์ด, `event.stopPropagation()`์™€ (`return false`๋กœ ์•Œ๋ ค์ง„)`event.preventDefault()` ๋Š” ๋ช…๋ฐฑํžˆ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฉ”์„œ๋“œ๋Š” ์—ฐ๊ด€์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค. +```smart header="event.stopPropagation()๊ณผ event.preventDefault()" +์œ„ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ๋ณด์•˜๋“ฏ์ด, `event.stopPropagation()`๊ณผ `return false`๋กœ ์•Œ๋ ค์ง„ `event.preventDefault()`๋Š” ๋ช…๋ฐฑํžˆ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฉ”์„œ๋“œ๋Š” ์—ฐ๊ด€์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค. ``` ```smart header="์ค‘์ฒฉ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์˜ ์•„ํ‚คํ…์ฒ˜" -There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow to store other handlers in it. +์ค‘์ฒฉ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์—ญ ๊ฐ์ฒด์— `document.oncontextmenu` ์ „์šฉ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. -์ด ์ „์—ญ ๊ฐ์ฒด๋Š” ๋ชจ๋“  ์šฐํด๋ฆญ์„ ์žก์•„๋‚ด์„œ ๋‚ด๋ถ€์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ดํŽด๋ณธ ํ›„, ์ ์ ˆํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ๊ฒ๋‹ˆ๋‹ค. +์ด ์ „์—ญ ๊ฐ์ฒด๋Š” ๋ชจ๋“  ์šฐํด๋ฆญ์„ ์žก์•„๋‚ด์„œ ๋‚ด๋ถ€์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ดํŽด๋ณธ ํ›„ ์ ์ ˆํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ๊ฒ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด, ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์— ๊ด€๋ จ๋œ ๊ฐ ์ฝ”๋“œ ์กฐ๊ฐ๋“ค์ด ์ด ๊ฐ์ฒด์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์–ด์•ผ๋งŒ ํ•˜๊ณ , ์ž์‹ ๋งŒ์˜ `contextmenu` ํ•ธ๋“ค๋Ÿฌ ๋Œ€์‹  ๊ฐ์ฒด์˜ ๋„์›€์„ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์— ๊ด€๋ จ๋œ ๊ฐ ์ฝ”๋“œ ์กฐ๊ฐ๋“ค์ด ์ด ๊ฐ์ฒด์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•˜๊ณ , ์ž์‹ ๋งŒ์˜ `contextmenu` ํ•ธ๋“ค๋Ÿฌ ๋Œ€์‹  ๊ฐ์ฒด์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๋‹จ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ``` ## ์š”์•ฝ -๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋ณธ ๋™์ž‘: +๊ฐ ์ด๋ฒคํŠธ์— ๋Œ€์‘ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `mousedown` -- (๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ธ ๊ณณ์—์„œ) ์„ ํƒ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. -- `<input type="checkbox">`์„ `click` -- `input`์„ ์„ ํƒ/์„ ํƒํ•ด์ œ(check/uncheck) ํ•ฉ๋‹ˆ๋‹ค. -- `submit` -- ํผ ์•ˆ์—์„œ `<input type="submit">`์„ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ `key:Enter`๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €๋Š” ํผ์„ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. +- `mousedown` -- ๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ธ ๊ณณ์—์„œ ์„ ํƒ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. +- `<input type="checkbox">`๋ฅผ `click` -- `input`์„ ์„ ํƒ/์„ ํƒํ•ด์ œ ํ•ฉ๋‹ˆ๋‹ค. +- `submit` -- ํผ ์•ˆ์—์„œ `<input type="submit">`์„ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ `key:Enter`๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €๋Š” ํผ์„ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. - `keydown` -- ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ…์ŠคํŠธ ๋ฐ•์Šค์— ๊ธ€์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ทธ ์™ธ์˜ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. - `contextmenu` -- ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋กœ, ๋ธŒ๋ผ์šฐ์ € ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. -- ...๊ทธ ์™ธ ๋‹ค์–‘ํ•œ ๋™์ž‘์ด ์žˆ์Šต๋‹ˆ๋‹ค... +- ์ด ์™ธ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋ณธ ๋™์ž‘์ด ์žˆ์Šต๋‹ˆ๋‹ค. -๋ชจ๋“  ๊ธฐ๋ณธ๋™์ž‘์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋‹ค๋ฃธ์œผ๋กœ์จ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ๋™์ž‘์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`event.preventDefault()` ๋‚˜ `return false`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๋ฉ”์„œ๋“œ๋Š” `on<event>`๋ฅผ ํ†ตํ•ด ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +`event.preventDefault()`๋‚˜ `return false`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `return false`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ `on<event>`๋ฅผ ํ†ตํ•ด ํ• ๋‹นํ•œ ํ•ธ๋“ค๋Ÿฌ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -`addEventListener`์˜ `passive: true` ์˜ต์…˜์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ ๋ชจ๋ฐ”์ผ์—์„œ ๋ฐœ์ƒํ•˜๋Š” `touchstart` ์™€ `touchmove`๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ์Šคํฌ๋กค๋ง์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +`addEventListener`์˜ `passive: true` ์˜ต์…˜์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ ๋ชจ๋ฐ”์ผ์—์„œ ๋ฐœ์ƒํ•˜๋Š” `touchstart`์™€ `touchmove`๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ์Šคํฌ๋กค๋ง์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์€ ๊ฒฝ์šฐ, `event.defaultPrevented` ๊ฐ’์€ `true`์ด๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” `false` ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. +๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์€ ๊ฒฝ์šฐ, `event.defaultPrevented` ๊ฐ’์€ `true`์ด๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” `false`์ž…๋‹ˆ๋‹ค. -```warn header="Stay semantic, don't abuse" -๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์š”์†Œ์˜ ๋™์ž‘์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์ ์ธ ์ œ์•ฝ ์—†์ด ๋ง์ด์ฃ . ๋งํฌ `<a>`๋ฅผ ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ๋ฒ„ํŠผ `<button>`์„ (๋‹ค๋ฅธ URL๋กœ ์ „์†ก์‹œ์ผœ์ฃผ๋Š”) ๋งํฌ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +```warn header="๊ธฐ๋ณธ ๋™์ž‘ ๋ง‰๊ธฐ๋ฅผ ๋„ˆ๋ฌด ๋‚จ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”." +๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ œ์•ฝ ์—†์ด ์š”์†Œ์˜ ๋™์ž‘์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ `<a>`๋ฅผ ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ๋ฒ„ํŠผ `<button>`์„ ๋‹ค๋ฅธ URL๋กœ ์ด๋™์‹œ์ผœ์ฃผ๋Š” ๋งํฌ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ HTML ์š”์†Œ์˜ ์˜๋ฏธ๋ฅผ ์ง€ํ‚ค๋ฉด์„œ ๋™์ž‘์„ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. `<a>`๋Š” ํŽ˜์ด์ง€๋ฅผ ๋Œ์•„๋‹ค๋‹ˆ๋Š” ๋™์ž‘์„ ํ•ด์•ผ ํ•˜์ง€ ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ด์„  ์•ˆ ๋ฉ๋‹ˆ๋‹ค. -์ด๋ ‡๊ฒŒ ์š”์†Œ๊ฐ€ ๊ฐ€์ง„ ์˜๋ฏธ๋ฅผ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด "์ข‹์€ ์ฝ”๋“œ"๊ฐ€ ๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ ‘๊ทผ์„ฑ ์ธก๋ฉด์—์„œ๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ์š”์†Œ๊ฐ€ ๊ฐ€์ง„ ์˜๋ฏธ๋ฅผ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด '์ข‹์€ ์ฝ”๋“œ'๊ฐ€ ๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ ‘๊ทผ์„ฑ ์ธก๋ฉด์—์„œ๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. -`<a>`๋ฅผ ์ด์šฉํ•œ ์˜ˆ์ œ๋ฅผ ๊ณ ๋ คํ•œ๋‹ค๋ฉด ๋‹ค์Œ์— ์ฃผ์˜ํ•˜์‹œ๊ธธ ๊ถŒํ•ฉ๋‹ˆ๋‹ค: ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ ๋•๋ถ„์— ์‚ฌ์šฉ์ž๋Š” ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ๋“ฑ์˜ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด ์ƒˆ ์ฐฝ์—์„œ ๋งํฌ๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ธ๊ธฐ๊ฐ€ ๋งŽ์ฃ . ํ•˜์ง€๋งŒ, ๋ฒ„ํŠผ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ ์กฐ์ž‘ํ•ด ๋งํฌ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , CSS๋ฅผ ์ด์šฉํ•ด ๋งํฌ์ฒ˜๋Ÿผ ๊พธ๋ฏธ๋”๋ผ๋„, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ œ๊ณตํ•˜๋Š” `<a>`์™€ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์€ ๋ฒ„ํŠผ์—์„  ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +`<a>`์™€ ๊ธฐ๋ณธ๋™์ž‘ ๋ง‰๊ธฐ๋ฅผ ์กฐํ•ฉํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌ์ƒํ•  ๋•Œ ์ฃผ์˜ํ•  ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ์‚ฌ์šฉํ•ด ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ๋“ฑ์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒˆ ์ฐฝ์—์„œ ๋งํฌ๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ธ๊ธฐ๊ฐ€ ๋งŽ์ฃ . ํ•˜์ง€๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ฒ„ํŠผ์„ ์กฐ์ž‘ํ•ด ๋งํฌ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  CSS๋ฅผ ์ด์šฉํ•ด ๋ฒ„ํŠผ์„ ๋งํฌ์ฒ˜๋Ÿผ ๊พธ๋ฏธ๋”๋ผ๋„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” `<a>` ๊ด€๋ จ ๊ธฐ๋Šฅ์€ ๋ฒ„ํŠผ์—์„  ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ``` diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md index 984e31d904..a9a3b2c3e3 100644 --- a/2-ui/2-events/05-dispatch-events/article.md +++ b/2-ui/2-events/05-dispatch-events/article.md @@ -1,40 +1,40 @@ -# Dispatching custom events +# ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ๋””์ŠคํŒจ์น˜ -We can not only assign handlers, but also generate events from JavaScript. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด๋ฒคํŠธ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -Custom events can be used to create "graphical components". For instance, a root element of our own JS-based menu may trigger events telling what happens with the menu: `open` (menu open), `select` (an item is selected) and so on. Another code may listen for the events and observe what's happening with the menu. +์ด๋ ‡๊ฒŒ ์ง์ ‘ ๋งŒ๋“  ์ปค์Šคํ…€ ์ด๋ฒคํŠธ(custom event)๋Š” '๊ทธ๋ž˜ํ”ฝ ์ปดํฌ๋„ŒํŠธ(graphical component)'๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ๋ฉ”๋‰ด์˜ ๋ฃจํŠธ ์š”์†Œ์— `open`(๋ฉ”๋‰ด๋ฅผ ์—ด์—ˆ์„ ๋•Œ ์‹คํ–‰๋จ), `select`(ํ•ญ๋ชฉ์„ ์„ ํƒํ–ˆ์„ ๋•Œ ์‹คํ–‰๋จ) ๊ฐ™์€ ์ด๋ฒคํŠธ๋ฅผ ๋‹ฌ์•„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฃจํŠธ ์š”์†Œ์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋‹ฌ์•„๋†“์œผ๋ฉด ๋ฐ”๊นฅ ์ฝ”๋“œ์—์„œ๋„ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋‹์„ ํ†ตํ•ด ๋ฉ”๋‰ด์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -We can generate not only completely new events, that we invent for our own purposes, but also built-in ones, such as `click`, `mousedown` etc. That may be helpful for automated testing. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชฉ์ ์— ๋”ฐ๋ผ `click`, `mousedown` ๊ฐ™์€ ๋‚ด์žฅ ์ด๋ฒคํŠธ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŒ๋“  ๋‚ด์žฅ ์ด๋ฒคํŠธ๋“ค์€ ํ…Œ์ŠคํŒ…์„ ์ž๋™ํ™”ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -## Event constructor +## Event์˜ ์ƒ์„ฑ์ž -Build-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in [Event](http://www.w3.org/TR/dom/#event) class. +๋‚ด์žฅ ์ด๋ฒคํŠธ ํด๋ž˜์Šค๋Š” DOM ์š”์†Œ ํด๋ž˜์Šค๊ฐ™์ด ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ ์ด๋ฒคํŠธ ํด๋ž˜์Šค ๊ณ„์ธต์˜ ๊ผญ๋Œ€๊ธฐ์—” [Event](http://www.w3.org/TR/dom/#event) ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -We can create `Event` objects like this: +`Event` ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js let event = new Event(type[, options]); ``` -Arguments: +์ธ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- *type* -- event type, a string like `"click"` or our own like `"my-event"`. -- *options* -- the object with two optional properties: - - `bubbles: true/false` -- if `true`, then the event bubbles. - - `cancelable: true/false` -- if `true`, then the "default action" may be prevented. Later we'll see what it means for custom events. +- *type* -- ์ด๋ฒคํŠธ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด๋กœ `"click"`๊ฐ™์€ ๋‚ด์žฅ ์ด๋ฒคํŠธ, `"my-event"` ๊ฐ™์€ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๊ฐ€ ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +- *options* -- ๋‘ ๊ฐœ์˜ ์„ ํƒ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ์˜ต๋‹ˆ๋‹ค. + - `bubbles: true/false` -- `true`์ธ ๊ฒฝ์šฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง ๋ฉ๋‹ˆ๋‹ค. + - `cancelable: true/false` -- `true`์ธ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € '๊ธฐ๋ณธ ๋™์ž‘'์ด ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ์„น์…˜์—์„œ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. - By default both are false: `{bubbles: false, cancelable: false}`. + ์•„๋ฌด๋Ÿฐ ๊ฐ’๋„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ `{bubbles: false, cancelable: false}`์ฒ˜๋Ÿผ `false`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ## dispatchEvent -After an event object is created, we should "run" it on an element using the call `elem.dispatchEvent(event)`. +์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ์—” `elem.dispatchEvent(event)`๋ฅผ ํ˜ธ์ถœํ•ด ์š”์†Œ์— ์žˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐ˜๋“œ์‹œ '์‹คํ–‰'์‹œ์ผœ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค(dispatch๋Š” ์ผ์„ '์ฒ˜๋ฆฌํ•˜๋‹ค'๋ผ๋Š” ๋œป์„ ๊ฐ€์ง„ ์˜์–ด๋‹จ์–ด์ž…๋‹ˆ๋‹ค - ์˜ฎ๊ธด์ด). -Then handlers react on it as if it were a regular browser event. If the event was created with the `bubbles` flag, then it bubbles. +์ด๋ ‡๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰์‹œ์ผœ์ค˜์•ผ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `bubbles` ํ”Œ๋ž˜๊ทธ๋ฅผ `true`๋กœ ํ•ด์„œ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ ์ด๋ฒคํŠธ๋Š” ์ œ๋Œ€๋กœ ๋ฒ„๋ธ”๋ง ๋ฉ๋‹ˆ๋‹ค. -In the example below the `click` event is initiated in JavaScript. The handler works same way as if the button was clicked: +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด `click` ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹คํ–‰ ์‹œ์ผœ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ์‹ค์ œ๋กœ ํด๋ฆญํ•˜์ง€ ์•Š์•˜์ง€๋งŒ, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run no-beautify -<button id="elem" onclick="alert('Click!');">Autoclick</button> +<button id="elem" onclick="alert('ํด๋ฆญ!');">์ž๋™์œผ๋กœ ํด๋ฆญ ๋˜๋Š” ๋ฒ„ํŠผ</button> <script> let event = new Event("click"); @@ -43,59 +43,59 @@ In the example below the `click` event is initiated in JavaScript. The handler w ``` ```smart header="event.isTrusted" -There is a way to tell a "real" user event from a script-generated one. +`event.isTrusted`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•œ ์ด๋ฒคํŠธ์ธ์ง€ '์ง„์งœ' ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ์ด๋ฒคํŠธ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The property `event.isTrusted` is `true` for events that come from real user actions and `false` for script-generated events. +`event`์˜ `isTrusted` ํ”„๋กœํผํ‹ฐ๊ฐ€ `true`์ด๋ฉด ์‚ฌ์šฉ์ž ์•ก์…˜์„ ํ†ตํ•ด ๋งŒ๋“  ์ด๋ฒคํŠธ๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. `isTrusted`๊ฐ€ `false`์ด๋ฉด ํ•ด๋‹น ์ด๋ฒคํŠธ๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋˜์—ˆ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -## Bubbling example +## ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ์˜ˆ์‹œ -We can create a bubbling event with the name `"hello"` and catch it on `document`. +`"hello"`๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฒ„๋ธ”๋ง ์‹œ์ผœ์„œ `document`์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -All we need is to set `bubbles` to `true`: +์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋˜๊ฒŒ ํ•˜๋ ค๋ฉด `bubbles`๋ฅผ `true`๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```html run no-beautify <h1 id="elem">Hello from the script!</h1> <script> - // catch on document... + // ๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚˜๋ฉด์„œ document์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋จ document.addEventListener("hello", function(event) { // (1) alert("Hello from " + event.target.tagName); // Hello from H1 }); - // ...dispatch on elem! + // ์ด๋ฒคํŠธ(hello)๋ฅผ ๋งŒ๋“ค๊ณ  elem์—์„œ ์ด๋ฒคํŠธ ๋””์ŠคํŒจ์น˜ let event = new Event("hello", {bubbles: true}); // (2) elem.dispatchEvent(event); - // the handler on document will activate and display the message. + // document์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ์–ผ๋Ÿฟ์ฐฝ์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. </script> ``` -Notes: +์œ„ ์˜ˆ์‹œ์—์„œ ์ฃผ์˜ํ•ด์„œ ๋ณผ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. We should use `addEventListener` for our custom events, because `on<event>` only exists for built-in events, `document.onhello` doesn't work. -2. Must set `bubbles:true`, otherwise the event won't bubble up. +1. `on<event>`์€ ๋‚ด์žฅ ์ด๋ฒคํŠธ์—๋งŒ ํ•ด๋‹นํ•˜๋Š” ๋ฌธ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์— `document.onhello`๋ผ๊ณ  ํ•˜๋ฉด ์›ํ•˜๋Š” ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋Š” ๋ฐ˜๋“œ์‹œ `addEventListener`๋ฅผ ์‚ฌ์šฉํ•ด ํ•ธ๋“ค๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +2. `bubbles:true`๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -The bubbling mechanics is the same for built-in (`click`) and custom (`hello`) events. There are also capturing and bubbling stages. +๋‚ด์žฅ ์ด๋ฒคํŠธ(`click`)์™€ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ(`hello`)์˜ ๋ฒ„๋ธ”๋ง ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ํ•˜์—ฌ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ์—๋„ ๋‚ด์žฅ ์ด๋ฒคํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์บก์ณ๋ง, ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -## MouseEvent, KeyboardEvent and others +## MouseEvent, KeyboardEvent ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ -Here's a short list of classes for UI Events from the [UI Event specification](https://www.w3.org/TR/uievents): +๋ช…์„ธ์„œ์˜ [UI ์ด๋ฒคํŠธ](https://www.w3.org/TR/uievents) ์„น์…˜์—” ๋‹ค์–‘ํ•œ UI ์ด๋ฒคํŠธ ํด๋ž˜์Šค๊ฐ€ ๋ช…์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘ ์ผ๋ถ€๋ฅผ ์ถ”๋ฆฌ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. - `UIEvent` - `FocusEvent` - `MouseEvent` - `WheelEvent` - `KeyboardEvent` -- ... +- ๋“ฑ๋“ฑ... -We should use them instead of `new Event` if we want to create such events. For instance, `new MouseEvent("click")`. +๊ทธ๋Ÿฐ๋ฐ ์ด ์ด๋ฒคํŠธ๋“ค์€ `new Event`๋กœ ๋งŒ๋“ค๋ฉด ์•ˆ ๋˜๊ณ , ๋ฐ˜๋“œ์‹œ ๊ด€๋ จ ๋‚ด์žฅ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค ํด๋ฆญ ์ด๋ฒคํŠธ๋ผ๋ฉด `new MouseEvent("click")`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ฃ . -The right constructor allows to specify standard properties for that type of event. +์ด๋ ‡๊ฒŒ ์ œ๋Œ€๋กœ ๋œ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ•ด๋‹น ์ด๋ฒคํŠธ ์ „์šฉ ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Like `clientX/clientY` for a mouse event: +`new MouseEvent("click")`๋ฅผ ์‚ฌ์šฉํ•ด ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์˜ `clientX`, `clientY` ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ค์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```js run let event = new MouseEvent("click", { @@ -110,71 +110,71 @@ alert(event.clientX); // 100 */!* ``` -Please note: the generic `Event` constructor does not allow that. +์ด์ œ ์ผ๋ฐ˜ `Event` ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ค์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -Let's try: +์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์ง์ ‘ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let event = new Event("click", { - bubbles: true, // only bubbles and cancelable - cancelable: true, // work in the Event constructor + bubbles: true, // Event ์ƒ์„ฑ์ž์—์„  + cancelable: true, // bubbles์™€ cancelable ํ”„๋กœํผํ‹ฐ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. clientX: 100, clientY: 100 }); *!* -alert(event.clientX); // undefined, the unknown property is ignored! +alert(event.clientX); // undefined, ์•Œ ์ˆ˜ ์—†๋Š” ํ”„๋กœํผํ‹ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. */!* ``` -Technically, we can work around that by assigning directly `event.clientX=100` after creation. So that's a matter of convenience and following the rules. Browser-generated events always have the right type. +`new Event`๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ, `event.clientX=100`์ฒ˜๋Ÿผ ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ์ง์ ‘ ๋ช…์‹œํ•ด์ฃผ๋ฉด ์ด๋Ÿฐ ์ œ์•ฝ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค. ์œ„์™€ ๊ฐ™์€ ์ œ์•ฝ์„ ๋”ฐ๋ฅด๋Š” ๊ฑด ๊ฐœ๋ฐœ์ž ๋งˆ์Œ์ด๊ธด ํ•˜์ฃ . ๊ทธ๋ ‡์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋งŒ๋“ค์–ด์ง€๋Š” UI ์ด๋ฒคํŠธ๋Š” ์ ํ™•ํ•œ ์ด๋ฒคํŠธ ํƒ€์ž…์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘๋Š” ๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. -The full list of properties for different UI events is in the specification, for instance, [MouseEvent](https://www.w3.org/TR/uievents/#mouseevent). +UI ์ด๋ฒคํŠธ๋ณ„ ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์€ ๋ช…์„ธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `MouseEvent`์˜ ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋Š” [๋งํฌ](https://www.w3.org/TR/uievents/#mouseevent)์— ์žˆ์œผ๋‹ˆ ํ™•์ธํ•ด ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -## Custom events +## ์ปค์Šคํ…€ ์ด๋ฒคํŠธ -For our own, completely new events types like `"hello"` we should use `new CustomEvent`. Technically [CustomEvent](https://dom.spec.whatwg.org/#customevent) is the same as `Event`, with one exception. +์ง€๊ธˆ๊นŒ์ง„ `new Event`๋กœ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ œ๋Œ€๋กœ ๋œ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด `new CustomEvent`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [CustomEvent](https://dom.spec.whatwg.org/#customevent)๋Š” `Event`์™€ ๊ฑฐ์˜ ์œ ์‚ฌํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -In the second argument (object) we can add an additional property `detail` for any custom information that we want to pass with the event. +`CustomEvent`์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜์—” ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ฐœ๋ฐœ์ž๋Š” ์ด ๊ฐ์ฒด์— `detail`์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ๊ด€๋ จ ์ •๋ณด๋ฅผ ๋ช…์‹œํ•˜๊ณ , ์ •๋ณด๋ฅผ ์ด๋ฒคํŠธ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```html run refresh -<h1 id="elem">Hello for John!</h1> +<h1 id="elem">์ด๋ณด๋ผ๋‹˜, ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!</h1> <script> - // additional details come with the event to the handler + // ์ถ”๊ฐ€ ์ •๋ณด๋Š” ์ด๋ฒคํŠธ์™€ ํ•จ๊ป˜ ํ•ธ๋“ค๋Ÿฌ์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. elem.addEventListener("hello", function(event) { alert(*!*event.detail.name*/!*); }); elem.dispatchEvent(new CustomEvent("hello", { *!* - detail: { name: "John" } + detail: { name: "๋ณด๋ผ" } */!* })); </script> ``` -The `detail` property can have any data. Technically we could live without, because we can assign any properties into a regular `new Event` object after its creation. But `CustomEvent` provides the special `detail` field for it to evade conflicts with other event properties. +`detail` ํ”„๋กœํผํ‹ฐ์—” ์–ด๋–ค ๋ฐ์ดํ„ฐ๋„ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค `new Event`๋กœ ์ผ๋ฐ˜ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด๋ฒคํŠธ ๊ฐ์ฒด์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— `detail` ํ”„๋กœํผํ‹ฐ ์—†์ด๋„ ์ถฉ๋ถ„ํžˆ ์ด๋ฒคํŠธ์— ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ๋„ `detail`์ด๋ผ๋Š” ํŠน๋ณ„ํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ํ”„๋กœํผํ‹ฐ์™€ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค. -Besides, the event class describes "what kind of event" it is, and if the event is custom, then we should use `CustomEvent` just to be clear about what it is. +์ด ์™ธ์—๋„ `new CustomEvent`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ ์ž์ฒด๋งŒ์œผ๋กœ '์ปค์Šคํ…€ ์ด๋ฒคํŠธ'๋ผ๊ณ  ์„ค๋ช…ํ•ด์ฃผ๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ## event.preventDefault() -Many browser events have a "default action", such as nagivating to a link, starting a selection, and so on. +๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ ๋Œ€๋‹ค์ˆ˜๋Š” '๊ธฐ๋ณธ ๋™์ž‘'๊ณผ ํ•จ๊ป˜ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋งํฌ ํด๋ฆญ ์‹œ ํŠน์ • URL๋กœ ์ด๋™ํ•˜๊ธฐ, ์ „์†ก ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์„œ๋ฒ„์— ํผ ์ „์†กํ•˜๊ธฐ ๊ฐ™์€ ๋™์ž‘์€ ์ด๋Ÿฐ ๊ธฐ๋ณธ ๋™์ž‘์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. -For new, custom events, there are definitely no default browser actions, but a code that dispatches such event may have its own plans what to do after triggering the event. +์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ๋งŒ๋“  ์ปค์Šคํ…€ ์ด๋ฒคํŠธ์—๋Š” ๋‹น์—ฐํžˆ ๊ธฐ๋ณธ ๋™์ž‘์ด ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๋””์ŠคํŒจ์นญ ํ•ด ์ฃผ๋Š” ์ฝ”๋“œ์— ์›ํ•˜๋Š” ๋™์ž‘์„ ๋„ฃ์œผ๋ฉด, ์ปค์Šคํ…€ ์ด๋ฒคํŠธ์—๋„ ๊ธฐ๋ณธ ๋™์ž‘์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -By calling `event.preventDefault()`, an event handler may send a signal that those actions should be canceled. +์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘์€ `event.preventDefault()`๋ฅผ ํ˜ธ์ถœํ•ด ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `event.preventDefault()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ธฐ๋ณธ ๋™์ž‘์ด ์ทจ์†Œ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -In that case the call to `elem.dispatchEvent(event)` returns `false`. And the code that dispatched it knows that it shouldn't continue. +์ด๋ฒคํŠธ ๊ธฐ๋ณธ๋™์ž‘์ด ์ทจ์†Œ๋˜๋ฉด `elem.dispatchEvent(event)` ํ˜ธ์ถœ ์‹œ `false`๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ๋””์ŠคํŒจ์น˜ ํ•˜๋Š” ์ฝ”๋“œ์—์„  ์ด๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ๋™์ž‘์ด ์ทจ์†Œ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ง€ํ•ฉ๋‹ˆ๋‹ค. -Let's see a practical example - a hiding rabbit (could be a closing menu or something else). +ํ† ๋ผ ์ˆจ๊ธฐ๊ธฐ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์ง์ ‘ ์‹ค์Šตํ•ด๋ด…์‹œ๋‹ค. ์ฐธ๊ณ ๋กœ ์ด ์˜ˆ์‹œ๋Š” ๋ฉ”๋‰ด ์ˆจ๊ธฐ๊ธฐ ๋“ฑ์œผ๋กœ ์‘์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -Below you can see a `#rabbit` and `hide()` function that dispatches `"hide"` event on it, to let all interested parties know that the rabbit is going to hide. +์˜ˆ์‹œ์—” `id`๊ฐ€ `rabbit`์ธ ์š”์†Œ, `"hide"` ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ํ•จ์ˆ˜ `hide()`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. `hide()`๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค์ด ์ด๋ฒคํŠธ ์‹คํ–‰ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -Any handler can listen for that event with `rabbit.addEventListener('hide',...)` and, if needed, cancel the action using `event.preventDefault()`. Then the rabbit won't disappear: +`rabbit.addEventListener('hide',...)`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ํ•ธ๋“ค๋Ÿฌ์—์„œ๋„ `"hide"`๋ฅผ ๋ฆฌ์Šค๋‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•„์š”ํ•˜๋‹ค๋ฉด `event.preventDefault()`๋ฅผ ์‚ฌ์šฉํ•ด `"hide"` ์ด๋ฒคํŠธ์˜ ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ๋™์ž‘์ด ์ทจ์†Œ๋˜๋ฉด ํ† ๋ผ๊ฐ€ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```html run refresh autorun <pre id="rabbit"> @@ -184,49 +184,49 @@ Any handler can listen for that event with `rabbit.addEventListener('hide',...)` =\_Y_/= {>o<} </pre> -<button onclick="hide()">Hide()</button> +<button onclick="hide()">hide()๋ฅผ ํ˜ธ์ถœํ•ด ํ† ๋ผ ์ˆจ๊ธฐ๊ธฐ</button> <script> // hide() will be called automatically in 2 seconds function hide() { let event = new CustomEvent("hide", { - cancelable: true // without that flag preventDefault doesn't work + cancelable: true // cancelable๋ฅผ true๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด preventDefault๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. }); if (!rabbit.dispatchEvent(event)) { - alert('The action was prevented by a handler'); + alert('๊ธฐ๋ณธ ๋™์ž‘์ด ํ•ธ๋“ค๋Ÿฌ์— ์˜ํ•ด ์ทจ์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'); } else { rabbit.hidden = true; } } rabbit.addEventListener('hide', function(event) { - if (confirm("Call preventDefault?")) { + if (confirm("preventDefault๋ฅผ ํ˜ธ์ถœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?")) { event.preventDefault(); } }); </script> ``` -ะžะฑั€ะฐั‚ะธั‚ะต ะฒะฝะธะผะฐะฝะธะต: ัะพะฑั‹ั‚ะธะต ะดะพะปะถะฝะพ ะธะผะตั‚ัŒ ั„ะปะฐะณ `cancelable: true`, ะธะฝะฐั‡ะต ะฒั‹ะทะพะฒ `event.preventDefault()` ะฑัƒะดะตั‚ ะฟั€ะพะธะณะฝะพั€ะธั€ะพะฒะฐะฝ. +์˜ˆ์‹œ์—์„œ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ด์•ผ ํ•  ์ ์€ `cancelable: true`์ž…๋‹ˆ๋‹ค. `event.preventDefault()`๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๋ฒคํŠธ `hide`์˜ `cancelable`์„ ๋ฐ˜๋“œ์‹œ `true`๋กœ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `event.preventDefault()`๊ฐ€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. -## Events-in-events are synchronous +## ์ด๋ฒคํŠธ ์•ˆ ์ด๋ฒคํŠธ -Usually events are processed asynchronously. That is: if the browser is processing `onclick` and in the process a new event occurs, then it awaits till `onclick` processing is finished. +์ด๋ฒคํŠธ๋Š” ๋Œ€๊ฒŒ ํ์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ `onclick` ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ๋Š”๋ฐ ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์—ฌ์„œ ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด ์ด ์ด๋ฒคํŠธ์— ์ƒ์‘ํ•˜๋Š” `mousemove` ํ•ธ๋“ค๋Ÿฌ๋Š” `onclick` ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚œ ํ›„์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -The exception is when one event is initiated from within another one. +๊ทธ๋Ÿฐ๋ฐ ์ด๋ฒคํŠธ ์•ˆ `dispatchEvent` ์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ ์•ˆ์— ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—” ์œ„์™€ ๊ฐ™์€ ๊ทœ์น™์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์•ˆ์— ์žˆ๋Š” ์ด๋ฒคํŠธ๋Š” ์ฆ‰์‹œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๋‚œ ํ›„์— ํ˜„์žฌ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง์ด ์žฌ๊ฐœ๋ฉ๋‹ˆ๋‹ค. -Then the control jumps to the nested event handler, and after it goes back. +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. `menu-open` ์ด๋ฒคํŠธ๋Š” `onclick` ์ด๋ฒคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ๋„์ค‘์— ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. + +`menu-open` ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋Š” `onclick` ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. -For instance, here the nested `menu-open` event is processed synchronously, during the `onclick`: ```html run autorun -<button id="menu">Menu (click me)</button> +<button id="menu">๋ฉ”๋‰ด(ํด๋ฆญํ•ด์ฃผ์„ธ์š”)</button> <script> menu.onclick = function() { alert(1); - // alert("nested") menu.dispatchEvent(new CustomEvent("menu-open", { bubbles: true })); @@ -234,17 +234,20 @@ For instance, here the nested `menu-open` event is processed synchronously, duri alert(2); }; - document.addEventListener('menu-open', () => alert('nested')); + // 1๊ณผ 2 ์‚ฌ์ด์— ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค + document.addEventListener('menu-open', () => alert('์ค‘์ฒฉ ์ด๋ฒคํŠธ')); </script> -``` +``` -The output order is: 1 -> nested -> 2. +์–ผ๋Ÿฟ์ฐฝ์— '1', '์ค‘์ฒฉ ์ด๋ฒคํŠธ', '2'๊ฐ€ ์ฐจ๋ก€๋Œ€๋กœ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Please note that the nested event `menu-open` fully bubbles up and is handled on the `document`. The propagation and handling of the nested event must be fully finished before the processing gets back to the outer code (`onclick`). +์ด ์˜ˆ์‹œ์—์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ๊ฒƒ์€ ์ค‘์ฒฉ ์ด๋ฒคํŠธ `menu-open`์ด `document`์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ค‘์ฒฉ ์ด๋ฒคํŠธ์˜ ์ „ํŒŒ์™€ ํ•ธ๋“ค๋ง์ด ์™ธ๋ถ€ ์ฝ”๋“œ(`onclick`)์˜ ์ฒ˜๋ฆฌ๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘๋˜๊ธฐ ์ „์— ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. -That's not only about `dispatchEvent`, there are other cases. JavaScript in an event handler can call methods that lead to other events -- they are too processed synchronously. +์ด๋Ÿฐ ์ผ์€ ์ค‘์ฒฉ ์ด๋ฒคํŠธ๊ฐ€ `dispatchEvent`์ผ ๋•Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์•ˆ์—์„œ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐ ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ด๋ฒคํŠธ ์•ˆ ์ด๋ฒคํŠธ๋Š” ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์ด์ฃ . -If we don't like it, we can either put the `dispatchEvent` (or other event-triggering call) at the end of `onclick` or, maybe better, wrap it in zero-delay `setTimeout`: +๊ทธ๋Ÿฐ๋ฐ ๋•Œ์— ๋”ฐ๋ผ ์ค‘์ฒฉ ์ด๋ฒคํŠธ๊ฐ€ ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š”๊ฑธ ์›์น˜ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ธฐ ๋งˆ๋ จ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ `menu-open`์ด๋ฒคํŠธ๋‚˜ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ์˜ ์ฒ˜๋ฆฌ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด `onclick` ์ด๋ฒคํŠธ๋ฅผ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? + +`onclick` ๋์— `dispatchEvent` ๋“ฑ์˜ ์ด๋ฒคํŠธ ํŠธ๋ฆฌ๊ฑฐ ํ˜ธ์ถœ์„ ๋„ฃ๋Š” ๊ฒŒ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ํ•˜์—ฌ ์ค‘์ฒฉ ์ด๋ฒคํŠธ๋ฅผ ์ง€์—ฐ์‹œ๊ฐ„์ด 0์ธ `setTimeout`์œผ๋กœ ๊ฐ์‹ธ๋Š” ๊ฒƒ๋„ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ```html run <button id="menu">Menu (click me)</button> @@ -253,7 +256,6 @@ If we don't like it, we can either put the `dispatchEvent` (or other event-trigg menu.onclick = function() { alert(1); - // alert(2) setTimeout(() => menu.dispatchEvent(new CustomEvent("menu-open", { bubbles: true }))); @@ -261,33 +263,33 @@ If we don't like it, we can either put the `dispatchEvent` (or other event-trigg alert(2); }; - document.addEventListener('menu-open', () => alert('nested')); + document.addEventListener('menu-open', () => alert('์ค‘์ฒฉ ์ด๋ฒคํŠธ')); </script> -``` +``` -Now `dispatchEvent` runs asynchronously after the current code execution is finished, including `mouse.onclick`, so event handlers are totally separate. +์ด์ œ ์›ํ•˜๋Š” ๋Œ€๋กœ `dispatchEvent`๊ฐ€ `mouse.onclick`์„ ํฌํ•จํ•œ ํ˜„์žฌ ์ฝ”๋“œ ์‹คํ–‰์ด ์ข…๋ฃŒ๋œ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋“ค์ด ์™„์ „ํžˆ ๋…๋ฆฝ์ ์œผ๋กœ ๋˜์—ˆ๋„ค์š”. -The output order becomes: 1 -> 2 -> nested. +์ถœ๋ ฅ ์ˆœ์„œ๋Š” '1', '2', '์ค‘์ฒฉ ์ด๋ฒคํŠธ'์ž…๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -To generate an event from code, we first need to create an event object. +์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฒคํŠธ๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋จผ์ € ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -The generic `Event(name, options)` constructor accepts an arbitrary event name and the `options` object with two properties: -- `bubbles: true` if the event should bubble. -- `cancelable: true` if the `event.preventDefault()` should work. +๋ฒ”์šฉ์ ์œผ๋กœ ์“ฐ์ด๋Š” `Event(name, options)` ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋Š” ์ž„์˜์˜ ์ด๋ฒคํŠธ ์ด๋ฆ„๊ณผ ๋‘ ๊ฐœ์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š” `options`๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. +- `bubbles: true` ์ด๋ฉด ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง๋ฉ๋‹ˆ๋‹ค. +- `cancelable: true` ์ด๋ฉด `event.preventDefault()`๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -Other constructors of native events like `MouseEvent`, `KeyboardEvent` and so on accept properties specific to that event type. For instance, `clientX` for mouse events. +์ด ์™ธ์— `MouseEvent`, `KeyboardEvent` ๊ฐ™์€ ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋“ค์€ ์ด๋ฒคํŠธ ํŠน์œ ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์˜ `clientX`๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. -For custom events we should use `CustomEvent` constructor. It has an additional option named `detail`, we should assign the event-specific data to it. Then all handlers can access it as `event.detail`. +์ด๋ฒคํŠธ๋ฅผ ์ง์ ‘ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด `CustomEvent` ์ƒ์„ฑ์ž๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. `CustomEvent` ์ƒ์„ฑ์ž์—” `detail`์ด๋ผ๋Š” ์ถ”๊ฐ€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์— ์ด๋ฒคํŠธ ๊ด€๋ จ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ์—์„œ `event.detail`์„ ํ†ตํ•ด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ์˜ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Despite the technical possibility to generate browser events like `click` or `keydown`, we should use with the great care. +์ปค์Šคํ…€ ์ด๋ฒคํŠธ์˜ ์ด๋ฆ„์„ `click`๋‚˜ `keydown` ๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ ์ด๋ฒคํŠธ์ฒ˜๋Ÿผ ์ง€์„ ์ˆ˜ ์žˆ๊ธด ํ•œ๋ฐ, ์ด๋Ÿฐ ๊ฒฝ์šฐ์—” ์•„์ฃผ ์กฐ์‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -We shouldn't generate browser events as it's a hacky way to run handlers. That's a bad architecture most of the time. +๋˜๋„๋ก์ด๋ฉด ๋‚ด์žฅ ์ด๋ฒคํŠธ์™€ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ๋ง๋„๋ก ํ•ฉ์‹œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์„ค๊ณ„ ๊ด€์ ์—์„œ ์•„์ฃผ ์ข‹์ง€ ์•Š์€ ์˜ํ•ญ์„ ๋ผ์น˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -Native events might be generated: +๊ทธ๋ ‡์ง€๋งŒ ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“œ๋Š”๊ฒŒ ๋ถˆ๊ฐ€ํ”ผ ํ•˜๋‹ˆ, ์‚ฌ์šฉํ•ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. -- As a dirty hack to make 3rd-party libraries work the needed way, if they don't provide other means of interaction. -- For automated testing, to "click the button" in the script and see if the interface reacts correctly. +- ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ. ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ ์ด์™ธ์—๋Š” ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ด ์—†๋Š” ๊ฒฝ์šฐ์—” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. +- ํ…Œ์ŠคํŒ…์„ ์ž๋™ํ™” ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ. '๋ฒ„ํŠผ ํด๋ฆญ'๋“ฑ์˜ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉ์ž ๋™์ž‘ ์—†์ด ์ฝ”๋“œ๋งŒ์œผ๋กœ ์œ ๋ฐœ์‹œํ‚ค๊ณ  ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ณ ์ž ํ•  ๋•Œ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. -Custom events with our own names are often generated for architectural purposes, to signal what happens inside our menus, sliders, carousels etc. +๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ์ด๋ฆ„๊ณผ ๊ฒน์น˜์ง€ ์•Š๊ฒŒ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์„ค๊ณ„ ์ธก๋ฉด์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ์ „๋žต์ž…๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ์‘์šฉํ•˜๋ฉด ๋ฉ”๋‰ด๋‚˜ ์‚ฌ์ด๋“œ๋ฐ”, ์บ๋Ÿฌ์…€ ๋“ฑ์˜ ์•ˆ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ผ์„ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/solution.view/index.html b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/solution.view/index.html index 4d1e2ea93f..fdbfb8847e 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/solution.view/index.html +++ b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/solution.view/index.html @@ -16,15 +16,15 @@ <body> - Click on a list item to select it. + ์„ ํƒํ•˜๊ณ ์ž ํ•˜๋Š” ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜์„ธ์š”. <br> <ul id="ul"> - <li>Christopher Robin</li> - <li>Winnie-the-Pooh</li> - <li>Tigger</li> - <li>Kanga</li> - <li>Rabbit. Just rabbit.</li> + <li>React</li> + <li>Angular</li> + <li>Vue</li> + <li>Svelte</li> + <li>Blazor</li> </ul> <script> @@ -39,7 +39,7 @@ } - // prevent unneeded selection of list elements on clicks + // ์š”์†Œ๋ฅผ ํด๋ฆญํ•  ๋•Œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์„ ํƒ๋˜์ง€ ์•Š๋„๋ก ๋ฐฉ์ง€ ul.onmousedown = function() { return false; }; diff --git a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/source.view/index.html b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/source.view/index.html index e18d4a9942..971f87e247 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/source.view/index.html +++ b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/source.view/index.html @@ -16,19 +16,19 @@ <body> - Click on a list item to select it. + ์„ ํƒํ•˜๊ณ ์ž ํ•˜๋Š” ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜์„ธ์š”. <br> <ul id="ul"> - <li>Christopher Robin</li> - <li>Winnie-the-Pooh</li> - <li>Tigger</li> - <li>Kanga</li> - <li>Rabbit. Just rabbit.</li> + <li>React</li> + <li>Angular</li> + <li>Vue</li> + <li>Svelte</li> + <li>Blazor</li> </ul> <script> - // ...your code... + // ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. </script> </body> diff --git a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md index 8d29134ff0..d997720b40 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md +++ b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Selectable list +# ์„ ํƒ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์ŠคํŠธ -Create a list where elements are selectable, like in file-managers. +ํŒŒ์ผ ๊ด€๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์ฒ˜๋Ÿผ ์š”์†Œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ์š”๊ตฌ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- A click on a list element selects only that element (adds the class `.selected`), deselects all others. -- If a click is made with `key:Ctrl` (`key:Cmd` for Mac), then the selection is toggled on the element, but other elements are not modified. +- ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ์š”์†Œ๊ฐ€ ์„ ํƒ(`.selected` ํด๋ž˜์Šค ์ถ”๊ฐ€)๋˜๊ณ , ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์€ ์„ ํƒ ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. +- `key:Ctrl`ํ‚ค(Mac์—์„œ `key:Cmd`ํ‚ค)๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ์š”์†Œ๋Š” ์›๋ž˜์ฒ˜๋Ÿผ ์„ ํƒ, ์„ ํƒ ํ•ด์ œ๋˜์ง€๋งŒ ๋‹ค๋ฅธ ์š”์†Œ๋“ค์˜ ์ƒํƒœ๋Š” ๋ณ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์ค‘๋ณต ์š”์†Œ ์„ ํƒ ๊ธฐ๋Šฅ). -The demo: +๋ฐ๋ชจ: [iframe border="1" src="solution" height=180] -P.S. For this task we can assume that list items are text-only. No nested tags. +์ฐธ๊ณ  1: ํ•ญ๋ชฉ๋“ค์ด ๋ชจ๋‘ ํ…์ŠคํŠธ์ด๋ฉฐ ์ค‘์ฒฉ ํƒœ๊ทธ๊ฐ€ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. -P.P.S. Prevent the native browser selection of the text on clicks. +์ฐธ๊ณ  2: ํ…์ŠคํŠธ๋ฅผ ํด๋ฆญํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md index 05b03e1623..fe88929d1a 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/article.md +++ b/2-ui/3-event-details/1-mouse-events-basics/article.md @@ -1,198 +1,210 @@ -# Mouse events basics +# ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ -In this chapter we'll get into more details about mouse events and their properties. +์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์™€ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. -Please note: such events may come not only from "mouse devices", but are also from other devices, such as phones and tablets, where they are emulated for compatibility. +๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ํ•™์Šตํ•˜๊ธฐ ์ „์— ์ฃผ์˜ํ•  ์ ์€, ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋Š” '๋งˆ์šฐ์Šค'๋ผ๋Š” ์žฅ์น˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ƒ๊ธฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ•ธ๋“œํฐ์ด๋‚˜ ํƒœ๋ธ”๋ฆฟ ๊ฐ™์€ ๋‹ค๋ฅธ ์žฅ์น˜์—์„œ๋„ ์ƒ๊ธด๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. -## Mouse event types +## ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์ข…๋ฅ˜ -We can split mouse events into two categories: "simple" and "complex" +์•ž์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -### Simple events +`mousedownยทmouseup` +: ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ, ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ ๋ˆ„๋ฅด๊ณ  ์žˆ๋‹ค๊ฐ€ ๋—„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -The most used simple events are: - -`mousedown/mouseup` -: Mouse button is clicked/released over an element. - -`mouseover/mouseout` -: Mouse pointer comes over/out from an element. +`mouseoverยทmouseout` +: ๋งˆ์šฐ์Šค ์ปค์„œ๊ฐ€ ์š”์†Œ ๋ฐ”๊นฅ์— ์žˆ๋‹ค๊ฐ€ ์š”์†Œ ์•ˆ์œผ๋กœ ์›€์ง์ผ ๋•Œ, ์ปค์„œ๊ฐ€ ์š”์†Œ ์œ„์— ์žˆ๋‹ค๊ฐ€ ์š”์†Œ ๋ฐ–์œผ๋กœ ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. `mousemove` -: Every mouse move over an element triggers that event. - -...There are several other event types too, we'll cover them later. - -### Complex events +: ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. `click` -: Triggers after `mousedown` and then `mouseup` over the same element if the left mouse button was used. - -`contextmenu` -: Triggers after `mousedown` if the right mouse button was used. +: ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•ด ๋™์ผํ•œ ์š”์†Œ ์œ„์—์„œ `mousedown` ์ด๋ฒคํŠธ์™€ `mouseup` ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๋‹ฌ์•„ ๋ฐœ์ƒ์‹œํ‚ฌ ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `dblclick` -: Triggers after a double click over an element. +: ๋™์ผํ•œ ์š”์†Œ ์œ„์—์„œ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ๋น ๋ฅด๊ฒŒ ํด๋ฆญํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์š”์ฆ˜์—” ์ž˜ ์“ฐ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +`contextmenu` +: ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ํŠน๋ณ„ํ•œ ๋‹จ์ถ•ํ‚ค๋ฅผ ๋ˆŒ๋Ÿฌ๋„ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ์ฒ˜๋Ÿผ ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ `contextmenu`๋ผ๋Š” ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์™€ ๋™์ผํ•˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. -Complex events are made of simple ones, so in theory we could live without them. But they exist, and that's good, because they are convenient. +์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋‹ค๋ฅธ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด์„  ๊ณง ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. -### Events order +## ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์ˆœ์„œ -An action may trigger multiple events. +์œ„์—์„œ ์†Œ๊ฐœํ•œ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋ฉด์„œ ๋ˆˆ์น˜์ฑ„์…จ๊ฒ ์ง€๋งŒ, ์‚ฌ์šฉ์ž๋Š” ๋‹จ ํ•˜๋‚˜์˜ ๋™์ž‘์„ ํ–ˆ์–ด๋„ ์‹คํ–‰๋˜๋Š” ์ด๋ฒคํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, a click first triggers `mousedown`, when the button is pressed, then `mouseup` and `click` when it's released. +๋‹จ์ˆœํ•˜๊ฒŒ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋”๋ผ๋„ `mousedown`, `mouseup`, ๋งˆ์ง€๋ง‰์œผ๋กœ `click` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ฃ . -In cases when a single action initiates multiple events, their order is fixed. That is, the handlers are called in the order `mousedown` -> `mouseup` -> `click`. +์ด๋ ‡๊ฒŒ ๋™์ž‘์€ ํ•˜๋‚˜์ง€๋งŒ ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์‹คํ–‰ ์ˆœ์„œ๋Š” ๋‚ด๋ถ€ ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ```online -Click the button below and you'll see the events. Try double-click too. +์•„๋ž˜ ๋ฒ„ํŠผ์„ ํด๋ฆญ ๋˜๋Š” ๋”๋ธ”ํด๋ฆญํ•ด ์‹ค์ œ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. -On the teststand below all mouse events are logged, and if there are more than 1 second delay between them, then they are separated by a horizontal ruler. +๋ชจ๋“  ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„ํŠผ ์•„๋ž˜ ์ฐฝ์— ๊ธฐ๋ก๋˜๋Š”๋ฐ, ์ด๋ฒคํŠธ ๋ฐœ์ƒ ๊ฐ„๊ฒฉ์ด 1์ดˆ ์ด์ƒ์ผ ๋•Œ๋Š” ์ด๋ฒคํŠธ ์‚ฌ์ด์— ๊ฐ€๋กœ ์„ ์ด ์ถ”๊ฐ€๋˜๋„๋ก ํ•ด๋†“์•˜์Šต๋‹ˆ๋‹ค. -Also we can see the `which` property that allows to detect the mouse button. +์ด๋ฒคํŠธ ์ด๋ฆ„ ์˜†์—” ์–ด๋–ค ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์ด ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผฐ๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” `button` ํ”„๋กœํผํ‹ฐ๋„ ๋ณด์ด๋Š”๋ฐ, `button` ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ๋ฐ”๋กœ ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -<input onmousedown="return logMouse(event)" onmouseup="return logMouse(event)" onclick="return logMouse(event)" oncontextmenu="return logMouse(event)" ondblclick="return logMouse(event)" value="Click me with the right or the left mouse button" type="button"> <input onclick="logClear('test')" value="Clear" type="button"> <form id="testform" name="testform"> <textarea style="font-size:12px;height:150px;width:360px;"></textarea></form> +<input onmousedown="return logMouse(event)" onmouseup="return logMouse(event)" onclick="return logMouse(event)" oncontextmenu="return logMouse(event)" ondblclick="return logMouse(event)" value="๋งˆ์šฐ์Šค ์™ผ์ชฝ์ด๋‚˜ ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•ด ํด๋ฆญํ•ด๋ณด์„ธ์š”." type="button"> <input onclick="logClear('test')" value="์ดˆ๊ธฐํ™”" type="button"> <form id="testform" name="testform"> <textarea style="font-size:12px;height:150px;width:360px;"></textarea></form> ``` -## Getting the button: which +## ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ -Click-related events always have the `which` property, which allows to get the exact mouse button. +ํด๋ฆญ๊ณผ ์—ฐ๊ด€๋œ ์ด๋ฒคํŠธ๋Š” ์ •ํ™•ํžˆ ์–ด๋–ค ๋ฒ„ํŠผ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” `button` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -It is not used for `click` and `contextmenu` events, because the former happens only on left-click, and the latter -- only on right-click. +`click` ์ด๋ฒคํŠธ๋Š” ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„, `contextmenu` ์ด๋ฒคํŠธ๋Š” ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— `click`๊ณผ `contextmenu` ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃฐ ๋• ๋ณดํ†ต `button` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -But if we track `mousedown` and `mouseup`, then we need it, because these events trigger on any button, so `which` allows to distinguish between "right-mousedown" and "left-mousedown". +๋ฐ˜๋ฉด `mousedown`์ด๋ฒคํŠธ๋‚˜ `mouseup` ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃฐ ๋• ํ•ด๋‹น ์ด๋ฒคํŠธ์˜ ํ•ธ๋“ค๋Ÿฌ์— `event.button`์„ ๋ช…์‹œํ•ด ์ค˜์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋“ค์€ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ ์–ด๋””์—์„œ๋‚˜ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ `button` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ์ •ํ™•ํžˆ ์–ด๋–ค ๋ฒ„ํŠผ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -There are the three possible values: +์ฃผ์š” `event.button` ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- `event.which == 1` -- the left button -- `event.which == 2` - the middle button -- `event.which == 3` - the right button +| ๋ฒ„ํŠผ | `event.button` | +|--------------|----------------| +| ์™ผ์ชฝ(์ฃผ์š” ๋ฒ„ํŠผ) | 0 | +| ๊ฐ€์šด๋ฐ(๋ณด์กฐ ๋ฒ„ํŠผ) | 1 | +| ์˜ค๋ฅธ์ชฝ (๋‘ ๋ฒˆ์งธ ๋ฒ„ํŠผ) | 2 | +| X1(๋’ค๋กœ ๊ฐ€๊ธฐ ๋ฒ„ํŠผ) | 3 | +| X2(์•ž์œผ๋กœ ๊ฐ€๊ธฐ ๋ฒ„ํŠผ) | 4 | -The middle button is somewhat exotic right now and is very rarely used. +์ƒ๋‹น์ˆ˜์˜ ๋งˆ์šฐ์Šค๋Š” ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋งˆ์šฐ์Šค๋“ค์ด ๋งŒ๋“ค์–ด๋‚ด๋Š” `event.button` ๊ฐ’์€ `0`์ด๋‚˜ `2`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ„ฐ์น˜๋ฅผ ์ง€์›ํ•˜๋Š” ๊ธฐ๊ธฐ๋“ค๋„ ์‚ฌ๋žŒ์ด ํ•ด๋‹น ๊ธฐ๊ธฐ๋ฅผ ํ„ฐ์น˜ํ–ˆ์„ ๋•Œ ์œ ์‚ฌํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. -## Modifiers: shift, alt, ctrl and meta +์ฐธ๊ณ ๋กœ `buttons`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋„ ์žˆ๋Š”๋ฐ, ์ด ํ”„๋กœํผํ‹ฐ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฒ„ํŠผ์„ ํ•œ๊บผ๋ฒˆ์— ๋ˆŒ๋ €์„ ๋•Œ ํ•ด๋‹น ๋ฒ„ํŠผ๋“ค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ •์ˆ˜ ํ˜•ํƒœ๋กœ ์ €์žฅํ•ด ์ค๋‹ˆ๋‹ค. ์‹ค๋ฌด์—์„œ `buttons` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋‚  ์ผ์€ ๊ทนํžˆ ๋“œ๋ฌผ๊ธด ํ•˜์ง€๋งŒ ํ˜น์‹œ๋ผ๋„ ํ•„์š”ํ•˜๋‹ค๋ฉด[MDN](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons)์—์„œ ํ™•์ธํ•ด๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. -All mouse events include the information about pressed modifier keys. +```warn header="์—ญ์‚ฌ์˜ ๋’ค์•ˆ๊ธธ๋กœ ์‚ฌ๋ผ์ง„ `event.which`" +์˜ค๋ž˜๋œ ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ค ๋ณด๋ฉด `event.which`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `event.which` ํ”„๋กœํผํ‹ฐ๋Š” ์–ด๋–ค ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ๋น„ํ‘œ์ค€ ํ”„๋กœํผํ‹ฐ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. -Event properties: +- `event.which == 1` โ€“ ์™ผ์ชฝ ๋ฒ„ํŠผ +- `event.which == 2` โ€“ ๊ฐ€์šด๋ฐ ๋ฒ„ํŠผ +- `event.which == 3` โ€“ ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ + +`event.which`๋Š” ์ด์   ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํ”„๋กœํผํ‹ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +``` -- `shiftKey`: `key:Shift` -- `altKey`: `key:Alt` (or `key:Opt` for Mac) -- `ctrlKey`: `key:Ctrl` -- `metaKey`: `key:Cmd` for Mac +## shift, alt, ctrl, meta ํ”„๋กœํผํ‹ฐ -They are `true` if the corresponding key was pressed during the event. +๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ํ•จ๊ป˜ ๋ˆ„๋ฅธ ๋ณด์กฐํ‚ค๊ฐ€ ๋ฌด์—‡์ธ์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -For instance, the button below only works on `key:Alt+Shift`+click: +๋ณด์กฐํ‚ค ๋ณ„๋กœ ์ง€์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. + +- `shiftKey`: `key:Shift` ํ‚ค +- `altKey`: `key:Alt` (MacOS์—์„  `key:Opt` ํ‚ค) +- `ctrlKey`: `key:Ctrl` ํ‚ค +- `metaKey`: MacOS์—์„œ `key:Cmd` ํ‚ค + +๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋„์ค‘์— ํ•ด๋‹น ํ‚ค๊ฐ€ ํ•จ๊ป˜ ๋ˆŒ๋Ÿฌ์กŒ๋‹ค๋ฉด ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ `true`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. + +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์•„๋ž˜ ๋ฒ„ํŠผ์€ `key:Alt+Shift` ํ‚ค์™€ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ํ•จ๊ป˜ ํด๋ฆญํ–ˆ์„ ๋•Œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```html autorun height=60 -<button id="button">Alt+Shift+Click on me!</button> +<button id="button">Alt, Shift ํ‚ค๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ ํด๋ฆญํ•ด์ฃผ์„ธ์š”!</button> <script> button.onclick = function(event) { *!* if (event.altKey && event.shiftKey) { */!* - alert('Hooray!'); + alert('์•ผํ˜ธ!'); } }; </script> ``` -```warn header="Attention: on Mac it's usually `Cmd` instead of `Ctrl`" -On Windows and Linux there are modifier keys `key:Alt`, `key:Shift` and `key:Ctrl`. On Mac there's one more: `key:Cmd`, corresponding to the property `metaKey`. +```warn header="MacOS์—์„  `Ctrl` ๋Œ€์‹  `Cmd`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”!" +Windows์™€ Linux๋Š” `key:Alt`, `key:Shift`, `key:Ctrl` ํ‚ค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ•œํŽธ MacOS์—์„  ์„ธ ๋ณด์กฐํ‚ค ์ด์™ธ์— `key:Cmd`๋ผ๋Š” ํ‚ค๋ฅผ ์ถ”๊ฐ€๋กœ ์ง€์›ํ•˜๋Š”๋ฐ, `key:Cmd` ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋กœ๋Š” `metaKey`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -In most applications, when Windows/Linux uses `key:Ctrl`, on Mac `key:Cmd` is used. +์‘์šฉํ”„๋กœ๊ทธ๋žจ ๋Œ€๋ถ€๋ถ„์€ Windows, Linux์—์„  `key:Ctrl`, MacOS์—์„  `key:Cmd`๋ฅผ ์‚ฌ์šฉํ•ด ๋‹จ์ถ•ํ‚ค๋ฅผ ์กฐํ•ฉํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. -That is: where a Windows user presses `key:Ctrl+Enter` or `key:Ctrl+A`, a Mac user would press `key:Cmd+Enter` or `key:Cmd+A`, and so on. +์ด๋Ÿฐ ์•”๋ฌต์ ์ธ ๊ทœ์น™ ๋•Œ๋ฌธ์— Windows ์‚ฌ์šฉ์ž๊ฐ€ `key:Ctrl+Enter`๋‚˜ `key:Ctrl+A` ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ๊ธฐ๋Šฅ์ด Mac์—์„  `key:Cmd+Enter`๋‚˜ `key:Cmd+A`๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. -So if we want to support combinations like `key:Ctrl`+click, then for Mac it makes sense to use `key:Cmd`+click. That's more comfortable for Mac users. +๋”ฐ๋ผ์„œ Mac ์‚ฌ์šฉ์ž๋„ ์ง€์›ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค๋ ค๋ฉด `key:Ctrl`ํ‚ค์™€ `click`์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋‚˜ํƒ€๋‚˜๋Š” ํšจ๊ณผ๊ฐ€ `key:Cmd`ํ‚ค์™€ `click`์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋‚˜ํƒ€๋‚˜๋Š” ํšจ๊ณผ์™€ ๋™์ผํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -Even if we'd like to force Mac users to `key:Ctrl`+click -- that's kind of difficult. The problem is: a left-click with `key:Ctrl` is interpreted as a *right-click* on MacOS, and it generates the `contextmenu` event, not `click` like Windows/Linux. +๋ฌผ๋ก  Mac ์‚ฌ์šฉ์ž๊ฐ€ `key:Ctrl` ํ‚ค์™€ ํด๋ฆญ์„ ๋™์‹œ์— ํ•˜๋„๋ก ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๊ธด ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ MacOS๋Š” `key:Ctrl` ํ‚ค์™€ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ํ•จ๊ป˜ ๋ˆ„๋ฅธ ๊ฒฝ์šฐ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ๊ฒƒ์œผ๋กœ ํ•ด์„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Windows, Linux์—์„  `click` ์ด๋ฒคํŠธ๋กœ ํ•ด์„๋  ์ˆ˜ ์žˆ๋Š” ๋™์ž‘์ด MacOS์—์„  `contextmenu` ์ด๋ฒคํŠธ๋กœ ํ•ด์„๋˜๋Š” ๊ฒƒ์ด์ฃ . -So if we want users of all operational systems to feel comfortable, then together with `ctrlKey` we should check `metaKey`. +๋”ฐ๋ผ์„œ ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ์šด์˜์ฒด์ œ ์ข…๋ฅ˜์— ์ƒ๊ด€์—†์ด ๋™์ผํ•œ ๊ฒฝํ—˜์„ ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด `ctrlKey` ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ์—” `metaKey`๋„ ํ•จ๊ป˜ ๋„ฃ์–ด์ฃผ์„ธ์š”. -For JS-code it means that we should check `if (event.ctrlKey || event.metaKey)`. +`if (event.ctrlKey || event.metaKey)`๊ฐ™์ด ๋ง์ด์ฃ . ``` -```warn header="There are also mobile devices" -Keyboard combinations are good as an addition to the workflow. So that if the visitor has a - keyboard -- it works. And if their device doesn't have it -- then there should be another way to do the same. +```warn header="๋ชจ๋ฐ”์ผ ์žฅ์น˜" +์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ๊ฐ€ ์žˆ๋Š” ๊ธฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋‹จ์ถ•ํ‚ค๋ฅผ ์ง€์›ํ•˜๋ฉด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ƒ์Šน์‹œ์ผœ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ๋ฐ ๋ชจ๋ฐ”์ผ ์žฅ์น˜๊ฐ™์ด ๊ธฐ๊ธฐ์— ํ‚ค๋ณด๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋„ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ ค๋ฉด ๋ณด์กฐ ํ‚ค๊ฐ€ ์—†๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์ง€์›ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ณ ๋ คํ•˜๋ฉฐ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ``` -## Coordinates: clientX/Y, pageX/Y +## clientX, clientY์™€ pageX, pageY + +๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋Š” ๋‘ ์ข…๋ฅ˜์˜ ์ขŒํ‘œ ์ •๋ณด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -All mouse events have coordinates in two flavours: +1. ํด๋ผ์ด์–ธํŠธ ์ขŒํ‘œ: `clientX`์™€ `clientY` +2. ํŽ˜์ด์ง€ ์ขŒํ‘œ: `pageX`์™€ `pageY` -1. Window-relative: `clientX` and `clientY`. -2. Document-relative: `pageX` and `pageY`. +๋‘ ์ •๋ณด์— ๋Œ€ํ•œ ์ฐจ์ด๋Š” <info:coordinates> ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฌ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. -For instance, if we have a window of the size 500x500, and the mouse is in the left-upper corner, then `clientX` and `clientY` are `0`. And if the mouse is in the center, then `clientX` and `clientY` are `250`, no matter what place in the document it is, how far the document was scrolled. They are similar to `position:fixed`. +๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‘ ์ขŒํ‘œ์— ๋Œ€ํ•ด ์š”์•ฝํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ขŒํ‘œ์ธ `clientX`์™€ `clientY`๋Š” ์›น ๋ฌธ์„œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ์™ผ์ชฝ์—์„œ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€, ์œ„์—์„œ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ ํŽ˜์ด์ง€๊ฐ€ ์Šคํฌ๋กค ๋˜์–ด๋„ ๋ณ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด `pageX`์™€ `pageY`๋Š” ์ฐฝ ์™ผ์ชฝ ์œ„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ ํŽ˜์ด์ง€๋ฅผ ์Šคํฌ๋กคํ•˜๋ฉด ๊ฐ’๋„ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค. + +์˜ˆ๋ฅผ ๋“ค์–ด๋ด…์‹œ๋‹ค. ์‚ฌ์ด์ฆˆ๊ฐ€ 500x500์ธ ์ฐฝ์—์„œ ๋งˆ์šฐ์Šค ์ปค์„œ๋ฅผ ์™ผ์ชฝ ์œ„ ๊ฐ€์žฅ์ž๋ฆฌ๋กœ ์˜ฎ๊ธฐ๋ฉด ํŽ˜์ด์ง€๋ฅผ ์–ด๋””๋กœ ์Šคํฌ๋กค ํ•˜๋“  ์ƒ๊ด€์—†์ด `clientX`, `clientY` ๊ฐ’์ด `0`์ด ๋ฉ๋‹ˆ๋‹ค. + +์ปค์„œ๋ฅผ ํ™”๋ฉด ์ • ๊ฐ€์šด๋ฐ๋กœ ์˜ฎ๊ธฐ๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์Šคํฌ๋กค๋ฐ” ์œ„์น˜์— ์ƒ๊ด€์—†์ด `clientX`, `clientY` ๊ฐ’์ด ๊ฐ๊ฐ `250`์ด ๋˜์ฃ . `position:fixed`์™€ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ````online -Move the mouse over the input field to see `clientX/clientY` (the example is in the `iframe`, so coordinates are relative to that `iframe`): +์ปค์„œ๋ฅผ input ํ•„๋“œ ์•ˆ์œผ๋กœ ์˜ฎ๊ฒจ `clientX`, `clientY` ๊ฐ’์ด ์–ด๋–ป๊ฒŒ ๋ณ€ํ•˜๋Š”์ง€ ์‚ดํŽด๋ด…์‹œ๋‹ค. ์ฐธ๊ณ ๋กœ ์•„๋ž˜ ์˜ˆ์‹œ๋Š” `iframe`์•ˆ์—์„œ ๊ตฌํ˜„๋˜๋„๋ก ํ•ด๋†“์•„์„œ ์ขŒํ‘œ ์ •๋ณด๊ฐ€ `iframe`์„ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ```html autorun height=50 <input onmousemove="this.value=event.clientX+':'+event.clientY" value="Mouse over me"> ``` ```` -Document-relative coordinates `pageX`, `pageY` are counted from the left-upper corner of the document, not the window. You can read more about coordinates in the chapter <info:coordinates>. +## mousedown ์ด๋ฒคํŠธ์™€ ์„ ํƒ ๋ง‰๊ธฐ -## Disabling selection +๊ธ€์ž ์œ„์—์„œ ๋งˆ์šฐ์Šค๋ฅผ ๋”๋ธ”ํด๋ฆญํ•˜๋ฉด ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜๋Š”๋ฐ, ์ด๋Ÿฐ ๊ธฐ๋ณธ ๋™์ž‘์ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์น  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -Double mouse click has a side-effect that may be disturbing in some interfaces: it selects the text. - -For instance, a double-click on the text below selects it in addition to our handler: +`dblclick` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ผ๋Ÿฟ ์ฐฝ์„ ๋„์šฐ๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ œ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์‹œ์— ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜๋Š” ๋ถˆํ•„์š”ํ•œ ๋ถ€์ˆ˜ํšจ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ```html autorun height=50 -<span ondblclick="alert('dblclick')">Double-click me</span> +<span ondblclick="alert('dblclick')">์ด๊ณณ์„ ๋”๋ธ”ํด๋ฆญํ•ด์ฃผ์„ธ์š”.</span> ``` -If one presses the left mouse button and, without releasing it, moves the mouse, that also makes the selection, often unwanted. +์ด์™ธ์—๋„ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ์ฑ„ ์ปค์„œ๋ฅผ ์ด๋ฆฌ์ €๋ฆฌ ์›€์ง์ด๋ฉด ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜๋Š” ๋ถ€์ˆ˜ํšจ๊ณผ ์—ญ์‹œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋ ‡๊ฒŒ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์ฃผ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•œ๋ฐ, <info:selection-range>์—์„œ ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -There are multiple ways to prevent the selection, that you can read in the chapter <info:selection-range>. +์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ• ์ค‘, ์˜ˆ์‹œ์—์„œ ๋ณด์—ฌ๋“œ๋ฆฐ ์ƒํ™ฉ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๋ฐฉ๋ฒ•์€ `mousedown` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ๋‚˜ํƒ€๋‚˜๋Š” ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜๋Š” ๋ถ€์ˆ˜ํšจ๊ณผ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In this particular case the most reasonable way is to prevent the browser action on `mousedown`. It prevents both these selections: ```html autorun height=50 -Before... -<b ondblclick="alert('Click!')" *!*onmousedown="return false"*/!*> - Double-click me +... +<b ondblclick="alert('ํด๋ฆญ!')" *!*onmousedown="return false"*/!*> + ์—ฌ๊ธฐ๋ฅผ ๋”๋ธ”ํด๋ฆญํ•ด์ฃผ์„ธ์š”. </b> -...After +... ``` -Now the bold element is not selected on double clicks, and pressing the left button on it won't start the selection. +๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰์•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตต์€ ๊ธ€์”จ๊ฐ€ ์žˆ๋Š” ์˜์—ญ์—์„œ ๋”๋ธ”ํด๋ฆญ์„ ํ•ด๋„ ๋‹จ์–ด๊ฐ€ ์„ ํƒ๋˜์ง€ ์•Š๊ณ , ๊ธ€์ž๋ฅผ ๋“œ๋ž˜๊ทธํ•ด๋„ ๊ธ€์ž๊ฐ€ ์„ ํƒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -Please note: the text inside it is still selectable. However, the selection should start not on the text itself, but before or after it. Usually that's fine for users. +๊ทธ๋Ÿฐ๋ฐ ์ด๋•Œ ๋ˆˆ์—ฌ๊ฒจ๋ด์•ผ ํ•  ์ ์€ ๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์•˜์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ธ€์ž๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—ฌ์ „ํžˆ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. `...`์ด ์žˆ๋Š” ๋ถ€๋ถ„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋“œ๋ž˜๊ทธ๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด ๊ตต์€ ๊ธ€์”จ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ฃ . -````smart header="Preventing copying" -If we want to disable selection to protect our page content from copy-pasting, then we can use another event: `oncopy`. +````smart header="๋ณต์‚ฌ ๋ง‰๊ธฐ" +์ฝ˜ํ…์ธ ๋ฅผ ๋ณดํ˜ธํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ ๋ฐฉ๋ฌธ์ž๊ฐ€ ๋‚ด์šฉ์„ ๋ณต์‚ฌ, ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋Š” ๊ฑธ ๋ง‰์œผ๋ ค๋ฉด `oncopy`๋ผ๋Š” ์ด๋ฒคํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```html autorun height=80 no-beautify -<div *!*oncopy="alert('Copying forbidden!');return false"*/!*> - Dear user, - The copying is forbidden for you. - If you know JS or HTML, then you can get everything from the page source though. +<div *!*oncopy="alert('๋ถˆ๋ฒ• ๋ณต์ œ๋ฅผ ์˜ˆ๋ฐฉํ•˜๊ธฐ ๋ณต์‚ฌ ๊ธฐ๋Šฅ์„ ๋ง‰์•„๋†“์•˜์Šต๋‹ˆ๋‹ค!');return false"*/!*> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent convallis ultrices lacus ut dictum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </div> ``` -If you try to copy a piece of text in the `<div>`, that won't work, because the default action `oncopy` is prevented. +๋ฐ”๋กœ์œ„ ์ƒ์ž ์•ˆ์— ์žˆ๋Š” ๊ธ€์ž๋ฅผ ์„ ํƒํ•œ ํ›„ ๋ณต์‚ฌํ•˜๋ ค๊ณ ํ•˜๋ฉด `oncopy` ์ด๋ฒคํŠธ์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๋ง‰์•„๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์‚ฌ๊ฐ€ ์•ˆ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Surely the user has access to HTML-source of the page, and can take the content from there, but not everyone knows how to do it. +ํŽ˜์ด์ง€ ์†Œ์Šค ๋ณด๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋ผ๋ฉด ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์ด ์†Œ์šฉ์ด ์—†๊ฒ ์ง€๋งŒ ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ์†Œ์Šค ๋ณด๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ถˆ๋ฒ• ๋ณต์ œ๋ฅผ ์–ด๋А ์ •๋„ ๋ง‰์„ ์ˆ˜ ์žˆ์ฃ . ```` -## Summary +## ์š”์•ฝ -Mouse events have the following properties: +๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- Button: `which`. -- Modifier keys (`true` if pressed): `altKey`, `ctrlKey`, `shiftKey` and `metaKey` (Mac). - - If you want to handle `key:Ctrl`, then don't forget Mac users, they usually use `key:Cmd`, so it's better to check `if (e.metaKey || e.ctrlKey)`. +- ๋ฒ„ํŠผ ๊ด€๋ จ: `button` +- ๋ณด์กฐํ‚ค ๊ด€๋ จ: `altKey`, `ctrlKey`, `shiftKey`์™€ MacOS ์ „์šฉ `metaKey`. ํ•ด๋‹น ํ‚ค๋ฅผ ๋ˆ„๋ฅธ ๊ฒฝ์šฐ์— ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด `true`๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. + - `key:Ctrl`๋ฅผ ๊ณ ๋ คํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค๋ฉด MacOS ์‚ฌ์šฉ์ž๋Š” ์ฃผ๋กœ `key:Cmd` ํ‚ค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•ด์„œ `if (e.metaKey || e.ctrlKey)`๊ฐ™์ด ๋ชจ๋“  ์‚ฌ์šฉ์ž๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- Window-relative coordinates: `clientX/clientY`. -- Document-relative coordinates: `pageX/pageY`. +- ํด๋ผ์ด์–ธํŠธ ์ขŒํ‘œ ๊ด€๋ จ: `clientX`, `clientY` +- ํŽ˜์ด์ง€ ์ขŒํ‘œ ๊ด€๋ จ: `pageX`, `pageY` -The default browser action of `mousedown` is text selection, if it's not good for the interface, then it should be prevented. +`mousedown` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ๋™์ž‘ ๋•Œ๋ฌธ์— ๊ธ€์ž๊ฐ€ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ธฐ๋ณธ ๋™์ž‘์ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์นœ๋‹ค๋ฉด ๊ธฐ๋ณธ๋™์ž‘์„ ๋ง‰์•„์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In the next chapter we'll see more details about events that follow pointer movement and how to track element changes under it. +๋‹ค์Œ ์ฑ•ํ„ฐ์—์„  ํฌ์ธํ„ฐ(์ปค์„œ)๊ฐ€ ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์™€ ํฌ์ธํ„ฐ๊ฐ€ ์›€์ง์ผ ๋•Œ ํฌ์ธํ„ฐ ์•„๋ž˜์— ์žˆ๋Š” ์š”์†Œ๋“ค์„ ์–ด๋–ป๊ฒŒ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/2-ui/3-event-details/1-mouse-events-basics/head.html b/2-ui/3-event-details/1-mouse-events-basics/head.html index f578fb7db0..1b9a73fca4 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/head.html +++ b/2-ui/3-event-details/1-mouse-events-basics/head.html @@ -25,7 +25,7 @@ function logMouse(e) { let evt = e.type; while (evt.length < 11) evt += ' '; - showmesg(evt + " which=" + e.which, 'test') + showmesg(evt + " button=" + e.button, 'test') return false; } diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html index df0f136568..0982321741 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html @@ -20,20 +20,17 @@ <div id="tooltip" hidden>Tooltip</div> <script> - // for the demo - setTimeout(function() { - new HoverIntent({ - elem, - over() { - tooltip.style.left = elem.getBoundingClientRect().left + 5 + 'px'; - tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px'; - tooltip.hidden = false; - }, - out() { - tooltip.hidden = true; - } - }); - }, 2000); + new HoverIntent({ + elem, + over() { + tooltip.style.left = elem.getBoundingClientRect().left + 5 + 'px'; + tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px'; + tooltip.hidden = false; + }, + out() { + tooltip.hidden = true; + } + }); </script> </body> diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js index 7c7f6d23df..f5d4aaffb3 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js @@ -49,18 +49,18 @@ describe("hoverIntent", function() { } }) - it("mouseover -> immediately no tooltip", function() { + it("mouseover -> when the pointer just arrived, no tooltip", function() { mouse('mouseover', 10, 10); assert.isFalse(isOver); }); - it("mouseover -> pause shows tooltip", function() { + it("mouseover -> after a delay, the tooltip shows up", function() { mouse('mouseover', 10, 10); this.clock.tick(100); assert.isTrue(isOver); }); - it("mouseover -> fast mouseout no tooltip", function() { + it("mouseover -> followed by fast mouseout leads doesn't show tooltip", function() { mouse('mouseover', 10, 10); setTimeout( () => mouse('mouseout', 300, 300, { relatedTarget: document.body}), diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js index caca940b1d..a38b42bc24 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js @@ -45,6 +45,7 @@ class HoverIntent { destroy() { /* your code to "disable" the functionality, remove all handlers */ + /* it's needed for the tests to work */ } } diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html index 856daf3a8f..0982321741 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html @@ -3,10 +3,9 @@ <head> <meta charset="UTF-8"> - <title>Document - + @@ -21,18 +20,17 @@ diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css index 980e9457e7..fa2f09eba8 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css @@ -2,6 +2,10 @@ color: red; } +body { + margin: 0; +} + .minutes { color: green; } @@ -20,9 +24,15 @@ top: 0; } -.tooltip { +#tooltip { position: absolute; - background: #eee; - border: 1px brown solid; - padding: 3px; + padding: 10px 20px; + border: 1px solid #b3c9ce; + border-radius: 4px; + text-align: center; + font: italic 14px/1.3 sans-serif; + color: #333; + background: #fff; + z-index: 100000; + box-shadow: 3px 3px 3px rgba(0, 0, 0, .3); } diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js index 44369d8c3f..f5d4aaffb3 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js @@ -3,7 +3,7 @@ describe("hoverIntent", function() { function mouse(eventType, x, y, options) { - let eventOptions = Object.assign({ + let eventOptions = Object.assign({ bubbles: true, clientX: x, clientY: y, @@ -11,15 +11,15 @@ describe("hoverIntent", function() { pageY: y, target: elem }, options || {}); - + elem.dispatchEvent(new MouseEvent(eventType, eventOptions)); } let isOver; let hoverIntent; - - + + before(function() { this.clock = sinon.useFakeTimers(); }); @@ -27,11 +27,11 @@ describe("hoverIntent", function() { after(function() { this.clock.restore(); }); - - + + beforeEach(function() { isOver = false; - + hoverIntent = new HoverIntent({ elem: elem, over: function() { @@ -49,18 +49,18 @@ describe("hoverIntent", function() { } }) - it("mouseover -> immediately no tooltip", function() { + it("mouseover -> when the pointer just arrived, no tooltip", function() { mouse('mouseover', 10, 10); assert.isFalse(isOver); }); - - it("mouseover -> pause shows tooltip", function() { + + it("mouseover -> after a delay, the tooltip shows up", function() { mouse('mouseover', 10, 10); this.clock.tick(100); assert.isTrue(isOver); }); - it("mouseover -> fast mouseout no tooltip", function() { + it("mouseover -> followed by fast mouseout leads doesn't show tooltip", function() { mouse('mouseover', 10, 10); setTimeout( () => mouse('mouseout', 300, 300, { relatedTarget: document.body}), @@ -94,5 +94,5 @@ describe("hoverIntent", function() { this.clock.tick(200); assert.isFalse(isOver); }); - + }); diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md index 6436c91db7..c7ac0d4db8 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md @@ -125,7 +125,7 @@ If there are some actions upon leaving the parent element, e.g. an animation run To avoid it, we can check `relatedTarget` in the handler and, if the mouse is still inside the element, then ignore such event. -Alternatively we can use other events: `mouseenter` ะธ `mouseleave`, that we'll be covering now, as they don't have such problems. +Alternatively we can use other events: `mouseenter` and `mouseleave`, that we'll be covering now, as they don't have such problems. ## Events mouseenter and mouseleave @@ -145,7 +145,7 @@ When the pointer leaves an element -- `mouseleave` triggers. ```online This example is similar to the one above, but now the top element has `mouseenter/mouseleave` instead of `mouseover/mouseout`. -As you can see, the only generated events are the ones related to moving the pointer in and out of the top element. Nothing happens when the pointer goes to the child and back. Transitions between descendants are ignores +As you can see, the only generated events are the ones related to moving the pointer in and out of the top element. Nothing happens when the pointer goes to the child and back. Transitions between descendants are ignored [codetabs height=340 src="mouseleave"] ``` @@ -195,10 +195,14 @@ Here's an example of code that accounts for all possible situations: [js src="mouseenter-mouseleave-delegation-2/script.js"] +Once again, the important features are: +1. It uses event delegation to handle entering/leaving of any `` inside the table. So it relies on `mouseover/out` instead of `mouseenter/leave` that don't bubble and hence allow no delegation. +2. Extra events, such as moving between descendants of `` are filtered out, so that `onEnter/Leave` runs only if the pointer leaves or enters `` as a whole. + ```online Here's the full example with all details: -[codetabs height=380 src="mouseenter-mouseleave-delegation-2"] +[codetabs height=460 src="mouseenter-mouseleave-delegation-2"] Try to move the cursor in and out of table cells and inside them. Fast or slow -- doesn't matter. Only `` as a whole is highlighted, unlike the example before. ``` diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/index.html index e129ee6a28..eedd387163 100755 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/index.html +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/index.html @@ -67,6 +67,10 @@ + + + + diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js index 27ae27b94f..6a3202467e 100755 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js @@ -18,7 +18,7 @@ table.onmouseover = function(event) { // hooray! we entered a new currentElem = target; - target.style.background = 'pink'; + onEnter(currentElem); }; @@ -40,6 +40,23 @@ table.onmouseout = function(event) { } // we left the . really. - currentElem.style.background = ''; + onLeave(currentElem); currentElem = null; }; + +// any functions to handle entering/leaving an element +function onEnter(elem) { + elem.style.background = 'pink'; + + // show that in textarea + text.value += `over -> ${currentElem.tagName}.${currentElem.className}\n`; + text.scrollTop = 1e6; +} + +function onLeave(elem) { + elem.style.background = ''; + + // show that in textarea + text.value += `out <- ${elem.tagName}.${elem.className}\n`; + text.scrollTop = 1e6; +} diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation.view/script.js index 4700d686e2..ae633ad67d 100755 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation.view/script.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation.view/script.js @@ -1,13 +1,15 @@ table.onmouseover = function(event) { let target = event.target; target.style.background = 'pink'; - text.value += "mouseover " + target.tagName + "\n"; + + text.value += `over -> ${target.tagName}\n`; text.scrollTop = text.scrollHeight; }; table.onmouseout = function(event) { let target = event.target; target.style.background = ''; - text.value += "mouseout " + target.tagName + "\n"; + + text.value += `out <- ${target.tagName}\n`; text.scrollTop = text.scrollHeight; -}; \ No newline at end of file +}; diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg index 07830295c5..6044eff17d 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg @@ -1 +1 @@ -mouseoutmouseover#parent#child \ No newline at end of file +mouseoutmouseover#parent#child \ No newline at end of file diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg index 07176ba2da..22335b52e1 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg @@ -1 +1 @@ -#TOtargetrelatedTarget = null \ No newline at end of file +#TOtargetrelatedTarget = null \ No newline at end of file diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg index 262ddf596e..437f03b102 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg @@ -1 +1 @@ -#TO#FROM<DIV><DIV><DIV>mouseovermouseout \ No newline at end of file +#TO#FROM<DIV><DIV><DIV>mouseovermouseout \ No newline at end of file diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg index 784f435de0..1277ddff55 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg @@ -1 +1 @@ -<DIV>mouseovermouseout \ No newline at end of file +<DIV>mouseovermouseout \ No newline at end of file diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg index b38d76fbed..78210845b4 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg @@ -1 +1 @@ -mouseoutmouseover#parent#child \ No newline at end of file +mouseoutmouseover#parent#child \ No newline at end of file diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg index f5562f97a9..4ae90b1c71 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg @@ -1 +1 @@ -(0,0)clientWidth \ No newline at end of file +(0,0)clientWidth \ No newline at end of file diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js index 1c1443a7e7..10ae2eeed0 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js @@ -7,7 +7,7 @@ document.addEventListener('mousedown', function(event) { if (!dragElement) return; event.preventDefault(); - + dragElement.ondragstart = function() { return false; }; @@ -19,7 +19,7 @@ document.addEventListener('mousedown', function(event) { function onMouseUp(event) { finishDrag(); }; - + function onMouseMove(event) { moveAt(event.clientX, event.clientY); } @@ -31,9 +31,9 @@ document.addEventListener('mousedown', function(event) { if(isDragging) { return; } - + isDragging = true; - + document.addEventListener('mousemove', onMouseMove); element.addEventListener('mouseup', onMouseUp); @@ -50,10 +50,10 @@ document.addEventListener('mousedown', function(event) { if(!isDragging) { return; } - + isDragging = false; - dragElement.style.top = parseInt(dragElement.style.top) + pageYOffset + 'px'; + dragElement.style.top = parseInt(dragElement.style.top) + window.pageYOffset + 'px'; dragElement.style.position = 'absolute'; document.removeEventListener('mousemove', onMouseMove); @@ -113,4 +113,4 @@ document.addEventListener('mousedown', function(event) { dragElement.style.top = newY + 'px'; } -}); \ No newline at end of file +}); diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md index 721357b7a0..664069e943 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md @@ -1,54 +1,54 @@ -# Drag'n'Drop with mouse events +# ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ๊ณผ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ -Drag'n'Drop is a great interface solution. Taking something, dragging and dropping is a clear and simple way to do many things, from copying and moving documents (as in file managers) to ordering (drop into cart). +๋“œ๋ž˜๊ทธ(drag)์™€ ๋“œ๋กญ(drop)์€ ์‚ฌ์šฉ์ž์™€ ์ปดํ“จํ„ฐ ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์„ ๋„์™€์ฃผ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ด€๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฌธ์„œ๋ฅผ ๋ณต์‚ฌํ•ด ์ด๋™ํ•˜๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์ฃผ๋ฌธํ•˜๋ ค๋Š” ๋ฌผ๊ฑด์„ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋“œ๋กญํ•˜๋Š” ๊ฒƒ๊นŒ์ง€, ๋“œ๋ž˜๊ทธ์™€ ๋“œ๋กญ์„ ์‚ฌ์šฉํ•˜๋ฉด ์•„์ฃผ ๋‹จ์ˆœํ•˜๊ณ  ๋ช…์พŒํ•˜๊ฒŒ ์›ํ•˜๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend` and so on. +๋ชจ๋˜ HTML ํ‘œ์ค€์—์„œ๋Š” `dragstart`, `dragend` ๋“ฑ์˜ ํŠน์ˆ˜ํ•œ ์ด๋ฒคํŠธ์™€ ํ•จ๊ป˜ [๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ](https://html.spec.whatwg.org/multipage/interaction.html#dnd)์— ๋Œ€ํ•œ ์ ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -They are interesting because they allow to solve simple tasks easily, and also allow to handle drag'n'drop of "external" files into the browser. So we can take a file in the OS file-manager and drop it into the browser window. Then JavaScript gains access to its contents. +`dragstart`๋‚˜ `dragend` ์ด๋ฒคํŠธ๋Š” ์šด์˜์ฒด์ œ์˜ ํŒŒ์ผ ๊ด€๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ๋ถ€ํ„ฐ ํŒŒ์ผ์„ ๋“œ๋ž˜๊ทธํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์— ๋“œ๋กญํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํŒŒ์ผ ๊ด€๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋“œ๋ž˜๊ทธํ•˜์—ฌ ๊ฐ€์ ธ์˜จ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API. +ํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ๋“œ๋ž˜๊ทธ ์ด๋ฒคํŠธ์—๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ์˜์—ญ์—์„œ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ˆ˜ํ‰์ด๋‚˜ ์ˆ˜์ง์œผ๋กœ๋งŒ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๊ฒƒ๋„ ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด์™ธ์—๋„ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ๊ธฐ๋Šฅ์œผ๋กœ ํ•  ์ˆ˜ ์—†๋Š” ์ž‘์—…์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ์˜ ์ง€์›๋„ ๋งŽ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. -Here we'll see how to implement Drag'n'Drop using mouse events. +๊ธฐ๋ณธ ๋“œ๋ž˜๊ทธ ์ด๋ฒคํŠธ์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -## Drag'n'Drop algorithm +## ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์•Œ๊ณ ๋ฆฌ์ฆ˜ -The basic Drag'n'Drop algorithm looks like this: +๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์˜ ๊ธฐ๋ณธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -1. On `mousedown` - prepare the element for moving, if needed (maybe create a copy of it). -2. Then on `mousemove` move it by changing `left/top` and `position:absolute`. -3. On `mouseup` - perform all actions related to a finished Drag'n'Drop. +1. `mousedown`์—์„œ๋Š” ์›€์ง์ž„์ด ํ•„์š”ํ•œ ์š”์†Œ๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๊ธฐ์กด ์š”์†Œ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜, ํ•ด๋‹น ์š”์†Œ์— ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +2. ์ดํ›„ `mousemove`์—์„œ `position:absolute`์˜ `leftโˆ™top`์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. +3. `mouseup`์—์„œ๋Š” ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์™„๋ฃŒ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. -These are the basics. Later we can extend it, for instance, by highlighting droppable (available for the drop) elements when hovering over them. +์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ๊ธฐ๋ณธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ดํ›„์—๋Š” ์ด๋™ ์ค‘์ธ ์š”์†Œ ์•„๋ž˜์— ์žˆ๋Š” ๋‹ค๋ฅธ ์š”์†Œ๋ฅผ ๊ฐ•์กฐํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -Here's the algorithm for drag'n'drop of a ball: +๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js -ball.onmousedown = function(event) { // (1) start the process - - // (2) prepare to moving: make absolute and on top by z-index +ball.onmousedown = function(event) { + // (1) absolute ์†์„ฑ๊ณผ zIndex ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•ด ๊ณต์ด ์ œ์ผ ์œ„์—์„œ ์›€์ง์ด๊ธฐ ์œ„ํ•œ ์ค€๋น„๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ball.style.position = 'absolute'; ball.style.zIndex = 1000; - // move it out of any current parents directly into body - // to make it positioned relative to the body - document.body.append(ball); - // ...and put that absolutely positioned ball under the pointer - moveAt(event.pageX, event.pageY); + // ํ˜„์žฌ ์œ„์น˜ํ•œ ๋ถ€๋ชจ์—์„œ body๋กœ ์ง์ ‘ ์ด๋™ํ•˜์—ฌ + // body๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์œ„์น˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. + document.body.append(ball); - // centers the ball at (pageX, pageY) coordinates + // ๊ณต์„ pageX, pageY ์ขŒํ‘œ ์ค‘์•™์— ์œ„์น˜ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. function moveAt(pageX, pageY) { ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; } + // ํฌ์ธํ„ฐ ์•„๋ž˜๋กœ ๊ณต์„ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค. + moveAt(event.pageX, event.pageY); + function onMouseMove(event) { moveAt(event.pageX, event.pageY); } - // (3) move the ball on mousemove + // (2) mousemove๋กœ ๊ณต์„ ์›€์ง์ž…๋‹ˆ๋‹ค. document.addEventListener('mousemove', onMouseMove); - // (4) drop the ball, remove unneeded handlers + // (3) ๊ณต์„ ๋“œ๋กญํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ball.onmouseup = function() { document.removeEventListener('mousemove', onMouseMove); ball.onmouseup = null; @@ -57,19 +57,19 @@ ball.onmousedown = function(event) { // (1) start the process }; ``` -If we run the code, we can notice something strange. On the beginning of the drag'n'drop, the ball "forks": we start dragging its "clone". +์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉด ๋ฌด์–ธ๊ฐ€ ์ด์ƒํ•œ ์ ์ด ๋ณด์ผ ๊ฒ๋‹ˆ๋‹ค. ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ์‹œ์ž‘ํ•  ๋•Œ ๊ณต์„ ์ฐ์–ด ์˜ฌ๋ฆฌ๊ณ , ๋ณต์‚ฌ๋œ ๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ```online -Here's an example in action: +์˜ˆ์‹œ: [iframe src="ball" height=230] -Try to drag'n'drop the mouse and you'll see such behavior. +๋งˆ์šฐ์Šค๋กœ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ์‹œ๋„ํ•˜๋ฉด ๊ณต์„ ์ฐ์–ด ์˜ฌ๋ ค ๋ณต์‚ฌ๋œ ๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๋™์ž‘์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ``` -That's because the browser has its own Drag'n'Drop for images and some other elements that runs automatically and conflicts with ours. +๋ธŒ๋ผ์šฐ์ € ์ž์ฒด์ ์œผ๋กœ ์ด๋ฏธ์ง€๋‚˜ ์š”์†Œ์— ๋Œ€ํ•œ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ž๋™ ์‹คํ–‰๋˜์–ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ์™€ ์ถฉ๋Œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -To disable it: +๋น„ํ™œ์„ฑํ™” ๋ฐฉ๋ฒ•: ```js ball.ondragstart = function() { @@ -77,42 +77,42 @@ ball.ondragstart = function() { }; ``` -Now everything will be all right. +์ด์ œ ์ž˜ ๋ฉ๋‹ˆ๋‹ค. ```online -In action: +์˜ˆ์‹œ: [iframe src="ball2" height=230] ``` -Another important aspect -- we track `mousemove` on `document`, not on `ball`. From the first sight it may seem that the mouse is always over the ball, and we can put `mousemove` on it. +๋‹ค๋ฅธ ์ค‘์š”ํ•œ ์ ์€ `ball`์ด ์•„๋‹Œ `document`์—์„œ `mousemove`๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ ๋ณผ ๋•Œ ๋งˆ์šฐ์Šค๊ฐ€ ํ•ญ์ƒ ๊ณต ์œ„์— ์žˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์— `mousemove`๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -But as we remember, `mousemove` triggers often, but not for every pixel. So after swift move the pointer can jump from the ball somewhere in the middle of document (or even outside of the window). +ํ•˜์ง€๋งŒ `mousemove`๋Š” ๋ชจ๋“  ํ”ฝ์…€์— ๋Œ€ํ•ด ์ž์ฃผ ํŠธ๋ฆฌ๊ฑฐ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋น ๋ฅด๊ฒŒ ์›€์ง์ด๋ฉด ํฌ์ธํ„ฐ๊ฐ€ ๊ณต์—์„œ document์˜ ์ค‘๊ฐ„์ด๋‚˜ ์œˆ๋„์šฐ ์–ด๋”˜๊ฐ€๋กœ ์ ํ”„ ๋˜๋Š” ํ˜„์ƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -So we should listen on `document` to catch it. +document์˜ ์ค‘๊ฐ„์ด๋‚˜ ์œˆ๋„์šฐ ์–ด๋”˜๊ฐ€๋กœ ์ ํ”„ ๋˜๋Š” ํ˜„์ƒ์„ ์žก๊ธฐ ์œ„ํ•ด document๋ฅผ ๋‹ค๋ค„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -## Correct positioning +## ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜ ์ง€์ • -In the examples above the ball is always moved so, that it's center is under the pointer: +์œ„ ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ ๊ณต์€ ํ•ญ์ƒ ํฌ์ธํ„ฐ ์•„๋ž˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ```js ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; ``` -Not bad, but there's a side-effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer. +๋‚˜์˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ๋ช‡ ๊ฐ€์ง€ ๋ถ€์ž‘์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ๊ณต ์œ„ ์–ด๋””์—์„œ๋“  `mousedown`์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต์˜ ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ `mousedown`์„ ํ•˜๊ฒŒ ๋˜๋ฉด, ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ ์•„๋ž˜๋กœ ๊ณต์ด ๊ฐ‘์ž๊ธฐ ์ ํ”„ ๋˜๋Š” ๋ถ€์ž‘์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -It would be better if we keep the initial shift of the element relative to the pointer. +ํฌ์ธํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์š”์†Œ์˜ ์ดˆ๊ธฐ ์ด๋™์„ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํฌ์ธํ„ฐ ์ค‘์•™์œผ๋กœ ์š”์†Œ๋ฅผ ์ด๋™์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋” ์ข‹์Šต๋‹ˆ๋‹ค. -For instance, if we start dragging by the edge of the ball, then the pointer should remain over the edge while dragging. +์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณต์˜ ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ ๋“œ๋ž˜๊ทธํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค๋ฉด ๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๋™์•ˆ ํฌ์ธํ„ฐ๋Š” ๊ณต์˜ ๊ฐ€์žฅ์ž๋ฆฌ์— ์œ ์ง€๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ![](ball_shift.svg) -Let's update our algorithm: +๊ฐœ์„ ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜: -1. When a visitor presses the button (`mousedown`) - remember the distance from the pointer to the left-upper corner of the ball in variables `shiftX/shiftY`. We'll keep that distance while dragging. +1. ๋ฐฉ๋ฌธ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ(`mousedown` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ) - `shiftXโˆ™shiftY` ๋ณ€์ˆ˜์— pointer์—์„œ ๊ณต์˜ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๋™์•ˆ ์ด ๊ฑฐ๋ฆฌ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. - To get these shifts we can substract the coordinates: + ๊ฑฐ๋ฆฌ๋ฅผ ์œ ์ง€ํ•˜๋Š” ์›€์ง์ž„์€ ํฌ์ธํ„ฐ์˜ ์ขŒํ‘œ์—์„œ ๊ณต์˜ ์™ผ์ชฝ ์œ„ ์ขŒํ‘œ๋ฅผ ๋นผ์„œ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js // onmousedown @@ -120,16 +120,16 @@ Let's update our algorithm: let shiftY = event.clientY - ball.getBoundingClientRect().top; ``` -2. Then while dragging we position the ball on the same shift relative to the pointer, like this: +2. ๊ณต์„ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๋™์•ˆ ํฌ์ธํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ™์€ ์œ„์น˜์— ๊ณต์ด ์ด๋™๋ฉ๋‹ˆ๋‹ค. ```js // onmousemove - // ัƒ ะผัั‡ะฐ ball ัั‚ะพะธั‚ position:absoute + // ๊ณต์€ ๊ณ ์ •๋œ ํฌ์ง€์…˜์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. ball.style.left = event.pageX - *!*shiftX*/!* + 'px'; ball.style.top = event.pageY - *!*shiftY*/!* + 'px'; ``` -The final code with better positioning: +๊ฐœ์„ ๋œ ์œ„์น˜ ์„ ์ • ์ตœ์ข… ์ฝ”๋“œ: ```js ball.onmousedown = function(event) { @@ -145,8 +145,8 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); - // moves the ball at (pageX, pageY) coordinates - // taking initial shifts into account + // ์ดˆ๊ธฐ ์ด๋™์„ ๊ณ ๋ คํ•œ ์ขŒํ‘œ (pageX, pageY)์—์„œ + // ๊ณต์„ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. function moveAt(pageX, pageY) { ball.style.left = pageX - *!*shiftX*/!* + 'px'; ball.style.top = pageY - *!*shiftY*/!* + 'px'; @@ -156,10 +156,10 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); } - // move the ball on mousemove + // mousemove๋กœ ๊ณต์„ ์›€์ง์ž…๋‹ˆ๋‹ค. document.addEventListener('mousemove', onMouseMove); - // drop the ball, remove unneeded handlers + // ๊ณต์„ ๋“œ๋กญํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ball.onmouseup = function() { document.removeEventListener('mousemove', onMouseMove); ball.onmouseup = null; @@ -173,32 +173,32 @@ ball.ondragstart = function() { ``` ```online -In action (inside ` diff --git a/3-frames-and-windows/index.md b/3-frames-and-windows/index.md index eb5069e39e..62a41cc21f 100644 --- a/3-frames-and-windows/index.md +++ b/3-frames-and-windows/index.md @@ -1 +1 @@ -# Frames and windows +๏ปฟ# ํ”„๋ ˆ์ž„๊ณผ ์œˆ๋„์šฐ \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md index 6710104b2a..80cdf87aab 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md @@ -1,4 +1,4 @@ -# Concatenate typed arrays +# ํƒ€์ž…์ด ์ง€์ •๋œ ๋ฐฐ์—ด ์—ฐ๊ฒฐํ•˜๊ธฐ -Given an array of `Uint8Array`, write a function `concat(arrays)` that returns a concatenation of them into a single array. +์ฃผ์–ด์ง„ `Uint8Array`์˜ ๋ฐฐ์—ด์„ ํ•˜๋‚˜์˜ ๋ฐฐ์—ด๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ `concat(arrays)`๋ฅผ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค. \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/8bit-integer-256.svg b/4-binary/01-arraybuffer-binary-arrays/8bit-integer-256.svg index 89ae964071..b697d63043 100644 --- a/4-binary/01-arraybuffer-binary-arrays/8bit-integer-256.svg +++ b/4-binary/01-arraybuffer-binary-arrays/8bit-integer-256.svg @@ -1 +1 @@ -8-bit integer256 \ No newline at end of file +8-bit integer256 \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/8bit-integer-257.svg b/4-binary/01-arraybuffer-binary-arrays/8bit-integer-257.svg index c7b74cd63c..8e3074fdf3 100644 --- a/4-binary/01-arraybuffer-binary-arrays/8bit-integer-257.svg +++ b/4-binary/01-arraybuffer-binary-arrays/8bit-integer-257.svg @@ -1 +1 @@ -8-bit integer257 \ No newline at end of file +8-bit integer257 \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/arraybuffer-view-buffersource.svg b/4-binary/01-arraybuffer-binary-arrays/arraybuffer-view-buffersource.svg index 12daeeaec4..b9de47de1e 100644 --- a/4-binary/01-arraybuffer-binary-arrays/arraybuffer-view-buffersource.svg +++ b/4-binary/01-arraybuffer-binary-arrays/arraybuffer-view-buffersource.svg @@ -1 +1 @@ -02134567012301new ArrayBuffer(16)ArrayBufferViewUint16Array Int16ArrayUint8Array Int8Array Uint8ClampedArrayUint32Array Int32Array Float32ArrayFloat64ArrayDataViewget/setUint8(offset) get/setFloat32(offset)...BufferSource1023456789101112131415 \ No newline at end of file +02134567012301new ArrayBuffer(16)ArrayBufferViewUint16Array Int16ArrayUint8Array Int8Array Uint8ClampedArrayUint32Array Int32Array Float32ArrayFloat64ArrayDataViewget/setUint8(offset) get/setFloat32(offset)...BufferSource1023456789101112131415 \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/arraybuffer-views.svg b/4-binary/01-arraybuffer-binary-arrays/arraybuffer-views.svg index 02160e31e5..b022796ad2 100644 --- a/4-binary/01-arraybuffer-binary-arrays/arraybuffer-views.svg +++ b/4-binary/01-arraybuffer-binary-arrays/arraybuffer-views.svg @@ -1 +1 @@ -100213234567891011121314154567012301new ArrayBuffer(16)Uint16ArrayUint8ArrayUint32ArrayFloat64Array \ No newline at end of file +100213234567891011121314154567012301new ArrayBuffer(16)Uint16ArrayUint8ArrayUint32ArrayFloat64Array \ No newline at end of file diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index b1d0bbb0d0..6e6ea8022f 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -73,8 +73,11 @@ for(let num of view) { The common term for all these views (`Uint8Array`, `Uint32Array`, etc) is [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). They share the same set of methods and properities. -They are much more like regular arrays: have indexes and iterable. +Please note, there's no constructor called `TypedArray`, it's just a common "umbrella" term to represent one of views over `ArrayBuffer`: `Int8Array`, `Uint8Array` and so on, the full list will soon follow. +When you see something like `new TypedArray`, it means any of `new Int8Array`, `new Uint8Array`, etc. + +Typed array behave like regular arrays: have indexes and iterable. A typed array constructor (be it `Int8Array` or `Float64Array`, doesn't matter) behaves differently depending on argument types. @@ -232,7 +235,7 @@ let dataView = new DataView(buffer); // get 8-bit number at offset 0 alert( dataView.getUint8(0) ); // 255 -// now get 16-bit number at offset 0, it consists of 2 bytes, together iterpreted as 65535 +// now get 16-bit number at offset 0, it consists of 2 bytes, together interpreted as 65535 alert( dataView.getUint16(0) ); // 65535 (biggest 16-bit unsigned int) // get 32-bit number at offset 0 @@ -241,7 +244,7 @@ alert( dataView.getUint32(0) ); // 4294967295 (biggest 32-bit unsigned int) dataView.setUint32(0, 0); // set 4-byte number to zero, thus setting all bytes to 0 ``` -`DataView` is great when we store mixed-format data in the same buffer. E.g we store a sequence of pairs (16-bit integer, 32-bit float). Then `DataView` allows to access them easily. +`DataView` is great when we store mixed-format data in the same buffer. For example, when we store a sequence of pairs (16-bit integer, 32-bit float), `DataView` allows to access them easily. ## Summary diff --git a/4-binary/02-text-decoder/article.md b/4-binary/02-text-decoder/article.md index d9f5e8fa55..619eb9d2d3 100644 --- a/4-binary/02-text-decoder/article.md +++ b/4-binary/02-text-decoder/article.md @@ -1,30 +1,30 @@ -# TextDecoder and TextEncoder +# ํ…์ŠคํŠธ ๋””์ฝ”๋”์™€ ํ…์ŠคํŠธ ์ธ์ฝ”๋” -What if the binary data is actually a string? For instance, we received a file with textual data. +์ด์ง„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌธ์ž์—ด์ด๋ผ๋ฉด ์–ด๋–จ์ง€ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ํŒŒ์ผ์„ ๋ฐ›์•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -The build-in [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder) object allows to read the value into an actual JavaScript string, given the buffer and the encoding. +๋‚ด์žฅ ๊ฐ์ฒด, [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder)๋Š” ์ฃผ์–ด์ง„ ๋ฒ„ํผ์™€ ์ธ์ฝ”๋”ฉ์œผ๋กœ ๊ฐ’์„ ์‹ค์ œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ์ž์—ด๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -We first need to create it: +์ฒซ ๋ฒˆ์งธ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ```js let decoder = new TextDecoder([label], [options]); ``` -- **`label`** -- the encoding, `utf-8` by default, but `big5`, `windows-1251` and many other are also supported. -- **`options`** -- optional object: - - **`fatal`** -- boolean, if `true` then throw an exception for invalid (non-decodable) characters, otherwise (default) replace them with character `\uFFFD`. - - **`ignoreBOM`** -- boolean, if `true` then ignore BOM (an optional byte-order unicode mark), rarely needed. +- **`label`** -- ๊ธฐ๋ณธ์ ์ธ ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์€ `utf-8`์ด์ง€๋งŒ `big5`, `windows-1251` ๋ฐ ๋‹ค๋ฅธ ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹๋„ ์ง€์›๋ฉ๋‹ˆ๋‹ค. +- **`options`** -- ์„ ํƒ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. + - **`fatal`** -- ๋ถˆ๋ฆฐ ๊ฐ’. `true`์ธ ๊ฒฝ์šฐ, ์ž˜๋ชป๋œ ๊ธ€์ž(๋””์ฝ”๋”ฉ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ธ€์ž)๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. `false(๊ธฐ๋ณธ๊ฐ’)`์ธ ๊ฒฝ์šฐ, ๊ธ€์ž๋ฅผ `\uFFFD`๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. + - **`ignoreBOM`** -- ๋ถˆ๋ฆฐ ๊ฐ’์ด `true`์ธ ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฐ”์ดํŠธ ์ˆœ์„œ ํ‘œ์‹(Byte Order Mark, BOM)์„ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค. -...And then decode: +๊ทธ๋Ÿฐ ๋‹ค์Œ ์ƒ์„ฑํ–ˆ๋˜ ๊ฐ์ฒด๋ฅผ ๋””์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค. ```js let str = decoder.decode([input], [options]); ``` -- **`input`** -- `BufferSource` to decode. -- **`options`** -- optional object: - - **`stream`** -- true for decoding streams, when `decoder` is called repeatedly with incoming chunks of data. In that case a multi-byte character may occasionally split between chunks. This options tells `TextDecoder` to memorize "unfinished" characters and decode them when the next chunk comes. +- **`input`** -- ๋””์ฝ”๋”ฉํ•  `BufferSource`๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. +- **`options`** -- ์„ ํƒ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. + - **`stream`** -- ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„๋“ค์—ฌ `decoder`๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœํ•  ๋•Œ๋„ decoding์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ๋ฉ€ํ‹ฐ ๋ฐ”์ดํŠธ ๋ฌธ์ž๊ฐ€ ๋งŽ์€ ๋ฐ์ดํ„ฐ๋กœ ๋ถ„ํ• ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ ๋ฐ์ดํ„ฐ ๋ถ„ํ• ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด `TextDecoder`์— "unfinished" ๋ฌธ์ž๋ฅผ ์ž…๋ ฅ์‹œํ‚ค๊ณ  ๋‹ค์Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๋ฉด ๋””์ฝ”๋”ฉํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. -For instance: +์˜ˆ์‹œ: ```js run let uint8Array = new Uint8Array([72, 101, 108, 108, 111]); @@ -39,34 +39,34 @@ let uint8Array = new Uint8Array([228, 189, 160, 229, 165, 189]); alert( new TextDecoder().decode(uint8Array) ); // ไฝ ๅฅฝ ``` -We can decode a part of the buffer by creating a subarray view for it: +๋ฒ„ํผ์˜ ํ•˜์œ„ ๋ฐฐ์—ด ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฒ„ํผ์˜ ์ผ๋ถ€๋ฅผ ๋””์ฝ”๋”ฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let uint8Array = new Uint8Array([0, 72, 101, 108, 108, 111, 0]); -// the string is in the middle -// create a new view over it, without copying anything +// ๋ฌธ์ž์—ด์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฐ์—ด์˜ ์š”์†Œ๋Š” ์ค‘๊ฐ„์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. +// ๋ฐฐ์—ด์˜ ๋ณต์‚ฌ ์—†์ด ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. let binaryString = uint8Array.subarray(1, -1); alert( new TextDecoder().decode(binaryString) ); // Hello ``` -## TextEncoder +## ํ…์ŠคํŠธ ์ธ์ฝ”๋” -[TextEncoder](https://encoding.spec.whatwg.org/#interface-textencoder) does the reverse thing -- converts a string into bytes. +[TextEncoder](https://encoding.spec.whatwg.org/#interface-textencoder)๋Š” ๋ฐ˜๋Œ€๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -The syntax is: +๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -```js run +```js let encoder = new TextEncoder(); ``` -The only encoding it supports is "utf-8". +`TextEncoder`๋Š” ์ธ์ฝ”๋”ฉ ์‹œ 'utf-8'๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -It has two methods: -- **`encode(str)`** -- returns `Uint8Array` from a string. -- **`encodeInto(str, destination)`** -- encodes `str` into `destination` that must be `Uint8Array`. +2๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +- **`encode(str)`** -- `Uint8Array`์— ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- **`encodeInto(str, destination)`** -- `Uint8Array` ๊ตฌ์กฐ ํ˜•ํƒœ๋กœ ๋ฌธ์ž์—ด `str`๋ฅผ `destination`์— ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค. ```js run let encoder = new TextEncoder(); diff --git a/4-binary/03-blob/article.md b/4-binary/03-blob/article.md index 062e1834bc..84cf6f1cca 100644 --- a/4-binary/03-blob/article.md +++ b/4-binary/03-blob/article.md @@ -97,7 +97,7 @@ That's what the value of `link.href` looks like: blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273 ``` -The browser for each URL generated by `URL.createObjectURL` stores an the URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`. +For each URL generated by `URL.createObjectURL` the browser stores a URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`. A generated URL (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the `Blob` in ``, ``, basically any other object that expects an url. diff --git a/4-binary/03-blob/blob.svg b/4-binary/03-blob/blob.svg index b1cf6fcc8e..8f42454516 100644 --- a/4-binary/03-blob/blob.svg +++ b/4-binary/03-blob/blob.svg @@ -1 +1 @@ -image/pngblob1blob2strbuffer...typeBlobblobParts+= \ No newline at end of file +image/pngblob1blob2strbuffer...typeBlobblobParts+= \ No newline at end of file diff --git a/4-binary/04-file/article.md b/4-binary/04-file/article.md index 43c0ca5837..20878b6508 100644 --- a/4-binary/04-file/article.md +++ b/4-binary/04-file/article.md @@ -61,8 +61,8 @@ The main methods: The choice of `read*` method depends on which format we prefer, how we're going to use the data. -- `readAsArrayBuffer` - for binary files, to do low-level binary operations. For high-level operations, like slicing, `File` inherits from `Blob`, so we can call them directly, without reading. -- `readAsText` - for text files, when we'd like to get a string. +- `readAsArrayBuffer` -- for binary files, to do low-level binary operations. For high-level operations, like slicing, `File` inherits from `Blob`, so we can call them directly, without reading. +- `readAsText` -- for text files, when we'd like to get a string. - `readAsDataURL` -- when we'd like to use this data in `src` for `img` or another tag. There's an alternative to reading a file for that, as discussed in chapter : `URL.createObjectURL(file)`. As the reading proceeds, there are events: diff --git a/4-binary/index.md b/4-binary/index.md index 2b0c5dc825..b06a12a1a3 100644 --- a/4-binary/index.md +++ b/4-binary/index.md @@ -1,3 +1,3 @@ -# Binary data, files +# ์ด์ง„ ๋ฐ์ดํ„ฐ์™€ ํŒŒ์ผ -Working with binary data and files in JavaScript. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ด์ง„ ๋ฐ์ดํ„ฐ์™€ ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค. diff --git a/5-network/01-fetch/01-fetch-users/_js.view/source.js b/5-network/01-fetch/01-fetch-users/_js.view/source.js index 0c62e7bb57..6944125fdb 100644 --- a/5-network/01-fetch/01-fetch-users/_js.view/source.js +++ b/5-network/01-fetch/01-fetch-users/_js.view/source.js @@ -1,4 +1,4 @@ async function getUsers(names) { - /* your code */ + /* ์—ฌ๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. */ } diff --git a/5-network/01-fetch/01-fetch-users/_js.view/test.js b/5-network/01-fetch/01-fetch-users/_js.view/test.js index 95eaf876e0..e826d0e980 100644 --- a/5-network/01-fetch/01-fetch-users/_js.view/test.js +++ b/5-network/01-fetch/01-fetch-users/_js.view/test.js @@ -1,9 +1,9 @@ describe("getUsers", function() { - it("gets users from GitHub", async function() { - let users = await getUsers(['iliakan', 'remy', 'no.such.users']); - assert.equal(users[0].login, 'iliakan'); - assert.equal(users[1].login, 'remy'); + it('GitHub์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์–ป์–ด์˜ต๋‹ˆ๋‹ค.', async function() { + let users = await getUsers(["C17AN", "Violet-Bora-Lee", "์ด๋Ÿฐ์‚ฌ์šฉ์ž๋Š”์—†์Šต๋‹ˆ๋‹ค"]); + assert.equal(users[0].login, "C17AN"); + assert.equal(users[1].login, "Violet-Bora-Lee"); assert.equal(users[2], null); }); diff --git a/5-network/01-fetch/01-fetch-users/solution.md b/5-network/01-fetch/01-fetch-users/solution.md index b8dfb62a2c..b5b99d2e05 100644 --- a/5-network/01-fetch/01-fetch-users/solution.md +++ b/5-network/01-fetch/01-fetch-users/solution.md @@ -1,11 +1,11 @@ -To fetch a user we need: `fetch('https://api.github.com/users/USERNAME')`. +fetch๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด `fetch('https://api.github.com/users/์‚ฌ์šฉ์ž๋ช…')`๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -If the response has status `200`, call `.json()` to read the JS object. +์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ `200`์ด๋ฉด `.json()`์„ ํ˜ธ์ถœํ•ด ๊ฐ์ฒด๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. -Otherwise, if a `fetch` fails, or the response has non-200 status, we just return `null` in the resulting arrray. +๋ฐ˜๋ฉด `fetch`๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 200์ด ์•„๋‹ˆ๋ผ๋ฉด `null`์„ ๋ฆฌํ„ดํ•˜๊ณ  ๋ฐฐ์—ด์— ๋‹ด์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -So here's the code: +๋‹ต์•ˆ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js demo async function getUsers(names) { @@ -33,8 +33,8 @@ async function getUsers(names) { } ``` -Please note: `.then` call is attached directly to `fetch`, so that when we have the response, it doesn't wait for other fetches, but starts to read `.json()` immediately. +`.then`์€ `fetch` ์งํ›„ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ์‘๋‹ต์ด ๋„์ฐฉํ•˜๋ฉด ๋‹ค๋ฅธ fetch๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋Œ€์‹  ๊ณง๋ฐ”๋กœ `.json()`์œผ๋กœ ์‘๋‹ต์„ ์ฝ๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. -If we used `await Promise.all(names.map(name => fetch(...)))`, and call `.json()` on the results, then it would wait for all fetches to respond. By adding `.json()` directly to each `fetch`, we ensure that individual fetches start reading data as JSON without waiting for each other. +`await Promise.all(names.map(name => fetch(...)))`์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ๋Œ€์ƒ์œผ๋กœ `.json()`์„ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด ๋ชจ๋“  fetch ์‘๋‹ต์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ `fetch`๋งˆ๋‹ค `.json()`์„ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค๋ฅธ fetch ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์œผ๋ฉด์„œ JSON ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -That's an example of how low-level Promise API can still be useful even if we mainly use `async/await`. +์ด ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ๋น„๋ก `async-await`์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์—ฌ์ „ํžˆ ํ•˜์œ„ ์ˆ˜์ค€์˜ ํ”„๋ผ๋ฏธ์Šค(Promise) API๊ฐ€ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. \ No newline at end of file diff --git a/5-network/01-fetch/01-fetch-users/task.md b/5-network/01-fetch/01-fetch-users/task.md index 4605b49550..5cde3e2c53 100644 --- a/5-network/01-fetch/01-fetch-users/task.md +++ b/5-network/01-fetch/01-fetch-users/task.md @@ -1,13 +1,13 @@ -# Fetch users from GitHub +# fetch๋ฅผ ์‚ฌ์šฉํ•ด Github์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ -Create an async function `getUsers(names)`, that gets an array of GitHub logins, fetches the users from GitHub and returns an array of GitHub users. +GitHub ์‚ฌ์šฉ์ž ์ด๋ฆ„์ด ๋‹ด๊ธด ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜ `getUsers(names)`๋ฅผ ๋งŒ๋“  ํ›„, GitHub์—์„œ fetchํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด๋“ค์ด ๋‹ด๊ธด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. -The GitHub url with user information for the given `USERNAME` is: `https://api.github.com/users/USERNAME`. +`์‚ฌ์šฉ์ž๋ช…`์— ํ•ด๋‹นํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด GitHub API `https://api.github.com/users/์‚ฌ์šฉ์ž๋ช…`์— ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. -There's a test example in the sandbox. +์ƒŒ๋“œ๋ฐ•์Šค์— ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ์ค€๋น„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -Important details: +์•„๋ž˜ ์กฐ๊ฑด๋“ค์„ ์ง€์ผœ ๊ณผ์ œ๋ฅผ ์™„์ˆ˜ํ•ด ๋ณด์„ธ์š”. -1. There should be one `fetch` request per user. -2. Requests shouldn't wait for each other. So that the data arrives as soon as possible. -3. If any request fails, or if there's no such user, the function should return `null` in the resulting array. +1. ์‚ฌ์šฉ์ž๋‹น `fetch` ์š”์ฒญ์€ ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +2. ๋ฐ์ดํ„ฐ๊ฐ€ ์ตœ๋Œ€ํ•œ ์ผ์ฐ ๋„์ฐฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ ์š”์ฒญ์€ ๋‹ค๋ฅธ ์š”์ฒญ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. +3. ์š”์ฒญ์— ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์š”์ฒญ์„ ๋ณด๋ƒˆ๋‹ค๋ฉด `null`์„ ๋ฆฌํ„ดํ•˜๊ณ  ๋ฐฐ์—ด ์š”์†Œ์— ๋‹ด์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md index 1170042e0f..3f6f3a9d49 100644 --- a/5-network/01-fetch/article.md +++ b/5-network/01-fetch/article.md @@ -1,87 +1,87 @@ -# Fetch +# fetch -JavaScript can send network requests to the server and load new information whenever is needed. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•„์š”ํ•  ๋•Œ ์„œ๋ฒ„์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ƒˆ๋กœ์šด ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For example, we can use a network request to: +๋„คํŠธ์›Œํฌ ์š”์ฒญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์ด๋ค„์ง‘๋‹ˆ๋‹ค. -- Submit an order, -- Load user information, -- Receive latest updates from the server, -- ...etc. +- ์ฃผ๋ฌธ ์ „์†ก +- ์‚ฌ์šฉ์ž ์ •๋ณด ์ฝ๊ธฐ +- ์„œ๋ฒ„์—์„œ ์ตœ์‹  ๋ณ€๊ฒฝ๋ถ„ ๊ฐ€์ ธ์˜ค๊ธฐ +- ๋“ฑ๋“ฑ -...And all of that without reloading the page! +๊ทธ๋Ÿฐ๋ฐ ์ด ๋ชจ๋“  ๊ฒƒ๋“ค์€ ํŽ˜์ด์ง€ ์ƒˆ๋กœ ๊ณ ์นจ ์—†์ด๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -There's an umbrella term "AJAX" (abbreviated Asynchronous JavaScript And XML) for network requests from JavaScript. We don't have to use XML though: the term comes from old times, that's why that word is there. You may have heard that term already. +AJAX(Asynchronous JavaScript And XML, ๋น„๋™๊ธฐ์  JavaScript์™€ XML)๋ผ๋Š” ์šฉ์–ด๋ฅผ ๋“ค์–ด๋ณด์‹  ๋ถ„์ด ์žˆ์œผ์‹ค ๊ฒ๋‹ˆ๋‹ค. AJAX๋Š” ์„œ๋ฒ„์—์„œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํฌ๊ด„์ ์ธ ๊ธฐ์ˆ ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์šฉ์–ด๋กœ, ๋งŒ๋“ค์–ด์ง„ ์ง€ ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. AJAX์— XML์ด ํฌํ•จ๋œ ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์ด ๋•Œ๋ฌธ์ด์ฃ . -There are multiple ways to send a network request and get information from the server. +AJAX ์ด์™ธ์—๋„ ์„œ๋ฒ„์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. -The `fetch()` method is modern and versatile, so we'll start with it. It's not supported by old browsers (can be polyfilled), but very well supported among the modern ones. +๊ทธ์ค‘ ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„  ๋ชจ๋˜ํ•˜๊ณ  ๋‹ค์žฌ๋‹ค๋Šฅํ•œ `fetch()` ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•ด๋“œ๋ฆฌ๋ ค ํ•ฉ๋‹ˆ๋‹ค. `fetch()`๋Š” ๊ตฌ์‹ ๋ธŒ๋ผ์šฐ์ €์—์„  ์ง€์›ํ•˜์ง„ ์•Š์ง€๋งŒ(ํด๋ฆฌํ•„์„ ์“ฐ๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅ) ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -The basic syntax is: +`fetch()` ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js let promise = fetch(url, [options]) ``` -- **`url`** -- the URL to access. -- **`options`** -- optional parameters: method, headers etc. +- **`url`** -- ์ ‘๊ทผํ•˜๊ณ ์ž ํ•˜๋Š” URL +- **`options`** -- ์„ ํƒ ๋งค๊ฐœ๋ณ€์ˆ˜, method๋‚˜ header ๋“ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ -Without `options`, that is a simple GET request, downloading the contents of the `url`. +`options`์— ์•„๋ฌด๊ฒƒ๋„ ๋„˜๊ธฐ์ง€ ์•Š์œผ๋ฉด ์š”์ฒญ์€ `GET` ๋ฉ”์„œ๋“œ๋กœ ์ง„ํ–‰๋˜์–ด `url`๋กœ๋ถ€ํ„ฐ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์šด๋กœ๋“œ ๋ฉ๋‹ˆ๋‹ค. -The browser starts the request right away and returns a promise that the calling code should use to get the result. +`fetch()`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ํ”„๋ผ๋ฏธ์Šค๋Š” `fetch()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -Getting a response is usually a two-stage process. +์‘๋‹ต์€ ๋Œ€๊ฐœ ๋‘ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. -**First, the `promise`, returned by `fetch`, resolves with an object of the built-in [Response](https://fetch.spec.whatwg.org/#response-class) class as soon as the server responds with headers.** +**๋จผ์ €, ์„œ๋ฒ„์—์„œ ์‘๋‹ต ํ—ค๋”๋ฅผ ๋ฐ›์ž๋งˆ์ž `fetch` ํ˜ธ์ถœ ์‹œ ๋ฐ˜ํ™˜๋ฐ›์€ `promise`๊ฐ€ ๋‚ด์žฅ ํด๋ž˜์Šค [Response](https://fetch.spec.whatwg.org/#response-class)์˜ ์ธ์Šคํ„ด์Šค์™€ ํ•จ๊ป˜ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.** -At this stage we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet. +์ด ๋‹จ๊ณ„๋Š” ์•„์ง ๋ณธ๋ฌธ(body)์ด ๋„์ฐฉํ•˜๊ธฐ ์ „์ด์ง€๋งŒ, ๊ฐœ๋ฐœ์ž๋Š” ์‘๋‹ต ํ—ค๋”๋ฅผ ๋ณด๊ณ  ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -The promise rejects if the `fetch` was unable to make HTTP-request, e.g. network problems, or there's no such site. Abnormal HTTP-statuses, such as 404 or 500 do not cause an error. +๋„คํŠธ์›Œํฌ ๋ฌธ์ œ๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์‚ฌ์ดํŠธ์— ์ ‘์†ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ๊ฐ™์ด HTTP ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์—†๋Š” ์ƒํƒœ์—์„  ํ”„๋ผ๋ฏธ์Šค๋Š” ๊ฑฐ๋ถ€์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. -We can see HTTP-status in response properties: +HTTP ์ƒํƒœ๋Š” ์‘๋‹ต ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **`status`** -- HTTP status code, e.g. 200. -- **`ok`** -- boolean, `true` if the HTTP status code is 200-299. +- **`status`** -- HTTP ์ƒํƒœ ์ฝ”๋“œ(์˜ˆ: 200) +- **`ok`** -- ๋ถˆ๋ฆฐ ๊ฐ’. HTTP ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 200๊ณผ 299 ์‚ฌ์ด์ผ ๊ฒฝ์šฐ `true` -For example: +์˜ˆ์‹œ: ```js let response = await fetch(url); -if (response.ok) { // if HTTP-status is 200-299 - // get the response body (the method explained below) +if (response.ok) { // HTTP ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 200~299์ผ ๊ฒฝ์šฐ + // ์‘๋‹ต ๋ชฌ๋ฌธ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค(๊ด€๋ จ ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์—์„œ ์„ค๋ช…). let json = await response.json(); } else { alert("HTTP-Error: " + response.status); } ``` -**Second, to get the response body, we need to use an additional method call.** +**๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„  ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์‘๋‹ต ๋ณธ๋ฌธ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.** -`Response` provides multiple promise-based methods to access the body in various formats: +`response` ์—๋Š” ํ”„๋ผ๋ฏธ์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **`response.text()`** -- read the response and return as text, -- **`response.json()`** -- parse the response as JSON, -- **`response.formData()`** -- return the response as `FormData` object (explained in the [next chapter](info:formdata)), -- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type), -- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level representaion of binary data), -- additionally, `response.body` is a [ReadableStream](https://streams.spec.whatwg.org/#rs-class) object, it allows to read the body chunk-by-chunk, we'll see an example later. +- **`response.text()`** -- ์‘๋‹ต์„ ์ฝ๊ณ  ํ…์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค, +- **`response.json()`** -- ์‘๋‹ต์„ JSON ํ˜•ํƒœ๋กœ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค, +- **`response.formData()`** -- ์‘๋‹ต์„ `FormData` ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. `FormData`์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋‹ค์Œ ์ฑ•ํ„ฐ](info:formdata)์—์„œ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. +- **`response.blob()`** -- ์‘๋‹ต์„ [Blob](info:blob)(ํƒ€์ž…์ด ์žˆ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ) ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- **`response.arrayBuffer()`** -- ์‘๋‹ต์„ [ArrayBuffer](info:arraybuffer-binary-arrays)(๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์šฐ ๋ ˆ๋ฒจ ํ˜•์‹์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ) ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +- ์ด ์™ธ์—๋„ `response.body`๊ฐ€ ์žˆ๋Š”๋ฐ, [ReadableStream](https://streams.spec.whatwg.org/#rs-class) ๊ฐ์ฒด์ธ `response.body`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ฒญํฌ ๋‹จ์œ„๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์šฉ๋ก€๋Š” ๊ณง ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -For instance, let's get a JSON-object with latest commits from GitHub: +์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ GitHub์—์„œ ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹์„ JSON ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ›์•„๋ด…์‹œ๋‹ค. ```js run async -let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'; +let url = 'https://api.github.com/repos/javascript-tutorial/ko.javascript.info/commits'; let response = await fetch(url); *!* -let commits = await response.json(); // read response body and parse as JSON +let commits = await response.json(); // ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ฝ๊ณ  JSON ํ˜•ํƒœ๋กœ ํŒŒ์‹ฑํ•จ */!* alert(commits[0].author.login); ``` -Or, the same without `await`, using pure promises syntax: +์œ„ ์˜ˆ์‹œ๋ฅผ `await` ์—†์ด ํ”„๋ผ๋ฏธ์Šค๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits') @@ -89,70 +89,71 @@ fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commi .then(commits => alert(commits[0].author.login)); ``` -To get the reponse text, `await response.text()` instead of `.json()`: +์‘๋‹ต์„ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ ์–ป์œผ๋ ค๋ฉด `.json()` ๋Œ€์‹  `await response.text()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```js run async let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); -let text = await response.text(); // read response body as text +let text = await response.text(); // ์‘๋‹ต ๋ณธ๋ฌธ์„ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ ์ฝ์Šต๋‹ˆ๋‹ค. alert(text.slice(0, 80) + '...'); ``` -As a show-case for reading in binary format, let's fetch and show a logo image of ["fetch" specification](https://fetch.spec.whatwg.org) (see chapter [Blob](info:blob) for details about operations on `Blob`): +์ด๋ฒˆ์—” `fetch`๋ฅผ ์‚ฌ์šฉํ•ด [fetch ๋ช…์„ธ์„œ](https://fetch.spec.whatwg.org) ์šฐ์ธก ์ƒ๋‹จ์— ์žˆ๋Š” ๋กœ๊ณ (๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ)๋ฅผ ๊ฐ€์ ธ์™€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ `Blob`์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋งํฌ](info:blob)์—์„œ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js async run let response = await fetch('/article/fetch/logo-fetch.svg'); *!* -let blob = await response.blob(); // download as Blob object +let blob = await response.blob(); // ์‘๋‹ต์„ Blob ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋‹ค์šด๋กœ๋“œ๋ฐ›์Šต๋‹ˆ๋‹ค. */!* -// create for it +// ๋‹ค์šด๋กœ๋“œ๋ฐ›์€ Blob์„ ๋‹ด์„ ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. let img = document.createElement('img'); img.style = 'position:fixed;top:10px;left:10px;width:100px'; document.body.append(img); -// show it +// ์ด๋ฏธ์ง€๋ฅผ ํ™”๋ฉด์— ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. img.src = URL.createObjectURL(blob); -setTimeout(() => { // hide after three seconds +setTimeout(() => { // 3์ดˆ ํ›„ ์ด๋ฏธ์ง€๋ฅผ ์ˆจ๊น๋‹ˆ๋‹ค. img.remove(); URL.revokeObjectURL(img.src); }, 3000); ``` ````warn -We can choose only one body-reading method. +๋ณธ๋ฌธ์„ ์ฝ์„ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋”ฑ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -If we've already got the response with `response.text()`, then `response.json()` won't work, as the body content has already been processed. +`response.text()`๋ฅผ ์‚ฌ์šฉํ•ด ์‘๋‹ต์„ ์–ป์—ˆ๋‹ค๋ฉด ๋ณธ๋ฌธ์˜ ์ฝ˜ํ…์ธ ๋Š” ๋ชจ๋‘ ์ฒ˜๋ฆฌ ๋œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— `response.json()`์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js -let text = await response.text(); // response body consumed -let parsed = await response.json(); // fails (already consumed) +let text = await response.text(); // ์‘๋‹ต ๋ณธ๋ฌธ์ด ์†Œ๋น„๋ฉ๋‹ˆ๋‹ค. +let parsed = await response.json(); // ์‹คํŒจ +``` ```` -## Response headers +## ์‘๋‹ต ํ—ค๋” -The response headers are available in a Map-like headers object in `response.headers`. +์‘๋‹ต ํ—ค๋”๋Š” `response.headers`์— ๋งต๊ณผ ์œ ์‚ฌํ•œ ํ˜•ํƒœ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. -It's not exactly a Map, but it has similar methods to get individual headers by name or iterate over them: +๋งต์€ ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งต๊ณผ ์œ ์‚ฌํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•˜์ฃ . ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ํ—ค๋” ์ผ๋ถ€๋งŒ ์ถ”์ถœํ•˜๊ฑฐ๋‚˜ ํ—ค๋” ์ „์ฒด๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run async let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); -// get one header +// ํ—ค๋” ์ผ๋ถ€๋ฅผ ์ถ”์ถœ alert(response.headers.get('Content-Type')); // application/json; charset=utf-8 -// iterate over all headers +// ํ—ค๋” ์ „์ฒด๋ฅผ ์ˆœํšŒ for (let [key, value] of response.headers) { alert(`${key} = ${value}`); } ``` -## Request headers +## ์š”์ฒญ ํ—ค๋” -To set a request header in `fetch`, we can use the `headers` option. It has an object with outgoing headers, like this: +`headers` ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด `fetch`์— ์š”์ฒญ ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `headers`์—” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ํ—ค๋” ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ```js let response = fetch(protectedUrl, { @@ -162,7 +163,7 @@ let response = fetch(protectedUrl, { }); ``` -...But there's a list of [forbidden HTTP headers](https://fetch.spec.whatwg.org/#forbidden-header-name) that we can't set: +๊ทธ๋Ÿฐ๋ฐ `headers`๋ฅผ ์‚ฌ์šฉํ•ด ์„ค์ •ํ•  ์ˆ˜ ์—†๋Š” ํ—ค๋”๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธˆ์ง€๋œ ํ—ค๋” ์ „์ฒด ๋ชฉ๋ก์€ [๋งํฌ](https://fetch.spec.whatwg.org/#forbidden-header-name)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - `Accept-Charset`, `Accept-Encoding` - `Access-Control-Request-Headers` @@ -185,22 +186,22 @@ let response = fetch(protectedUrl, { - `Proxy-*` - `Sec-*` -These headers ensure proper and safe HTTP, so they are controlled exclusively by the browser. +์ด๋Ÿฐ ์ œ์•ฝ์€ HTTP๋ฅผ ๋ชฉ์ ์— ๋งž๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๊ณ  ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ธˆ์ง€ ๋ชฉ๋ก์— ์žˆ๋Š” ํ—ค๋”๋Š” ๋ธŒ๋ผ์šฐ์ €๋งŒ ๋ฐฐํƒ€์ ์œผ๋กœ ์„ค์ •, ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## POST requests +## POST ์š”์ฒญ -To make a `POST` request, or a request with another method, we need to use `fetch` options: +`GET` ์ด์™ธ์˜ ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ์ถ”๊ฐ€ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- **`method`** -- HTTP-method, e.g. `POST`, -- **`body`** -- the request body, one of: - - a string (e.g. JSON-encoded), - - `FormData` object, to submit the data as `form/multipart`, - - `Blob`/`BufferSource` to send binary data, - - [URLSearchParams](info:url), to submit the data in `x-www-form-urlencoded` encoding, rarely used. +- **`method`** -- HTTP ๋ฉ”์„œ๋“œ(์˜ˆ: `POST`) +- **`body`** -- ์š”์ฒญ ๋ณธ๋ฌธ์œผ๋กœ ๋‹ค์Œ ํ•ญ๋ชฉ ์ค‘ ํ•˜๋‚˜์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + - ๋ฌธ์ž์—ด(์˜ˆ: JSON ๋ฌธ์ž์—ด) + - `FormData`๊ฐ์ฒด -- `form/multipart` ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ์ž…๋‹ˆ๋‹ค. + - `Blob`๋‚˜ `BufferSource` -- ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์œ„ํ•ด ์“ฐ์ž…๋‹ˆ๋‹ค. + - [URLSearchParams](info:url) -- ๋ฐ์ดํ„ฐ๋ฅผ `x-www-form-urlencoded` ํ˜•ํƒœ๋กœ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์“ฐ์ด๋Š”๋ฐ, ์š”์ฆ˜์—” ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -The JSON format is used most of the time. +๋Œ€๋ถ€๋ถ„์€ JSON์„ ์š”์ฒญ ๋ณธ๋ฌธ์— ์‹ค์–ด ๋ณด๋‚ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -For example, this code submits `user` object as JSON: +`user` ๊ฐ์ฒด๋ฅผ ๋ณธ๋ฌธ์— ์‹ค์–ด ๋ณด๋‚ด๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```js run async let user = { @@ -222,21 +223,21 @@ let result = await response.json(); alert(result.message); ``` -Please note, if the request `body` is a string, then `Content-Type` header is set to `text/plain;charset=UTF-8` by default. +`POST` ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ฃผ์˜ํ•  ์ ์€ ์š”์ฒญ `๋ณธ๋ฌธ`์ด ๋ฌธ์ž์—ด์ผ ๋•Œ `Content-Type` ํ—ค๋”๊ฐ€ `text/plain;charset=UTF-8`๋กœ ๊ธฐ๋ณธ ์„ค์ •๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. -But, as we're going to send JSON, we use `headers` option to send `application/json` instead, the correct `Content-Type` for JSON-encoded data. +ํ•˜์ง€๋งŒ ์œ„ ์˜ˆ์‹œ์—์„  JSON์„ ์ „์†กํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `headers`์— ์ œ๋Œ€๋กœ ๋œ `Content-Type`์ธ `application/json`์„ ์„ค์ •ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. -## Sending an image +## ์ด๋ฏธ์ง€ ์ „์†กํ•˜๊ธฐ -We can also submit binary data with `fetch` using `Blob` or `BufferSource` objects. +`Blob`์ด๋‚˜ `BufferSource` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `fetch`๋กœ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -In this example, there's a `` where we can draw by moving a mouse over it. A click on the "submit" button sends the image to server: +์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ``์— ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ณ  '์ „์†ก' ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ด๋ฏธ์ง€๋ฅผ ์„œ๋ฒ„์— ์ „์†กํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ```html run autorun height="90" - + ``` -In this example, the server code is not presented, as it's beyound our scope. The server accepts the POST request and replies "User saved". +์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ์„œ๋ฒ„ ์ธก ์ฝ”๋“œ๋Š” ํŠœํ† ๋ฆฌ์–ผ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„œ์„œ ์ถ”๊ฐ€ํ•˜์ง„ ์•Š์•˜๋Š”๋ฐ, ์„œ๋ฒ„๋Š” POST ์š”์ฒญ์„ ๋ฐ›์•„ '์ €์žฅ ์„ฑ๊ณต'์ด๋ผ๋Š” ์‘๋‹ต์„ ๋ณด๋‚ด์ค€๋‹ค๊ณ  ์ •๋„๋งŒ ์•Œ๊ณ  ๊ณ„์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. -## FormData Methods +## FormData ๋ฉ”์„œ๋“œ -We can modify fields in `FormData` with methods: +`FormData`์— ์†ํ•˜๋Š” ํ•„๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- `formData.append(name, value)` - add a form field with the given `name` and `value`, -- `formData.append(name, blob, fileName)` - add a field as if it were ``, the third argument `fileName` sets file name (not form field name), as it it were a name of the file in user's filesystem, -- `formData.delete(name)` - remove the field with the given `name`, -- `formData.get(name)` - get the value of the field with the given `name`, -- `formData.has(name)` - if there exists a field with the given `name`, returns `true`, otherwise `false` +- `formData.append(name, value)` - `name`๊ณผ `value`๋ฅผ ๊ฐ€์ง„ ํผ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ +- `formData.append(name, blob, fileName)` - ``ํ˜•ํƒœ์˜ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€. ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜ `fileName`์€ (ํ•„๋“œ ์ด๋ฆ„์ด ์•„๋‹ˆ๊ณ ) ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ด๋ฆ„์„ ๊ฐ€์ง„ ํŒŒ์ผ์„ ํผ์— ์ถ”๊ฐ€ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์„ค์ •ํ•ด์คŒ +- `formData.delete(name)` - `name`์— ํ•ด๋‹นํ•˜๋Š” ํ•„๋“œ๋ฅผ ์‚ญ์ œ +- `formData.get(name)` - `name`์— ํ•ด๋‹นํ•˜๋Š” ํ•„๋“œ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด +- `formData.has(name)` - `name`์— ํ•ด๋‹นํ•˜๋Š” ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด `true`๋ฅผ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ -A form is technically allowed to have many fields with the same `name`, so multiple calls to `append` add more same-named fields. +ํผ์€ ์ด๋ฆ„(`name`)์ด ๊ฐ™์€ ํ•„๋“œ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— `append` ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด ์ด๋ฆ„์ด ๊ฐ™์€ ํ•„๋“œ๋ฅผ ๊ณ„์† ์ถ”๊ฐ€ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -There's also method `set`, with the same syntax as `append`. The difference is that `.set` removes all fields with the given `name`, and then appends a new field. So it makes sure there's only field with such `name`, the rest is just like `append`: +`append` ๋ฉ”์„œ๋“œ ์ด์™ธ์— ํ•„๋“œ ์ถ”๊ฐ€ ์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋กœ `set`๋„ ์žˆ์Šต๋‹ˆ๋‹ค. `set`์ด `append` ๋ฉ”์„œ๋“œ์™€ ๋‹ค๋ฅธ ์ ์€ `set`์€ `name`๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ํ•„๋“œ๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ๋กœ์šด ํ•„๋“œ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `set` ๋ฉ”์„œ๋“œ๋ฅผ ์“ฐ๋ฉด `name`์„ ๊ฐ€์ง„ ํ•„๋“œ๊ฐ€ ๋‹จ ํ•œ ๊ฐœ๋งŒ ์žˆ๊ฒŒ๋” ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์— ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์€ `append` ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -- `formData.set(name, value)`, -- `formData.set(name, blob, fileName)`. +- `formData.set(name, value)` +- `formData.set(name, blob, fileName)` -Also we can iterate over formData fields using `for..of` loop: +์ฐธ๊ณ ๋กœ ํผ ๋ฐ์ดํ„ฐ ํ•„๋“œ์— ๋ฐ˜๋ณต ์ž‘์—…์„ ํ• ๋• `for..of` ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js run let formData = new FormData(); formData.append('key1', 'value1'); formData.append('key2', 'value2'); -// List key/value pairs +// key/value ์Œ์ด ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ for(let [name, value] of formData) { - alert(`${name} = ${value}`); // key1=value1, then key2=value2 + alert(`${name} = ${value}`); // key1 = value1, then key2 = value2 } ``` -## Sending a form with a file +## ํŒŒ์ผ์ด ์žˆ๋Š” ํผ ์ „์†กํ•˜๊ธฐ -The form is always sent as `Content-Type: form/multipart`, this encoding allows to send files. So, `` fields are sent also, similar to a usual form submission. +ํผ์„ ์ „์†กํ•  ๋•Œ HTTP ๋ฉ”์‹œ์ง€์˜ `Content-Type` ์†์„ฑ์€ ํ•ญ์ƒ `multipart/form-data`์ด๊ณ  ๋ฉ”์‹œ์ง€๋Š” ์ธ์ฝ”๋”ฉ๋˜์–ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด ์žˆ๋Š” ํผ๋„ ๋‹น์—ฐํžˆ ์ด ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ``๋กœ ์ง€์ •ํ•œ ํ•„๋“œ ์—ญ์‹œ ์ผ๋ฐ˜ ํผ์„ ์ „์†กํ•  ๋•Œ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. -Here's an example with such form: +ํŒŒ์ผ์ด ์žˆ๋Š” ํผ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค. ```html run autorun
- + Picture:
@@ -110,21 +110,21 @@ Here's an example with such form: ``` -## Sending a form with Blob data +## Blob ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ํผ ์ „์†กํ•˜๊ธฐ -As we've seen in the chapter , it's easy to send dynamically generated binary data e.g. an image, as `Blob`. We can supply it directly as `fetch` parameter `body`. + ์ฑ•ํ„ฐ์—์„œ ์‚ดํŽด๋ณธ ๋ฐ”์™€ ๊ฐ™์ด ์ด๋ฏธ์ง€ ๊ฐ™์€ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์€ `Blob` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ์‰ฝ๊ฒŒ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ `Blob` ๊ฐ์ฒด๋Š” `fetch` ๋ฉ”์„œ๋“œ์˜ `body` ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฐ”๋กœ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์ฃ . -In practice though, it's often convenient to send an image not separately, but as a part of the form, with additional fields, such as "name" and other metadata. +๊ทธ๋Ÿฐ๋ฐ ์‹ค์ œ ์ฝ”๋”ฉ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์ด๋ฏธ์ง€๋ฅผ ๋ณ„๋„๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ํผ์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์—ฌ๊ธฐ์— ์ด๋ฏธ์ง€ '์ด๋ฆ„' ๋“ฑ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ™์ด ์‹ค์–ด ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒŒ ์ข€ ๋” ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -Also, servers are usually more suited to accept multipart-encoded forms, rather than raw binary data. +์„œ๋ฒ„ ์ž…์žฅ์—์„œ๋„ ์›์‹œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š” ๊ฒƒ๋ณด๋‹ค multipart-encoded ํผ์„ ๋ฐ›๋Š” ๊ฒŒ ์ข€ ๋” ์ ํ•ฉํ•˜์ฃ . -This example submits an image from ``, along with some other fields, as a form, using `FormData`: +์•„๋ž˜๋Š” ``๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“  ์ด๋ฏธ์ง€๋ฅผ `FormData`๋ฅผ ์‚ฌ์šฉํ•ด ํผ ํ˜•ํƒœ๋กœ ๋‹ค๋ฅธ ์ถ”๊ฐ€ ํ•„๋“œ์™€ ํ•จ๊ป˜ ์ „์†กํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ```html run autorun height="90" - + ``` -There are 4 properties to describe CSS transitions: +CSS ํŠธ๋žœ์ง€์…˜์— ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๋„ค ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. - `transition-property` - `transition-duration` - `transition-timing-function` - `transition-delay` -We'll cover them in a moment, for now let's note that the common `transition` property allows to declare them together in the order: `property duration timing-function delay`, and also animate multiple properties at once. +๊ฐ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋Š” ์ž ์‹œ ํ›„์— ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ `transition`์ด๋ผ๋Š” ๊ณตํ†ต ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ด ๋„ค ํ”„๋กœํผํ‹ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค ์ •๋„๋งŒ ์•Œ์•„๋‘ก์‹œ๋‹ค. `transition` ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ์ด ๊ฐ’์€ `property`, `duration`, `timing-function`, `delay` ํ”„๋กœํผํ‹ฐ์— ๊ฐ๊ฐ ํ• ๋‹น๋˜๊ณ , ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋Š” ํ•œ ๋ฒˆ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. -For instance, this button animates both `color` and `font-size`: +์•„๋ž˜์™€ ๊ฐ™์ด `transition` ํ”„๋กœํผํ‹ฐ๋ฅผ ์ •์˜ํ•˜๋ฉด `font-size`๋Š” 3์ดˆ ๋™์•ˆ, `color`๋Š” 2์ดˆ ๋™์•ˆ ๋ณ€ํ™”ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```html run height=80 autorun no-beautify - + ``` -There are many articles about `@keyframes` and a [detailed specification](https://drafts.csswg.org/css-animations/). +`@keyframes`์„ ๋‹ค๋ฃจ๋Š” ๊ธ€์ด๋‚˜ [๋ช…์„ธ์„œ](https://drafts.csswg.org/css-animations/)๋ฅผ ์ฝ์œผ๋ฉด ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. -Probably you won't need `@keyframes` often, unless everything is in the constant move on your sites. +์ฐธ๊ณ ๋กœ ์‚ฌ์ดํŠธ์— ์žˆ๋Š” ํŠน์ • ์š”์†Œ๋ฅผ ๊ณ„์† ์ •์ ์ธ ํ˜•ํƒœ๋กœ ์›€์ง์ด์ง€ ์•Š๋Š” ํ•œ์€ `@keyframes`๋ฅผ ์“ธ ์ผ์€ ๋งŽ์ง€ ์•Š์„ ๊ฒ๋‹ˆ๋‹ค. -## Summary +## ์š”์•ฝ -CSS animations allow to smoothly (or not) animate changes of one or multiple CSS properties. +CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜ ๋˜๋Š” ์—ฌ๋Ÿฌ CSS ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ(๋ถ€๋“œ๋Ÿฝ์ง€ ์•Š๊ฒŒ๋„ ๊ฐ€๋Šฅ) ๋ณ€ํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -They are good for most animation tasks. We're also able to use JavaScript for animations, the next chapter is devoted to that. +CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์ „ํ™˜์ด ํ•„์š”ํ•œ ๋Œ€๋‹ค์ˆ˜์˜ ๊ฒฝ์šฐ์— ํฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ „ํ™˜ ํšจ๊ณผ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ธด ํ•œ๋ฐ ์ด์— ๋Œ€ํ•ด์„  ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -Limitations of CSS animations compared to JavaScript animations: +์ฐธ๊ณ ๋กœ CSS ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜๊ณผ ๋น„๊ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```compare plus="CSS animations" minus="JavaScript animations" -+ Simple things done simply. -+ Fast and lightweight for CPU. -- JavaScript animations are flexible. They can implement any animation logic, like an "explosion" of an element. -- Not just property changes. We can create new elements in JavaScript for purposes of animation. ++ ๊ฐ„๋‹จํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ฐ„๋‹จํžˆ ์ˆ˜ํ–‰ํ•จ ++ ๋น ๋ฅด๊ณ  CPU๋ฅผ ๋งŽ์ด ์†Œ๋ชจํ•˜์ง€ ์•Š์Œ +- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜๋ณด๋‹ค ๋œ ์œ ์—ฐํ•จ. ์š”์†Œ์˜ 'ํญ๋ฐœ' ๊ฐ™์€ ํŠน์ˆ˜ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์Œ +- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€ํ™”๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์• ๋‹ˆ๋ฉ”์ด์…˜์— ํ•„์š”ํ•œ ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ, CSS๋งŒ์œผ๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•จ ``` -The majority of animations can be implemented using CSS as described in this chapter. And `transitionend` event allows to run JavaScript after the animation, so it integrates fine with the code. +์‚ฌ์‹ค ๋Œ€๋ถ€๋ถ„์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์ด๋ฒˆ ์ฑ•ํ„ฐ์— ์„ค๋ช…ํ•œ CSS ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•˜์—ฌ `transitionend` ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋๋‚œ ํ›„์— ์‹คํ–‰์‹œํ‚ฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์ฃ . -But in the next chapter we'll do some JavaScript animations to cover more complex cases. +ํ•˜์ง€๋งŒ ์ข€ ๋” ๋ณต์žกํ•œ ์ผ€์ด์Šค๋ฅผ ๋‹ค๋ฃจ๋ ค๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์•Œ์•„์•ผ ํ•˜๋ฏ€๋กœ ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„  ์ด๋ฅผ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/7-animation/2-css-animations/bezier-linear.svg b/7-animation/2-css-animations/bezier-linear.svg index 34949d61e0..0c2e970f29 100644 --- a/7-animation/2-css-animations/bezier-linear.svg +++ b/7-animation/2-css-animations/bezier-linear.svg @@ -1 +1 @@ -12 \ No newline at end of file +12 \ No newline at end of file diff --git a/7-animation/2-css-animations/bezier-train-over.svg b/7-animation/2-css-animations/bezier-train-over.svg index ff5501c43a..d12d092259 100644 --- a/7-animation/2-css-animations/bezier-train-over.svg +++ b/7-animation/2-css-animations/bezier-train-over.svg @@ -1 +1 @@ -(1,1)(0,0)(0,1)(1,0)1243 \ No newline at end of file +(1,1)(0,0)(0,1)(1,0)1243 \ No newline at end of file diff --git a/7-animation/2-css-animations/digits-negative-delay.view/index.html b/7-animation/2-css-animations/digits-negative-delay.view/index.html index dbeefaae2c..4671d61782 100644 --- a/7-animation/2-css-animations/digits-negative-delay.view/index.html +++ b/7-animation/2-css-animations/digits-negative-delay.view/index.html @@ -8,7 +8,7 @@ - Click below to animate: + ์•„๋ž˜ ์ˆซ์ž๋ฅผ ํด๋ฆญํ•˜์„ธ์š”.
0123456789
diff --git a/7-animation/2-css-animations/digits.view/index.html b/7-animation/2-css-animations/digits.view/index.html index a156d8189e..dfb7155624 100644 --- a/7-animation/2-css-animations/digits.view/index.html +++ b/7-animation/2-css-animations/digits.view/index.html @@ -8,7 +8,7 @@ - Click below to animate: + ์•„๋ž˜ ์ˆซ์ž๋ฅผ ํด๋ฆญํ•˜์„ธ์š”.
0123456789
diff --git a/7-animation/2-css-animations/ease-in-out.svg b/7-animation/2-css-animations/ease-in-out.svg index 29ef69a113..d5c8809d81 100644 --- a/7-animation/2-css-animations/ease-in-out.svg +++ b/7-animation/2-css-animations/ease-in-out.svg @@ -1 +1 @@ -1234 \ No newline at end of file +1234 \ No newline at end of file diff --git a/7-animation/2-css-animations/ease-in.svg b/7-animation/2-css-animations/ease-in.svg index 0e8b797ab5..38c98ecbc1 100644 --- a/7-animation/2-css-animations/ease-in.svg +++ b/7-animation/2-css-animations/ease-in.svg @@ -1 +1 @@ -1234 \ No newline at end of file +1234 \ No newline at end of file diff --git a/7-animation/2-css-animations/ease-out.svg b/7-animation/2-css-animations/ease-out.svg index c283728706..9d22eeafd5 100644 --- a/7-animation/2-css-animations/ease-out.svg +++ b/7-animation/2-css-animations/ease-out.svg @@ -1 +1 @@ -1234 \ No newline at end of file +1234 \ No newline at end of file diff --git a/7-animation/2-css-animations/ease.svg b/7-animation/2-css-animations/ease.svg index a3a1feecdb..8f9d41fe83 100644 --- a/7-animation/2-css-animations/ease.svg +++ b/7-animation/2-css-animations/ease.svg @@ -1 +1 @@ -1234 \ No newline at end of file +1234 \ No newline at end of file diff --git a/7-animation/2-css-animations/step-end.view/index.html b/7-animation/2-css-animations/step-end.view/index.html index 2c8df72758..5398e1d44f 100644 --- a/7-animation/2-css-animations/step-end.view/index.html +++ b/7-animation/2-css-animations/step-end.view/index.html @@ -8,7 +8,7 @@ - Click below to animate: + ์•„๋ž˜ ์ˆซ์ž๋ฅผ ํด๋ฆญํ•˜์„ธ์š”.
0123456789
diff --git a/7-animation/2-css-animations/step.view/index.html b/7-animation/2-css-animations/step.view/index.html index 2c8df72758..5398e1d44f 100644 --- a/7-animation/2-css-animations/step.view/index.html +++ b/7-animation/2-css-animations/step.view/index.html @@ -8,7 +8,7 @@ - Click below to animate: + ์•„๋ž˜ ์ˆซ์ž๋ฅผ ํด๋ฆญํ•˜์„ธ์š”.
0123456789
diff --git a/7-animation/2-css-animations/train-curve.svg b/7-animation/2-css-animations/train-curve.svg index f152359906..298dacd4c3 100644 --- a/7-animation/2-css-animations/train-curve.svg +++ b/7-animation/2-css-animations/train-curve.svg @@ -1 +1 @@ -1243 \ No newline at end of file +1243 \ No newline at end of file diff --git a/7-animation/3-js-animation/back.svg b/7-animation/3-js-animation/back.svg index 836a72cc56..fcef09ad75 100644 --- a/7-animation/3-js-animation/back.svg +++ b/7-animation/3-js-animation/back.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/bezier-linear.svg b/7-animation/3-js-animation/bezier-linear.svg index 34949d61e0..0c2e970f29 100644 --- a/7-animation/3-js-animation/bezier-linear.svg +++ b/7-animation/3-js-animation/bezier-linear.svg @@ -1 +1 @@ -12 \ No newline at end of file +12 \ No newline at end of file diff --git a/7-animation/3-js-animation/bounce-inout.svg b/7-animation/3-js-animation/bounce-inout.svg index 7274d715d7..363633abd4 100644 --- a/7-animation/3-js-animation/bounce-inout.svg +++ b/7-animation/3-js-animation/bounce-inout.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/circ-ease.svg b/7-animation/3-js-animation/circ-ease.svg index cf2ed8d9e3..a7db9abcf7 100644 --- a/7-animation/3-js-animation/circ-ease.svg +++ b/7-animation/3-js-animation/circ-ease.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/circ.svg b/7-animation/3-js-animation/circ.svg index 1c2beade46..3595dd6248 100644 --- a/7-animation/3-js-animation/circ.svg +++ b/7-animation/3-js-animation/circ.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/elastic.svg b/7-animation/3-js-animation/elastic.svg index 851da406bb..17f04ccde7 100644 --- a/7-animation/3-js-animation/elastic.svg +++ b/7-animation/3-js-animation/elastic.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/linear.svg b/7-animation/3-js-animation/linear.svg index 7a5bd71a38..daa753f0c2 100644 --- a/7-animation/3-js-animation/linear.svg +++ b/7-animation/3-js-animation/linear.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/quad.svg b/7-animation/3-js-animation/quad.svg index e9bc6ac99b..25a4d00053 100644 --- a/7-animation/3-js-animation/quad.svg +++ b/7-animation/3-js-animation/quad.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/3-js-animation/quint.svg b/7-animation/3-js-animation/quint.svg index ad8ece285f..c879ef9318 100644 --- a/7-animation/3-js-animation/quint.svg +++ b/7-animation/3-js-animation/quint.svg @@ -1 +1 @@ -011 \ No newline at end of file +011 \ No newline at end of file diff --git a/7-animation/index.md b/7-animation/index.md index 37bc847adb..220b29599d 100644 --- a/7-animation/index.md +++ b/7-animation/index.md @@ -1,3 +1,3 @@ -# Animation +# ์• ๋‹ˆ๋ฉ”์ด์…˜ -CSS and JavaScript animations. +CSS์™€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. diff --git a/8-web-components/1-webcomponents-intro/article.md b/8-web-components/1-webcomponents-intro/article.md index 3279cb1333..37a5d71565 100644 --- a/8-web-components/1-webcomponents-intro/article.md +++ b/8-web-components/1-webcomponents-intro/article.md @@ -1,76 +1,76 @@ -# From the orbital height +# ๊ถค๋„์˜ ๋†’์ด์—์„œ -This section describes a set of modern standards for "web components". +์ด ์„น์…˜์—์„œ๋Š” '์›น ์ปดํฌ๋„ŒํŠธ(Web components)'์— ๋Œ€ํ•œ ์ตœ์‹  ํ‘œ์ค€ ์ง‘ํ•ฉ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. -As of now, these standards are under development. Some features are well-supported and integrated into the modern HTML/DOM standard, while others are yet in draft stage. You can try examples in any browser, Google Chrome is probably the most up to date with these features. Guess, that's because Google fellows are behind many of the related specifications. +ํ˜„์žฌ๋กœ์„œ ์ด ํ‘œ์ค€ ๊ทœ๊ฒฉ์€ ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€ ๊ธฐ๋Šฅ์€ ์ž˜ ์ง€์›๋˜๊ณ  ์ตœ์‹  HTML/DOM ํ‘œ์ค€๊ทœ๊ฒฉ์— ํ†ตํ•ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ผ๋ถ€ ๊ธฐ๋Šฅ์€ ์•„์ง ์ดˆ์•ˆ ๋‹จ๊ณ„์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์˜ˆ์ œ๋ฅผ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Google Chrome์ด ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ์ตœ์‹  ๋ฒ„์ „์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Google ๋™๋ฃŒ๋“ค์ด ๋งŽ์€ ๊ด€๋ จ ์‚ฌํ•ญ์„ ๋”ฐ๋ฅธ๋‹ค๋Š” ๊ฒƒ์ด ๊ทธ ์ด์œ ์ž…๋‹ˆ๋‹ค. -## What's common between... +## ๊ตญ์ œ ์šฐ์ฃผ์ •๊ฑฐ์žฅ๊ณผ ์›น ์ปดํฌ๋„ŒํŠธ(Web components) ์‚ฌ์ด์˜ ๊ณตํ†ต์  -The whole component idea is nothing new. It's used in many frameworks and elsewhere. +์ „์ฒด ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋Š” ์ƒˆ๋กœ์šด ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฏธ ๋งŽ์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ทธ ๋ฐ–์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -Before we move to implementation details, take a look at this great achievement of humanity: +๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์œผ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ์— ์•ž์„œ ์ธ๋ฅ˜์˜ ์œ„๋Œ€ํ•œ ์—…์ ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ![](satellite.jpg) -That's the International Space Station (ISS). +๊ตญ์ œ ์šฐ์ฃผ์ •๊ฑฐ์žฅ์˜ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค(ISS). -And this is how it's made inside (approximately): +๊ตญ์ œ ์šฐ์ฃผ์ •๊ฑฐ์žฅ์˜ ๋Œ€๋žต์ ์ธ ๋‚ด๋ถ€ ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ![](satellite-expanded.jpg) -The International Space Station: -- Consists of many components. -- Each component, in its turn, has many smaller details inside. -- The components are very complex, much more complicated than most websites. -- Components are developed internationally, by teams from different countries, speaking different languages. +๊ตญ์ œ ์šฐ์ฃผ์ •๊ฑฐ์žฅ์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค. +- ๋งŽ์€ ๋ถ€ํ’ˆ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. +- ๊ฐ ๋ถ€ํ’ˆ์€ ๊ทธ ์•ˆ์— ๋” ์ž‘๊ณ  ๋งŽ์€ ๋ถ€ํ’ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +- ๋ถ€ํ’ˆ๋“ค์€ ๋งค์šฐ ๋ณต์žกํ•œ๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ์›น์‚ฌ์ดํŠธ ๋ณด๋‹ค ํ›จ์”ฌ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. +- ๋ถ€ํ’ˆ์€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ตญ๊ฐ€๋“ค์˜ ํŒ€์ด ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค. -...And this thing flies, keeps humans alive in space! +๊ทธ๋ฆฌ๊ณ  ์šฐ์ฃผ์ •๊ฑฐ์žฅ์€ ์ธ๊ฐ„์ด ์šฐ์ฃผ์—์„œ ๋‚ ๊ณ , ์‚ด์•„์žˆ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -How such complex devices are created? +์–ด๋–ป๊ฒŒ ์ด๋ ‡๊ฒŒ ๋ณต์žกํ•œ ์žฅ์น˜๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์„๊นŒ์š”? -Which principles we could borrow to make our development same-level reliable and scalable? Or, at least, close to it. +๊ฐœ๋ฐœ์„ ์•ˆ์ •์ ์ด๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ˆ˜์ค€์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋˜๋Š” ๊ทธ์— ๊ฐ€๊น๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์›์น™์„ ๋นŒ๋ ค์˜ฌ ์ˆ˜ ์žˆ์„๊นŒ์š”? -## Component architecture +## ์ปดํฌ๋„ŒํŠธ ์•„ํ‚คํ…์ฒ˜ -The well known rule for developing complex software is: don't make complex software. +๋ณต์žกํ•œ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์— ๋Œ€ํ•œ ์ž˜ ์•Œ๋ ค์ง„ ๊ทœ์น™์€ ๋ฐ”๋กœ ๋ณต์žกํ•œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -If something becomes complex -- split it into simpler parts and connect in the most obvious way. +์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ๋ณต์žกํ•ด์ง„๋‹ค๋ฉด ๋” ๊ฐ„๋‹จํ•œ ๋ถ€๋ถ„๋“ค๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ€์žฅ ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์—ฐ๊ฒฐํ•˜์„ธ์š”. -**A good architect is the one who can make the complex simple.** +**์ข‹์€ ์•„ํ‚คํ…ํŠธ๋Š” ๋ณต์žกํ•œ ๊ฒƒ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ž…๋‹ˆ๋‹ค.** -We can split user interface into visual components: each of them has own place on the page, can "do" a well-described task, and is separate from the others. +์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‹œ๊ฐ์  ์ปดํฌ๋„ŒํŠธ๋“ค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€๋Š” ๋ณ„๊ฐœ๋กœ ํŽ˜์ด์ง€์—์„œ ๊ณ ์œ ํ•œ ์œ„์น˜๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์ž์„ธํžˆ ์„ค๋ช…๋œ ์ž‘์—…์„ '์ˆ˜ํ–‰'ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Let's take a look at a website, for example Twitter. +์›น ์‚ฌ์ดํŠธ์˜ ์˜ˆ๋กœ ํŠธ์œ„ํ„ฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -It naturally splits into components: +์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ปดํฌ๋„ŒํŠธ๋“ค๋กœ ๋‚˜๋‰˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ![](web-components-twitter.svg) -1. Top navigation. -2. User info. -3. Follow suggestions. -4. Submit form. -5. (and also 6, 7) -- messages. +1. ์ƒ๋‹จ ๋‚ด๋น„๊ฒŒ์ด์…˜ +2. ์‚ฌ์šฉ์ž ์ •๋ณด +3. ์ถ”์ฒœ ํŒ”๋กœ์šฐ +4. ๊ธ€์“ฐ๊ธฐ ์–‘์‹ +5. ๋ฉ”์‹œ์ง€๋“ค(6, 7 ํฌํ•จ) -Components may have subcomponents, e.g. messages may be parts of a higher-level "message list" component. A clickable user picture itself may be a component, and so on. +์ปดํฌ๋„ŒํŠธ์—๋Š” ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฉ”์‹œ์ง€๋Š” ์ƒ์œ„ '๋ฉ”์‹œ์ง€ ๋ชฉ๋ก' ์ปดํฌ๋„ŒํŠธ์˜ ์ผ๋ถ€์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ์‚ฌ์ง„ ์ž์ฒด๋Š” ์ปดํฌ๋„ŒํŠธ ๋“ฑ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -How do we decide, what is a component? That comes from intuition, experience and common sense. Usually it's a separate visual entity that we can describe in terms of what it does and how it interacts with the page. In the case above, the page has blocks, each of them plays its own role, it's logical to make these components. +๋ฌด์—‡์ด ์ปดํฌ๋„ŒํŠธ์ธ์ง€ ์–ด๋–ป๊ฒŒ ๊ฒฐ์ •ํ•˜๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ์ง๊ด€, ๊ฒฝํ—˜ ๋ฐ ์ƒ์‹์—์„œ ๋น„๋กฏ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋Š” ๊ธฐ๋Šฅ๊ณผ ํŽ˜์ด์ง€์˜ ์ƒํ˜ธ ์ž‘์šฉ ๋ฐฉ์‹์œผ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ„๋„์˜ ์‹œ๊ฐ์  ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค. ์œ„์˜ ๊ฒฝ์šฐ ํŽ˜์ด์ง€์—๋Š” ๋ธ”๋ก์ด ์žˆ์œผ๋ฉฐ ๊ฐ ๋ธ”๋ก์€ ๊ณ ์œ ํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ์ด๋Ÿฌํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋…ผ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. -A component has: -- Its own JavaScript class. -- DOM structure, managed solely by its class, outside code doesn't access it ("encapsulation" principle). -- CSS styles, applied to the component. -- API: events, class methods etc, to interact with other components. +์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ–์ถฐ์•ผ ํ•  ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +- ๊ณ ์œ ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค +- ์™ธ๋ถ€์ฝ”๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ํ•ด๋‹น ํด๋ž˜์Šค์—์„œ๋งŒ ๊ด€๋ฆฌ๋˜๋Š” DOM ๊ตฌ์กฐ('์บก์Аํ™”' ์›์น™) +- ๊ตฌ์„ฑ์š”์†Œ์— ์ ์šฉ๋˜๋Š” CSS ์Šคํƒ€์ผ +- ๋‹ค๋ฅธ ๊ตฌ์„ฑ์š”์†Œ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ด๋ฒคํŠธ, ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ ๋“ฑ์„ ์ผ์ปซ๋Š” API -Once again, the whole "component" thing is nothing special. +๋‹ค์‹œ ํ•œ๋ฒˆ ๋งํ•˜์ง€๋งŒ, ์ „์ฒด '์ปดํฌ๋„ŒํŠธ'๋Š” ํŠน๋ณ„ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. -There exist many frameworks and development methodologies to build them, each with its own bells and whistles. Usually, special CSS classes and conventions are used to provide "component feel" -- CSS scoping and DOM encapsulation. +์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ๋งŽ์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ๊ฐ๊ฐ์€ ํŠน์ˆ˜ํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ CSS ๋ฒ”์œ„์ง€์ •๊ณผ DOM ์บก์Аํ™”์™€ ๊ฐ™์€ '์ปดํฌ๋„ŒํŠธ ๋А๋‚Œ'์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ˆ˜ CSS ํด๋ž˜์Šค ๋ฐ ๊ทœ์น™์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -"Web components" provide built-in browser capabilities for that, so we don't have to emulate them any more. +'์›น ์ปดํฌ๋„ŒํŠธ(Web components)'๋Š” ํŠน์ˆ˜ CSS ํด๋ž˜์Šค ๋ฐ ๊ทœ์น™์„ ์œ„ํ•ด ๋‚ด์žฅ๋œ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ๋” ๋ชจ๋ฐฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -- [Custom elements](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) -- to define custom HTML elements. -- [Shadow DOM](https://dom.spec.whatwg.org/#shadow-trees) -- to create an internal DOM for the component, hidden from the others. -- [CSS Scoping](https://drafts.csswg.org/css-scoping/) -- to declare styles that only apply inside the Shadow DOM of the component. -- [Event retargeting](https://dom.spec.whatwg.org/#retarget) and other minor stuff to make custom components better fit the development. +- [Custom elements](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) -- ์‚ฌ์šฉ์ž ์ •์˜ HTML ์š”์†Œ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +- [Shadow DOM](https://dom.spec.whatwg.org/#shadow-trees) -- ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ์ˆจ๊ฒจ์ ธ ์žˆ๋Š” ๋‚ด๋ถ€ DOM์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +- [CSS Scoping](https://drafts.csswg.org/css-scoping/) -- ์ปดํฌ๋„ŒํŠธ์˜ Shadow DOM ๋‚ด๋ถ€์—๋งŒ ์ ์šฉ๋˜๋Š” ์Šคํƒ€์ผ์„ ์„ ์–ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +- [Event retargeting](https://dom.spec.whatwg.org/#retarget)๊ณผ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋”์šฑ ์ ํ•ฉํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋‹ค๋ฅธ ์‚ฌ์†Œํ•œ ๊ฒƒ๋“ค๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -In the next chapter we'll go into details of "Custom Elements" -- the fundamental and well-supported feature of web components, good on its own. +๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ๋Š” ์›น ์ปดํฌ๋„ŒํŠธ(Web components)์˜ ๊ธฐ๋ณธ์ ์ด๊ณ  ์ž˜ ์ง€์›๋˜๋Š” ๊ธฐ๋Šฅ์ธ '์ปค์Šคํ…€ ์—˜๋ฆฌ๋จผํŠธ'์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/8-web-components/1-webcomponents-intro/web-components-twitter.svg b/8-web-components/1-webcomponents-intro/web-components-twitter.svg index 534e629b9d..9d3b0b00b3 100644 --- a/8-web-components/1-webcomponents-intro/web-components-twitter.svg +++ b/8-web-components/1-webcomponents-intro/web-components-twitter.svg @@ -1 +1 @@ -1243567 \ No newline at end of file +1243567 \ No newline at end of file diff --git a/8-web-components/2-custom-elements/1-live-timer/solution.md b/8-web-components/2-custom-elements/1-live-timer/solution.md index a9eacc8803..6a426d0e00 100644 --- a/8-web-components/2-custom-elements/1-live-timer/solution.md +++ b/8-web-components/2-custom-elements/1-live-timer/solution.md @@ -1,4 +1,4 @@ -Please note: -1. We clear `setInterval` timer when the element is removed from the document. That's important, otherwise it continues ticking even if not needed any more. And the browser can't clear the memory from this element and referenced by it. -2. We can access current date as `elem.date` property. All class methods and properties are naturally element methods and properties. +๋‘ ๊ฐ€์ง€ ์ฐธ๊ณ  ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +1. ์š”์†Œ๊ฐ€ ๋ฌธ์„œ์—์„œ ์ œ๊ฑฐ๋˜๋ฉด `setInterval` ํƒ€์ด๋จธ๋„ ์ง€์›๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ๋” ํ•„์š”ํ•˜์ง€ ์•Š๋”๋ผ๋„ ๊ณ„์† tick ํ•˜๋ฏ€๋กœ ํƒ€์ด๋จธ๋ฅผ ์ง€์šฐ๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  `setInterval` ํƒ€์ด๋จธ๋ฅผ ์ง€์šฐ์ง€ ์•Š์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์š”์†Œ์˜ ๋ฉ”๋ชจ๋ฆฌ์™€ ์š”์†Œ์— ์˜ํ•ด ์ฐธ์กฐ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง€์šฐ๊ณ  ์ฐธ์กฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +2. ํ˜„์žฌ ๋‚ ์งœ๋Š” `elem.date` ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ ๋ชจ๋“  ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋Š” ์š”์†Œ ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. diff --git a/8-web-components/2-custom-elements/1-live-timer/task.md b/8-web-components/2-custom-elements/1-live-timer/task.md index 1feb7490ab..3d2c25e5e3 100644 --- a/8-web-components/2-custom-elements/1-live-timer/task.md +++ b/8-web-components/2-custom-elements/1-live-timer/task.md @@ -1,14 +1,14 @@ -# Live timer element +# ๋ผ์ด๋ธŒ ํƒ€์ด๋จธ ์š”์†Œ -We already have `` element to show a nicely formatted time. +์ž˜ ๊ตฌ์„ฑ๋œ ์‹œ๊ฐ์„ ํ‘œ์‹œํ•˜๋Š” `` ์š”์†Œ๊ฐ€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค. -Create `` element to show the current time: -1. It should use `` internally, not duplicate its functionality. -2. Ticks (updates) every second. -3. For every tick, a custom event named `tick` should be generated, with the current date in `event.detail` (see chapter ). +ํ˜„์žฌ ์‹œ๊ฐ„์„ ํ‘œ๊ธฐํ•˜๊ธฐ ์œ„ํ•ด ``์š”์†Œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. +1. ๋‚ด๋ถ€์ ์œผ๋กœ ``๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ``์˜ ๊ธฐ๋Šฅ์„ ๋˜‘๊ฐ™์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. +2. ๋งค์ดˆ tick์„ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค. +3. ๋ชจ๋“  tick์— ๋Œ€ํ•ด `event.detail`์— ํ˜„์žฌ ๋‚ ์งœ์™€ ํ•จ๊ป˜ `tick`์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ฑ•ํ„ฐ ์ฐธ์กฐ). -Usage: +์‚ฌ์šฉ๋ฒ•: ```html @@ -18,6 +18,6 @@ Usage: ``` -Demo: +๋ฐ๋ชจ: [iframe src="solution" height=40] diff --git a/8-web-components/2-custom-elements/article.md b/8-web-components/2-custom-elements/article.md index 4437319141..702ff90739 100644 --- a/8-web-components/2-custom-elements/article.md +++ b/8-web-components/2-custom-elements/article.md @@ -397,4 +397,4 @@ Custom elements can be of two types: /*