javascript란? - 탐구편

고계 자바스크립트

javascript는 동적형식이고 객체지향적 범용언어이자, 지금까지 인류가 만든 모든 언어 중 가장 널리 쓰이고 있다. 특히 웹세상을 대표하는 맹주 언어라는 점이 특징이다.

객체지향 vs 함수형

객체기반은 캡슐화에 지나치게 의존한 채 가변 상태의 무결성을 유지합니다. 결국 객체의 데이터와 잘게 나뉜 기능이 단단히 유착되어 응집도가 높은 패키지가 형성됩니다. 
한편, 함수형 프로그램은 호출자로부터 데이터를 숨길 필요 없이 소규모의, 아주 단순한 자료형만을 대상으로 움직입니다. 만사가 불변이니 얼마든지 객체를 직접 만지작 거려도 되지만, 객체 스코프 밖에 위치한 일반적인 함수를 거치는 편이 낫다. 그로인해 객체데이터가 특정코드에 종속되지 않아 재사용성, 유지보수성이 좋다. 또한 함수형 프로그램은 객체를 불변값으로 취급한다.

객체관리법(불변성을 유지하는 방법)

방법1. 엄격한 규율로 스스로 관리
자바스크립트의 동적인 특징으로 소스코드에서 휘향찬란하게 재주를 부릴 자유가 있지만, 중대형 규모의 프로그램에서는 자칫 도저히 관리 안되는 코드로 발전할 소지가 있습니다. 이 부분을 해결하기 위해선 불변성을 관리할 수 있는 능력이 갖추어 져야 한다.  

방법2. 객체 리터럴 인터페이스
메서드를 일부만 호출자에게 공개하고 완전한 불변성을 유지시킬 수 있다. 정해진 메소드를 통해서 불변성을 유지하여 새로운 객체를 전달하는 형태이다. 아래의 소스코드를 참조
단, writable처럼 숨겨진 메타속성을 제어하면 내부 조작이 가능해진다. 


방법3. 객체 얼리기
Object.freeze() 함수는 writable속성을 false로 세팅해서 객체 상태를 못 바꾸게 동결합니다. 아래의 소스코드를 참조.
단, 중첩된 객체 속성까지 모두 동결하는 건 불가능합니다. (tip. 중첩된 객체 모두 얼릴 경우 완전한 불변성을 띄울 수 있다.)


방법4. 카피 온 라이트 전략
카피온라이트란? - 컴퓨터 과학에서 기억 공간을 관리하는 전략 중 하나입니다. 데이터 복사 명령을 받아도 잠정적으로 원본 주소값만 기록하여 마치 원본이 사본인 것처럼 보여주다가, 원본 또는 사본 어느 한쪽이 수정되면 그제서야 복사를 합니다. 쉽게 말해, 정말 복사 작업을 해야 할 시점에 복사를 하고 그 전까지는 이미 복사한 것처럼 버티는 전략입니다. 
렌즈 또는 함수형 레퍼런스 라고도 불리는 이 기법은 상태적 자료형의 속성에 접근하여 불변화하는 함수형 프로그래밍 기법입니다.  
기본적으로 javascript에서는 람다JS의 전역 객체 R로 모든 기능을 노출합니다.  
[javascript에서 렌즈기능 사용법 알아보기]

함수

함수형 프로그래밍에서 함수는 작업의 기본 단위입니다. 표현식(값을 내는 함수)과 구문(값을 내지 않는 함수) 두 용어를 구분합니다. FP(Function Programing)코드는 전반적으로 표현위주라서 구문형태의 void함수는 도움이 되지 않습니다.
자바스크립트 함수는 모두 function형식의 인스턴스 입니다.
자바스크립트 함수는 일급이라서 일단 변수에 할당한 뒤 나중에 실행해도 된다.
함수형 코드에서는 this를 쓸일이 거의 없다. (실은 어떤일이 있어도 쓰지 말아야 한다.)

클로저와 스코프

javascript는 클로저(closure)라는 기능 때문에 자유자재로 바깥스코프(전역), 부모함수의 내부 스코프에 위치한 변수, 부모 함수의 매개변수, 함수 선언부 다음에 선언한 변수까지 모두 접근가능하다.

전역스코프(global scope)는 가장 단순하면서, 가장 나쁜 스코프입니다. 함수형 프로그래밍에서는 관찰 가능한 어떤 변화도 함수에서 전파되는 것을 금기시하는데, 전역 스코프에선 한 줄 한 줄이 그런 변화를 이르키는 원인이 될 수 있지요. 전역 데이터는 변수 상태가 언제 어떻게 바뀌는지 머릿속에서 따라가야 해서 점점 알 수 없는 프로그램을 만드는 부작용을 초래합니다. 코드가 많아질수록 복잡도가 높아지는 주요 원인 중 하나죠. 또 전역 데이터를 읽고 쓸라치면 어쩔 수 없이 외부에 의존하게 되어 함수가 부수효과를 유발하는 원인이 됩니다.

함수 스코프(function scope)는 자바스크립트가 선호하는 스코프 방식입니다. 함수 내부에 선언된 변수는 모두 해당 함수의 지역 변수라서 다른 곳에서는 안 보이고, 함수가 반환되는 시점에 이들은 모두 바람과 함께 사라집니다. 다른 프로그램 언어 경험자라면 함수 스코프가 별로 낯설지 않겠지만, 자바스크립트가 C언어와 구문이 흡사하다 보니 블록 스코프도 작동 방식이 비슷할 거라고 오해하는 경우가 있습니다.
javascript는 아래의 소스코드와 같이 블록 바깥에서 내부스코프 변수에 접근이 가능합니다.


클로저를 응용한 해결방안
방법1. 프라이빗 변수를 모방
내부 변수를 캡슐화 하면서 전역 레퍼런스 개수를 줄이고 외부 세계에는 딱 필요한 기능만 표출하기 위해 즉시 실행 함수를 사용합니다. 아래 소스코드 참조


방법2. 서버 측 비동기 호출
자바스크립트의 일급 고계함수는 다른 함수에 콜백으로 건넬 수 있습니다. 콜백은 다른 프로그램에 영향을 끼치지 않고 이벤트를 가로채 처리할 때 유용한 장치죠. 서버에 데이터를 요청한 다음 그 수신 여부를 통보 받는 프로그램을 생각해 봅시다. 예를들어 getJSON() 메소드가 존재합니다. getJSON은 성공/실패 두 콜백 함수를 인수로 받습니다.

방법3. 가상의 블록 스코프 변수를 생성
함수형으로 접근한다면 클로저와 함수 스코프를 적극 활용한 forEach를 사용하면 된다.


정리

  • javascript는 객체지향적 프로그래밍과 함수형 프로그래밍 양쪽 다 가능하다.
  • 객체지향적 프로그래밍에 불변성을 도입하면 함수형 프로그래밍을 멋지게 섞어 사용할 수 있다.
  • 고계/일급 함수는 함수형 자바스크립트를 구사하는 근간입니다.
  • 클로저는 정보 감춤, 모듈 개발뿐만 아니라, 여러 자료형에 걸쳐 굵게 나뉜 함수에 원하는 기능을 매개변수로 넘기는 등 다양한 쓰임새를 자랑합니다.



출처 : 책(함수형 자바스크립트 - 루이스 아텐시오 지음)

댓글

가장 많이 본 글