본문 바로가기
Web/Javascript

함수 - (스코프, 클로저)

by juein 2018. 2. 26.

06] 예외

- 자바스크립트는 예외를 다룰 수 있는 메커니즘을 제공한다.

  예외란 정상적인 프로그램의 흐름을 방해하는 비정상적인 사고를 말한다.(오류발생)


- try~ catch 문은 try 블록 내에서 예외가 발생하면, catch 블록이 실행된다.

var test_try = function(){

  try{

    var message = document.getElementById('message');

    message.innerHTML = '테스트 메시지222';

  }catch(error){

    console.log('오류! '+ error);

  }finally{

    console.log('무조건 실행할거야');

  }
 
}

test_try();



07] 기본 타입에 기능 추가

- 모든 객체가 연결되어있는 prototype 에 기능(메소드)을 추가하는것이 가능하다.

var person = function( name, age ){

}

console.dir(person);

//console.dir(person); 출력시 콘솔창의 모습



위 함수에 prototype 추가

person.prototype.eyes = 2;
person.prototype.mouth = 1;

//console.dir(person); 출력시 콘솔창의 모습





이러한 방법으로 기본적인 타입에 기능을 추가 할 수 있다.


- 프로토타입에 메소드를 추가하면 메소드가 추가되기 전에 생성되었던 값들에게도 바로 적용된다.


- 기본타입의 프로토타입은 public 구조이므로

if( !person.prototype.eyes ){

person.prototype.eyes = 2;
    
}


위와 같이 추가하려는 값이 존재하지 않을 때에 메소드를 추가하는 방식으로 하면 좋다.




08] 재귀적 호출

- 함수 안에서 자기 자신을 호출하는것을 재귀적 함수 호출(Recursive Function Call)   간단하게 재귀(Recursion) 라고 한다.



- 재귀함수의 예로, 수열 앞에 나오는 두 개의 숫자를 더해가는 피보나치 수열을 예제로 든다.

var fibonacci = function( n ){

 if( n === 0 || n === 1 ){

    return 1;

  }else {

    return fibonacci(n-1) + fibonacci(n-2);

  }

}

for (var i = 0; i < 10; i++){

  console.log( fibonacci(i) );  // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 출력

}



위 예제에서 눈여겨 볼 부분은 함수 안에서 자기 자신을 호출하는것이 가능하다는 점이다.




09] 유효범위(Scope)

- 유효범위는 이름들이 충돌하는 문제를 덜어주고 자동으로 메모리를 관리하기 때문에 중요하다.


- C언어 유형의 구문을 가진 언어들은 블록 {} 유효범위가 있어서 {} 내에서 정의된 모든 변수는 {} 바깥쪽에서 접근할 수 없는 구조로 되어있지만 자바스크립트 에서는 {}은 유효범위를 지원하지 않는다.


- {} 유효범위는 없지만 함수 유효범위는 존재한다. 

함수 내부에서 선언한 변수와, 함수의 매개변수는 함수 외부에서 유효하지 않는다.



var test = function(){

  var b_text = "bbbbb"; //지역변수, var 선언 안하면 전역변수가 된다.

  document.write("함수 내에서 출력 : " + a_text );

}

test();

 document.write("함수 밖에서 출력 : " + a_text );



10] 클로저 (closure)

- 내부함수에서 자신을 포함하고 있는 외부함수의 변수에 접근할 수 있는것을 클로저 라고 한다.

  다른 의미로 이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수 자체가 클로저다.

var out_func = function(){

  var a = 10;    // <-- 자유변수

  return function(){    // <-- 클로저

    //a 를 활용한 로직(클로저)
    console.log( a + ' add text' );

  };

};

위 예제에서 out_func에 선언된 변수 a 를 참조하는 함수가 클로저가 된다.

그리고 클로저로 참조되는 외부변수, 즉 out_func의 a와 같은 변수를 '자유변수' 라고 한다.

클로저에 대한 예를 하나 더 보자면

//클로저를 사용하지 않은 코드
var count = 0; //전역변수

window.onload = function(){

  var button = document.getElementById('btn');
  button.onclick = btn_click;

}

var btn_click = function(){

  count ++;
  
  console.log( count +'번 클릭 (클로저 사용 안함)');

}
//클로저를 사용
window.onload = function(){

  var count = 0; // <-- 자유변수
  var button = document.getElementById('btn');

  button.onclick = function(){  // <-- 클로저

    count ++;

    //button.onclick 속성에 할당된 함수에 대한 클로저를 생성
    console.log( count +'번 클릭 (클로저를 사용)');

  };

}

위 예제의 클로저 사용 부분을 보면

버튼을 클릭하는 onclick 속성에 클로저가 할당 된다.

외부 함수에 있는 button 변수는 window.onload 함수가 종료될때 사라졌지만

button 객체는 onclick 속성에 저장된 클로저를 갖고 있다.





'Web > Javascript' 카테고리의 다른 글

상속  (0) 2018.02.27
콜백, 모듈, 커링, 메모이제이션  (0) 2018.02.27
함수  (0) 2018.02.26
객체  (0) 2018.02.26
자바스크립트 기본, 타입, 함수  (0) 2018.02.26

댓글