์ด๋ฒ ํฌ์คํ ์์๋ ์๋ฐ์คํฌ๋ฆฝํธ Property Attribute์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ์ด ๊ธ์ ๋ชฉํ๋ Property Attribute์ ๊ฐ๋ ์ ์ดํดํ๊ณ , ๋ค์ํ ํ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฒ์ ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ค๋ฃจ๋ ๊ฐ๋ฐ์๋ผ๋ฉด ๊ผญ ์์์ผ ํ ์ค์ํ ๊ฐ๋ ์ด๋, ๋๊น์ง ์ฝ์ด์ฃผ์ธ์!
โฃ ๋ชฉ์ฐจ
์๋ฐ์คํฌ๋ฆฝํธ์ Property Attribute๋ฅผ ์ดํดํ๊ธฐ ์ ์ ๊ฐ์ฒด์ ๊ธฐ๋ณธ ๊ฐ๋
์ ๋จผ์ ํ์ธํด ์ฃผ์ธ์๐
01. Property Attribute๋?๐
Property Attribute๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ ์์ฑ์ ๋ํ ๋ฉํ๋ฐ์ดํฐ์ ๋๋ค. ์์ฑ์ด ์ด๋ป๊ฒ ๋์ํ๋์ง๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค. ํฌ๊ฒ ๋ ๊ฐ์ง๋ก ๋๋ฉ๋๋ค.
- Data Property Attributes (๋ฐ์ดํฐ ์์ฑ)
- Accessor Property Attributes (์ ๊ทผ์ ์์ฑ)
๊ฐ ์์ฑ์ ์ข ๋ฅ์ ์ญํ ์ ์์๋ณด๊ฒ ์ต๋๋ค.
02. Data Property Attributes๐พ
Data Property Attributes๋ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ์์ฑ์ ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์์ฑ๋ค์ด ์์ต๋๋ค.
1. ๊ฐ(Value)
- ์์ฑ์ ์ค์ ๊ฐ์ ๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์ undefined์ ๋๋ค.
2. Writable
- ์์ฑ์ ๊ฐ์ ์์ ํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค.
- true๋ก ์ค์ ๋๋ฉด ๊ฐ์ ์์ ํ ์ ์์ผ๋ฉฐ, false๋ก ์ค์ ๋๋ฉด ๊ฐ์ ์์ ํ ์ ์์ต๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
3. Enumerable
- ์์ฑ์ด ์ด๊ฑฐ ๊ฐ๋ฅํ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค.
- true๋ก ์ค์ ๋๋ฉด for...in ๋ฃจํ๋ Object.keys()์ ๊ฐ์ ๋ฉ์๋๋ฅผ ํตํด ์์ฑ์ ์ด๊ฑฐํ ์ ์์ต๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
4. Configurable
- ์์ฑ์ ์ ์๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ์์ฑ์ ์ญ์ ํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค.
- true๋ก ์ค์ ๋๋ฉด ์์ฑ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ญ์ ํ ์ ์์ผ๋ฉฐ, false๋ก ์ค์ ๋๋ฉด ๋ณ๊ฒฝํ๊ฑฐ๋ ์ญ์ ํ ์ ์์ต๋๋ค.
(๋จ, writable์ด true์ธ ๊ฒฝ์ฐ Value, Writable์ ๋ณ๊ฒฝํ๋ ๊ฑด ๊ฐ๋ฅ) - ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
let person = {
name: "John"
};
Object.defineProperty(person, 'age', {
value: 30,
writable: true,
enumerable: true,
configurable: true
});
console.log(person.age); // 30
03. Accessor Property Attributes ๐
Accessor Property Attributes๋ ๊ฐ์ ๊ฐ์ ธ์ค๊ฑฐ๋ ์ค์ ํ ๋ ํธ์ถ๋๋ ํจ์์ ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์์ฑ๋ค์ด ์์ต๋๋ค.
1. Get
- ์์ฑ์ ๊ฐ์ ์ฝ์ ๋ ํธ์ถ๋๋ ํจ์์ ๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์ undefined์ ๋๋ค.
2. Set
- ์์ฑ์ ๊ฐ์ ์ค์ ํ ๋ ํธ์ถ๋๋ ํจ์์ ๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์ undefined์ ๋๋ค.
let person = {
firstName: "John",
lastName: "Doe",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
}
};
console.log(person.fullName); // John Doe
person.fullName = "Jane Smith";
console.log(person.fullName); // Jane Smith
04. Property Attribute์ ํ์ฉ๐ ๏ธ
์๋ฐ์คํฌ๋ฆฝํธ์ Property Attributes๋ ๊ฐ์ฒด์ ์์ฑ์ ๋์ฑ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๊ฒ ํด ์ค๋๋ค. ์ด๋ฅผ ํ์ฉํ๋ฉด ๊ฐ์ฒด์ ๋์ ๋ฐฉ์์ ๋ง์ถคํํ๊ณ , ๋ณด์์ฑ ๋ฐ ์์ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ๋ค์์ Property Attributes์ ๋ค์ํ ํ์ฉ ์์ ์
๋๋ค.
Object.defineProperty()๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑ์ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค.
1. ๋ถ๋ณ ์์ฑ ๋ง๋ค๊ธฐ (์ฝ๊ธฐ ์ ์ฉ ์์ฑ)
์์ฑ์ ๊ฐ์ ํ ๋ฒ ์ค์ ํ ํ ๋ณ๊ฒฝ๋์ง ์๋๋ก ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด writable ์์ฑ์ false๋ก ์ค์ ํฉ๋๋ค.
const obj = {};
Object.defineProperty(obj, 'readOnly', {
value: 'This value cannot be changed',
writable: false,
enumerable: true,
configurable: true
});
console.log(obj.readOnly); // 'This value cannot be changed'
obj.readOnly = 'Trying to change value';
console.log(obj.readOnly); // ์ฌ์ ํ 'This value cannot be changed'
2. ์ด๊ฑฐ ๋ถ๊ฐ๋ฅํ ์์ฑ ๋ง๋ค๊ธฐ
์์ฑ์ for...in ๋ฃจํ๋ Object.keys() ๋ฉ์๋์์ ์ ์ธ์ํค๊ณ ์ถ์ ๋ enumerable ์์ฑ์ false๋ก ์ค์ ํฉ๋๋ค.
const obj = {};
Object.defineProperty(obj, 'hidden', {
value: 'This value is hidden from enumeration',
enumerable: false,
writable: true,
configurable: true
});
for (let key in obj) {
console.log(key); // ์ถ๋ ฅ๋์ง ์์
}
console.log(Object.keys(obj)); // ๋น ๋ฐฐ์ด ์ถ๋ ฅ
3. ์ญ์ ๋ถ๊ฐ๋ฅํ ์์ฑ ๋ง๋ค๊ธฐ
์์ฑ์ ์ญ์ ํ ์ ์๋๋ก ํ๊ธฐ ์ํด configurable ์์ฑ์ false๋ก ์ค์ ํฉ๋๋ค.
const obj = {};
Object.defineProperty(obj, 'permanent', {
value: 'This value cannot be deleted',
configurable: false,
writable: true,
enumerable: true
});
console.log(obj.permanent); // 'This value cannot be deleted'
delete obj.permanent;
console.log(obj.permanent); // ์ฌ์ ํ 'This value cannot be deleted'
4. ์ ๊ทผ์ ์์ฑ ํ์ฉ
์์ฑ์ ๊ฐ์ ์ฝ๊ฑฐ๋ ์ค์ ํ ๋ ์ฌ์ฉ์ ์ ์ ๋ก์ง์ ์คํํ๊ธฐ ์ํด get๊ณผ set ์์ฑ์ ์ฌ์ฉํฉ๋๋ค.
const obj = {};
let internalValue = 0;
Object.defineProperty(obj, 'number', {
get() {
return internalValue;
},
set(value) {
if (typeof value === 'number' && value > 0) {
internalValue = value;
} else {
console.error('Value must be a positive number');
}
},
enumerable: true,
configurable: true
});
obj.number = 42;
console.log(obj.number); // 42
obj.number = -10; // 'Value must be a positive number'
console.log(obj.number); // 42
5. ๋ฐ์ดํฐ ๋ชจ๋ธ๋ง ๋ฐ ์บก์ํ
Property Attributes๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ํน์ ์์ฑ๋ค์ ๋ณดํธํ๊ณ ์บก์ํํ ์ ์์ต๋๋ค.
function Person(name, age) {
Object.defineProperty(this, 'name', {
value: name,
writable: false,
enumerable: true,
configurable: false
});
let _age = age;
Object.defineProperty(this, 'age', {
get() {
return _age;
},
set(value) {
if (typeof value === 'number' && value > 0) {
_age = value;
} else {
console.error('Invalid age value');
}
},
enumerable: true,
configurable: true
});
}
const person = new Person('John', 30);
console.log(person.name); // 'John'
person.name = 'Doe'; // ๋ฌด์๋จ
console.log(person.name); // ์ฌ์ ํ 'John'
person.age = 31;
console.log(person.age); // 31
person.age = -5; // 'Invalid age value'
console.log(person.age); // ์ฌ์ ํ 31
05. ์์ฑ ๊ธฐ์ ์(Property Descriptor)ํ์ธํ๊ธฐ๐
์์ฑ ๊ธฐ์ ์๋ ์์ฑ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
Object.getOwnPropertyDescriptor()์ Object.getOwnPropertyDescriptors()๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ์ ์์ฑ๋ค์ ํ์ธํ ์ ์์ต๋๋ค.
let user = {
name: "Alice"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);
/*
{
value: "Alice",
writable: true,
enumerable: true,
configurable: true
}
*/