개발자 99% 커뮤니티에서 수다 떨어요!
오늘 TIL 3줄 요약
코딩을 하다보면 외부 접근으로부터 데이터를 보호해야 할 일이 생긴다.
애석하게도 javascript는 접근 제한자가 없다.
방법을 찾아서 익히자!!
TIL (Today I Learned)
2024. 06.30
오늘 읽은 범위 - 6장. 객체와 자료구조
책에서 기억하고 싶은 내용을 써보세요.
이 챕터에서 저자는 외부의 접근으로부터 제한된 비공개 변수를 안전하게 유지하기 위한 방법을 소개한다.
하지만 javascript에는 다른 언어와 달리 public, private, protected와 같은 접근 제한자가 존재하지 않기 때문에 책에 나온 내용을 그대로 적용하기 어렵다.
때문에 이번 TIL에서는 js에서 변수, 즉 state를 안전하게 관리하는 방법에 대해 알아보고, 그 내용을 정리해 보기로 했다.
출처
-우아한테크 유튜브 엘라님의 Scope와 Closure에 대한 테코톡
https://www.youtube.com/watch?v=PVYjfrgZhtU
-모던 자바스크립트 deep dive 24장 클로저
스코프
-변수이름, 함수이름, 클래스 이름과 같은 식별자가 본인이 선언된 위치에 따라 다른 코드에서 자신이 참조될 수 있을지 없을지 결정되는 것
스코프체인
-함수 내부에서 정의된 함수를 중첩함수라 하고, 중첩함수를 포함하는 함수를 외부 함수라고 한다.
함수가 중첩된다면, 각 함수의 지역 스코프 역시 중첩될 수 있다.
즉 내,외부 함수 각각의 스코프가 함수의 중첩에 의해 계층 구조를 가지게 되는데, 이를 스코프체인이라고 한다.
스코프체인의 반방향성
-변수를 참조항 때 js엔진은 스코프체인을 통해 변수를 참조한다.
변수 값을 참조할 때, 해당 변수의 스코프에서 값을 찾고, 값이 존재하지 않을 경우 상위 스코프에서 재탐색 한다.
최상위 스코프인 전역 스코프에도 값이 존재하지 않는 경우 referenceErorr를 출력한다.
이처럼 변수를 참조할 때 하위 스코프에서 상위 스코프로 탐색을 이어나가는 것을 스코프체인의 반방향성이라 한다.
렉시컬 스코프
-js 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다. 이를 렉시컬 스코프(정적 스코프)라 한다.
함수가 정의되는 환경과 호출되는 환경은 다를 수 있다.
따라서 렉시컬 스코프가 가능하려면 함수는 자신이 호출되는 환경과는 상관없이 자신이 정의된 환경, 즉 상위 스코프를 기억해야 한다.
js 함수는 선언되는 시점에 본인의 내부 슬롯에 상위 스코프에 대한 참조를 저장한다.
때문에 호출되는 위치와 상관없이 자신의 상위 스코프가 어디인지 항상 참조 가능하다.
클로저
-함수 중첩 구조에서 외부 함수보다 내부 함수가 더 오래 유지되는 경우, 내부 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다.
이러한 내부 중첩 함수를 클로저(closure) 라고 한다.
MDM에서는 클로저를 다음과 같이 정의한다.
‘A closure is the combination of a function and the lexical environment within which that function was declared.’
모든 함수는 클로저인가?
-js의 모든 함수는 상위 스코프를 기억하므로 이론적으로 모든 함수는 클로저다. 하지만 일반적으로 모든 함수를 클로저라고 하지는 않는다.
클로저는 중첩된 내부 함수가 상위 스코프의 식별자를 참조하고 있고, 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에 한정하는것이 일반적이다.
자유변수
-클로저에 의해 참조되는 상위 스코프의 변수를 자유변수 라고 한다.
클로저란 ’함수가 자유 변수에 대해 닫혀있다’ 라는 의미다.
클로저의 활용
-클로저는 state가 의도치 않게 변경되지 않도록 안전하게 은닉하고, 특정 함수에게만 상태변경을 허용하기 위해 사용한다.
변수 값은 누군가에 의해 언제든지 변경될 수 있어 오류의 원인이 될 수 있다.
외부 상태 변경이나 mutable data를 피하고 불변성을 지향하는 함수형 프로그래밍에서 부수 효과를 최대한 억제하여 오류를 피하고 안정성을 높이기 위해 클로저는 적극적으로 활용된다.
캡슐화와 정보 은닉
-캡슐화: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 의미
-정보은닉:캡슐화를 특정 프로퍼티나 메서드를 감출 목적으로 사용하는 방식
한계
-js는 정보 은닉을 완전하게 지원하지 않는다.
인스턴스 메서드를 사용한다면 자유 변수를 통해 private을 흉내 낼 수 있지만, prototype 메서드를 사용하면 이마저 불가능하다.
ES6의 symbol 또는 WeakMap이 있지만 근본적인 해결책이 되지 않는다.
대안
-TC39 프로세스의 stage 3에는 클래스에 private필드를 정의할 수 있는 새로운 표준 사양이 제안되어 있다.
이를 익혀 사용하면 정보은닉의 문제를 해결할 수 있을지 모른다.
(추후 TC39 프로세스 공부해보기)
핵심 요약, 소감
프로그래밍을 함에 있어 외부 접근으로부터 보호되어야 하는 데이터를 다룰 일이 많다.
이를 안전하게 관리하기 위해 기술을 익혀둘 필요가 있다.
javascript에는 접근 제한자가 없기 때문에 클로저를 이용해 어느정도 접근 제한이 가능하지만, 완벽하지는 않다.
TC39프로세스에 대해 알아보고 js에서 활용할 수 있는 데이터 접근 제한 방법을 익혀두자.