-
[Javascript] ํ๋กํ ํ์ ๊ณผ ํ๋กํ ํ์ ์์Language/JavaScript 2023. 1. 3. 15:22
๐ ์ถ์ฒ : https://ko.javascript.info/
ํ๋กํ ํ์ ์์
[[Prototype]]
์ ์
์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ์ฒด๋ [[Prototype]]์ด๋ผ๋ ์จ๊น ํ๋กํผํฐ๋ฅผ ๊ฐ๋๋ค. ์ด ๊ฐ์ null์ด๊ฑฐ๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๊ฐ ๋๋๋ฐ, ๋ค๋ฅธ ๊ฐ์ฑ๋ฅผ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ ๊ทธ ์ฐธ์กฐ ๋์์ ํ๋กํ ํ์ ์ด๋ผ ๋ถ๋ฅธ๋ค.
๋์๋ฐฉ์
const animal = { eats: true } const rabbit = { jumps:true } console.log(rabbit.eats) // undefined Object.setPrototypeOf(rabbit, animal) //rabbit.__proto__ = animal; console.log(rabbit.eats) // true
ํ๋กํผํฐ๊ฐ ์ ์๋ ๊ฐ์ฒด ๋ ๊ฐ์ ์์๋ฅผ ๋ณด์.
๊ฐ์ฒด rabbit๊ฐ ๊ฐ๋ ํ๋กํผํฐ์ ์ ๊ทผํ ๋, ํด๋น ํ๋กํผํฐ๊ฐ ์์ผ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ ์๋์ผ๋ก ํ๋กํ ํ์ ์์ ํ๋กํผํฐ๋ฅผ ์ฐพ๋๋ค. ๊ฐ์ฒด rabbit์ jumps๋ผ๋ ํ๋กํผํฐ๋ง์ ๊ฐ๊ณ ์๋ค. ๊ทธ๋ฐ๋ฐ rabbit์ ๋์์ animal์ด๊ธฐ ๋๋ฌธ์ eats๋ผ๋ ํ๋กํผํฐ์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ํ๊ณ ์ถ๋ค๋ฉด, ์ด๋ป๊ฒ ํ ๊น? ์ด ๋, ํ๋กํ ํ์ ์์์ด๋ผ๋ ๋์ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์๋ค.
[[Prototype]] ํ๋กํผํฐ๋ ๋ด๋ถ ํ๋กํผํฐ์ด๋ฉด์ ์จ๊น ํ๋กํผํฐ์ด์ง๋ง ๋ค์ํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด ๊ฐ๋ฐ์๊ฐ ๊ฐ์ ์ค์ ํ ์ ์๋ค. ์ ์์์ฒ๋ผ __proto__์ ์ฌ์ฉํ๋ฉด ๊ฐ์ ์ค์ ํ ์ ์๋ค. ์ด์ ๋ฐ๋ผ rabbit์ animal์ด๋ผ๋ ํ๋กํ ํ์ ์ ์ง์ ํด์ฃผ๋ฉด, ์ฌ์ ํ rabbit์๋ eats๋ผ๋ ํ๋กํผํฐ๊ฐ ์กด์ฌํ์ง ์์ง๋ง, ํด๋น ํ๋กํผํฐ๊ฐ ์์ผ๋ฉด ์๋์ผ๋ก ํ๋กํ ํ์ ์์ ํ๋กํผํฐ๋ฅผ ์ฐพ์ ์ ๊ทผ์ด ๊ฐ๋ฅํด์ง๋ค.
์ฆ ๊ฐ์ฒด rabbit์์ ํ๋กํผํฐ์ ์ ๊ทผํ๊ณ ์ถ์ง๋ง ํด๋น ํ๋กํผํฐ๊ฐ ์๋ค๋ฉด ์๋์ผ๋ก animal์ด๋ผ๋ ํ๋กํ ํ์ ๊ฐ์ฒด์์ ํ๋กํผํฐ์ ์ ๊ทผํ๊ฒ ๋๋ค. ์ด๋ฌํ ๊ด๊ณ๋ฅผ “rabbit์ ํ๋กํ ํ์ ์ animal์ด๋ค” ํน์ “rabbit์ animal์ ์์๋ฐ๋๋ค”๊ณ ๋งํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ์์๋ฐ์ ํ๋กํผํฐ๋ฅผ ‘์์ ํ๋กํผํฐ’๋ผ๊ณ ํ๋ค.
๐ __proto__๋ [[Prototype]] ์ฉ getter, setter์ด๋ค. ํ์ ํธํ์ฑ ๋๋ฌธ์ ์ฌ์ ํ __proto__๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง ๊ทผ๋์๋ Object.getPrototypeOf๋ Object.setPrototypeOf์ ์จ์ ํ๋กํ ํ์ ์ getํ๊ฑฐ๋ set ํ๋ค๊ณ ํ๋ค.
ํ๋กํ ํ์ ์์์ ํ๋กํผํฐ ๋ฟ๋ง์๋๋ผ ๋ฉ์๋๋ ๊ฐ๋ฅํ๋ค.
const animal = { eats: true, walk() { console.log("๋๋ฌผ์ ๊ฑธ์ ์ ์์ต๋๋ค.") } } const rabbit = { jumps:true, __proto__: animal } rabbit.walk() // ๋๋ฌผ์ ๊ฑธ์ ์ ์์ต๋๋ค.
ํ๋กํ ํ์ ์ฒด์ธ์ ๋์ฑ ๊ธธ์ด์ง ์ ์๋ค.
const animal = { eats: true, walk() { console.log("๋๋ฌผ์ ๊ฑธ์ ์ ์์ต๋๋ค.") } } const rabbit = { jumps:true, __proto__: animal } const longEar = { earLength: 10, __proto__: rabbit } longEar.walk() // ๋๋ฌผ์ ๊ฑธ์ ์ ์์ต๋๋ค. console.log(longEar.jumps) // true
๋จ, ํ๋กํ ํ์ ์ฒด์ด๋์ ๋ ๊ฐ์ง ์ ์ฝ์ฌํญ์ด ์๋ค.
- ์ํ ์ฐธ์กฐ๋ ํ์ฉ๋์ง ์๋๋ค. __proto__๋ฅผ ์ด์ฉํด ๋ซํ ํํ๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- __proto__์ ๊ฐ์ ๊ฐ์ฒด๋ null๋ง ๊ฐ๋ฅํ๋ค. ๋ค๋ฅธ ์๋ฃํ์ ๋ฌด์๋๋ค.
- ๊ฐ์ฒด๋ ๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์์๋ฐ์ง ๋ชปํ๋ค.
ํ๋กํ ํ์ ์ ์ฝ๊ธฐ ์ ์ฉ์ด๋ค
ํ๋กํ ํ์ ์ ํ๋กํผํฐ๋ฅผ ์ฝ์ ๋๋ง ์ฌ์ฉํฉ๋๋ค.
ํ๋กํผํฐ๋ฅผ ์ถ๊ฐ, ์์ ํ๊ฑฐ๋ ์ง์ฐ๋ ์ฐ์ฐ์ ๊ฐ์ฒด์ ์ง์ ํด์ผ ํฉ๋๋ค.
๊ฐ์ฒด rabbit์ ๋งค์๋ walk๋ฅผ ์ง์ ํ ๋นํด ๋ณด๊ฒ ์ต๋๋ค.
const animal = { eats:true, walk() { console.log("๋๋ฌผ์ ๊ฑธ์ ์ ์์ต๋๋ค.") } } const rabbit = { __proto__: animal } rabbit.walk = () => {console.log("ํ ๋ผ๊ฐ ๊นก์ถฉ๊นก์ถฉ ๋ต๋๋ค.")} rabbit.walk() // ํ ๋ผ๊ฐ ๊นก์ถฉ๊นก์ถฉ ๋๋๋ค.
rabbit.walk()๋ฅผ ํธ์ถํ๋ฉด ํ๋กํ ํ์ ์์๋ ๋ฉ์๋๊ฐ ์คํ๋์ง ์๊ณ , ๊ฐ์ฒด rabbit์ ์ง์ ์ถ๊ฐํ ๋ฉ์๋๊ฐ ์คํ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ ๊ทผ์ ํ๋กํผํฐ๋ setter ํจ์๋ฅผ ์ฌ์ฉํด ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๋ฏ๋ก ์ ๊ทผ์ ํ๋กํผํฐ์ ๊ฐ์ ํ ๋น (**)ํ๋ฉด ๊ฐ์ฒด(admin)์ ํ๋กํผํฐ(fullName)๊ฐ ์ถ๊ฐ๋๋๊ฒ ์๋๋ผ setter ํจ์๊ฐ ํธ์ถ๋๋ฉด์ ์ ์์์๋ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ๋์ํ๋ค.
์๋ ์์์์ admin.fullName์ด ์๋ํ ๋๋ก ์ ์๋ํ๋์ง ํ์ธํด๋ณด์
const user = { name: "John", surname:"Smith", set fullName(value) { [this.name, this.surname] = value.split(" ") }, get fullName() { return `${this.name} ${this.surname}` } } const admin = { __proto__: user, isAdmin: true } console.log(admin.fullName) // "John Smith" (*) admin.fullName = "Alice Cooper" // setter ํจ์ ์คํ console.log(admin.fullName) // "Alice Cooper" (**) console.log(user.fullName) // "John Smith"
this๊ฐ ๋ํ๋ด๋ ๊ฒ
this๋ ํ๋กํ ํ์ ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค. ๋ฉ์๋๋ฅผ ๊ฐ์ฒด์์ ํธ์ถํ๋ ํ๋กํ ํ์ ์์ ํธ์ถํ๋ ์๊ด์์ด this๋ ์ธ์ ๋ . ์์ ์๋ ๊ฐ์ฒด์ด๋ค.
this๋ ๊ฐ์ฒด ์์ ์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํ ์๊ธฐ์ฐธ์กฐ ๋ณ์๋ค.
this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ, ์ฆ this ๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ๋ฐฉ์์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
[this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ]
- ์ผ๋ฐ ํจ์๋ก์ ํธ์ถ ํ ๋ : ์ ์ญ ๊ฐ์ฒด(๋ธ๋ผ์ฐ์ - window, Node.js - global)
- ๋ฉ์๋๋ก ํธ์ถ : ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด(dot notation ์์ ๊ฐ์ฒด)
- ์์ฑ์ ํจ์๋ก์ ํธ์ถ : ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์คconst animal = { walk() { if(!this.isSleeping) { console.log("๋๋ฌผ์ด ๊ฑธ์ด๊ฐ๋ค.") } else { console.log("์๋ ๋๋ฌผ์ ๊ฑธ์ ์ ์๋ค.") } }, sleep() { this.isSleeping = true }, awake() { this.isSleeping = false } } const rabbit = { name :"ํ์ํ ๋ผ", __proto__: animal } // rabbit์ ์๋ก์ด ํ๋กํผํฐ isSleeping์ ์ถ๊ฐํ๊ณ ๊ทธ ๊ฐ์ true๋ก ๋ณ๊ฒฝํฉ๋๋ค. rabbit.sleep(); console.log(rabbit.isSleeping) // true rabbit.walk() // "์๋ ๋๋ฌผ์ ๊ฑธ์ ์ ์๋ค." rabbit.awake(); console.log(rabbit.isSleeping) // false rabbit.walk() // "๋๋ฌผ์ด ๊ฑธ์ด๊ฐ๋ค." console.log(animal.isSleeping)// undefined (ํ๋กํ ํ์ ์๋ isSleeping์ด๋ผ๋ ํ๋กํผํฐ๊ฐ ์์ต๋๋ค.)
for..in ๋ฐ๋ณต๋ฌธ
for in ๋ฐ๋ณต๋ฌธ์ ์์ ํ๋กํผํฐ๋ ์ํ ๋์์ ํฌํจ์ํจ๋ค.
const animal = { eats: true } const rabbit = { jumps: true, __proto__: animal } console.log(Object.keys(rabbits)) // [jumps] for(let prop in rabbit) console.log(prop) // jumps, eats
๊ทธ๋์ ์์ ํ๋กํผํฐ๋ฅผ ์ํ์์ ์ ์ธํ๋ ค๋ฉด obj.hasOwnProperty(key)๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค.
const animal = { eats: true } const rabbit = { jumps: true, __proto__: animal }; for (let prop in rabbit) { const isOwn = rabbit.hasOwnProperty(prop) if(isOwn) { console.log(`๊ฐ์ฒด ์์ ์ ํ๋กํผํฐ : ${prop}`) } else { console.log(`์์ ํ๋กํผํฐ : ${prop}`) } } // "๊ฐ์ฒด ์์ ์ ํ๋กํผํฐ: jumps" // "์์ ํ๋กํผํฐ : eats"
๊ทธ๋ฐ๋ฐ, hasOwnProperty()๋ rabbit์ ์๋ ๋ฉ์๋์ด๋ค. ์ด๊ฑด ์ด๋ป๊ฒ ์ธ ์ ์์๋?
๋ฐ๋ก, rabbit์ ํ๋กํ ํ์ animal์ ํ๋กํ ํ์ ์ด Object์ด๊ธฐ ๋๋ฌธ์ด๋ค. (์ฐธ๊ณ ๋ก Object์ prototype์ null์ด๋ค!) animal์ ํ๋กํ ํ์ ์ด Object์ธ ๊ฒ์ animal์ ๊ฐ์ฒด๋ฆฌํฐ๋ด ๋ฐฉ์์ผ๋ก ์ ์ธํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๊ฒ ๋ฌด์จ๋ง์ด๋ ?
๊ทธ๋ฆฌ๊ณ ์ฝ์์ hasOwnProperty ๋ฉ์๋๊ฐ ์ฐํ์ง ์์๋ค. ๊ทธ ์ด์ ๋ hasOwnProperty๋ ์ด๊ฑฐ ๊ฐ๋ฅํ(enumerable) ํ๋กํผํฐ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ด๋ค. Object.prototype์ ์๋ ๋ชจ๋ ๋ฉ์๋์ enumerable ํ๋๊ทธ๋ false์ธ๋ฐ for..in์ ์ค์ง ์ด๊ฑฐ ๊ฐ๋ฅํ ํ๋กํผํฐ๋ง ์ํ ๋์์ ํฌํจํ๊ธฐ ๋๋ฌธ์ hasOwnProperty๋ ์ฝ์์ ์ถ๋ ฅ๋์ง ์์ ๊ฒ์ด๋ค.
๐ ํค-๊ฐ์ ์ํํ๋ ๋ฉ์๋ ๋๋ถ๋ถ์ ์์ ํ๋กํผํฐ๋ฅผ ์ ์ธํ๊ณ ๋์ํ๋ค. Object.keys, Object.values ๊ฐ์ด ๊ฐ์ฒด์ ํค-๊ฐ์ ๋์์ผ๋ก ์ํํ๋ ๋ฉ์๋ ๋๋ถ๋ถ์ ์์ ํ๋กํผํฐ๋ฅผ ์ ์ธํ๊ณ ๋์ํ๋ค.
'Language > JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Javascript] ํด๋์ค์ ์ ์ (static)๋ฉ์๋์ ํ๋กํผํฐ, ์์ (0) 2023.01.03 [Javascript] ํด๋์ค์ ๋์์๋ฆฌ์ ํด๋์ค ์์(์ค๋ฒ๋ผ์ด๋ฉ) (0) 2023.01.03 Sync Audio with Text Using Javascript (0) 2022.12.26 Binary / Base64 / Blob / ArrayBuffer / File (0) 2022.12.22 ๋ฐฐ์ด์์ ์ต๋๊ฐ, ์ต์๊ฐ ๊ตฌํ๊ธฐ (0) 2022.10.29