JavaScript 특징의 이해 - JS의 중심 Function 살펴보기(1)

2011. 2. 14. 00:43
JavaScript(이하 JS)라는 언어는 다른 언어와 달리 몇가지 특징을 가지고 있습니다. 그런 특징들은 사실 UI를 개발하는데 매우큰 걸림돌이 되지는 않는것 같습니다. 이는 언어적인 자유도가 상대적으로 높은 JS에서 잘못된 패턴을 허용하기 때문이기도 합니다.
몇가지 언어적인 특징을 이해하기 앞서 가장 중요하다고 생각되는 Function , Object , Scope등을 앞으로 단계적으로 작성해보려고 합니다. 저도 이기회에 몇가지 참고할 수 있는 책과 웹을 탐독한 후 머리속에 정리되는 내용을 적어보려고 합니다. 어쩌면 짜집기식의 내용취합일 수 도 있지만 그래도 몇가지 책에서 이해하기 어려운 부분을 쉽게 작성해보려고 노력해 보겠습니다 ^^

Function - 삼형제
Function의 그 종류부터 알아보겠습니다. 정확히 딱 3가지뿐입니다.
첫번째 --> var fc = new Function();
두번째 --> function fd(){/* ...*/}
세번째 --> var fl = function(){/* ...*/}

어떻습니까? 간단하지 않습니까? 아닌가요? 사실은 비슷하기도 합니다. 당연히 사용하려는 목적(function은 기능이라는 뜻이자나요)은 동일합니다.

첫번째 var fc = new Function();
이것은 Function Class라고합니다.(어렵죠?) 생성자 함수라고도 합니다. 바로 말씀드리면 잘 사용하지 말아야할 방법입니다. (그러니 전문가도 아니고 잘 모르겠다면 안쓰면 됩니다).
심지어 Function() 안에 prameter와 함수내용을 콤마로 구분해서 (문자열의 경우 escape처리까지) 작성해야 하니 보기도 상당히 난감할 것 입니다.
몇가지 특징을 추가로 나열하면 다음과 같습니다(특징이 모두 단점이군요)
- 메모리 사용이 매우 좋지 않음
- Dynamic하게 실행될때마다 매번 생성된다(비효율)
- OOP개념의 프로그램이라고 볼 수는 있다
- 재귀호출을 지원할 수 없다(아래 두번째 방법도 이건 마찬가지 입니다)
- Scope 가 애매모호 할 수 있다(실제 실행되는 장소에 따라서 local,global등이 결정됩니다)


두번째 function fd(){/*.....*/}
이것은 가장 전형적인 함수의 모습 그 자체 입니다. Function Declarations라고 합니다. 쉬운 한국말로는 함수문장 이라고 합니다. 함수문장이라.. 말그래도 함수라는 이야기겠죠?
우리는 이런 것을 가장 흔하기 사용합니다.
사실 이것은 아래의 것과 같다고 볼 수 있습니다
같다 ==> var fd = function fd();

JS의 함수는 모든 것이 value라는 개념이라고 보시면 됩니다.(함수는 객체라고도 합니다. 이것도 분명히 맞다고 봅니다) 아무튼 우리는 이것을 가장 많이 별 걱정없이 사용하면 됩니다.

세번째 var fl = function(){/* ...*/}
이놈은 가장 골치아픈 놈이기도 합니다. (함수에 이름도 없군요). Function literal 한국말로는 함수리터럴(그렇게 그냥 읽습니다)이라고 합니다. 또는 Function Expression 이라고도 합니다.(함수표현식이라고 할 수 도 있군요)
전 함수리터럴 이라고 부릅니다. 이놈의 특징은 무엇보다 변수 fl에 함수를 저장하고 있다는 것입니다.
앞서 이야기 했지만 사실 모든 함수는 value('값')임으로 이표현은 당연하기도 합니다. 이처럼 함수는 변수에 저장할 수도 있고, 다른함수에 전달인자로 사용 할 수도 있습니다. 아 다른 함수의 리턴으로 사용할 수 도 있습니다.
함수리터럴을 설명하다보면 함수의 특징이 모두 다 나오게 됩니다. 일단 종류 설명에서는 여기까지 하고 나머지는 뒤로 미루겠습니다.
한가지 함수리터럴에서 함수의 이름을 붙일 수는 있습니다. 하지만 이것은 좋은 방법이 아닙니다. 왜냐면 함수의 Hoisting 이라는 특징이 있는데(IE에서는 이런 부분에서 오류가 발생 할 수 있다고 합니다) Hoisting이라는 것은 간략히 말해서 함수문장(Function Declarations)종류만 함수정의를 실행영역 뒤에 두어도, scope상단으로 이동하는 특징으로 인해 오류가 생기지 않는 다는 것입니다.(아 이해 가십니까? 차후 자세한 설명을 하겠습니다)
아무튼 함수리터럴에서 함수이름을 사용하는 것을 자제하면 됩니다.
var fl = function funName(){}   (x)
var fl = function(){}   (o)



Function - 객체입니다
JS에서 함수는 객체(Object)입니다.
객체는 무엇인가요? 프로퍼티(Properties)와 메소드(Method)가 있습니다. 정말 함수도 프로퍼티와 메소드가 있을까요? 그렇습니다. 존재합니다.
length, prototype, arguments 라는 프로퍼터가 있습니다.(몇개 안되는 함수의 프로퍼티(속성)임으로 꽤 중요한 특징을 담고 있겠습니다)
apply() , call(), length() 는 함수가 가지고 있는 메소드 입니다. 메소드라는 용어는 객체상에서 호출되는 함수라고 생각하면 됩니다.

몇가지 간단히 추가로 알아보겠습니다
전달인자의 개수를 판단하는 arguments.length()와 다릅니다. 함수의 length()는 argument.callee.length()로 접근하고 원래 함수가 정의된 인자의 개수를 판단할 때 사용합니다.

call()과 apply()는 함수가 실행되는 시점의 Scope을 특정 객체의 영역안으로 지정하는 효과를 얻을 수 있습니다
예를 들어 아래와 같은 식입니다.
var objectEx = {
  var funInObj : function(){},
}

objectEx.funInObj()로 호출하는 것은 objectEx객체의 메소드로 호출되는 것입니다. 그런에 이런 경우 this의 scope는 Global입니다.
this Scope를 객체로 제한하려면 아래와 같이 해야 합니다.
funInObj.apply(objectEx , ["arg"]);

이와 같은 경우 함수의 몸체안에서의 scope는 objectEx객체를 가르킵니다. call과 apply의 차이는 두번째 인자를 배열로 처리가 가능한지 아닌지의 차이만 존재 합니다.
그리고 apply의 첫번째 인자를 null로 주는 경우 this Scope는 Global을 가르킴으로 주의 해야 합니다.

함수는 객체라고 하는데요, First Class Object라는 용어로도 쓰입니다(Javascript Patterns라는 책에서 정의되었더군요) 위에서 이야기 했지만 몇가지 함수의 특징을 다시 정리하면 아래와 같습니다.
- 런타임과정에서 생성될 수 있다
- 다른 함수의 인자로 사용이 가능, 다른 함수의 리턴값으로 사용이 가능하다
- 변수로 지정할 수 있다.
- 배열의 프로퍼티로 지정 가능하다(a[0] = function(){ })
- 객체(object)의 프로퍼티로 지정 가능하다

이런 특징만으로 여러가지 형태의 패턴을 가진 함수가 존재 합니다. 이런 패턴은 여러가지 장점을 가질 수 있으면, 잘 알려진 방법도 있지만 매우 특이한 방법도 존재 합니다.
이점은 다음편에 작성해보도록 하겠습니다.


함수의 Scope
함수의 Scope는 간략히 아래와 같은 특징이 있는것 같습니다.
함수의 이름은 함수가 정의되는 순간에 Global scope가 됩니다. 하지만 함수안의 인자,변수등은 모두 지역변수로 지정됩니다.
다시말해, 자바스크립트에서 함수는 실행되는 영역이 아니고, 정의되는 영역에서 수행이 됩니다.
중첩된 함수에서 함수의 Scope는 복잡하고 재미있는 상황이 발생 합니다.
중첩된 함수라는 것은 함수안에 함수가 존재하는 형태인데요. 중첩된 함수(inner Function)가 자신의 부모함수의 변수를 사용하는 경우(중첩된 함수는 부모의 모든 지역변수를 사용할 수 있습니다)에 이를 리턴하는 경우에 부모의 변수가 함수가 종료되어도 계속 사용이 됩니다. 
이것을  closure라고 합니다(클로저)
일반적인 함수의 종료후에 그 변수가 scope chain에서 사라지는 것이여야 하는데, 이런것에 대한 약간의 예외 상황이 발생하는 것입니다.
scope chain에 대해서는 추가적으로 아래의 url에서 더 자세한 정보를 다루고 있습니다.
http://dev.naver.com/tech/ajaxui/ajaxui_2.php#a_2_2 <정말 정리가 잘되어 있습니다>
함수의 scope에 대해서 제가 더 추가적인 이해를 통해 설명을 드릴 수 있기를 기대해 봅니다 ^^


함수의 몇가지 추가사항
전달인자
전달인자는 정의된 함수의 그 개수보다 더 많아도 되고, 적어도 됩니다. 어떤 경우에도 오류를 발생 하지 않습니다. 많다면 무시되고, 적다면 undefined입니다.

name 프로퍼티
함수는 name이라는 프로퍼티가 있습니다.
function funName(){}
funName.name // funName 이 리턴

이것은 디버깅하는 경우 유용할 수 있으니 참고하시기 바랍니다.


다음에는 함수의 나머지 특징(여러가지 사용 예)에 대해서 작성해보도록 하겠습니다. 아마도 이런것이 될 것 같습니다.
  • callback()
  • hoisting
  • 즉시실행함수
  • 커링
  • 자기호출함수
<얼마나 깊이 있게 작성 하게 될지는 모르겠네요 ㅎㅎ>

마지막으로 블로그 작성이 꾸준하지 않으면 얼마나 어려운지 알게 되네요 ㅎㅎ

참고한 내용
http://rx4ajax-jscore.com
책 - JavaScript Patterns
책 - 자바스크립트 핵심가이드(The Good Parts)
책 - Javascript Definitive Guide
기타 웹상의 내용들과 어딘지 모르는 머리속 기억들..


비회원 HTML5_JS_CSS , , , , , ,