Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 일반 인스턴스 간에 비공개(private) 멤버를 공유하고 활용하는 방법

클로저를 활용한 비공개 멤버의 기본 원리

JavaScript에서는 생성자 함수 내부에 let 또는 var로 변수를 선언하면, 클로저(closure) 덕분에 외부에서 직접 접근할 수 없는 비공개(private) 멤버를 만들 수 있습니다. 이렇게 선언된 변수는 함수 내부에서 정의된 메서드(소위 특권 메서드)를 통해서만 접근할 수 있으며, 객체 속성처럼 obj.personName 형태로 접근하려 하면 undefined가 반환됩니다.

흥미로운 점은 각 인스턴스가 생성될 때마다 새로운 클로저 스코프가 만들어진다는 것입니다. 따라서 아래 예제처럼 여러 인스턴스가 존재할 경우, 각 인스턴스는 서로에게 영향을 주지 않는 독립적인 비공개 멤버를 가지게 됩니다.

예제 코드

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
    body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    }
    .result {
        font-size: 18px;
        font-weight: 500;
        color: blueviolet;
    }
</style>
</head>
<body>
<h1>Share private members among common instances in JavaScript</h1>
<div class="result"></div>
<br />
<button class="Btn">Click Here</button>
<h3>Click on the above button to display the personName property</h3>
<script>
    let resEle = document.querySelector(".result");
    let BtnEle = document.querySelector(".Btn");
    function Person(name) {
        // let으로 선언했기 때문에 외부에서 직접 접근 불가
        let personName = name;
        // 클로저를 통해 personName에 접근하는 특권 메서드
        this.returnName = function () {
            return personName;
        };
    }
    let person1 = new Person("Rohan");
    let person2 = new Person("Shawn");
    BtnEle.addEventListener("click", () => {
        resEle.innerHTML =
        "person1.returnName() = " + person1.returnName() + "<br>";
        resEle.innerHTML +=
        "person2.returnName() = " + person2.returnName() + "<br>";
        resEle.innerHTML +=
        "person1.personName = " + person1.personName + "<br>";
        resEle.innerHTML +=
        "person2.personName = " + person2.personName + "<br>";
    });
</script>
</body>
</html>

실행 결과

페이지를 처음 열었을 때의 초기 화면입니다.

JavaScript에서 일반 인스턴스 간에 비공개(private) 멤버를 공유하고 활용하는 방법

'Click Here' 버튼을 클릭하면 다음과 같이 결과가 표시됩니다.

JavaScript에서 일반 인스턴스 간에 비공개(private) 멤버를 공유하고 활용하는 방법

결과 해석

  • returnName() 호출: person1.returnName()은 'Rohan', person2.returnName()은 'Shawn'을 반환합니다. 즉, 각 인스턴스가 자신만의 비공개 멤버 값을 유지하고 있습니다.
  • 직접 접근 시도: person1.personNameperson2.personName은 모두 undefined를 출력합니다. 이는 personName이 객체의 속성이 아니라 클로저 내부의 지역 변수이기 때문에 외부에 전혀 노출되지 않았음을 의미합니다.

참고: 최신 JavaScript의 비공개 필드

ES2022부터는 클래스 문법에서 # 접두사를 사용한 비공개 필드(private field)가 표준으로 도입되었습니다. 예를 들어 #personName처럼 선언하면 별도의 클로저 없이도 진짜 비공개 멤버를 만들 수 있습니다. 다만 구형 브라우저 호환성이나 생성자 함수 기반 패턴이 필요한 경우라면, 위 예제처럼 클로저를 활용한 방식이 여전히 널리 사용되는 검증된 접근법입니다.