1. 내부슬롯과 내부 메서드
- JS 엔진에서 객체의 동작을 설명하기 위해 사용되는 개념이다.
- => JS 엔진이 객체의 내부 상태를 추적하기 위해 사용
- 이중괄호'[[]]' 로 감싼 이름들을 내부 슬롯과 내부 메서드라고 한다.
- JS 엔진에서 실제로 동작하지만 개발자가 직접 접근할 수 있는 것은 아니다.
1-1. 내부 슬롯 (Internal Slot)
- 내부 슬롯은 객체 내부에 저장된 특수한 속성.
일반적인 객체 속성과 달리, 내부 슬롯은 자바스크립트 코드에서 직접 접근하거나 수정할 수 없다. - [[...]] 형태로 표기
예를들어 .. 배열 객체는 length 속성을 가지고 있다. .
이 length 속성은 배열의 길이를 나타내는데, 이 값은 실제로 배열 객체의 내부 슬롯 중 하나에 저장된다.
이때 배열 객체는 [[ArrayLength]]라는 내부 슬롯을 가질 수 있다.
1-2. 내부 메서드 (Internal Method)
- 내부 메서드는 객체가 특정 작업을 수행할 때 자바스크립트 엔진에 의해 호출되는 메서드.
- 이들도 자바스크립트 코드에서 직접 호출할 수 없다.
- 내부 메서드는 객체가 특정 행동을 취할 때 어떻게 반응해야 하는지 정의한다.
예를 들어, 객체가 다른 객체와 비교될 때 자바스크립트 엔진은 [[HasProperty]]라는 내부 메서드를 호출해
객체에 특정 속성이 있는지를 확인한다.
마찬가지로 객체가 함수처럼 호출될 때 [[Call]] 내부 메서드가 실행된다.
const o = {};
o.[[prototype]] // 직접 접근하거나 사용할 수 없음
2. 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
- 자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
프로퍼티의 상태란??
프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부를 말한다.
프로퍼티 어트리뷰트란:?
자바스크립트 엔진이 관리하는 내부 상태값인 내부 슬롯 [[value]], [[writable]], [[enumerable]], [[Configurable]] 을 말한다.
따라서 프로퍼티 어트리뷰트에 직접 접근할 수는 없지만 Object.getOwnPropertyDescriptor 메서드를 사용하여
간접적으로 접근할 수 있다.
프로퍼티 디스크립터 객체란?
프로퍼티 어트리뷰트 정보를 제공하는 객체
3. 데이터 프로퍼티와 접근자 프로퍼티
프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.
3-1. 데이터 프로퍼티
- 키와 값으로 구성된 일반적인 프로퍼티
- 우리가 살펴본 모든 프로퍼티는 데이터 프로퍼티이다
- 프로퍼티를 생성할 때 기본값으로 자동 정의된다.
프로퍼티 어트리뷰트 | 프로퍼티 디스크립터 객체의 프로퍼티 | 설명 |
[[Value]] | value | -프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값 -프로퍼티 키를 통해 프로퍼티 값을 변경하면 [[value]]에 값을 재할당함... -이때 프로퍼티 키를 통해 프로퍼티 값을 변경하면 [[value ]] 값을 재할당 -프로퍼티가 없으면 동적 생성하고 생성된 프로퍼티의 [[value]] 에 값을 저장함 |
[[writable]] | writable | -변경가능 여부 -불리언 값 가짐 -false 인 경우 읽기전용 프로퍼티됨 |
[[enumerable]] | enumerable | -열거가능여부 -false 인경우 열거 불가능 |
[[Configurable]] | configurable | -재정의 가능 여부 -불리언 값 가짐 -false 인경우 어트리뷰트 값의 변경이 금지됨 |
let obj = {
a: 10 // 'a'는 데이터 프로퍼티
};
// 데이터 프로퍼티의 상태를 확인
console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
/*
출력:
{
value: 10,
writable: true,
enumerable: true,
configurable: true
}
*/
3-2. 접근자 프로퍼티
- 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는
- 접근자 함수로 구성된 프로퍼티이다.
프로퍼티 어트리뷰트 | 프로퍼티 디스크립터 객체의 프로퍼티 | 설명 |
[[Get]] | get | =getter 함수 호출 |
[[Set]] | set | setter 함수 호출 |
[[Enumerable]] | enumerable | 데이터 프로퍼티의 [[enumerable]] 과 동일 |
[[Configurable]] | Configurable | 데이터 프로퍼티의 [[Configurable]] 과 동일 |
let obj = {
a: 10 // 'a'는 데이터 프로퍼티
};
// 데이터 프로퍼티의 상태를 확인
console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
/*
출력:
{
value: 10,
writable: true,
enumerable: true,
configurable: true
}
*/
3-3. 접근자 프로퍼티와 데이터 프로퍼티 구별
데이터 프로퍼티는 값을 직접 보관하는 프로퍼티이고. 접근자 프로퍼티는 값을 읽고 쓸 때 특정 로직을 실행할 수 있는 프로퍼티이다.
Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
// 일반객체의 __proto__는 접근자 프로퍼티
Object.getOwnPropertyDescriptor(function(){},'prototype');
// 함수객체의 prototype 은 데이터 프로퍼티
4. 프로퍼티 정의
새로운 프로퍼티를 추가하면서
프로퍼티 어트리뷰트를 명시적으로 정의하거나
기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다.
* 프로퍼티 디스크립터 객체의 프로퍼티를 일부 생략할 수 있다.
프로퍼티 디스크립터 객체의 프로퍼티 | 대응하는 프로퍼티 어트리뷰트 | 생략했을 때의 기본값 |
value | [[value]] | undefined |
get | [[Get]] | undefined |
set | [[Set]] | undefined |
writable | [[Writable]] | false |
enumerable | [[Enumerable]] | false |
configurable | [[Configurable]] | false |
*Object.definedProperty 메서드는 한번에 하나의 프로퍼티만 정의할 수 있다.
그런데 만약 .. 여러개의 프로퍼티를 한번에 정의하고싶다면 ‼️
⏯️ Object.definedProperties 메서드를 사용하면 된다.
const person ={};
Object.definedProperties(person, {
firstName: {
value:"Ungmo",
writable:true,
enumerable:true,
configurable:true
},
lastName: {
value:"Lee",
writable:true,
enumerable:true,
configrable:true
},
//접근자 프로퍼티 정의
fullName: {
//getter 함수
get() {
return `${this.firstName} ${this.lastName}`;
},
set(name) {
[this.firstName, this.lastName] = name.split('');
},
enumerable : true,
configurable: true
}
});
5. 객체 변경 방지
객체는 변경 가능한 값이므로 재할당 없이 직접!! 변경할 수 있다.
프로퍼티를 추가, 삭제, 갱신, 재정의 드을 할 수 있다.
따라서 자바스크립트 엔진은 객체의 변경을 방지하는 다양한 메서드를 제공한다.
=> 각 메서드들은 금지하는 강도가 다르다.
구분 | 메서드 | 프로퍼티 추가 | 프로퍼티 삭제 | 프로퍼티 값읽기 | 프로퍼티 값쓰기 | 프로퍼티 어트리뷰트 재정의 |
객체확장금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
5-1. 객체 확장금지
- 객체 확장금지란? 프로퍼티 추가 금지를 의미
- 확장이 금지된 객체는 프로퍼티 추가가 금지됨
//객체생성
const person = {name:"hihilong"};
// 확장해보자
console.log(Object.isExtensible(person)); //true
이렇게 정의한 아이를 확장금지 메서드를 활용해보자
Object.preventExtensions(person);
//이렇게 하면
person.age=20; //무시됨.. 에러나기도 함
console.log(person) //{name:"hihilong"}
age 로 프로퍼티 추가를 시도하였는데 안되는 걸 확인할 수 있다.
5-2. 객체 밀봉
- 객체 밀봉이란 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지를 의미
- 밀봉된 객체는 읽기와 쓰기만 가능함
// 아까 위에서 정의한 person 을 이번에는 밀봉시켜보자.
Object.seal(person);
person.age = 20;
console.log(person); //{name:"hihilong"}
delete person.name: //무시됨... 에러나기도 함
console.log(person); //{name:"hihilong"}
밀봉을 시키면.. 삭제를 시도해도 안되는 걸 확인할 수 있다.
🤔 오오 근데 갱신은 가능함 !
person.name = "byebyelong";
console.log(person) //{name:"byebyelong"}
5-3. 객체 동결
- 프로퍼티 추가 삭제 재정의 금지, 갱신 금지 의미
- 즉 읽기만 가능함!
객체 밀봉은 갱신까지 가능했지만 얘는 갱신마저 금지되는 거임
person.name = "byebyelong"; //무시..
console.log(person) //{name:"hihilong"}
'Deep Dive 정리' 카테고리의 다른 글
[JS] this 조금 더 정리하기 (0) | 2024.09.04 |
---|---|
[JS Deep Dive] 17장 - 생성자 함수에 의한 객체 생성 (0) | 2024.09.04 |
[JS Deep Dive] 15장 - let const 키워드와 블록레벨 스코프 (0) | 2024.08.28 |
[JS Deep Dive] 13장 - 스코프 (0) | 2024.08.28 |
[JS Deep Dive] 12장 -함수 (2) (4) | 2024.08.28 |