728x90

최근 자바스크립트를 다시 공부해보기 시작했다..

그러다가 다시 한번 예전에 공부했던 클로저를 접하게 되었다. 다시 한번 공부 해보자

(내가 이해하고 생각하여 글을 적는것이다.. 틀린 부분이 있을수도 있다...)

 

자바스크립트의 특징중 하나는 함수 안에 함수를 중첩으로 가질수 있다.

그리고 객체지향 관점에서 본다면 자바스크립트에서는 함수 또한 객체로 취급하기도 한다.

함수 안에 프로퍼티나, 메소드를 가질수 있기 때문이다.

 

자바스크립트의 매우 큰 특징 중 하나인 클로저는

이러한 함수의 특징을 이용하는 방법중 하나다.

 

*이해하기 쉬우라고 자식, 부모 키워드 쓰는거일뿐 상속 뭐 이런거랑은 틀리니 오해 하지 마시길.

 

클로저란 특정한 함수에서 자신(자식 함수..? 라고 할까..?) 을 감싸고 있는 함수(부모함수 라고 하면 될려나...?)의 변수나, 중첩함수등을 그대로 활용할수 있게 만들어주는 함수다.

 

즉 클로저라는 것은 그 자체로 함수이며 위에 설명과 같은 특징을 가지게 된다.

 

우선 그냥 평범한 함수를 예로 들어 보자

 

function add() {

   var counter = 0;

   counter += 1;    

} 

 

이라는 함수가 있고 add() 함수를 세번 호출한다고 생각해보자.

그럼 counter의 값은 얼마가 되어 있을까?

이경우엔 몇번을 호출하든 counter의 값은 1이상 증가하지 않는다

호출한후 새로운 지역 변수 counter를 0으로 초기화한후 1을 증가시키고 끝나기 떄문이다.

 

여기서 생각해야 될껀 값도 값이지만 함수는 독립적으로 실행되고 실행 후에는 선언된 변수들은 함수의 역할이 끝나면 모두 사라진다.

 

하지만 우리가 코딩을 하면서 함수안에 선해 놓은 어떠한 변수를 함수가 끝난 후에도 계속해서 사용하게 하고 싶다면 어떻게 해야 할까

 

보통은 해당 변수를 전역으로 선언하는 방식을 생각할수 있을 것이다.

 

하지만 자바 스크립트에서는 위에서 설명한 특징으로 인해 좀더 응집력 있게 클로저로 이러한 방식을 만들어 낼수 있다.

 

var add = (function add() {

  var counter =0;

  return function () { return counter += 1;}

})();

 

add();

add();

add();

 

위에 소스가 바로 클로저를 이용한 함수이다. 이 경우엔 정상적으로 counter의 값이 3까지 증가를 하게 된다.

 

앞서 설명한 특징처럼 add라는 함수가 function() 함수를 감싸고 있다. add 함수 안에는 counter라는 지역변수가 선언되어 있고 return 값으로 function() 자체를 넘겨 주고 있으며 function() 내용은 counter의 값을 1 증가 시킨다.

 

이렇게 사용함으로써 지역변수지만 그 값을 계속해서 보존해서 사용할수 있게 된다.

 

클로저라는게 재대로 이해하기 힘들수도 있지만 저런 특징을 자바스크립트에서 가지고 있고 사용할수 있구나 라는 정도로 알고 있으면 될듯 하다.

 

그렇다면 클로저를 왜 사용해야 하는가.

 

자바스크립트의 변수들은 기본적으로 public으로 되어있는데 객체 지향중에서 지향하는 캡슐화의 형태로 만들려면 클로저를 사용하면 구현 가능하다.

외부에서 counter라는 변수에 접근할수 없지만 내부에선 접근이 가능하기 때문이다.

게다가 딴 지역에서 counter라는 변수를 선언한들 add 함수 안에 있는 counter랑은 별개의 변수이므로 겹칠 위험도 없다.

 

간단히 정리하면

 

전역변수의 오용이 없는 깔끔한 스크립트의 작성

보다 자바스크립트에 적합한 방식의 스크립트 구성

다양한 자바스크립트의 디자인 패턴의 적용

 

등으로 생각을 하고 있다면 자바스크립트에서 클로저를 사용하면 좋다.

 

 

728x90

'JAVASCRIPT' 카테고리의 다른 글

자바스크립트 주의사항 2  (0) 2013.10.05
자바스크립트의 캡슐화  (0) 2012.12.31
클로저에 대한 정리  (0) 2012.12.27
자바스크립트 변수 유효 범위  (0) 2012.08.09
자바스크립트 주의사항  (0) 2012.08.03
Posted by 정망스
,
728x90

자바나, C나, C++ 등등 여러 언어에서 우리들은 코드를 작성할때 항상 ' ; ' 세미콜론을 끝으로 알림으로써 붙인다.


하지만 자바스크립트 에서는 줄구분이 되어있는 상태에서의 세미콜론 생략은 스크립트가 알아서 세미콜론이 있다고 생각하고 코드가 실행된다 예를 들면


return 

true ;


이러한 상태가 있다면 줄구분이 되어있고 return에는 세미콜론이 되어있지 않다 하지만 스크립트는 저기 끝에 세미콜린이 있다라고 생각하고 코드를 실행하게 된다. 


하지만 이러한 쓰임은 좋지 않으므로 좋은 프로그래밍 습관을 들이기 위해 항상 세미콜론을 붙이도록 하자, 왜냐하면


return ture; 이러한 트루값을 리턴하고 싶어서 


혹여나 위의 return과 true 선언처럼 똑같이 해버리면 트루를 리턴하는 문장이 되는것이 아니라 return 끝에 세미콜론이 생겨나게 되버리는 결과와 똑같이 되버리고 원하던 값이 제대로 되지 않거나 


오류가 생길수도 있으므로 이러한 방법이 있다라는 정도로만 알고 넘어가면 될듯 하다. 

728x90
Posted by 정망스
,
728x90
잘못 사용될 수 있는 객체의 특정 부분을 사용자가 직접 사용할 수 없게 막는 기술

보통 자바스크립트에서 캡슐화를 구현할 때 클로저를 활용한다.
728x90
Posted by 정망스
,
728x90

<script>

function outer(){

return function(){

alert('hello world');

};

}

 

outer()();

</script>

 

보통 이렇게 함수를 리턴하게 만들수 있다.

결론은 함수를 리턴하는 함수를 사용하는 이유는 클로저(closure)때문이다.

 

<script>

function outer(name){

var output = 'hello' + name + '!';

}

 

alert(output);

</script>

 

이문장은 아무것도 출력하지 않는다 함수안에 있는 output 변수는 지역변수이므로 함수 외부에서 사용할수 없다

 

하지만 클로저를 사용하면 이 규칙을 위반할 수 있다.

 

 

<script>

function outer(name){

var output = 'hello' + name + '!';

return function(){

alert(output);

};

}

 

outer('anTta')();

</script>

 

오류가 발생할것 같지만 정상적으로 실행된다.

자바스크립트 스스로 지역 변수 output를 지우면 안된다는 것을 인식하고 남겨두는 특성이다 이것을 클로저라고 한다.

 

클로저의 정의는 다양하다.

지역변수를 남겨두는 현상을 클로저라고 부르기도 하고

함수 outer() 내부의 변수들이 살아있는것으로 함수 outer()으로 인해 생성된 공간을 클로저라고 부르기도한다.

또한 리턴되는 함수 자체를 클로저라고 부르기도 하며, 살아남은 지역 변수 output를 클로저라고 부르기도 한다.

클로저의 정의는 다양하므로 클로저가 어떤것인지 감만 잡으면 될듯 하다.

728x90
Posted by 정망스
,
728x90

자바나 , c등과 같은 언어에 비해 자바스크립트의 변수는 다른 언어들과 좀 달라서

저도 많이 혼동이 되는 부분입니다. 그래서 정리를해서 올립니다

 

var 문장

 

-함수 내부에서 사용되면 해당 함수의 호출객체에 프로퍼티를 생성하여 변수를 정의한다.

-만일 함수의 몸체 내부가 아니면 전역 객체에 프로퍼티를 생성한다.

-var 문으로 명시적으로 생성되는 변수는 delete 연산자로 삭제 할수 없다.

  false 리턴

 

변수 선언의 반복과 생략

 

-선언되지 않은 변수의 값을 읽으려 하면 에러가 발생한다.

-var로 선언하지 않은 변수에 값을 할당하려하면 자바스크립트가 암묵적으로 변수를 선언한다.

 이때는, 전역변수로 생성된다(함수 내에서도 동일)

 

함수내에서는 지역변수가 같은 이름의 전역변수보다 우선한다.

(유효범위 체인의 앞단계에 해당 변수가 없을경우, 전역객체에서 검색한다.)

 

변수의 값이 undefined가 되는 경우

-아직 선언되지 않은 변수

이때 변수를 읽으려 하면 에러가 발생, 하지만 선언되지 않은 변수에 값을 집어넣으려 할땐 암묵적으로 전역변수로 선언된 후 값이 입력된다.

-선언은 되었으나 값을 초기화 하지 않은 경우

이때 변수를 읽으려 하면 변수의 초기값인 undefined가 출력된다.

 

블록단위의 유효범위가 없다.

 

-함수에서 선언된 변수는 모두 해당 함수 전체에 걸쳐 정의되어 있다, (C나 JAVA 등과 같은 언어의 블록단위의 유효범위가 없다)

 

전역변수와 지역변수

 

-전역변수

자바스크립트 인터프리터가 구동되면 자바스크립트 코드를 실행하기전에 전역객체를 생성한다.

이 전역 객체의 프로퍼티는 자바스크립트 프로그램의 전역변수 들이다.

전역변수를 선언하면 실제로는 전역객체의 프로퍼티가 된다.

최상위 코드(어떤 함수에도 속하지 않는 코드)에서는 자바스크립트의 this 키워드로 전역객체를 참조할 수 있다.

 

-지역변수

어떤 객체의 프로퍼티에 해당하며, 이 어떤 객체를 호출객체라 한다.

자바스크립트에서는 지역변수용으로 전혀 별개의 객체를 사용하기 떄문에 지역변수가 같은 이름의 전역변수를 덮어 버리는 것을 방지 한다.

 

변수의 유효범위

 

모든 자바스크립트 실행 컨텍스트에는 유효 범위 체인이란 것이 있는데 이는 객체들의 나열이다.

자바스크립트 코드에서 scope 라는 변수의 값을 찾으려면 우선 첫번째 객체의 프로퍼티부터 검색한 후 있으면 이 값이 쓰이게 되고 이 객체에 없으면 다음 객체로 검색이 계속되고 마지막 전역 객체에도 없으면 이 변수의 값은 undefined 이다.

 

중첩되지 않은 함수라면 유효범위 체인은 호출객체와 전역객체로 이루어지며 호출 객체에서 프로퍼티를 검색한 후 없다면 전역객체를 검색한다.

 

중첩된 함수인 경우 유효범위 체인은 여러개로 구성되며, 맨 안쪽의 중첩된 함수부터 검색하기 시작한다.

 

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침