[๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ] - ๊ฐ์ฒด(Object)
by rlaehddnd0422[๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ]๋ ์๋ ํํ ๋ฆฌ์ผ ๊ณผ์ ์ ๋ฐํ์ผ๋ก ์์ฑํ์์ต๋๋ค.
์ด๋ฒ์๋ ์ด์ ํฌ์คํ ์ ์๋ฃํ ํํธ์์ ์งง๊ฒ ์ค๋ช ํ๋ "๊ฐ์ฒด"์ ๋ํด ์์ธํ ์์๋ด ์๋ค.
1. ๊ฐ์ฒด
๊ฐ์ฒดํ ํ์ ์ ์ ์ธํ ๋๋จธ์ง 7๊ฐ์ง ํ์ ๋ค์ ํ๋์ ๋ณ์์ ํ๋์ ๋ฐ์ดํฐ๋ง ๋ด์ ์ ์์์ต๋๋ค. ์ด๋ฐ ์ ํ๋ค์ ์์(primitive) ํ์ ์ด๋ผ ๋ถ๋ฆ ๋๋ค. ํ์ง๋ง ๊ฐ์ฒดํ์ ๋ค๋ฆ ๋๋ค. ํ๋์ ๋ณ์์ ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ์ ์์ต๋๋ค. ๊ฐ์ฒด ํ์ ์๋ key๋ก ๊ตฌ๋ถ๋ ๋ฐ์ดํฐ ์งํฉ์ด๋ ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ ๋ค๋ฃจ๋ ค๋ฉด ์ด ๊ฐ์ฒด๋ฅผ ์ ์ดํดํ๊ณ ์์ด์ผ ํฉ๋๋ค.
๊ฐ์ฒด๋ ์ค๊ดํธ {}๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค๊ฑฐ๋ new Object()๋ฅผ ํตํด ๋ง๋ค ์ ์์ต๋๋ค.
let user = new Object(); // '๊ฐ์ฒด ์์ฑ์' ๋ฌธ๋ฒ
let user = {}; // '๊ฐ์ฒด ๋ฆฌํฐ๋ด' ๋ฌธ๋ฒ, ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์ฃผ๋ก ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํจ
์ค๊ดํธ ์์๋ 'key-value'์์ผ๋ก ๊ตฌ์ฑ๋ ํ๋กํผํฐ๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ฃ์ ์ ์๋๋ฐ, "key"์๋ ๋ฌธ์ํ, "value"์๋ ๋ชจ๋ ์๋ฃํ์ด ์ฌ ์ ์์ต๋๋ค. (์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ ๊ฐ์ฒดํ๋ ๊ฐ๋ฅํฉ๋๋ค.)
let user = { // ๊ฐ์ฒด
name: "John", // ํค: "name", ๊ฐ: "John"
age: 30, // ํค: "age", ๊ฐ: 30
"likes birds" : true // ํค : likes birds, ๊ฐ : true
};
์ด ๋ ์ฃผ์ํ ์ ์ผ๋ก๋ ์ธ ๋ฒ์งธ ํ๋กํผํฐ์ ๊ฐ์ด ๊ณต๋ฐฑ๊ธ์๊ฐ ํฌํจ๋ key๋ฅผ ์ค์ ํ๊ณ ์ถ๋ค๋ฉด ํฐ ๋ฐ์ดํ๋ก ๋ฌถ์ ์ ์์ต๋๋ค.
์ ๋ฌ๋ผ๊ณ ๋ง๋ ๊ธฐ๋ฅ์ ์๋ ๊ฒ ๊ฐ๋ค์. ํ๋์ ์์์ผ๋ถ ์ฌ๋งํ๋ฉด ์ธ๋์ค์ฝ์ด ์์๋ค
์ธ๋ถ์์ ๊ฐ์ฒด ํ๋กํผํฐ์ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํ๋ฉด ๋ ๊น์? ์๋ฐ์ฒ๋ผ ์ ํ๊ธฐ๋ฒ(dot notation)์ ์ด์ฉํ๋ฉด ํ๋กํผํฐ ๊ฐ์ ์ฝ์ ์ ์์ต๋๋ค. ์ ํจํ ๋ณ์ ์๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ์ ์ ํ๊ธฐ๋ฒ ๋์ ๋๊ดํธ ํ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
// ํ๋กํผํฐ ๊ฐ ์ป๊ธฐ
alert( user.name ); // John
alert( user.age ); // 30
alert( user.full name ); // error
alert(user["full name"]);
๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ๊ทธ๋ฅ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.
user.isAdmin = true;
user["likes birds"] = true;
ํ๋กํผํฐ ์ญ์ ๋์? delete ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ์ฝ๋ค์
delete user.age;
delete user["likes birds"];
๋๊ดํธ ํ๊ธฐ๋ฒ
๋๊ดํธ ํ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ํํ์์ ํ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
let key = "likes birds";
// user["likes birds"] = true; ์ ๊ฐ์ต๋๋ค.
user[key] = true;
๋ณ์ key๋ ๋ฐํ์์ ํ๊ฐ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์ ์ ๋ ฅ๊ฐ ๋ณ๊ฒฝ ๋ฑ์ ๋ฐ๋ผ ๊ฐ์ด ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ์ด๋ค ๊ฒฝ์ฐ๋ , ํ๊ฐ๊ฐ ๋๋ ์ดํ์ ๊ฒฐ๊ณผ๊ฐ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ฅผ ์์ฉํ๋ฉด ์ฝ๋๋ฅผ ์ ์ฐํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
let user = {
name: "John",
age: 30
};
let key = prompt("์ฌ์ฉ์์ ์ด๋ค ์ ๋ณด๋ฅผ ์ป๊ณ ์ถ์ผ์ ๊ฐ์?", "name");
// ๋ณ์๋ก ์ ๊ทผ
alert( user[key] ); // John (ํ๋กฌํํธ ์ฐฝ์ "name"์ ์
๋ ฅํ ๊ฒฝ์ฐ)
ํ์ง๋ง ์๋์ ๊ฐ์ด ์ ํ๊ธฐ๋ฒ์ผ๋ก๋ ์ด๋ฐ ๋ฐฉ์์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
let user = {
name: "John",
age: 30
};
let key = "name";
alert( user.key ) // undefined
๊ณ์ฐ๋ ํ๋กํผํฐ
์ด๋ ๊ฒ ํ๋กํผํฐ ํค๋ฅผ ๋๊ดํธ๋ก ๋๋ฌ์ธ๋ ๊ฒฝ์ฐ ์ด๋ฅผ "๊ณ์ฐ๋ ํ๋กํผํฐ" ๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ์. ๋ฐ๋๋ก ์ด๋ ๊ฒ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
let fruit = prompt("์ด๋ค ๊ณผ์ผ์ ๊ตฌ๋งคํ์๊ฒ ์ต๋๊น?", "apple");
let bag = {
[fruit]: 5, // ๋ณ์ fruit์์ ํ๋กํผํฐ ์ด๋ฆ์ ๋์ ์ผ๋ก ๋ฐ์ ์ต๋๋ค.
};
alert( bag.apple ); // fruit์ "apple"์ด ํ ๋น๋์๋ค๋ฉด, 5๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
๋๊ดํธ ํ๊ธฐ๋ฒ์ ํ๋กํผํฐ ์ด๋ฆ๊ณผ ๊ฐ์ ์ ์ฝ์ ์์ ์ฃผ๊ธฐ ๋๋ฌธ์ ์ ํ๊ธฐ๋ฒ๋ณด๋ค ํจ์ฌ ๊ฐ๋ ฅํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์์ฑํ๊ธฐ ๋ฒ๊ฑฐ๋กญ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค. ์ด๋ฐ ์ด์ ๋ก ํ๋กํผํฐ ์ด๋ฆ์ด ํ์ ๋ ์ํฉ์ด๊ณ , ๋จ์ํ ์ด๋ฆ์ด๋ผ๋ฉด ์ฒ์์ ์ ํ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ค๊ฐ ๋ญ๊ฐ ๋ณต์กํ ์ํฉ์ด ๋ฐ์ํ์ ๋ ๋๊ดํธ ํ๊ธฐ๋ฒ์ผ๋ก ๋ฐ๊พธ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค๊ณ ํฉ๋๋ค.
๋จ์ถ ํ๋กํผํฐ
์ค๋ฌด์์ ํ๋กํผํฐ ๊ฐ์ ๊ธฐ์กด ๋ณ์์์ ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
function makeUser(name, age) {
return {
name: name,
age: age,
// ...๋ฑ๋ฑ
};
}
let user = makeUser("John", 30);
alert(user.name); // John
์ ์ฝ๋์์๋ ํจ์๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์ ํ๊ธฐ๋ฒ์ผ๋ก ํ๋กํผํฐ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์์ต๋๋ค. ๋์ฌ๊ฒจ๋ด์ผ ํ ์ ์ ๋งค๊ฐ๋ณ์ ์ด๋ฆ๊ณผ ํ๋กํผํฐ ํค ์ด๋ฆ์ด ๋์ผํ๋ค๋ ์ ์ธ๋ฐ์. ์ด๋ฌํ ๊ฒฝ์ฐ ๋ ์งง๊ฒ ์ค์ผ ์ ์์ต๋๋ค. ์๋ ์ฝ๋๋ ์์ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค.
function makeUser(name, age) {
return {
name, // name: name ๊ณผ ๊ฐ์
age, // age: age ์ ๊ฐ์
// ...
};
}
ํ ๊ฐ์ฒด์์ ์ผ๋ฐ ํ๋กํผํฐ์ ๋จ์ถ ํ๋กํผํฐ๋ฅผ ๋์์ ์ฌ์ฉํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
let user = {
name, // name: name ๊ณผ ๊ฐ์
age: 30
};
ํ๋กํผํฐ ์ด๋ฆ์๋ ์ ์ฝ ์ฌํญ์ด ์๋ค.
๋ณ์๋ช ์๋ ์์ฝ์ด๋ ์ฌ์ฉํ ์ ์์์ต๋๋ค. ์ ์ฝ์ฌํญ์ด ์์์ต๋๋ค์ฃ . ํ๋กํผํฐ ์ด๋ฆ์ ๋ค๋ฆ ๋๋ค. ์์ฝ์ด๋ฅผ ์ฌ์ฉํ ์ ์์ด์.
// ์์ฝ์ด๋ฅผ ํค๋ก ์ฌ์ฉํด๋ ๊ด์ฐฎ์ต๋๋ค.
let obj = {
for: 1,
let: 2,
return: 3
};
alert( obj.for + obj.let + obj.return ); // 6
- ์์ฝ์ด ๋ฟ๋ง ์๋๋ผ ์ซ์ํ ๊ฐ, ๋ฌธ์ํ ๊ฐ, ์ฌ๋ณผํ ๊ฐ(๋ค์์ ๋ค๋ฃฐ ์์ )๋ ํ๋กํผํฐ์ ํค๊ฐ ๋ ์ ์์ต๋๋ค.
- ์ซ์ํ ๊ฐ์ ํ๋กํผํฐ ํค๋ก ์ค์ ํ๋ ๊ฒฝ์ฐ ๋ฌธ์์ด๋ก ์๋๋ณํ ๋ฉ๋๋ค. 0 -> "0"
- alert( obj["0"] ); // test
- alert( obj[0] ); // test (๋์ผํ ํ๋กํผํฐ)
์ด์๊ฐ์ด ๊ฐ์ฒด ํ๋กํผํฐ ํค์ ์ธ ์ ์๋ ๋ฌธ์์ด์ ์ ์ฝ์ด ์์ง๋ง, ์ญ์ฌ์ ์ธ ์ด์ ๋๋ฌธ์ ํน๋ณ ๋์ฐ๋ฅผ ๋ฐ๋ ์ด๋ฆ์ด ํ๋ ์์ต๋๋ค.
๋ฐ๋ก, __proto__์ ๋๋ค.
let obj = {};
obj.__proto__ = 5; // ์ซ์๋ฅผ ํ ๋นํฉ๋๋ค.
alert(obj.__proto__); // [object Object] - ์ซ์๋ฅผ ํ ๋นํ์ง๋ง ๊ฐ์ ๊ฐ์ฒด๊ฐ ๋์์ต๋๋ค. ์๋ํ๋๋ก ๋์ํ์ง ์๋ค์.
__proto__์ ๋ณธ์ง์ "ํ๋กํ ํ์ ์์"์์, ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์์ง์ ๋ํด์ ํ๋กํ ํ์ ๋ฉ์๋์ __proto__๊ฐ ์๋ ๊ฐ์ฒด์์ ์์ธํ ๋ค๋ฃฐ ์์ ์ ๋๋ค.
‘in’ ์ฐ์ฐ์๋ก ํ๋กํผํฐ ์กด์ฌ ์ฌ๋ถ ํ์ธํ๊ธฐ
์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ์๋ฐ์ ๋ค๋ฅธ์ ์ ๊ฐ์ฒด์ ์ฐพ๊ณ ์ ํ๋ ํ๋กํผํฐ๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ณ "undefined๋ฅผ ๋ฆฌํด"ํ๋ค๋ ์ ์ธ๋ฐ์. ์ด๋ฐ ํน์ง์ ์ด๋ ค ํ๋กํผํฐ ์กด์ฌ ์ฌ๋ถ๋ฅผ ์ฝ๊ฒ ํ์ธํ ์ ์์ต๋๋ค.
alert( user.noSuchProperty === undefined ); // true๋ 'ํ๋กํผํฐ๊ฐ ์กด์ฌํ์ง ์์'์ ์๋ฏธํฉ๋๋ค.
์์ฒ๋ผ ํ์ธํ ์๋ ์์ง๋ง in ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ธํ ์๋ ์์ต๋๋ค.
let user = { name: "John", age: 30 };
/**
์ด ๋ ๋ฐ๋์
1. in ์ผ์ชฝ์ ํ๋กํผํฐ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๊ฐ์ธ์ผ ํฉ๋๋ค.
2.
*/
alert( "age" in user ); // user.age๊ฐ ์กด์ฌํ๋ฏ๋ก true๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
alert( "blabla" in user ); // user.blabla๋ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ false๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
== undefined๋ก ํ์ธํ๋ ๊ฒ๊ณผ in์ผ๋ก ํ์ธํ๋ ๊ฒ์ ๋ฌด์จ ์ฐจ์ด๊ฐ ์์๊น์?
๋ง์ฝ ์๋์ ๊ฐ์ด ํ๋กํผํฐ๋ ์กด์ฌํ๋๋ฐ, ๊ฐ์ undefined๊ฐ ํ ๋น๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด๋ฉด in์ ์ฐ๋ ๊ฒ์ด ํ๋กํผํฐ ์กด์ฌ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ์ ๋ ์ ํฉํ๋ค๋ ๊ฒ์ ๋๋ผ์ค ์ ์์ผ์ค ๊ฒ๋๋ค.
let obj = {
test: undefined
};
alert( obj.test == undefined ); // ๊ฐ์ด `undefined`์ด๋ฏ๋ก, true.
// ํ์ง๋ง ์กด์ฌ์ฌ๋ถ๋ก ํ๋จํ ๊ฒ์ด ์๋๋ผ test ํ๋กํผํฐ์ ๊ฐ์ด undefined์ธ ๊ฒ์ผ๋ก ํ๋จํ ๊ฒ์ด๋ฏ๋ก ์ ํํ์ง X
alert( "test" in obj ); // `in`์ ์ฌ์ฉํ๋ฉด ํ๋กํผํฐ ์ ๋ฌด๋ฅผ ์ ๋๋ก ํ์ธํ ์ ์์ต๋๋ค(true๊ฐ ์ถ๋ ฅ๋จ).
for...in ๋ฐ๋ณต๋ฌธ
for..in ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด์ ๋ชจ๋ ํค๋ฅผ ์ํํ ์ ์์ต๋๋ค. for..in์ for(;;) ๋ฐ๋ณต๋ฌธ๊ณผ๋ ์์ ํ ๋ค๋ฆ ๋๋ค.
let user = {
name: "John",
age: 30,
isAdmin: true
};
for (let key in user) {
// ํค
alert( key ); // name, age, isAdmin
// ํค์ ํด๋นํ๋ ๊ฐ
alert( user[key] ); // John, 30, true
}
๋ฒ์ธ : ํ๋กํผํฐ์๋ ์์๊ฐ ์์๊น?
๊ฐ์ฒด๋ ํน๋ณํ ๋ฐฉ์์ผ๋ก ์ ๋ ฌ๋ฉ๋๋ค. ์ ์ ํ๋กํผํฐ๋ ์ค๋ฆ์ฐจ์์ผ๋ก ์๋์ผ๋ก ์ ๋ ฌ๋๊ณ ๊ทธ ์ธ์ ํ๋กํผํฐ๋ ๊ฐ์ฒด์ ์ถ๊ฐํ ์์ ๊ทธ๋๋ก ์ ๋ ฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ์์ ๋ฅผ ํตํด ์ดํด๋ด ์๋ค.
- ์ฐธ๊ณ ๋ก ์ ์ ํ๋กํผํฐ๋ ๋ฌธ์์ด->์ซ์ํ, ์ซ์ํ->๋ฌธ์์ด๋ก ๊ฐ์ ๋ณํ์์ด ์๋ค๊ฐ๋ค ํ ์ ์๋ ํ๋กํผํฐ๋ฅผ ๋งํจ.
- alert( String(Math.trunc(Number("49"))) ); // '49'๊ฐ ์ถ๋ ฅ. ๊ธฐ์กด์ ์ ๋ ฅํ ๊ฐ๊ณผ ๊ฐ์ผ๋ฏ๋ก ์ ์ ํ๋กํผํฐ์.
- alert( String(Math.trunc(Number("+49"))) ); // '49'๊ฐ ์ถ๋ ฅ. ๊ธฐ์กด์ ์ ๋ ฅํ ๊ฐ(+49)๊ณผ ๋ค๋ฅด๋ฏ๋ก ์ ์ ํ๋กํผํฐ๊ฐ ๋
- alert( String(Math.trunc(Number("1.2"))) ); // '1'์ด ์ถ๋ ฅ. ๊ธฐ์กด์ ์ ๋ ฅํ ๊ฐ(1.2)๊ณผ ๋ค๋ฅด๋ฏ๋ก ์ ์ ํ๋กํผํฐ๊ฐ ์๋
let codes = {
"49": "๋
์ผ",
"41": "์ค์์ค",
"44": "์๊ตญ",
// ..,
"+1": "๋ฏธ๊ตญ"
};
for (let code in codes) {
alert(code); // 41, 44, 49, 1
}
let user = {
name: "John",
surname: "Smith"
};
user.age = 25; // ํ๋กํผํฐ๋ฅผ ํ๋ ์ถ๊ฐํฉ๋๋ค.
// ์ ์ ํ๋กํผํฐ๊ฐ ์๋ ํ๋กํผํฐ๋ ์ถ๊ฐ๋ ์์๋๋ก ๋์ด๋ฉ๋๋ค.
for (let prop in user) {
alert( prop ); // name, surname, age
}
๋ฒ์ธ : ์์ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์์ ํ ์ ์์๊น?
const user = {
name: "John"
};
user.name = "Pete"; // (*)
alert(user.name); // Pete
- const๋ user์ ๊ฐ์ ๊ณ ์ ํ ๊ฒ์ด์ง, ๊ทธ๊ฒ user์ ํ๋กํผํฐ๋ฅผ ๊ณ ์ ํ ๊ฒ์ ์๋ฏธํ์ง๋ ์์ต๋๋ค.
- ๋ฐ๋ผ์ user = ~~;์ ๊ฐ์ด 'user' ๊ทธ ์์ฒด๋ฅผ ๋ณ๊ฒฝํ๋ ค๊ณ ํ๋ ๊ฒฝ์ฐ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ง, ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ๊ฑด๋ ๋ค๊ณ ํด์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ ์์ต๋๋ค.
2. ์ฐธ์กฐ์ ์ํ ๊ฐ์ฒด ๋ณต์ฌ
์๋ฐ ์คํฌ๋ฆฝํธ์์ ์์ํ์ ์ call by value, ๊ฐ์ฒดํ์ ์ call by reference ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค.
์ฆ, ์์ํ์ ์ ๊ฒฝ์ฐ ๋ณต์ฌํ์ ๊ฒฝ์ฐ "๊ฐ" ์์ฒด๊ฐ ๋ณต์ฌ๋๋ฏ๋ก ๊ฐ์ ๋ณ๊ฒฝ์ด ์ด๋ฃจ์ด์ง๋ค๊ณ ํด์ ๋ณต์ฌ๋ ๊ฐ์ฒด๊น์ง ๋ณ๊ฒฝ๋์ง ์๋๋ค๋ ๋ง์ ๋๋ค. ์๋๊ฐ ๊ทธ ์์์ ๋๋ค.
let a = 1;
let b = a;
console.log(a); // 1
console.log(b); // 1
a = 2;
console.log(a); // 2
console.log(b); // 1
๋ฐ๋ฉด, ๊ฐ์ฒด๋ call by reference ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ "์ฃผ์"๊ฐ ๋ณต์ฌ๋๋ ๋ฐฉ์์ผ๋ก ๋ณต์ฌ๊ฐ ์ด๋ฃจ์ด์ ธ, ์๋ณธ๊ฐ์ฒด๊ฐ ๋ฐ๋๋ค๋ฉด ๋ณต์ฌ๊ฐ์ฒด๋ ๋ฐ๋๊ฒ ๋ฉ๋๋ค.
let a = {
name : 'kim'
}
let b = a;
console.log(a.name); // kim
console.log(b.name); // kim
a.name = 'park';
console.log(a); // park
console.log(b); // park
๊ฐ์ฒด ๋ณต์ฌ, ๋ณํฉ, Object.assign
๊ทธ๋ ๋ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋ ๋ฆฝ๋ ๊ฐ์ฒด๋ก ๋ณต์ ํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ๊ฐ์ฒด๋ฅผ ๋ ๋ฆฝ๋ ๊ฐ์ฒด๋ก ๋ณต์ฌํ๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค๋ง, ๊ฝค๋ ๋ณต์กํฉ๋๋ค. ๊ทธ๋ด ์ผ๋ ์ ์๊ตฌ์.
iterateํ์ฌ key ๋ณต์ฌ
let user = {
name: "John",
age: 30
};
let clone = {}; // ์๋ก์ด ๋น ๊ฐ์ฒด
// ๋น ๊ฐ์ฒด์ user ํ๋กํผํฐ ์ ๋ถ๋ฅผ ๋ณต์ฌํด ๋ฃ์ต๋๋ค.
for (let key in user) {
clone[key] = user[key];
}
// ์ด์ clone์ ์์ ํ ๋
๋ฆฝ์ ์ธ ๋ณต์ ๋ณธ์ด ๋์์ต๋๋ค.
clone.name = "Pete"; // clone์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
alert( user.name ); // ๊ธฐ์กด ๊ฐ์ฒด์๋ ์ฌ์ ํ John์ด ์์ต๋๋ค.
Object.assgin ์ฌ์ฉ
Object.assign(dest, [src1, src2, src3...])
- ์ฒซ ๋ฒ์งธ ์ธ์ dest๋ ๋ณต์ฌ๋ ๊ฐ์ฒด์ ๋๋ค.
- ์ด์ด์ง๋ ์ธ์ src1, ..., srcN๋ ๋ณต์ฌํ๊ณ ์ ํ๋ ๊ฐ์ฒด์ ๋๋ค. ...์ ํ์์ ๋ฐ๋ผ ์ผ๋ง๋ ์ง ๋ง์ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ ๋ํ๋ ๋๋ค.
์ฌ์ฉ ์์
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// permissions1๊ณผ permissions2์ ํ๋กํผํฐ๋ฅผ user๋ก ๋ณต์ฌํฉ๋๋ค.
Object.assign(user, permissions1, permissions2);
// now user = { name: "John", canView: true, canEdit: true }
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ์๋์ ๊ฐ์ด ๊ฐ์ฒด์ ํ๋กํผํฐ์ ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let k = {};
Object.assign(k, user);
user.sizes.height = 10;
console.log(k.sizes.height); // 10
์ด ๊ฒฝ์ฐ์๋ sizes ํ๋กํผํฐ๋ ๊ฐ์ฒดํ์ด๊ธฐ ๋๋ฌธ์ call by reference๋ก ๋ณต์ฌ๊ฐ ์ด๋ฃจ์ด์ง๋๋ค. ์ฆ, user์ sizes์ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด k์ sizes์๋ ๋์ผํ๊ฒ ๋ณ๊ฒฝ์ด ์ผ์ด๋๊ฒ ๋์ฃ .
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ 1๋ฒ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ ๊ฐ ๊ฐ์ ๊ฒ์ฌํ๋ฉด์ ๊ทธ ๊ฐ์ด ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ ๊ฐ์ฒด์ ๊ตฌ์กฐ๋ call by value๋ก ๋ณต์ฌํด์ฃผ๋ "๊น์ ๋ณต์ฌ" ๋ฐฉ์์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
_.cloneDeep(obj)
์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ lodash์ ๋ฉ์๋์ธ _.cloneDeep(obj)์ ์ฌ์ฉํ๋ฉด ์ด ์๊ณ ๋ฆฌ์ฆ์ ์ง์ ๊ตฌํํ์ง ์๊ณ ๋ ๊น์ ๋ณต์ฌ๋ฅผ ์ฒํ ์ ์์ต๋๋ค.
let _ = require('lodash');
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let k = _.cloneDeep(user);
user.sizes.height = 100;
console.log(k.sizes.height); // 182
3. ๊ฐ๋น์ง ์ปฌ๋ ์
์๋ฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ๋์ํฉ๋๋ค. Java๋ ์ฃผ๋ก ์๋ฒ๋ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์ ํ๊ฒฝ์์ ๋์ํ๋ฉฐ, JVM์ ํตํ ์ธ๋๋ณ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๋ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๊ธฐ๋ฒ์ ์ ์ฉํฉ๋๋ค. ๋ฐ๋ฉด JavaScript๋ ๋ธ๋ผ์ฐ์ ๋ Node.js์ ๊ฐ์ ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋์ํ๋ฉฐ, ๋น๊ต์ ๊ฐ๋จํ ๊ฐ๋น์ง ์ปฌ๋ ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
JS์์๋ "๋๋ฌ ๊ฐ๋ฅ์ฑ"์ด๋ผ๋ ๊ฐ๋ ์ ์ฌ์ฉํด ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ํํฉ๋๋ค. "๋๋ฌ ๊ฐ๋ฅํ๋ค"๋ ๊ฐ์ ์ฝ๊ฒ ๋งํด ์ด๋ป๊ฒ๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ ๊ฐ์ ์๋ฏธํ๋๋ฐ, ์ด ๊ฒฝ์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ญ์ ๋์ง ์์ต๋๋ค.
์๋ ๊ฐ๋ค์ ํ์๋ถํฐ "๋๋ฌ ๊ฐ๋ฅํ ๊ฐ"๋ค์ด๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ์์ ์ญ์ ๋์ง ์๋๋ค๋ ์ ์ ๊ธฐ์ตํฉ์๋ค.
- ํ์ฌ ํจ์์ ์ง์ญ๋ณ์์ ๋งค๊ฐ๋ณ์
- ์ค์ฒฉ ํจ์์ ์ฒด์ธ์ ์๋ ํจ์์์ ์ฌ์ฉ๋๋ ๋งค๊ฐ๋ณ์, ๋ณ์
- ์ ์ญ ๋ณ์
์ด๋ฐ ๊ฐ๋ค์ "root"๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด "๋๋ฌํ ์ ์๋" ๊ฐ์ ๋ฌด์์ผ๊น์? ์์๋ก ์ดํด๋ด ์๋ค.
// user์ ๊ฐ์ฒด ์ฐธ์กฐ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค.
let user = {
name: "John"
};
user = null;
// ์, ์ด์ "John"์ ๋๋ฌํ ์ ์๋ ์ํ๊ฐ ๋์์ต๋๋ค.
user์ null ๊ฐ์ ํ ๋นํ๋ ์๊ฐ๋ถํฐ๋ user.name์ ์ ๊ทผํ ๋๋ฆฌ๊ฐ ์์ต๋๋ค. user์ ๋ณต์ฌํ ๊ฒ์ด ์๋๋ผ๋ฉด์. "๋๋ฌํ ์ ์๋ค"๋ ์๋ฏธ๊ฐ ์ดํด๊ฐ ๋์ จ๋์?
JS์์๋ ๋ฃจํธ ์ ๋ณด๋ฅผ ์์งํ๊ณ ์ด๋ฅผ mark(๊ธฐ์ต)ํ๋ฉฐ, ์ฃผ๊ธฐ์ ์ผ๋ก ๋ฃจํธ๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ชจ๋ ๊ฐ์ฒด๋ค ๋ํ ๋ฐฉ๋ฌธํ๊ณ ์ด๊ฒ๋ค์ markํฉ๋๋ค. mark๋ ๊ฐ์ฒด๋ค์ด ์ฐธ์กฐํ๋ ๊ฐ์ฒด๋ค๋ mark ํฉ๋๋ค. ์ด๋ ๊ฒ ๋๋ฌ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฐ์ฒด๋ค์ ๊ฐ ํ๋ฒ์ฉ ๋ฐฉ๋ฌธ(๋ฐฉ๋ฌธํ๋ ๊ฐ์ฒด๋ฅผ ๋ค์ markํ๋ ๊ฒฝ์ฐ๋ ์์)ํ๋ฉฐ, ๊ฐ์ฒด๊ฐ ์ฌ์ ํ ์ฌ์ฉ ์ค์ธ์ง ํ์ธํ๊ธฐ ์ํด ๊ฐ์ฒด๋ฅผ '๋งํฌ'ํ๊ณ , ์ฌ์ฉ๋์ง ์๋ ๊ฐ์ฒด๋ '์ค์' ๊ณผ์ ์ ํตํด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
์ด๋ฐ ๋ฐฉ์์ Mark-And-Sweep ๋ฐฉ์์ด๋ผ ๋ถ๋ฆ ๋๋ค.
๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋ํด ๋ ์์ธํ ์์๋ณด๊ณ ์ถ์ผ์๋ค๋ฉด ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
4. ๋ฉ์๋์ this
JS์์๋ ๋น์ฐํ ๊ฐ์ฒด์๋ ๋ฉ์๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
let user = {
name: "John",
age: 30,
bye : function() {
console.log(this.name + " : ์๋
ํ ๊ณ์ธ์.");
}
};
user.sayHi = function() {
console.log("์๋
ํ์ธ์!");
};
user.sayHi();
user.bye();
๋ฉ์๋ ๋จ์ถ ๊ตฌ๋ฌธ
๊ฐ์ฒด ๋ฆฌํฐ๋ด ์์ ๋ฉ์๋๋ฅผ ์ ์ธํ ๋ ์ฌ์ฉํ ์ ์๋ ๋จ์ถ ๋ฌธ๋ฒ์ ๋๋ค.
// ์๋ ๋ ๊ฐ์ฒด๋ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค.
user = {
sayHi: function() {
alert("Hello");
}
};
// ๋จ์ถ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ ๋ ๊น๋ํด ๋ณด์ด๋ค์.
user = {
sayHi() { // "sayHi: function()"๊ณผ ๋์ผํฉ๋๋ค.
alert("Hello");
}
};
์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ๊ณผ ๋จ์ถ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ด ์์ ํ ๋์ผํ์ง ์์ต๋๋ค. ๊ฐ์ฒด ์์๊ณผ ๊ด๋ จ๋ ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์กด์ฌํ๋๋ฐ ์ง๊ธ์ผ๋ก์ ์ด ์ฐจ์ด๊ฐ ์ค์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋์ด๊ฐ๋๋ก ํ๊ฒ ์ต๋๋ค.
this
๋ฉ์๋ ๋ด๋ถ์์ this ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด ๋ ์ ์์ this๋ ๊ฐ์ฒด๋ฅผ ๋ํ๋ ๋๋ค. ์ ํํ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ์ฌ์ฉ๋ ๊ฐ์ฒด๋ฅผ ๋ํ๋ด์ฃ .
let user = {
name: "John",
age: 30,
sayHi() {
// 'this'๋ 'ํ์ฌ ๊ฐ์ฒด'๋ฅผ ๋ํ๋
๋๋ค.
alert(this.name);
}
};
user.sayHi(); // John
user.sayHi()๊ฐ ์คํ๋๋ ๋์์ this๋ user๋ฅผ ๋ํ๋
๋๋ค.
this๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ธ๋ถ ๋ณ์๋ฅผ ์ฐธ์กฐํด ๊ฐ์ฒด์ ์ ๊ทผํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
let user = {
name: "John",
age: 30,
sayHi() {
alert( user.name ); // Error: Cannot read property 'name' of null
}
};
let admin = user;
user = null; // user๋ฅผ null๋ก ๋ฎ์ด์๋๋ค.
admin.sayHi(); // sayHi()๊ฐ ์๋ฑํ ๊ฐ์ฒด๋ฅผ ์ฐธ๊ณ ํ๋ฉด์ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ์ธ๋ถ ๋ณ์๋ฅผ ์ฌ์ฉํด ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ฉด ์์์น ๋ชปํ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. user๋ฅผ ๋ณต์ฌํด ๋ค๋ฅธ ๋ณ์์ ํ ๋น(admin = user)ํ๊ณ , user๋ ์ ํ ๋ค๋ฅธ ๊ฐ์ผ๋ก ๋ฎ์ด์ผ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. sayHi()๋ ์์น ์๋ ๊ฐ(null)์ ์ฐธ์กฐํ ๊ฒ๋๋ค. user.name๋์ this.name์ ์ธ์๋ก ๋ฐ์๋ค๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ฒ ์ฃ .
์๋ฐ์คํฌ๋ฆฝํธ์์ this๋ ๋ค๋ฅธ ์ธ์ด์ this์ ๋์๋ฐฉ์์ด ์กฐ๊ธ ๋ค๋ฆ ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๋ชจ๋ ํจ์์ this๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฆ, ์๋์ฒ๋ผ ์์ฑํด๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
function sayHi() {
alert( this.name );
}
this ๊ฐ์ ๋ฐํ์์ ๊ฒฐ์ ๋ฉ๋๋ค. ์ฆ, ๋์ผํ ํจ์๋ผ๋ ๋ค๋ฅธ ๊ฐ์ฒด์์ ํธ์ถํ๋ค๋ฉด this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ด ๋ฌ๋ฆฌ์ง๊ฒ ๋ฉ๋๋ค.
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// ๋ณ๊ฐ์ ๊ฐ์ฒด์์ ๋์ผํ ํจ์๋ฅผ ์ฌ์ฉํจ
user.f = sayHi;
admin.f = sayHi;
// 'this'๋ '์ (.) ์์' ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์
// this ๊ฐ์ด ๋ฌ๋ผ์ง
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (์ ๊ณผ ๋๊ดํธ๋ ๋์ผํ๊ฒ ๋์ํจ)
๊ฐ์ฒด๊ฐ ์์ด๋ ํจ์๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. strict mode๋ผ๋ฉด undefined๊ฐ ํ ๋น๋๊ณ , strict mode๊ฐ ์๋ ๋์๋ this๋ window๋ผ๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฐ ์์ ์ฝ๋๋ ๋๊ฐ ์ค์๋ก ์์ฑ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋ง์ฝ ํจ์ ๋ณธ๋ฌธ์ this๊ฐ ์ฌ์ฉ๋์๋ค๋ฉด, ๊ฐ์ฒด ์ปจํ ์คํธ ๋ด์์ ํจ์๋ฅผ ํธ์ถํ ๊ฒ์ด๋ผ๊ณ ์์ํ์๋ฉด ๋ฉ๋๋ค.
function sayHi() {
alert(this);
}
sayHi(); // undefined
'use strict';
function sayBye() {
console.log(this);
}
sayBye();
/**
ref *1> Object [global] {
global: [Circular *1],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
queueMicrotask: [Function: queueMicrotask],
structuredClone: [Function: structuredClone],
atob: [Getter/Setter],
btoa: [Getter/Setter],
performance: [Getter/Setter],
fetch: [Function: fetch],
crypto: [Getter]
}
*/
this๊ฐ ์๋ ํ์ดํ ํจ์
ํ์ดํ ํจ์๋ ์ผ๋ฐ ํจ์์๋ ๋ฌ๋ฆฌ ‘๊ณ ์ ํ’ this๋ฅผ ๊ฐ์ง์ง ์์ต๋๋ค. ํ์ดํ ํจ์์์ this๋ฅผ ์ฐธ์กฐํ๋ฉด, ํ์ดํ ํจ์๊ฐ ์๋ ‘ํ๋ฒํ’ ์ธ๋ถ ํจ์์์ this ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค.
์๋ ์์์์ ํจ์ arrow()์ this๋ ์ธ๋ถ ํจ์ user.sayHi()์ this๊ฐ ๋ฉ๋๋ค.
let user = {
firstName: "๋ณด๋ผ",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // ๋ณด๋ผ
๋ณ๊ฐ์ this๊ฐ ๋ง๋ค์ด์ง๋ ๊ฑด ์ํ์ง ์๊ณ , ์ธ๋ถ ์ปจํ
์คํธ์ ์๋ this๋ฅผ ์ด์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ ํ์ดํ ํจ์๊ฐ ์ ์ฉํฉ๋๋ค. ์ด์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ณ๋์ ์ฑํฐ, ํ์ดํ ํจ์ ๋ค์ ์ดํด๋ณด๊ธฐ์์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
5. new ์ฐ์ฐ์์ ์์ฑ์ ํจ์
์ค๊ดํธ ๊ฐ์ฒด ๋ฆฌํฐ๋ด ({...})๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด๋ฅผ.์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ๋ฟ๋ง ์๋๋ผ new ํค์๋์ ํจ์๋ฅผ ํตํด์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์๋ ์๋๋ฐ์. ๊ทธ ๋ฐฉ๋ฒ์ ์๋ฐ๋ด ์๋ค.
์์ฑ์ ํจ์
"์ผ๋ฐ ํจ์"์ ๊ตฌ๋ถ๋๋ "์์ฑ์ ํจ์"๋ผ๋ ๊ฒ์ด ์์ต๋๋ค. ๊ธฐ์ ์ ์ธ ์ฐจ์ด๋ ์๊ณ , ๋ ๊ด๋ก๋ฅผ ๋ฐ๋ฅผ ๋ฟ์ ๋๋ค.
- ํจ์์ ์ฒซ ๊ธ์๋ ๋๋ฌธ์๋ก.
- ๋ฐ๋์ "new" ์ฐ์ฐ์๋ฅผ ์์ ๋ถ์ฌ ์คํ
์์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("๋ณด๋ผ");
alert(user.name); // ๋ณด๋ผ
alert(user.isAdmin); // false
new User(...)๋ฅผ ์จ์ ํจ์๋ฅผ ์คํํ๋ฉด ์์์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ๋์ํฉ๋๋ค.
// ์์์ ์ผ๋ก ์๋์ ๊ฐ์ด ๋์ํจ.
function User(name) {
// this = {}; (๋น ๊ฐ์ฒด๊ฐ ์์์ ์ผ๋ก ๋ง๋ค์ด์ง)
// ์๋ก์ด ํ๋กํผํฐ๋ฅผ this์ ์ถ๊ฐํจ
this.name = name;
this.isAdmin = false;
// return this; (this๊ฐ ์์์ ์ผ๋ก ๋ฐํ๋จ)
}
1. ๋น ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด this์ ํ ๋น
2. ํจ์ ๋ณธ๋ฌธ ์คํ. (this์ ์๋ก์ด ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด this ์์ )
3. this return
์์ฑ์ ํจ์๊ฐ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด, ์ต๋ช ํจ์๋ก ์ด๋ ๊ฒ ๋ง๋ค ์๋ ์๊ฒ ์ต๋๋ค. ํ ๋ฒ๋ง ์ฌ์ฉํ๋ค๋ฉด ์ฌ์ฌ์ฉ์ ๋ง์ผ๋ฉด์ ์ฝ๋๋ฅผ ์บก์ํ ํ ์ ์์ต๋๋ค.
let user = new function() {
this.name = "John";
this.isAdmin = false;
// ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ฌ๋ฌ ์ฝ๋.
// ์ง์ญ ๋ณ์, ๋ณต์กํ ๋ก์ง, ๊ตฌ๋ฌธ ๋ฑ์
// ๋ค์ํ ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ๋ค์ด๊ฐ๋๋ค.
};
new.target๊ณผ ์์ฑ์ ํจ์
new.target ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์๊ฐ new์ ํจ๊ป ํธ์ถ๋์๋์ง ์๋์ง ์ ์ ์์ต๋๋ค.
- new ํค์๋์ ํจ๊ป ํธ์ถ๋ ๊ฒฝ์ฐ : ํจ์ ์์ฒด๋ฅผ return
- new ํค์๋ ์์ด ํธ์ถ๋ ๊ฒฝ์ฐ : undefined retrurn
function User() {
console.log(new.target);
}
User(); // undefined
new User(); // [Function: User]
new.target์ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์์๊น์? ๋ฐ๋ก ์ด๋ฅผ ํ์ฉํด new ํค์๋ ์์ด๋ new ํค์๋๋ฅผ ๋ถ์ฌ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ ๊ฒ์ฒ๋ผ ๋์ํ๊ฒ ํ ์ ์๊ฒ ์ต๋๋ค.
function User(name) {
if(!new.target) {
return new User(name);
}
this.name = name;
}
let userA = User("a");
let userB = new User("b");
console.log(userA.name); // a
console.log(userB.name); // b
์ด๋ฐ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด new๋ฅผ ๋ถ์ฌ ํจ์๋ฅผ ํธ์ถํ๋ ์๋๋ ์ฝ๋๊ฐ ๋์ผํ๊ฒ ๋์ํ๊ธฐ ๋๋ฌธ์, ์ข ๋ ์ ์ฐํ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. new๋ฅผ ์๋ตํด์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ผ์ด ์์ ์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง, ๋ง์ฝ ์๋ค๋ฉด ์ ์ฝ๋์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋๊ฒ ๋ค์.
์์ฑ์์ return๋ฌธ
๋ฐํํด์ผ ํ ๊ฒ๋ค์ ๋ชจ๋ this์ ์ ์ฅ๋๊ณ , this๋ ์๋์ผ๋ก ๋ฐํ๋๊ธฐ ๋๋ฌธ์ ๋ฐํ๋ฌธ์ ๋ช ์์ ์ผ๋ก ์จ ์ค ํ์๊ฐ ์์ต๋๋ค. ๋ฐ๋ผ์ ์์ฑ์ํจ์์ ๋ณดํต return ๋ฌธ์ด ์์ต๋๋ค. ๋ง์ฝ return ๋ฌธ์ด ์๋ค๋ฉด ์ด๋ป๊ฒ ๋์ํ ๊น์?
- return ์์ํ : ๋ฌด์๋จ
- return ๊ฐ์ฒด : this ๋์ ๊ฐ์ฒด๊ฐ ๋ฐํ๋จ.
function BigUser() {
this.name = "์์ญ์ด";
return { name: "๊ณ ๋ฆด๋ผ" }; // <-- this๊ฐ ์๋ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ฐํํจ
}
alert( new BigUser().name ); // ๊ณ ๋ฆด๋ผ
function SmallUser() {
this.name = "์์ญ์ด";
return; // <-- this๋ฅผ ๋ฐํํจ
}
alert( new SmallUser().name ); // ์์ญ์ด
์์ฑ์ ๋ด ๋ฉ์๋
์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋งค๊ฐ๋ณ์๋ฅผ ์ด์ฉํด ๊ฐ์ฒด ๋ด๋ถ๋ฅผ ์์ ๋กญ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์์ฒญ๋ ์ ์ฐ์ฑ์ด ํ๋ณด๋์ฃ .
์ง๊ธ๊น์ง this์ ํ๋กํผํฐ๋ฅผ ๋ํด์ฃผ๋ ์์๋ง ์ดํด๋ดค๋๋ฐ, ๋ฉ์๋๋ฅผ ๋ํด์ฃผ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
์๋ ์์์์ new User(name)๋ ํ๋กํผํฐ name๊ณผ ๋ฉ์๋ sayHi๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
function User(name) {
this.name = name;
this.sayHi = function() {
alert( "์ ์ด๋ฆ์ " + this.name + "์
๋๋ค." );
};
}
let bora = new User("์ด๋ณด๋ผ");
bora.sayHi(); // ์ ์ด๋ฆ์ ์ด๋ณด๋ผ์
๋๋ค.
/*
bora = {
name: "์ด๋ณด๋ผ",
sayHi: function() { ... }
}
*/
6. ์ต์ ๋ ์ฒด์ด๋ '?.'
์ต์ ๋ ์ฒด์ด๋ "?."์ ์ฌ์ฉํ๋ฉด ํ๋กํผํฐ๊ฐ "์๋" ์ค์ฒฉ ๊ฐ์ฒด๋ฅผ ์๋ฌ์์ด ์์ ํ๊ฒ ์ ๊ทผํ ์ ์์ต๋๋ค.
์์ JS์์๋ ์ฒด์ด๋๋ ๊ฐ์ฒด์ ํน์ ํ๋กํผํฐ์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ํญ์ AND๋ก ์ฐ๊ฒฐํด์ ์ค์ ํด๋น ๊ฐ์ฒด๋ ํ๋กํผํฐ๊ฐ ์๋์ง ๋จผ์ ํ์ธ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์์ต๋๋ค.
// ์์
alert( obj && obj.obj2 && obj.obj2.obj3 && obj.obj2.obj3.property )
์ด๋ ๊ฒ AND๋ก ์ฐ๊ฒฐํ๋ฉด ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ค๋ ๋จ์ ์ ํด๊ฒฐํด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก ์ต์ ๋ ์ฒด์ด๋ "?."์ ๋๋ค.
?.์ ?.'์’์ ํ๊ฐ ๋์์ด undefined๋ null์ด๋ฉด ํ๊ฐ๋ฅผ ๋ฉ์ถ๊ณ undefined๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ๋ ๋ฐ๋์ '์'์ ํ๊ฐ ๋์์ ์กด์ฌํด์ผ ํฉ๋๋ค. ์ฝ๊ฒ๋งํด, '์'์ ํ๊ฐ ๋์์ ๋ณ์๋ก์ ์ ์ธ ๋์ด ์์ด์ผ ํฉ๋๋ค. (๊ทธ๋ ์ง ์์ผ๋ฉด ์ค๋ฅ๋จ)
let user = {
name : {
containsA : false,
}
};
undefined?.name // undefined
null?.name // undefined
user?.name // kim
user.name?.containsA // false
// user๊ฐ null ๋๋ undefined๊ฐ ์๋๊ณ ์ค์ ๊ฐ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋
// ๋ฐ๋์ user.address ํ๋กํผํฐ๋ ์์ด์ผ ํฉ๋๋ค.
// ๊ทธ๋ ์ง ์์ผ๋ฉด user?.address.street์ ๋ ๋ฒ์งธ ์ ์ฐ์ฐ์์์ ์๋ฌ๊ฐ ๋ฐ์
// ์ด๋ฅผ ํ์ฉํ๋ค๋ฉด ?.๋ก ๊ณ์ ์ฐ๊ฒฐํด์ ์ค์ฒฉ ํ๋กํผํฐ๋ค์ ์์ ํ๊ฒ ์ ๊ทผํ ์ ์์.
user?.address.street // error : address prop is not exist.
์ด ์ธ์๋ "?."๋ ๋ ๋ค๋ฅธ ํํ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ํ์ ์ผ๋ก ?.[prop], ?.method() ๊ฐ ์์ต๋๋ค.
- obj?.prop – obj๊ฐ ์กด์ฌํ๋ฉด obj.prop์ ๋ฐํํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด undefined๋ฅผ ๋ฐํํจ.
- obj?.[prop] – obj๊ฐ ์กด์ฌํ๋ฉด obj[prop]์ ๋ฐํํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด undefined๋ฅผ ๋ฐํํจ.
- obj?.method() – obj๊ฐ ์กด์ฌํ๋ฉด obj.method()๋ฅผ ํธ์ถํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด undefined๋ฅผ ๋ฐํํจ.
7. Symbol
JS๋ ๊ฐ์ฒด์ ํ๋กํผํฐ ํค๋ก ์ค์ง ๋ฌธ์ํ๊ณผ ์ฌ๋ณผํ๋ง์ ํ์ฉํฉ๋๋ค.
let obj = {};
obj[true] // error
obj[undefined] // error
obj[1] // error
obj[null] // error
์ง๊ธ๊น์ง๋ ํ๋กํผํฐ ํค๊ฐ ๋ฌธ์ํ์ธ ๊ฒฝ์ฐ๋ง ์ดํด๋ณด์์ต๋๋ค. ์ด๋ฒ์๋ ํ๋กํผํฐ ํค๋ก ์ฌ๋ณผ๊ฐ์ ์ฌ์ฉํด๋ณด๋ฉด์ ์ด์ ์ ์์๋ณด๊ฒ ์ต๋๋ค.
์ฌ๋ณผ์ "์ ์ผ ์๋ณ์"๋ฅผ ๋ง๋ค๊ณ ์ ํ ๋ ์ ์ฉํฉ๋๋ค.
์ฌ๋ณผ๊ฐ์ Symbol()์ ์ฌ์ฉํด ๋ง๋ค ์ ์์ต๋๋ค.
let k = Symbol("k");
์ฌ๋ณผ์ ์ ์ผ์ฑ์ ๋ณด์ฅํ๋ "์๋ฃํ"์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฆ์ด ๋์ผํ ์ฌ๋ณผ์ด๋ผ๊ณ ํด์ ๊ฐ ์ฌ๋ณผ์ด ๊ฐ์ง ์์ต๋๋ค.
let id1 = Symbol("id");
let id2 = Symbol("id");
console.log(id1 == id2); // false
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ฌธ์ํ์ผ๋ก์ ์์์ ํ ๋ณํ์ด ๋น๊ต์ ์์ ๋กญ๊ฒ ์ผ์ด๋๋ ํธ์
๋๋ค. alert ํจ์๊ฐ ๊ฑฐ์ ๋ชจ๋ ๊ฐ์ ์ธ์๋ก ๋ฐ์ ์ ์๋ ์ด์ ๊ฐ ์ด ๋๋ฌธ์ด์ฃ . ๊ทธ๋ฌ๋ ์ฌ๋ณผ์ ์์ธ์
๋๋ค. ์ฌ๋ณผํ ๊ฐ์ ๋ค๋ฅธ ์๋ฃํ์ผ๋ก ์์์ ํ ๋ณํ(์๋ ํ ๋ณํ)๋์ง ์์ต๋๋ค.
์๋ ์์์์ alert๋ ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
let id = Symbol("id");
console.log(id); // error
- ๋ณด์๋ ๊ฒ์ฒ๋ผ ๋ฌธ์์ด๊ณผ ์ฌ๋ณผ์ ๊ทผ๋ณธ๋ถํฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์๋ก์ ํ์ ์ผ๋ก ๋ณํํด์๋ ์๋ฉ๋๋ค. ๋ง์ฝ ๋ฐ๋์ ์ถ๋ ฅํด์ผ ํ๋ ์ํฉ์ด๋ผ๋ฉด .toString() ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฑฐ๋ ์ฌ๋ณผ์ .description ํ๋กํผํฐ๋ฅผ ์ด์ฉํ ์ ์๊ฒ ์ต๋๋ค.
'์จ๊น' ํ๋กํผํฐ
์ฌ๋ณผ์ ์ฌ์ฉํ๋ฉด ์จ๊น ํ๋กํผํฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์จ๊น ์ฒ๋ฆฌ๋ฅผ ํตํด ์ธ๋ถ ์ฝ๋์์ ์ ๊ทผ ๋ฐ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๋๋ก ๋ง๋๋ ๊ฒ์ด์ฃ . ์์๋ฅผ ํตํด ์จ๊น ํ๋กํผํฐ๋ฅผ ๋ง๋ค์ด ๋ด ์๋ค.
let user = {
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // ์ฌ๋ณผ์ ํค๋ก ์ฌ์ฉํด ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
user ๊ฐ์ฒด๊ฐ ์๋ํํฐ๋ก๋ถํฐ ๊ฐ์ ธ์ ์๋ก์ด ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ ์ ์๋ ์ํฉ์ด๋ผ ๊ฐ์ ํด๋ด ์๋ค.
์ด ๋ ์ฌ๋ณผ์ ์ฌ์ฉํ๋ค๋ฉด ์๋ํํฐ ์ฝ๋์์ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์, ์๋ํํฐ ์ฝ๋๊ฐ ๋ชจ๋ฅด๊ฒ user์ ์๋ณ์๋ฅผ ๋ถ์ฌํ ์ ์์ต๋๋ค.
์ฌ๋ณผ์ ์ ์ผ์ฑ์ด ๋ณด์ฅ๋๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์๋ณ์์ ์ 3์ ์คํฌ๋ฆฝํธ์์ ๋ง๋ ์๋ณ์๊ฐ ์ถฉ๋ํ์ง ์์ต๋๋ค. ์ด๋ฆ์ด ๊ฐ๋๋ผ๋ ๋ง์ด์ฃ .
let user = { name: "John" };
// ๋ฌธ์์ด "id"๋ฅผ ์ฌ์ฉํด ์๋ณ์๋ฅผ ๋ง๋ค์์ต๋๋ค.
user.id = "์คํฌ๋ฆฝํธ id ๊ฐ";
// ๋ง์ฝ ์ 3์ ์คํฌ๋ฆฝํธ๊ฐ ์ฐ๋ฆฌ ์คํฌ๋ฆฝํธ์ ๋์ผํ๊ฒ ๋ฌธ์์ด "id"๋ฅผ ์ด์ฉํด ์๋ณ์๋ฅผ ๋ง๋ค์๋ค๋ฉด...
user.id = "์ 3 ์คํฌ๋ฆฝํธ id ๊ฐ"
// ์๋์น ์๊ฒ ๊ฐ์ด ๋ฎ์ด ์ฐ์ฌ์ ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์๋ณ์๋ ๋ฌด์๋ฏธํด์ง๋๋ค.
๋ง์ฝ ์ฌ๋ณผ ๋์ ๋ฌธ์์ด "id"๋ฅผ ์ฌ์ฉํด ์๋ณ์๋ฅผ ๋ง๋ค์๋ค๋ฉด ๊ธฐ์กด ๊ฐ๊ณผ์ ์ถฉ๋์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ์ฌ๋ณผ์ ์ฌ์ฉํ๋ ์ด์ ์
๋๋ค.
๋ํ ์ฌ๋ณผ์ for in์์๋ ๋ฐฐ์ ๋์ด ์ฌ๋ณผ ๊ทธ ์์ฒด๋ก ์จ๊น ํ๋กํผํฐ์ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๋ฟ๋ง ์๋๋ผ Object.keys(user)์์๋ ํค๊ฐ ์ฌ๋ณผ์ธ ํ๋กํผํฐ๋ ๋ฐฐ์ ๋ฉ๋๋ค. '์ฌ๋ณผํ ํ๋กํผํฐ ์จ๊ธฐ๊ธฐ(hiding symbolic property)'๋ผ ๋ถ๋ฆฌ๋ ์ด๋ฐ ์์น ๋๋ถ์ ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ๋ณผํ ํค๋ฅผ ๊ฐ์ง ํ๋กํผํฐ์ ์ ๊ทผํ์ง ๋ชปํฉ๋๋ค.
But, Object.assgin์ ํค๊ฐ ์ฌ๋ณผ์ธ ํ๋กํผํฐ๋ฅผ ํฌํจํ ๋ชจ๋ ํ๋กํผํฐ๋ฅผ ๋ณต์ฌํฉ๋๋ค.
let id = Symbol("id");
let user = {
[id]: 123
};
let clone = Object.assign({}, user);
alert( clone[id] ); // 123
์ถ๊ฐ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ ํ์ ์ฌ๋ณผ์ ์ถ๊ฐํ๊ธฐ๋ณด๋ค, ๊ฐ์ฒด ์์ฑ ๊ณผ์ ์์ ์ฌ๋ณผ์ ํ๋กํผํฐ๋ก ๋ฃ๊ณ ์ถ๋ค๋ฉด [] ๋๊ดํธ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // "id": 123์ ์๋จ
};
Symbol.for() - ์ ์ญ ์ฌ๋ณผ ์์ฑ
// ์ ์ญ ๋ ์ง์คํธ๋ฆฌ์์ ์ฌ๋ณผ์ ์ฝ์ต๋๋ค.
let id = Symbol.for("id"); // ๋ง์ฝ "id"์ด๋ฆ์ ์ฌ๋ณผ์ด ์ ์ญ ๋ ์ง์คํธ๋ฆฌ์ ์กด์ฌํ์ง ์์ผ๋ฉด ์๋ก์ด ์ฌ๋ณผ์ ๋ง๋ญ๋๋ค.
// ๋์ผํ ์ด๋ฆ์ ์ด์ฉํด ์ฌ๋ณผ์ ๋ค์ ์ฝ์ต๋๋ค(์ข ๋ ๋ฉ๋ฆฌ ๋จ์ด์ง ์ฝ๋์์๋ ๊ฐ๋ฅํฉ๋๋ค).
let idAgain = Symbol.for("id");
// ๋ ์ฌ๋ณผ์ ๊ฐ์ต๋๋ค.
alert( id === idAgain ); // true
์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉํด์ผ ํ๋ ์ฌ๋ณผ์ด๋ผ๋ฉด ์ ์ญ ์ฌ๋ณผ์ ์ฌ์ฉํ๋ฉด ๋๊ฒ ์ต๋๋ค.
Symbol.keyFor() - ์ ์ญ ์ฌ๋ณผ์ ์ด๋ฆ get
Symbol.for๊ณผ ๋ฐ๋๋ก ์ฌ๋ณผ์ ์ด์ฉํด ์ฌ๋ณผ์ ์ด๋ฆ์ getํ ์ ์๋ ํจ์๊ฐ ๋ฐ๋ก keyFor()์ ๋๋ค.
// ์ด๋ฆ์ ์ด์ฉํด ์ฌ๋ณผ์ ์ฐพ์
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");
// ์ฌ๋ณผ์ ์ด์ฉํด ์ด๋ฆ์ ์ป์
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
์ ์ญ ์ฌ๋ณผ์ด ์๋ ๋ชจ๋ ์ฌ๋ณผ์ description ํ๋กํผํฐ๊ฐ ์์ต๋๋ค. ๋ง์ฝ ์ ์ญ์ฌ๋ณผ์ด ์๋ ์ผ๋ฐ ์ฌ๋ณผ์์ ์ด๋ฆ์ ์ป๊ณ ์ถ์ผ๋ฉด description ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
let localSymbol = Symbol("name");
alert( localSymbol.description ); // name
์์คํ ์ฌ๋ณผ
'์์คํ ์ฌ๋ณผ(system symbol)'์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ด๋ถ์์ ์ฌ์ฉ๋๋ ์ฌ๋ณผ์ ๋๋ค. ์์คํ ์ฌ๋ณผ์ ํ์ฉํ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฏธ์ธ ์กฐ์ ํ ์ ์์ต๋๋ค.
- Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.toPrimitive ๊ธฐํ ๋ฑ๋ฑ
8. ๊ฐ์ฒด๋ฅผ ์์ํ์ผ๋ก ๋ณํ
JS์์๋ ๊ฐ์ฒด๋ฅผ ํ๋ณํํ๋ ๊ฒฝ์ฐ "hint"๋ผ๊ณ ํ๋ ๊ธฐ์ค ๊ฐ์ ์ํด ํ๋ณํ์ด ์ผ์ด๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ์ฒด๋ฅผ console๋ก ์ถ๋ ฅํ๋ ค ํ๋ค๊ณ ํด๋ด ์๋ค. ์ด ๊ฒฝ์ฐ์๋์ด "hint"์ ์ํด ์๋์ผ๋ก string์ผ๋ก ํ๋ณํ์ด ์ผ์ด๋ฉ๋๋ค. hint์ ์ข ๋ฅ์๋ string, number, default ์ด 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
ํ๋์ฉ ์์๋ด ์๋ค.
string
let user = {
name : 'kim'
};
console.log(user); // string์ผ๋ก ํ๋ณํ
console.log ๋ฉ์๋๋ ๋งค๊ฐ๋ณ์๋ก ์ค๋ ๊ฐ์ฒด๋ค์ string์ผ๋ก ๋ณํํ์ฌ ์ฝ์์ ์ถ๋ ฅํฉ๋๋ค. ๊ฐ์ฒด๋ฅผ ์์ํ์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์์ "hint"๊ฐ string์ด ๋ฉ๋๋ค.
number
๊ฐ์ฒด๊ฐ ์ฐ์ฐ์ ์๋ํ๋ ๊ฒฝ์ฐ ๊ฐ์ฒด์ hint๋ number๊ฐ ๋ฉ๋๋ค.
const people = {
age: 24,
name: 'James'
}
const now = Date.now();
const someday = new Date('2024-09-27');
const num = +people; // ๊ฐ์ฒด -> ์ซ์ํ ๋ณํ
const day = now - someday; // ๋ ๋ ์ง๊ฐ์ ์ฐจ์ด
console.log(num, day); // NaN, 93788797
default
์ฐ์ฐ์๊ฐ ๊ธฐ๋ํ๋ ์๋ฃํ์ด ํ์คํ์ง ์์ ๋๋ 'hint'๊ฐ default ๊ฐ ๋ฉ๋๋ค. ์ดํญ ๋ง์ ์ฐ์ฐ์ + ๋ ํผ์ฐ์ฐ์์ ์๋ฃํ์ ๋ฐ๋ผ "๋ฌธ์์ด์ ํฉ์น๋ ์ฐ์ฐ"์ ํ ์๋, "์ซ์๋ฅผ ๋ํด์ฃผ๋ ์ฐ์ฐ"์ ํ ์๋ ์์ต๋๋ค. ๋ฐ๋ผ์ +์ ์ธ์๊ฐ "๊ฐ์ฒด"์ผ ๋๋ hint๊ฐ default๊ฐ ๋ฉ๋.
๋ฟ๋ง ์๋๋ผ ๋๋ฑ์ฐ์ฐ์ == ๋ํ ๊ฐ์ฒด-๋ฌธ์ํ, ๊ฐ์ฒด-์ซ์ํ, ๊ฐ์ฒด-์ฌ๋ณผํ๋ผ๋ฆฌ ๋น๊ตํ ๋๋ ๊ฐ์ฒด๋ฅผ ์ด๋ค ์๋ฃํ์ผ๋ก ๋ฐ๊ฟ์ผ ํ ์ง ๋ช ํํ์ง ์์ผ๋ฏ๋ก hint ๊ฐ default ๊ฐ ๋ฉ๋๋ค.
// ์ดํญ ๋ง์
์ฐ์ฐ์ hint๋ก `default`๋ฅผ ์ฌ์ฉํฉ๋๋ค.
let total = obj1 + obj2;
// obj == number ์ฐ์ฐ์ hint๋ก `default`๋ฅผ ์ฌ์ฉํฉ๋๋ค.
if (user == 1) { ... };
"boolean" hint๋ ์์ต๋๋ค.
hint๋ ์ด ์ธ ๊ฐ์ง์ ๋๋ค. ์์ฃผ ๊ฐ๋จํ์ฃ .‘boolean’ hint๋ ์กด์ฌํ์ง ์์ต๋๋ค.
๋ชจ๋ ๊ฐ์ฒด๋ ๊ทธ๋ฅ true๋ก ํ๊ฐ๋ฉ๋๋ค.
Symbol.toPrimitive
์๋ฐ์คํฌ๋ฆฝํธ์ Symbol.toPrimitive๋ผ๋ ๋ด์ฅ ์ฌ๋ณผ์ด ์กด์ฌํ๋๋ฐ, ์ด ์ฌ๋ณผ์ ์๋์ ๊ฐ์ด ๋ชฉํ๋ก ํ๋ ์๋ฃํ(hint)์ ๋ด ์ ๋ง๋๋ก ๋ค๋ฃฐ ์ ์์ต๋๋ค.
let user = {
name : 'John',
money : 10000,
[Symbol.toPrimitive](hint) {
console.log(`hint: ${hint}`);
return hint == "string" ? `{name: "${this.name}"}` : this.money;
}
}
console.log(user); // hint ๊ฐ string์ด๋ฏ๋ก return {name: ${this.name}}
console.log(+user); // hint ๊ฐ string์ด ์๋๋ฏ๋ก return this.money
console.log(user + 500); // hint ๊ฐ string์ด ์๋๋ฏ๋ก return this.money
์ด๋ ๊ฒ ๋ฉ์๋๋ฅผ ๊ตฌํํด ๋์ผ๋ฉด user๋ hint์ ๋ฐ๋ผ (์๊ธฐ ์์ ์ ์ค๋ช ํด์ฃผ๋) ๋ฌธ์์ด๋ก ๋ณํ๋๊ธฐ๋ ํ๊ณ (๊ฐ์ง๊ณ ์๋ ๋์ ์ก์๋ฅผ ๋ํ๋ด๋) ์ซ์๋ก ๋ณํ๋๊ธฐ๋ ํฉ๋๋ค. user[Symbol.toPrimitive]๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์๋ ํ๋๋ก ๋ชจ๋ ์ข ๋ฅ์ ํ ๋ณํ์ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
toString(), valueOf()
Symbol.toPrimitive์ ์ฌ์ฉํ์ง ์๊ณ ๋ ํ๋ณํ ํ ์ ์์ต๋๋ค. ๋ฐ๋ก toString()๊ณผ valueOf()๋ฅผ ์ฌ์ฉํด์ ๋ง์ด์ฃ .
๊ฐ์ฒด-์์ํ ๋ณํ์ ๋ค์๊ณผ ๊ฐ์ ์๊ณ ๋ฆฌ์ฆ์ ์ํด ๋์ํฉ๋๋ค.
๊ฐ์ฒด์ Symbol.toPrimitive๊ฐ ์์ผ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ ์๋ ๊ท์น์ ๋ฐ๋ผ toString์ด๋ valueOf๋ฅผ ํธ์ถํฉ๋๋ค.
- hint๊ฐ 'string’์ธ ๊ฒฝ์ฐ: toString -> valueOf ์(toString์ด ์๋ค๋ฉด toString์ ํธ์ถ, toString์ด ์๋ค๋ฉด valueOf๋ฅผ ํธ์ถํจ)
- ๊ทธ ์ธ(number, default) : valueOf -> toString ์ ํธ์ถ
๋ฐ๋ผ์ ์ด hint๊ฐ string์ธ ๊ฒฝ์ฐ์๋ toString(), number๋ default์ธ ๊ฒฝ์ฐ์๋ valueOf() ๋ฉ์๋์ ์ด๋ป๊ฒ ์์ํ์ ์ผ๋ก ๋ณํํ ์ง ๋ณํ ๋ฐฉ๋ฒ์ ์์ฑํ๋ฉด ๋๊ฒ ์ต๋๋ค.
let user = {
name: "John",
money: 1000,
// hint๊ฐ "string"์ธ ๊ฒฝ์ฐ
toString() {
return `{name: "${this.name}"}`;
},
// hint๊ฐ "number"๋ "default"์ธ ๊ฒฝ์ฐ
valueOf() {
return this.money;
}
};
alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500
๊ฐํน ๋ชจ๋ ํ ๋ณํ์ ํ ๊ณณ์์ ์ฒ๋ฆฌํด์ผ ํ๋ ๊ฒฝ์ฐ (hint๊ฐ number๋ string์ด๋ default๋ ์๊ด์์ด ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ณํํ๊ณ ์ ํ๋ ๊ฒฝ์ฐ) ์๋ toString()๋ง ๊ตฌํํด์ฃผ๋ฉด ๋๊ฒ ์ต๋๋ค.
(Symbol.toPrimitive์ valueOf๊ฐ ๋ชจ๋ ์์ผ๋ฉด toString์ด ๋ชจ๋ ํ๋ณํ์ ์ฑ ์์ง๊ธฐ ๋๋ฌธ์ด์ฃ .)
let user = {
name: "John",
toString() {
return this.name;
}
};
alert(user); // toString -> John
alert(user + 500); // toString -> John500
๋ฒ์ธ : ์ถ๊ฐ ํ๋ณํ
์์ ๊ฐ์ด toString()๋ง ์์ฑํ ๊ฒฝ์ฐ ์๋ ์ฝ๋๋ ๊ฐ๊ฐ ์ด๋ป๊ฒ ๋์ํ ๊น์?
let obj = {
toString() {
return "2";
}
};
alert(obj + 2); // (1)
let obj = {
toString() {
return "2";
}
};
alert(obj * 2); // (2)
(1) : toString()์ ๊ธฐ๋ณธ์ ์ผ๋ก hint๊ฐ 'string'์ ๋๋ค. ๋ฐ๋ผ์ ๋ฌธ์์ด ๋ณํฉ์ ์ฐ์ ์์๋ก ๋๊ฒ ์ฃ . ๊ฒฐ๊ณผ๋ 22์ ๋๋ค.
(2) : toString()์ ์ํด obj๊ฐ ๋ฌธ์์ด "2"๊ฐ ๋ฉ๋๋ค. ๊ทธ๋ ๋ด "2" * 2๊ฐ ๋๊ณ ์ด๊ฒ์ ๋ค์ 2 * 2๋ก ๋ณํ๋์ด ๊ฒฐ๊ณผ๋ 4๊ฐ ๋๊ฒ ์ต๋๋ค.
์ฌ์ค obj.toString()๋ง ์ฌ์ฉํด๋ '๋ชจ๋ ๋ณํ’์ ๋ค ๋ค๋ฃฐ ์ ์๊ธฐ ๋๋ฌธ์, ์ค๋ฌด์์ obj.toString()๋ง ๊ตฌํํด๋ ์ถฉ๋ถํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๊ทธ๋ ์ง๋ง Symbol.toPrimitive๋ก๋ ๊ฐ hint๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค๋ ์ . valueOf()๋ก number, default๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค๋ ์ ์ ๊ธฐ์ตํฉ์๋ค.
9. ํ๋กํผํฐ Flag์ ์ค๋ช ์
์ง๊ธ๊น์ง๋ ํ๋กํผํฐ๋ฅผ ๋จ์ํ key-value ๊ด์ ์์๋ง ๋ค๋ค์ต๋๋ค. ํ์ง๋ง ํ๋กํผํฐ๋ ์๊ฐ๋ณด๋ค ๋ ์ ์ฐํ๊ณ ๊ฐ๋ ฅํ ๊ตฌ์กฐ์ธ๋ฐ์.
์ด๋ฒ์๋ ๊ฐ์ฒด ํ๋กํผํฐ ์ถ๊ฐ ๊ตฌ์ฑ ์ต์ ๋ช ๊ฐ์ง๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.
ํ๋กํผํฐ Flag
- writable : true ๋ฉด ํด๋น ํ๋กํผํฐ์ ๊ฐ์ ์์ ํ ์ ์์ต๋๋ค. false์ธ ๊ฒฝ์ฐ ์ฝ๊ธฐ(get)๋ง ๊ฐ๋ฅํฉ๋๋ค.
- enumerable : true ๋ฉด ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํด ๋์ดํ ์ ์์ต๋๋ค. false์ธ ๊ฒฝ์ฐ ๋ฐ๋ณต๋ฌธ์ ํฌํจ๋์ง ์์ต๋๋ค.
- configurable : true ๋ฉด ํ๋กํผํฐ ์ญ์ ๋ ํ๋๊ทธ ์์ ์ด ๊ฐ๋ฅํฉ๋๋ค. false์ธ ๊ฒฝ์ฐ ์ญ์ , ์์ ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ flag๋ default๋ก true๋ก ์ค์ ๋์ด ์์ต๋๋ค.
ํ๋กํผํฐ์ flag ์ ๋ณด๋ Object.getOwnPropertyDescriptor๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํน์ ํ๋กํผํฐ์ ๋ํ ์ ๋ณด๋ฅผ ๋ชจ๋ ์ป์ ์ ์์ต๋๋ค.
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
let user = {
name: "John"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
alert( JSON.stringify(descriptor, null, 2 ) );
/* property descriptor:
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
*/
๋ฉ์๋ Object.defineProperty๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋๊ทธ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
let user = {
name: "John"
};
Object.defineProperty(user, "name", {
writable: false
});
Object.defineProperties(obj, descriptors) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋กํผํฐ ์ฌ๋ฌ ๊ฐ๋ฅผ ํ ๋ฒ์ ์ ์ํ ์ ์์ต๋๋ค.
Object.defineProperties(user, {
name: { value: "John", writable: false },
surname: { value: "Smith", writable: false },
// ...
});
Object.getOwnPropertyDescriptors(obj) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋กํผํฐ ์ค๋ช ์๋ฅผ ์ ๋ถ ํ๊บผ๋ฒ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ด ๋ฉ์๋๋ฅผ Object.defineProperties์ ํจ๊ป ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด ๋ณต์ฌ ์ ํ๋๊ทธ๋ ํจ๊ป ๋ณต์ฌํ ์ ์์ต๋๋ค. ( for๋ฌธ์ ํตํด ๊น์ ๋ณต์ฌ๋ฅผ ํ๋ค๊ณ ํด์ ํ๋กํผํฐ์ ํ๋๊ทธ๊น์ง ๋ณต์ฌ๋์ง๋ ์์ต๋๋ค. )
let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
์ด ์ธ์๋ ๊ฐ์ฒด ์์ ์ ๋ง์์ฃผ๋ ๋ค์ํ ๋ฉ์๋๋ค์ด ์์ต๋๋ค. ์ ์ฌ์ฉ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฐ๊ฒ ์๊ตฌ๋ ์ ๋๋ก ๋ณด๋ฉด ๋๊ฒ ์ต๋๋ค.
- Object.preventExtensions(obj)
- ๊ฐ์ฒด์ ์๋ก์ด ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ ์ ์๊ฒ ํฉ๋๋ค.
- Object.seal(obj)
- ์๋ก์ด ํ๋กํผํฐ ์ถ๊ฐ๋ ๊ธฐ์กด ํ๋กํผํฐ ์ญ์ ๋ฅผ ๋ง์์ค๋๋ค. ํ๋กํผํฐ ์ ์ฒด์ configurable: false๋ฅผ ์ค์ ํ๋ ๊ฒ๊ณผ ๋์ผํ ํจ๊ณผ์ ๋๋ค.
- Object.freeze(obj)
- ์๋ก์ด ํ๋กํผํฐ ์ถ๊ฐ๋ ๊ธฐ์กด ํ๋กํผํฐ ์ญ์ , ์์ ์ ๋ง์์ค๋๋ค. ํ๋กํผํฐ ์ ์ฒด์ configurable: false, writable: false๋ฅผ ์ค์ ํ๋ ๊ฒ๊ณผ ๋์ผํ ํจ๊ณผ์ ๋๋ค.
์๋ ๋ฉ์๋๋ ์ ์ธ ๊ฐ์ง ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์ค์ ํ ์ ์ฝ์ฌํญ์ ํ์ธํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- Object.isExtensible(obj)
- ์๋ก์ด ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ false๋ฅผ, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ true๋ฅผ ๋ฐํํฉ๋๋ค.
- Object.isSealed(obj)
- ํ๋กํผํฐ ์ถ๊ฐ, ์ญ์ ๊ฐ ๋ถ๊ฐ๋ฅํ๊ณ ๋ชจ๋ ํ๋กํผํฐ๊ฐ configurable: false์ด๋ฉด true๋ฅผ ๋ฐํํฉ๋๋ค.
- Object.isFrozen(obj)
- ํ๋กํผํฐ ์ถ๊ฐ, ์ญ์ , ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๊ณ ๋ชจ๋ ํ๋กํผํฐ๊ฐ configurable: false, writable: false์ด๋ฉด true๋ฅผ ๋ฐํํฉ๋๋ค.
10. Getter & Setter
๊ฐ์ฒด์ ํ๋กํผํฐ๋ ํฌ๊ฒ ๋ ์ข ๋ฅ๋ก ๋๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ํ๋กํผํฐ : ์ง๊ธ๊น์ง ์ฌ์ฉํ key-value ์์ ๋ฐ์ดํฐ. ์ด ๋ฐ์ดํฐ ํ๋กํผํฐ๋ฅผ ์กฐ์ํ๋ ํ๋กํผํฐ flag๋ฅผ ์์์ ๋ค๋ฃจ์์.
- ์ ๊ทผ์ ํ๋กํผํฐ : getter์ setter.
JS์์ Getter์ Setter๋ get๊ณผ set์ผ๋ก ๋ํ๋ผ ์ ์์ต๋๋ค.
let user = {
name : 'kim',
get name() {
...
},
set name(value) {
...
}
};
getter ๋ฉ์๋๋ user.name์ ์ฌ์ฉํด ํ๋กํผํฐ๋ฅผ ์ฝ์ผ๋ ค๊ณ ํ ๋ ์คํ๋๊ณ , setter ๋ฉ์๋๋ user.name = value๋ก ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๋ ค ํ ๋ ์คํ๋ฉ๋๋ค.
console.log(user.name); // name Getter ์คํ
user.name = 'park'; // name Setter ์คํ
๊ทธ๋ ๋ค๋ฉด get๊ณผ set์ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ ํ๋กํผํฐ์ ๋ํด์๋ง ์์ฑํ ์ ์์๊น์? ๊ทธ๋ ์ง ์์ต๋๋ค.
์๋์ฒ๋ผ getter์ setter ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๊ฐ์ฒด์ fullName์ด๋ผ๋ '๊ฐ์’์ ํ๋กํผํฐ๊ฐ ์๊น๋๋ค. ๊ฐ์์ ํ๋กํผํฐ๋ ์ฝ๊ณ ์ธ ์ ์์ง๋ง ์ค์ ๋ก๋ ์กด์ฌํ์ง ์์ต๋๋ค.
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
};
alert(user.fullName); // John Smith
user.fullName = "Test"; // Error (ํ๋กํผํฐ์ getter ๋ฉ์๋๋ง ์์ด์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.)
Getter & Setter ์ค๋ช ์
์ ๊ทผ์ ํ๋กํผํฐ์ธ getter, setter์๋ ํ๋กํผํฐ flag๊ฐ ์์ต๋๋ค.
๋ฐ์ดํฐ ํ๋กํผํฐ flag์ value์ writable์ด ์๋ ๋์ get๊ณผ set์ด๋ผ๋ ํจ์๊ฐ ์์ต๋๋ค.
- get – ์ธ์๊ฐ ์๋ ํจ์๋ก, ํ๋กํผํฐ๋ฅผ ์ฝ์ ๋ ๋์ํจ
- set – ์ธ์๊ฐ ํ๋์ธ ํจ์๋ก, ํ๋กํผํฐ์ ๊ฐ์ ์ธ ๋ ํธ์ถ๋จ
- enumerable – ๋ฐ์ดํฐ ํ๋กํผํฐ์ ๋์ผํจ
- configurable – ๋ฐ์ดํฐ ํ๋กํผํฐ์ ๋์ผ
๋ฐ๋ผ์ ์๋์ ๊ฐ์ด defineProperty์ ์ค๋ช ์ get๊ณผ set์ ์ ๋ฌํ๋ฉด fullName์ ์ํ ์ ๊ทผ์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
let user = {
name: "John",
surname: "Smith"
};
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
alert(user.fullName); // John Smith
for(let key in user) alert(key); // name, surname
์ฃผ์ํ ์ ์ผ๋ก๋ ํ๋กํผํฐ๋ ์ ๊ทผ์ ํ๋กํผํฐ(get/set ๋ฉ์๋๋ฅผ ๊ฐ์ง)๋ ๋ฐ์ดํฐ ํ๋กํผํฐ(value๋ฅผ ๊ฐ์ง) ์ค ํ ์ข
๋ฅ์๋ง ์ํ๊ณ ๋ ๋ค์ ์ํ ์ ์๋ค๋ ์ ์ ํญ์ ์ ์ํ์๊ธฐ ๋ฐ๋๋๋ค.
๋ฐ๋ผ์ ํ ํ๋กํผํฐ์ get๊ณผ value๋ฅผ ๋์์ ์ค์ ํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
// Error: Invalid property descriptor.
Object.defineProperty({}, 'prop', {
get() {
return 1
},
value: 2
});
getter, setter ํ์ฉํ๊ธฐ
getter, setter๋ฅผ ํ์ฉํ์ฌ ํ๋กํผํฐ์ ๊ฐ์ ์ํ๋๋๋ก ํต์ ํ ์ ์์ต๋๋ค.
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("์
๋ ฅํ์ ๊ฐ์ด ๋๋ฌด ์งง์ต๋๋ค. ๋ค ๊ธ์ ์ด์์ผ๋ก ๊ตฌ์ฑ๋ ์ด๋ฆ์ ์
๋ ฅํ์ธ์.");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // ๋๋ฌด ์งง์ ์ด๋ฆ์ ํ ๋นํ๋ ค ํจ
user์ ์ด๋ฆ์ _name์ ์ ์ฅ๋๊ณ , ํ๋กํผํฐ์ ์ ๊ทผํ๋ ๊ฒ์ getter์ setter๋ฅผ ํตํด ์ด๋ค์ง๋๋ค.
๊ธฐ์ ์ ์ผ๋ก ์ธ๋ถ ์ฝ๋์์ user._name์ ์ฌ์ฉํด ์ด๋ฆ์ ๋ฐ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
์ด ๋ ๋ฐ์ค "_" ๋ก ์์ํ๋ ํ๋กํผํฐ๋ ๊ฐ์ฒด ๋ด๋ถ์์๋ง ํ์ฉํ๊ณ , ์ธ๋ถ์์๋ ๊ฑด๋๋ฆฌ์ง ์๋ ๊ฒ(getterํ๋ค๊ฑฐ๋ setterํ์ง ์๋ ๊ฒ)์ด ๊ด์ต์ ๋๋ค.
์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ํ์ฉํ์ฌ OCP ์งํค๊ธฐ
๋ง์ฝ ์๋์ ๊ฐ์ ๊ธฐ์กด ์ฝ๋๊ฐ ์กด์ฌํ ๋,
function User(name, age) {
this.name = name;
this.age = age;
}
let john = new User("John", 25);
alert( john.age ); // 25
age ํ๋กํผํฐ ๋์ birthday ํ๋กํผํฐ๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค๋ ์๊ตฌ์ฌํญ์ ๋ณ๊ฒฝ์ด ์ผ์ด๋ฌ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
age ํ๋กํผํฐ๋ ์ญ์ ํ์ง ์์์ผ ํ๋ค๊ณ ํ ๋, ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์์ฑํ๋ฉด ์ข์๊น์?
์๋ ์ฝ๋๊ฐ ๊ทธ ์ ๋ต์ ๋๋ค.
function User(name, birthday) {
this.name = name;
this.birthday = birthday;
Object.defineProperty(this, 'age', {
get() {
let nowYear = new Date().getFullYear();
return nowYear - this.birthday.getFullYear();
},
});
}
let john = new User('John', new Date(1992, 6, 1));
console.log(john.age);
console.log(john.birthday);
์ด์ ๊ธฐ์กด ์ฝ๋๋ ์ ์๋ํ๊ณ , ํ๋กํผํฐ๋ ์๊ฒผ๋ค์. ์ด๋ ๊ฒ ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ์ ํ์ฉํ๋ฉด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ํ์ฅํ์ฌ OCP๋ฅผ ์งํฌ ์ ์๋ต๋๋ค.
์ด๋ ๊ฒ JS์ Object์ ๋ํด ์์๋ณด์์ต๋๋ค. ๊ธฐ์กด์ ์ฌ์ฉํ๋ OOP ์ธ์ด์ ๋น์ทํ ์ ๋ ๋ง๊ณ , ์๋ก์ด ์ ๋ ๋ง์ ๊ฒ ๊ฐ์ต๋๋ค.
ํนํ ๊ฐ๊ฐ์ ํ๋กํผํฐ์ ๋ํด Object.defineProperty()๋ฅผ ํตํด getter์ setter๋ฅผ ์ ์ดํ๋ค๋ ์ ์ด ์บก์ํ ์ธก๋ฉด์์ Java์๋ ๋ฐฉ์์ด ๋ฌ๋ผ ํฅ๋ฏธ๋ก์ ์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ์ ๊ทผ ๋ฐฉ์์ ๋ณด๋ค ์ ์ฐํ๊ณ ์ธ๋ฐํ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ์ง๋ง, ์๋ฐ์ ์บก์ํ๋ private, protected, public ๊ฐ์ ์ ๊ทผ ์ ์ด์๋ฅผ ์ฌ์ฉํด ํด๋์ค ๋ด ๋ฉค๋ฒ(ํ๋, ๋ฉ์๋ ๋ฑ)์ ์ ๊ทผ ๊ถํ์ ๋ช ํํ๊ฒ ์ ์ดํ์ฌ ์์ ์ ์ด๊ณ ์๊ฒฉํ ๋ฐ์ดํฐ ๋ณดํธ๋ฅผ ์ ๊ณตํ๋ ์ ์์ ์ฐจ์ด๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์ ํฌ์คํ ์์๋ ์ด์ด ๊ฐ์ฒด์ ๊ด๋ จ ๊น์ JS์ ํด๋์ค์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
'๐ Frontend > JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ] - ํด๋์ค(class) ๊ธฐ๋ณธ ๋ฌธ๋ฒ (3) | 2024.09.28 |
---|---|
[๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ] - JavaScript ๊ธฐ๋ณธ ๋ฌธ๋ฒ (7) | 2024.09.24 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422