diff --git "a/docs/24_\355\201\264\353\241\234\354\240\200/\355\225\234\354\210\230\354\247\200.md" "b/docs/24_\355\201\264\353\241\234\354\240\200/\355\225\234\354\210\230\354\247\200.md" index db8520b3..229bbcaa 100644 --- "a/docs/24_\355\201\264\353\241\234\354\240\200/\355\225\234\354\210\230\354\247\200.md" +++ "b/docs/24_\355\201\264\353\241\234\354\240\200/\355\225\234\354\210\230\354\247\200.md" @@ -89,3 +89,93 @@ innerFunc(); 1. 중첩 함수가 상위 스코프의 식별자를 참조하고 있다. 2. 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에 한정된다. + +--- + +### 📌 24-4. 클로저의 활용 + +> 클로저는 **상태를 안전하게 변경하고 유지하기 위해 사용**한다. (= 클로저를 사용하는 목적) + +구체적으로는, `상태가 의도치 않게 변경되는 것을 막고` 상태를 `안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위함`이다. + +**클로저를 사용하는 목적** + +1. 상태가 의도치 않게 변경되는 것을 막는다. +2. 안전하게 은닉한다. +3. 특정 함수에게만 상태변경을 허용하여 상태를 안전하게 변경하고 유지한다. + +--- + +### 📌 24-5. 캡슐화와 정보 은닉 + +- **캡슐화**: **객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것**을 말한다. + +- **정보은닉**: 캡슐화는 객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용하기도 하는데 이를 정보 은닉이라고 한다. + +**정보은닉의 이점** + +`정보은닉`은 외부에 공개할 필요가 없는 `구현의 일부를 외부에 공개되지 않도록 감춘다.` + +- 적절치 못한 접근으로부터 **객체의 상태가 변경되는 것을 방지해 정보를 보호**할 수 있다. +- 객체 간의 상호 **의존성, 즉 결합도를 낮추는 효과**가 있다. + +**객체 지향 프로그래밍에서의 공개범위 설정** + +대부분의 객체지향 프로그래밍 언어는 클래스를 정의하고 그 클래스를 구성하는 멤버(프로퍼티와 메서드)에 대하여 `public, private, protected 같은 접근 제한자를 선언하여 공개 범위를 한정` 할 수 있다. + +- public으로 선언된 프로퍼티와 메서드: 클래스 외부에서 참조 가능하다. +- private으로 선언된 프로퍼티와 메서드: 클래스 외부에서 참조할 수 없다. + +> **자바스크립트는 public, private, protected같은 접근 제한자를 제공하지 않는다.** + +따라서 자바스크립트 객체의 모든 프로퍼티와 메서드는 **기본적으로 외부에 공개**되어 있다. +(객체의 모든 프로퍼티와 메서드는 기본적으로 public이다.) + +하지만, 2021기준 **클래스에 private 필드를 정의할 수 있는 새로운 표준 사양이 제안**되었다. + +--- + +### 📌 24-6. 자주 발생하는 실수 + +**전역 변수의 함수 레벨 스코프 특성으로 인해 발생하는 문제** + +```js +// 문제발생 코드 +var funcs = []; + +for (var i = 0; i < 3; i++) { + funcs[i] = function () { + return i; + }; +} + +for (var j = 0; j < funcs.length; j++) { + console.log(funcs[j]()); +} + +// 코드 개선 +const funcs = []; + +for (let i = 0; i < 3; i++) { + funcs[i] = function () { + return i; + }; +} + +for (let i = 0; i < funcs.length; i++) { + console.log(funcs[i]()); // 0 1 2 +} +``` + +위 코드는 클로저를 사용할 때 자주 발생할 수 있는 실수를 보여주는 예시 코드이다. + +해당 코드는 funcs 배열의 요소로 추가된 3개의 함수가 0,1,2 를 반환할 것으로 기대했지만 +아쉽게도 결과는 그렇지 않다. + +for 문의 변수 선언문에서 var 키워드로 선언한 i 변수는 블록 레벨 스코프가 아닌 함수 레벨 스코프를 갖기 때문에 전역 변수이다. + +전역 변수 i에는 각각 0, 1, 2가 순차적으로 할당되고 funcs 배열의 요소로 추가한 함수를 호출하면 전역 변수 i 를 참조하여 i의 값이 3이 출력된다. + +자바스크립트의 함수 레벨 스코프 특성으로 인해 발생하는 문제는 ES6의 let 키워드를 사용하면 번거로움이 깔끔하게 해결된다. + +> **let이나 const 키워드를 사용하는 반복문**은 코드블록을 **반복 실행할 때마다 새로운 렉시컬 환경을 생성하여 반복할 당시의 상태를 마치 스냅숏을 찍는 것 처럼 저장**한다.