본문 바로가기
javascript

[자바스크립트] 함수는 무엇이다

by jinbro 2017. 3. 15.

[함수란]

1) 일반적 기능
- 특정 작업에 필요한 일련의 구문들을 그룹화하기위한 개념
- 동일 작업을 필요할 때마다 불러오기위해 필요한 개념 : 코드 재사용

2) 자바스크립트 기능
- 객체생성 : 생성자함수(http://jinbroing.tistory.com/54 : 생성자함수 검색)
=> 정보은닉(데이터), 함수 생성, 모듈화
- 함수도 객체(first-class object, 일급객체)이기때문에 변수나 객체, 배열에 저장될 수 있고, 다른 함수의 파라미터, 반환값으로 사용될 수 있음


[함수정의]
1) 함수선언식 : function 키워드로 선언함
- 함수명 : 함수명 생략 불가, 함수명으로 재귀적 호출(자신 호출), 디버거가 해당함수를 구분할 수 있는 식별자 역할
- 파라미터(매개변수) : 함수가 호출될 시 필요한 데이터를 받을 때 사용, 0개 이상 괄호( ( ... ) )로 묶고, 2개 이상일 경우 쉼표(,)로 구분
- 함수 내부 : 함수가 호출되었을 때 실행되는 구문의 집합, 함수 중괄호( { ... } )내에 정의함, return 문을 통해 결과값을 반환할 수 있음
- 익명함수가 허용되지 않음 : 함수명을 반드시 기입해야함
1
2
3
function myFunction(num1, num2) {
     return num1 + num2;
}
cs

2) 함수표현식 : 함수도 객체이므로 리터럴 방식 정의가 가능함, 익명함수라고 하기도 함
- 함수 자체를 변수에 저장하는 것이 아니라 함수를 가리키는 참조값을 저장함
- 리터럴 표기 : 값 그 자체를 표기하는 것, function을 변수에 할당 : function 키워드 + function명으로 함수를 정의하는 것이 아님
- 리터럴 표기로 정의할 때 익명으로 할 수 있고, 기명으로 할 수 있지만 함수를 호출할 때에는 변수로 호출해야함
- 함수선언식도 자바스크립트 엔진에 의해 내부적으로 함수명과 같은 변수명을 만들고, 외부에서는 변수명을 호출하는 것임 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var sum = function(num1, num2) {
     return num1+num2;
}
 
var sum2 = sum;
console.log(sum2(10,10)); // 20
 
var multiply = function mul(num1, num2) {
     return num1 * num2;
}
 
console.log(mul(53));
/ *
      Uncaught ReferenceError: mul is not defined
     함수표현식으로 선언된 함수는
     외부에서 함수명으로 호출 못하게되어있음
*/
 
var multiply = function multiply(num1, num2){
     return num1 * num2;
}
 
console.log(multiply(53));
/*
     함수명으로 호출하는 것 같지만
     함수의 변수명으로 호출하는 것임
     (함수선언식도 내부적으로 같은 구조 == 리터럴 방식으로 정의되는 것)
*/
cs

3) Function() 생성자함수 : 객체 생성자가 아니라 함수를 생성하는 생성자함수
- 추천하지않음
- 1~2번 항목이 3번 방식을 단순화한 것
1
2
3
4
5
var sum = new Function('num1''num2''return num1 + num2');
/*
     new Function(arg1, arg2, ....., argN, functionBody);
*/
console.log(sum(53)); // 15 
cs


[함수 호이스팅]
- var 키워드나 function 키워드로 생성된 것을 해당 스코프 맨위로 옮기는 것
- 이로인해 함수가 선언되기 전에, 변수가 선언되기 전에 명령을 해도, 연산을 해도 에러가 나지않음
- 발생원인 : 자바스크립트는 변수 생성과 초기화(값 할당)가 분리되어 진행되기 때문(추후 자세한 포스팅)
- 함수 선언 방식에 따라 호이스팅 되는 것이 다름 

1) 함수선언식 : 함수 호이스팅이 됨, 함수가 호출문보다 뒤에 선언되어있어도 호출 가능
- 함수선언식으로 선언된 함수는 자바스크립트 엔진으로 스크립트가 로딩되는 시점에 바로 초기화를 한 후 VO(variable object)에 저장
- 앞으로 살펴봐야할 것 : 자바스크립트 엔진 내부 동작 흐름


2) 함수표현식 : 변수 호이스팅 됨, 함수를 먼저 호출할 경우 TypeError가 발생함


- 함수선언식이 함수호이스팅에 의해 함수 호출 전 반드시 함수를 선언해야한다는 규칙을 무시함
    => 코드 구조를 엉성하게 만들 수 있어 함수표현식만을 사용할 것을 권고하고 있음
- 함수 선언식으로 정의를 하면 개발자가 사용하기에는 쉽지만 대규모 애플리케이션 개발하는 경우 인터프리터가 너무 많은 코드를 VO에 
  저장하므로 애플리케이션 응답속도가 현저히 떨어질 수 있으므로 주의해야한다고 함
- 앞으로 살펴봐야할 것 : VO(자바스크립트 엔진 동작 원리?를 찾아볼 것)


[일급객체, 함수]
- 대상 자체가 무명리터럴로 선언될 수 있고, 파라미터, 반환값, 객체/배열에 저장될 수 있으면 일급객체라 함
- 흡사 변수와 같이, 일반값 같이 사용할 수 있음

1) 객체에 저장됨


2) 파라미터로 사용됨


3) 반환값으로 사용됨 : 객체 -> 함수 호출

- 함수 내의 객체에 저장된 함수 호출 : return으로 함수를 리턴함
- 파라미터 전달 
- 연산 후 값 리턴
- 객체(object)의 key값(value는 함수명)으로 문자열을 사용할 수 있는데, 객체명["key값"]으로 함수를 불러올 수 있다는 점
    => 객체[index값]을 줘도 됨


[함수 매개변수]
- 함수 실행에 있어서 필요한 값이 있을 때 함수명 옆 괄호( (....) )에 매개변수명을 기입하여 사용함
- 개수는 상관없음 
- 함수 내에서 사용하는 변수(지역)와 같이 메모리가 할당되며, 초기값은 함수를 호출할 때 전달하는 값(인수)가 초기값이 됨
- 일반 변수는 값을 지정해주지 않으면 undefined가 지정됨
- 함수를 정의할 때 파라미터를 함께 정의했다면 반드시 파라미터를 기입해야하므로 호출 시 전달되는 값(인수)로 초기화 됨
- 매개변수로 기본자료형(primitive type), 객체형(object type, reference type)을 사용할 수 있음
- 객체형(또는 참조형 : 변수에 실제 저장된 값은 값이 저장된 메모리 주소값 이하 참조값)은 값을 전달하는게 아니라 참조값이 저장됨



[함수 반환값]
- 자신을 호출한 코드에게 수행한 결과를 반환(return)할 때 사용함
- return 키워드를 사용하여 값을 반환함
- 반드시 사용하는 것은 아님, 생략가능 이때의 반환값은 undefined임
- 자바스크립트 해석기는 return 키워드를 만나면 호출한 곳으로 돌아감, return 이후 구문은 실행되지않음 

1) 반환값이 있을 경우


2) 반환값이 없는 경우 : undefined


3) return 키워드의 힘




[함수, 객체 그리고 구조]
- 함수는 객체, 따라서 속성을 가질 수 있음
- 기본적으로 함수가 가지고 있는 속성들이 있음, 이제부터 그걸 알아볼 것임
- 함수의 구조를 콘솔로 보고싶을 때 : console.dir(함수명)



1) arguments
- 함수 호출 시 전달되는 인수 정보를 배열 형태로 담고있는 객체(유사배열 - 배열은 아니지만 length 속성을 사용할 수 있는 객체)
- 함수 내에서 지역변수로 사용
- 전달되는 인수가 없을 때 빈 배열, 초기화 시에는 undefined로 초기화됨
- 인수 개수가 초과되면 초과되는 것부터는 무시함 : arguments는 유사배열이기 때문에 이것을 활용해 또다른 로직을 짤 수 있음


2) caller 
- 자신을 호출한 함수를 담고 있음 : 함수에서 함수를 호출했을 때 어디에서 호출했는지 볼 수 있음
- 호출한 함수가 없을 때에는 null임 : 일반적으로 자신을 그냥 호출했을 때



3) length
- 함수 정의 시 작성된 매개변수의 개수를 의미함
 


4) name
- 함수명을 나타냄(익명, 기명 상관없이 가짐 : 함수선언식이 내부적으로 함수표현식으로 변환)

[prototype과 __proto__ 속성 설명에 들어가기전, 프로토타입이란?]
 (1) 한국말로 원형
 (2) 자바스크립트 생성자 : 함수, 함수를 호출할 때 new를 붙여주면 생성자함수 -> 결과 : 새로운 객체를 만들고 리턴함 
 (3) 빈 객체를 사용하려면 객체리터럴로 생성하면되지만 공통 속성, 동작들을 주기위해 생성자함수(new를 통해 객체 생성)를 사용함
 (4) 프로토타입은 공통속성, 동작들이 정의된 객체(함수)의 원형(자기 자신을 뜻하는 프로퍼티가 function 속성에서 prototype임)

 - prototype 속성은 생성자함수의 정보(속성, 동작)이 담겨있음
 - 함수는 생성자 속성 이외에도 공통된 속성, 동작을 가질 수 있음 
 - 자바스크립트가 함수 기반이기때문에 가지는 특징 - 프로토타입 / 함수의 속성, 동작 
 - prototype 속성을 활용하면 상속의 개념과 비슷하게 구현이 가능함 : 이런 개념을 프로토타입 체인(prototpye chain)이라 함 
 - 프로토타입은 생성자 함수를 통해 객체를 생성했을 때 공통의 속성, 동작이 담겨져있는 객체임, 생성자 함수의 원형 객체이고, new를 통해 사용자 정의 객체를 생성하면 원형(프로토타입) 객체에 있는 공통 정보를 가져오고 각각에 맞는 정보로 수정하면 됨, 생성자함수의 공통적인 값, 동작(함수)을 생성하면 new로 생성된 객체에서 사용가능함
- 프로토타입을 이용하여 내장객체(Array, Number 등)에 사용자정의 속성, 함수를 추가하여 확장을 시킬 수 있음

5) __proto__
- __proto__ 속성은 본 함수가 아니라 본 함수와 연결된 상위 객체의 원형, 부모/자식(상속)관계 비슷하도록 구현할 수 있도록 두 객체 사이 연결시켜주는 함수 속성 
- 본인(본 함수객체, 여기서는 Sub 함수) 함수 객체 인스턴스의 속성으로 연결된(Super 함수) 함수의 속성을 사용할 수 있음
- 모든 객체가 가지고 있으며, 어느 특정 함수를 상위객체로 가지고 있지 않다면 상위객체로 기본 객체인 빈 Object를 가지고 있음
- __proto__ 를 통해 연결되는 것을 프로토타입 체인(prototype chain)이라고 함 


6) prototype 
- prototype 속성은 본 함수의 객체 원형(공통 속성(프로퍼티), 동작(메서드))를 담는 객체
- prototype 속성(객체)의 속성 중 constructor가 함수 객체 자신을 가리키는 속성임


- 함수 객체만(new를 통해 생성되는 객체가 x) 가지는 속성 : new를 통해 생성되는 객체들이 공통적으로 가지는 속성

5와 6번 항목) 정리
- prototype 속성은 본인(자기 자신 함수)의 원형(초기값을 가질, 객체의 원형, 자바에서 생성자함수 역할) 
-  __proto__ 속성은 본인과 연결된 상위 함수의 객체 원형
- 상위 함수의 객체 원형과 현재 함수의 원형을 연결시키는 방법 : 현재 함수의 원형 속성에 상위객체 생성자(new 함수명)를 연결 
- 함수도 자체도 객체다 를 잊지말 것 


[함수의 다양한형태]
1) 내부함수 : 함수 내에 함수를 두는 것
- 내부함수는 부모함수의 변수에 접근 가능하지만, 반대로(부모->내부) 는 접근 불가 : 함수가 호출되어야만 함수가 동작을 함
- 내부함수는 부모함수 이외의 외부에서 접근할 수 없음


2) 콜백함수 : 특정이벤트가 발생했을 때 호출되는 함수
- 함수는 일급객체(값처럼 사용가능하다는 것을 일급객체라 함)이기 때문에 이벤트 리스너 함수의 파라미터로 전달가능함
- 콜백함수는 콜백 큐에 들어가 있다가 해당 이벤트가 발생하면 호출됨
- 웹 통신 관련 비동기처리를 할 때에도 사용된다고하는데 이것은 나중에 다시 알아보겠음!(Ajax!)
- 이벤트 관련 함수가 있는지 찾아보자






'javascript' 카테고리의 다른 글

[웹 기본개념] HTTP 통신  (0) 2017.03.21
[자바스크립트] 프로토타입  (0) 2017.03.18
[자바스크립트] 객체 #2  (0) 2017.03.14
[자바스크립트] 객체  (0) 2017.03.11
[자바스크립트] 제어문(control-flow)  (0) 2017.03.10

댓글