๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive ๋์์ 16์ฅ์ ์ ๋ฆฌํ์์ต๋๋ค.
๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฉ์๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๊ตฌํ ์๊ณ ๋ฆฌ์ฆ์ ์ค๋ช
ํ๊ธฐ ์ํด ECMAScript ์ฌ์์์ ์ฌ์ฉํ๋ ์์ฌ ํ๋กํผํฐ์ ์์ฌ ๋ฉ์๋์ด๋ค. ECMAScript ์ฌ์์ ์์ฃผ ๋ฑ์ฅํ๋ ์ด์ค ๋๊ดํธ [[...]]
๋ก ๊ฐ์ผ ์ด๋ฆ๋ค์ด ๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฉ์๋์ด๋ค.
๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฉ์๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๋ด๋ถ ๋ก์ง์ด๋ฏ๋ก ์์น์ ์ผ๋ก JS๋ ๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฌด์ธ๋์ ์ง์ ์ ์ผ๋ก ์ ๊ทผ, ํธ์ถํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง ์๋๋ค. ๋จ, ์ผ๋ถ ๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฉ์๋์ ํํ์ฌ ๊ฐ์ ์ ์ผ๋ก ์ ๊ทผํ ์ ์๋ ์๋จ์ด ์๋ค.
const o = {};
o.[[Prototype]] // ์ง์ ์ ๊ทผ ๋ถ๊ฐ
o.__proto__ //Object.prototype
์์ ๊ฐ์ [[ProtoType]] ์ด๋ผ๋ ๋ด๋ถ ์ฌ๋กฏ ์์์ฒ๋ผ ์ง์ ์ ๊ทผ์ ๋ชปํ์ง๋ง ๊ฐ์ ์ ์ผ๋ก ์ ๊ทผ ํ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํ๋กํผํฐ๋ฅผ ์์ฑํ ๋ ํ๋กํผํฐ์ ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ
๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์๋ ์ ์ํ๋ค.
ํ๋กํผํฐ์ ์ํ๋ง๋ค ๋ํ๋ด๋ ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ
์์ ๊ฐ์ ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ์ ์ง์ ์ ๊ทผํ ์ ์์ง๋ง Object.getOwnPropertyDescriptor ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ์ ์ผ๋ก ํ์ธํ ์๋ ์๋ค.
const person = {
name:'waterglasses'
}
console.log(Object.getOwnPropertyDescriptor(person, 'name'));
// {value : 'waterglasses', writagle, enumerable:true, configurable: true}
Object.getOwnPropertyDescriptor
ํ๋กํผํฐ ๋์คํฌ๋ฆฝํฐ ๊ฐ์ฒด
๋ฅผ ๋ฐํundefined
๋ฐํObject.getOwnPropertyDescriptors
ํ๋กํผํฐ ๋์คํฌ๋ฆฝํฐ ๊ฐ์ฒด๋ค
์ ๋ฐํํ๋กํผํฐ์ ๊ตฌ๋ถ
ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ | ํ๋กํผํฐ ๋์คํฌ๋ฆฝํฐ ๊ฐ์ฒด์ ํ๋กํผํฐ | ์ค๋ช |
---|---|---|
[[Value]] | value | - ํ๋กํผํฐ ํค๋ฅผ ํตํด ํ๋กํผํฐ ๊ฐ์ ์ ๊ทผํ๋ฉด ๋ฐํ๋๋ ๊ฐ |
[[Writable]] | writable | - ํ๋กํผํฐ ๊ฐ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ฉฐ ๋ถ๋ฆฌ์ธ ๊ฐ์ ๊ฐ์ง |
[[Enumerable]] | enumerable | - ํ๋กํผํฐ์ ์ด๊ฑฐ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ฉฐ ๋ถ๋ฆฌ์ธ ๊ฐ์ ๊ฐ์ง - false์ธ ๊ฒฝ์ฐ for ... in๋ฌธ์ด๋ Object.keys ๋ฑ์ผ๋ก ์ด๊ฑฐํ ์ ์๋ค. |
[[Configurable]] | configurable | - ํ๋กํผํฐ ์ฌ์ ์ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ฉฐ ๋ถ๋ฆฌ์ธ ๊ฐ์ ๊ฐ์ง |
ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ | ํ๋กํผํฐ ๋์คํฌ๋ฆฝํฐ ๊ฐ์ฒด์ ํ๋กํผํฐ | ์ค๋ช |
---|---|---|
[[Get]] | get | - ๋ฐ์ดํฐ ํ๋กํผํฐ๋ฅผ ํตํด ๋ฐ์ดํฐ ํ๋กํผํฐ์ ๊ฐ์ ์ฝ์ ๋ ํธ์ถ๋๋ ์ ๊ทผ์ ํจ์ |
[[Set]] | set | - ๋ฐ์ดํฐ ํ๋กํผํฐ๋ฅผ ํตํด ๋ฐ์ดํฐ ํ๋กํผํฐ์ ๊ฐ์ ์ ์ฅํ ๋ ํธ์ถ๋๋ ์ ๊ทผ์ ํจ์ |
[[Enumerable]] | enumerable | - ๋ฐ์ดํฐ ํ๋กํผํฐ์ [[Enumerable]]์ ๊ฐ๋ค. |
[[Configurable]] | configurable | - ๋ฐ์ดํฐ ํ๋กํผํฐ์ [[Configurable]]์ ๊ฐ๋ค. |
์ ๊ทผ์ ํจ์๋ getter/setter
ํจ์๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. ๋ ํจ์ ๋ชจ๋ ์ ์ํ ์ ์๊ณ ํ๋๋ง ์ ์ํ ์๋ ์๋ค.
const person = {
firstName: 'KilDong',
lastName: 'Hong',
//fullName์ ์ ๊ทผ์ ํจ์๋ก ๊ตฌ์ฑ๋ ์ ๊ทผ์ ํ๋กํผํฐ์ด๋ค.(getter ํจ์)
get fullName(){
return `${this.firstName} ${this.lastName}`;
},
//setter ํจ์
set fullName(name){
[this.firstName, this.lastname] = name.split(' ');
}
}
person.fullName = 'GilDong Hong';
console.log(person.fullName); //GilDong Hong
person ๊ฐ์ฒด์ firstName๊ณผ lastName ํ๋กํผํฐ๋ ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ ํ๋กํผํฐ์ด๋ค. ๋ฉ์๋ ์์ get
,set
๋ฉ์๋๋ getter
์ setter
ํจ์์ด๋ค. ์ฆ fullName์ด ์ ๊ทผ์ ํ๋กํผํฐ์ด๋ค.
๋ด๋ถ ์ฌ๋กฏ/๋ฉ์๋ ๊ด์ ์์ ๋ด๋ณด์
์ ๊ทผ์ ํ๋กํผํฐ fullName์ผ๋ก ํ๋กํผํฐ ๊ฐ์ ์ ๊ทผํ๋ฉด ๋ด๋ถ์ ์ผ๋ก [[Get]] ๋ด๋ถ ๋ฉ์๋๊ฐ ํธ์ถ๋์ด ๋ค์๊ณผ ๊ฐ์ด ๋์ํ๋ค.
๋ฐ์ดํฐ ํ๋กํผํฐ ์ ์
const person = {};
Object.defineProperty(person, 'firstName',{
value: 'GilDong'
});
// ๋์คํฌ๋ฆฝํฐ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ๋๋ฝ์ํค๋ฉด undefined, false๊ฐ ๊ธฐ๋ณธ๊ฐ์ด๋ค.
console.log(Object.getOwnPropertyDescriptor(person, 'firstName'));
// {value:'GilDong', writable: false, ...}
์ ๊ทผ์ ํ๋กํผํฐ ์ ์
const person = {};
Object.defineProperty(person, 'fullName',{
get(){
return `${this.firstName} ${this.lastName}`;
},
set(name){
[this.firstName, this.lastname] = name.split(' ');
},
enumerable: true,
configurable: true
}
Object.defineProperties
๊ตฌ๋ถ | ๋ฉ์๋ | ํ๋กํผํฐ ์ถ๊ฐ | ํ๋กํผํฐ ์ญ์ | ํ๋กํผํฐ ๊ฐ ์ฝ๊ธฐ | ํ๋กํผํฐ ๊ฐ ์ฐ๊ธฐ | ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ ์ฌ์ ์ |
---|---|---|---|---|---|---|
๊ฐ์ฒด ํ์ฅ ๊ธ์ง | Object.preventExtensions | X | O | O | O | O |
๊ฐ์ฒด ๋ฐ๋ด | Object.seal | X | X | O | O | X |
๊ฐ์ฒด ๋๊ฒฐ | Object.freeze | X | X | O | X | X |
ํ๋กํผํฐ ์ถ๊ฐ ๊ธ์ง
๋ฅผ ์๋ฏธObject.preventExtensions
๋ฉ์๋๋ก ํ์ฅ์ ๊ธ์งObject.isExtensible
๋ฉ์๋๋ก ํ์ธObject.seal
๋ฉ์๋๋ก ๊ฐ์ฒด ๋ฐ๋ดObject.isSealed
๋ฉ์๋๋ก ํ์ธ ๊ฐ๋ฅObject.freeze
๋ฉ์๋๋ก ๊ฐ์ฒด ๋๊ฒฐObject.isFrozen
๋ฉ์๋๋ก ํ์ธํ ์ ์๋ค.const person {
name: 'GilDong',
address:{
{ city : 'Joseon' }
}
}
Object.freeze(person);
console.log(Object.isFrozen(person.address)); //false
person.address.city = 'Korea';
console.log(person); //{name : "GilDong", address: {city : "Korea"}}
๋ฐ๋ผ์ ์ค์ฒฉ ๊ฐ์ฒด๊น์ง ๋๊ฒฐํ์ฌ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๊ฐ์ฒด๋ฅผ ๊ฐ์ผ๋ก ๊ฐ๋ ๋ชจ๋ ํ๋กํผํฐ์ ๋ํด ์ฌ๊ท์ ์ผ๋ก Object.freeze ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ๋ค.
function deepFreeze(target){
// ๊ฐ์ฒด๊ฐ ์๋๊ฑฐ๋ ๋๊ฒฐ๋ ๊ฐ์ฒด๋ ๋ฌด์ํ๊ณ ๊ฐ์ฒด์ด๊ณ ๋๊ฒฐ๋์ง ์์ ๊ฐ์ฒด๋ง ๋๊ฒฐํจ!
if(target && typeof === 'object' && !Object.isFrozon(target)){
Object.freeze(target};
}
Object.keys(target).forEach(key => deepFreeze(target[key]));
return target;
}