javascript

[함수형 자바스크립트] 객체의 불변성을 관리하는 방법들

자바스크립트는 동적인 언어(Dynamic-Weak typing)이기 때문에 객체의 상태를 보호하는 일이 힘들다.

따라서 이러한 관리를 하는 여러 방법들이 있다.

 

1. const(상수값)으로 선언

ex) const gravity_ms = 9.806; 

gravity_ms 변수에는 다른 값을 재할당하지 못한다.

러나 객체의 경우 객체 자체의 레퍼런스 참조는 잠그더라도 객체 attritubte의 레퍼런스 변화까지는 막지 못한다.

 

2. 값 객체 패턴: 객체 리터럴 인터페이스({}) 반환을 통해 내부 상태 접근 막기

function zipCode(code, location){
	let _code = code;
    let _location = location || '';
    
    return{
    	code : function(){
        	return _code;
        }
        location: function(){
        	return _location;
        }
        fromString: function (str) {
        	let parts = str.split('-');
            return zipCode(parts[0], parts[1]);
        }
        toString: function (){
        	return _code + '-' + location;
        }
    };
}

const princetonZip = zipCode('08544', '3345');

princetonZip.code(); // '08544'

princentonZip.code = '11111' // error

 

여기서 클로저 개념이 쓰이고 있는 것을 확인할 수 있는데 이는

함수 안에 있는 변수 code가 함수 바깥에서 계속 접근이 가능하기 때문이다.

보통은 불가능한 일이나 함수의 클로저는 모든 함수의 매개변수 뿐만 아니라

바깥 스코프에 위치한 모든 변수들을 스냅샷 찍듯 가지고 있기 때문에 가능한 일이다.

 

클로저는 함수 선언 당시의 환경에 함수를 묶어둔 자료구조로 자바스크립트의 스코핑 규칙과 밀접한 연관이 있다.

스코프는 변수 바인딩들을 모아 변수가 정의된 코드 영역을 확정하는 것으로

클로저는 이 함수 스코프를 상속하는 것이라고 볼 수 있다.

 

자바스크립트는 변수 타입은 Dynamic하게 타이핑하지만 스코프는 정적이기 때문에 프로그램이 작성될 때 변수의 스코프가 정해진다. 이를 어휘적 스코핑(Lexical Scoping)이라고도 하며 Lexical은 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미한다.

더 자세한 설명은 아래에서 확인해볼 수 있다.

 

클로저

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

developer.mozilla.org

 

3. 사본을 새로 만들어 반환하는 메서드

function coordinate(lat, long){
	let _lat = lat;
    let _long = loong;
    
    return {
    	latitude: function() {
        	return _lat;
        },
        longitude: function() {
        	return _long;
        }
        translate: function (dx, dy){
        	return coordinate(_lat + dx, _long + dy);
        },
        toString: function (){
        	return '(' + _lat + ',' + _long + ')';
        }
    };
}

const greenwich = coordinate(51.4778, 0.0015);

greenwich.translate(10,10).toString(); // (61.4778, 10.0015);

translate 메서드는 새 coordinate 객체를 만들어 기존 lat, long에 접근할 수 있는 방법을 차단한다. 

 

이외에도 freeze 함수라 렌즈 또는 함수형 레퍼런스라고 불리는 기법이 있지만 간단히 이렇게만 정리하고 넘어가겠다.