it공부 (개념)/javascript

readonly modifier(readonly제어자): 한번쓰면 수정불가! /타입스크립트 예제

cantor 2023. 2. 14. 00:00

readonly로 선언된 속성은 한번쓰면 수정이불가능하다.

Access 접근제어자, abstract 제어자, static 제어자, 에 이어서 readonly 제어자에 대해 공부해 보자.

 

목차

1. readonly 제어자 소개

오브젝트 속성을 "읽기 전용"으로 설정하는

readonly 제어자를 소개한다.


2. 타입스크립트 예제코드

readonly 제어자로 선언가능한

속성들을 다루는 간단한 예제코드를 다룬다.


3. const와 readonly

const로 선언한 변수 또한 "읽기 전용" 변수가 된다.

하지만 readonly와 const는 전혀 다른 쓰임새를 가지고 있다.


4. 자바스크립트에서 "읽기 전용" 속성 만들기

많은 타입스크립트 고유 코드들은 컴파일된 자바스크립트 코드에선 자취를 감춘다.

또 코드만 사라지는 것이 아니라 그 기능도 함께 사라진다.

readonly도 마찬가지다. 하지만 자바스크립트에선 다른 방식으로 "읽기 전용"속성을 구현할 수 있다.

디스크립터를 통해 "읽기전용" 속성을 구현해 보았다.

 

 

 

1. readonly 제어자 소개


목차로 돌아가기

  • readonly의 뜻:

    읽기 전용

 

  • 타입스크립트의 readonly 제어자:

    클래스, 인터페이스 등 오브젝트로 구현된  컴포넌트의 (property) 속성을  "읽기 전용"으로 선언하는 제어자.

    readonly로 생성된 속성은 생성과 초기화를 동시에 해줄 필요는 없다.
    하지만 첫 번째 초기화 이후엔 값을 번경할 수 없다.

 

*커스텀타입, 클래스 등의 오브젝트 컴포넌트 내부의 변수를 "속성"이라 한다.

다시 말해, 컴포넌트. 변수명으로 호출하는 변수는 전부 "속성"이다.

 

 

2. 타입스크립트 예제코드


목차로 돌아가기

 

readonly 제어자는 클래스, 인터페이스, 타입 등 오브젝트의 속성을 선언하는 데 사용된다.

 

하지만 커스텀 오브젝트의 속성 선언에는 사용할 수 없다.

readonly 로 선언해줄수 없다.

 

readonly 제어자로 선언할 수 있는 것

    • 1. 함수 매개변수의 타입을 지정하는 오브젝트의 속성
    • 2. 커스텀 타입의 속성
    • 3. interface의 속성
    • 4. class의 속성

 

이제 위의 4개의 사용에 대한 예제코드를 살펴보자.

 

 

1. 함수의 parameter(매개변수) 오브젝트 속성



함수매개변수의 타입을 오브젝트로 지정하는 경우,

그 오브젝트의 속성 선언에 사용될 수 있다.

 

 

예제코드:

function myFunc(param: {readonly forParam: number}): number { 
      
    return param.forParam;
};
    
console.log(myFunc({forParam: 7}));
console.log(myFunc({forParam: 9}));

 

위의 코드에서 forParam은 readonly 속성이다.

즉, 함수내부에서 값을 번경하는 것이 불가능하다.

값번경을 시도시 오류가발생한다.
forParam은 read-only라서 값을 바꿔줄수 없다.

 

2. 커스텀 타입의 속성

 

"type" 키워드로 선언하는 타입의 구성요소를 선언할 수 있다.

type myType = {
    readonly forType:7,
    readonly withType: string
}

3. interface의 속성

 

인터페이스의 속성 선언에도 사용된다.


interface myInterface {
    readonly forInterface: "Hello",
    readonly withInterface: number
}

4. class와 함께 사용

클래스의 속성 선언에도 사용할 수 있다.

실제로 제일 많이 사용되는 곳이다.

class myClass {
    readonly forClass: number[];
    readonly withClass = true;
}

 

 

 

3. const와 readonly


목차로 돌아가기

 

 

const 또한 "읽기 전용" 변수를 선언하는 데 사용된다.

하지만 readonly와 사용 위치도 다르고, 사용 방법도 미묘하게 다르다.



1. 사용위치의 차이

 

readonly는 오브젝트 속성, const는 스코프 변수 선언에 사용된다.

 

*속성은 class, interface 등의 오브젝트 내부에 묶이는 객체이다.

*만약 어떤 변수가 abc. 변수명으로 호출된다면 그것은 변수가 아니라 속성이다.

 



const로 변수를 정의하는 곳

 

    • 함수 스코프 내부 변수 {}
    • 조건문 스코프 내부변수 {}
    • 전역변수

 

위의 모든 경우엔 readonly가 사용될 수 없다.

또, readonly가 사용되는 곳 역시 const를 사용할 수없다.

 

한 가지 둘의 공통점은 커스텀 오브젝트의 속성 선언에 사용할 수 없다는 것이다.



2. 사용방법

const는 반드시 선언과 동시에 초기화를 해주어야 한다.

하지만 readonly는 선언과 초기화가 분리될 수 있다.

미리 선언을 해놓고 초기화는 나중에 할 수 있ㄷ.



const: 선언과 초기화는 분리가 불가능

 

const의 선언은 초기화와 함께이루어져야한다 / const로 선언된 변수는 초기화가 불가능하다.

 

readonly: 선언과 초기화 분리가 가능

 

constructor로 초기화하는 코드

 
class MyClass {
    readonly forClass: number; 
    
    constructor(){
        this.forClass = 7;
    }
};    



상속받은 클래스가 초기화하는 코드


interface MyInterface {
    readonly forInterface: number,
}
    
class InterClass implements MyInterface {
    forInterface = 7;
}   

 

 

4. 자바스크립트에서 "읽기 전용" 속성 만들기


목차로 돌아가기

읽기 전용 변수는 "const"로 선언한다.

읽기 전용 속성을 선언할 수 있는 방법은 없다.

 

하지만 descriptor를 활용해서 객체속성을 바꿔버리면 "읽기 전용 속성"을 만들 수 있다.,

 

descriptor(디스크립터):

객체의 속성 및 행동에 대한 정의를 담고 있는 오브젝트이다.



일반적으로 디스크립터에 포함되는 요소들은 다음과 같다.

    • configurable: boolean 객체의 속성이 수정가능여부를 표시한다.
    • enumerable: boolean 객체의 속성이... spread 연산자를 통해 나열가능한지 여부를 표시한다
    • value: 그 속성에 저장된 값을 의미한다.
    • writable: boolean 객체의 값을 바꿀 수 있는지에 대한 여부이다. 만약 false이면 값을 바꿔줄 수 없다.
    • get: 겟 메서드
    • set: 셋 메서드

 

 

위의 속성 중, set 메서드의 기능을 망가뜨리거나,
writable의 값을 false로 바꿔준다면 "읽기 전용"속성의 구현이 가능하다.

 

 

 

자바스크립트에서 읽기 전용 속성 구현하기

class MyClass {
    constructor() {
        this.forClass = 7;
    }
    
};
const myInstance = new MyClass();

//getOwnPropertyDescriptors: 속성의 디스크립터를가져오는 메서드

const a = Object.getOwnPropertyDescriptors(myInstance, myInstance.forClass);
console.log(a)

콘솔에 출력된 descriptor.

writable: true, 즉 "쓰기"가 가능한 상태이다.

forClass의 디스크립터를 writable을 false로 설정한 디스크립터로 덮어씌워주자.

// 디스크립터를 상수(변수)에 저장

const newDescriptor = a.forClass;


//writable값을 false로 바꾸기

newDescriptor.writable = false;


//새로운 디스크립터를 myInstance.forClass의 디스크립터에 덮어씌운다

Object.defineProperty(myInstance,'forClass', newDescriptor);

 

이제 forClass 속성은 writable값이 false가 되면서 읽기 전용 속성으로 바뀌었다.

콘솔창을 이용해 테스트해 보자.

forClass의 값을 바꿀수 없다.

 

여기에 configurable 값까지 false로 바꿔주면 웬만해선 값의 재설정이 불가능하다.

 

이처럼 클래스속성은 "const"로 선언할 수 없고, readonly는 타입스크립트 고유의 제어자이지만

자바스크립트에서도 읽기 전용 속성을 구현할 수 있는 방법이 있다.

 

 

속성 값을 초기화하는 코드와 writeable을 false로 바꿔주는 코드를 묶어서 메서드를 만들고,

초기화 시 실행되게 코드를 설정한다면, "readonly" 속성 설정이 가능한 나만의 자바스크립트 클래스도 만들 수 있을 것이다.




읽어주셔서 감사합니다.

오탈자나 오류를 발견할 시 댓글에 남겨주세요.

감사합니다.