본문 바로가기

Web + APP/JavaScript

JavaScript 함수와 프로토타입 체이닝 (1)

반응형
SMALL

안녕하세요 되게 오랜만이네요 !

진짜 오랜만

오늘 12월 13일, 제 생일에 맞춰서 글을 써보려 합니다.

 

글 주제는 JavaScript 함수와 프로토타입 체이닝인데, 저번 글에서 JavaScript 함수에 관해 글을 썼는데, 너무 성의 없었나해서 블로그에 다시 글을 남겨보려 합니다 !

 

본 글은 아마 프론트엔드 개발자라면 분명히 알고 있어야하는 개념인거 같고, 면접에서도 자주 나올 법한 이야기가 아닐까 싶네요 !

 

시작해볼게요 !


자바스크립트에서 가장 중요한 개념 1순위는 뭘까요?

 

당연히 함수입니다. 제가 처음 자바스크립트를 공부하면서 이 함수 부분에서는 굉장히 헷갈리는 부분이 많았습니다.

 

기존에 알고있던 Python, C 언어와는 뭔가 다른 느낌이었거든요.

 

자바스크립트에서는 이 함수를 얼마나 제대로 이해하고 활용하느냐에 따라서 고급 자바스크립트 개발자라고 할 수 있겠죠.

 

저희가 자바스크립트 함수를 조금 어색해하는 이유는 다양한 기능이 존재하기에 그렇습니다. 대표적으로 모듈화 처리, 클로저, 객체 생성과 같은 개념을 이해하고 있어야하는데 이를 세밀하게 살펴보도록 합시다.

 

  • 함수 생성
  • 함수 객체
  • 다양한 함수 형태
  • 함수 호출과 this
  • 프로토타입과 프로토타입 체이닝

함수 정의

자바스크립트 함수를 공부하는데에 있어서 헷갈리는 부분은 함수를 생성하는 방법이 3가지나 존재하기 때문이 아닐까 싶습니다.

  • 함수 선언문
  • 함수 표현식
  • Function() 생성자 함수

진심 개 싫음. 처음 공부할 때 얼마나 헷갈렸는지..

사실 지금도 가끔 헷갈림

함수 선언문

function add(x, y) {
	return x + y;
}

여타 다른 언어의 함수 선언과 큰 차이점을 잘 모르겠죠?

 

본 방법을 함수 선언문 방식으로 함수를 생성한 것입니다. Python과 마찬가지로 변수 타입을 기술하지 않는다는 점에서는 동일한데, 이 방법들이 추후에 너무 에러를 많이 불러 일으켜서 TypeScript라는 것이 각광받기도 했었죠. 본 내용은 이 글의 범위에서 넘어가니 다음에 살펴보도록 하죠

 

함수 표현식

자바스크립트에서는 함수도 하나의 값처럼 취급됩니다. (본 특징 때문에 자바스크립트의 함수가 일급 객체라고 불리죠)

 

이런 방식으로 함수를 하나 만들고 생성된 함수를 변수에 할당하여 함수를 생성하는 것을 함수 표현식이라고 합니다.

var add = function (x, y) {
	return x + y;
};

var plus = add;

console.log(add(3,7)); // 10
console.log(plus(3,7)); //  10

여기서 함수 리터럴로 생성한 함수는 함수명이 없기에 익명 함수라 불립니다.

 

add는 함수의 참조값을 가지므로 또 다른 변수 plus에도 그 값을 그대로 할당할 수 있습니다.

 

본 위의 방법을 익명 함수를 이용한 함수 표현식 방법 (익명 함수 표현식) 이라고 불리기도 합니다.

 

함수 표현식은 함수 선언문 문법과 거의 유사하지만, 함수 표현식 방법에서는 함수 이름이 선택 사항이라는 것입니다. 보통은 사용하지 않습니다.

 

이름을 붙히면 기명 함수 표현식이라 하는데 이런 경우엔 주의점이 있습니다.

var add = function sum(x, y) {
	return x + y;
};
    
console.log(add(3,7)); // 10
console.log(sum(3, 7)); // Error

위의 코드에서 sum 함수의 경우엔 에러가 발생하는데, 이것은 함수 표현식에서 사용된 함수 이름이 외부 코드에서 접근이 불가능하기 때문입니다.

 

실제로 함수 표현식에 사용된 함수 이름은 정의된 함수 내부에서 해당 함수를 재귀적으로 호출하거나, 디버거 등에서 함수를 구분할 때 사용됩니다.

 

var factorialVar = function factorial(n) {
	if (n <= 1) {
    	return 1;
	}
    return n * factorial(n-1);
};

console.log(factorialVar(3)) // 6
console.log(factorial(3)) // Error

function statement와 function expression에서의 세미콜론

함수 선언문 방식으로 add() 함수를 정의할 때는 세미콜론(;)을 붙이지 않고, 함수 표현식 방법에서는 세미콜론(;)을 붙인걸 발견하신 분이면 당신은 관찰력이 매우 좋으신 분이시군요 !!

오타라고 생각하실 수도 있지만 이는 하나의 관습입니다.

 

일반적으로 자바스크립트 코드를 작성할 때 함수 선언문 방식으로 선언된 함수의 경우엔 세미콜론을 붙이지 않지만, 함수 표현식으로 선언된 함수의 경우엔 세미콜론을 붙이는걸 권장합니다.

 

그 이유는 뭘까요??

 

추후에 배울 즉시 실행 함수(나중에 배울)에서의 난감한 상황이 있을 수 있기 때문입니다.

 

아래 예시를 보시죠.

var func = function () {
	return 42;
} // 세미콜론을 사용하지 않음
(function() {
	console.log("function called");
})();

본 코드에서 세미콜론을 사용하지 않았으므로, 실제로 func() 함수를 호출하면 의도와는 다르게 'number is not a function' 이라는 에러가 발생합니다.

 

그 이유는 자바스크립트 파서가 func()의 함수 정의에서 세미콜론을 사용하지 않아, return 42; 문장을 지나 func()의 함수 정의 끝에 있는 중괄호(})만으로 func() 함수가 끝났다고 판단하지 않기 때문입니다. 결국엔 즉시실행 함수를 보고 이를 마치 func() 함수 호출 연산으로 생각해서 func() 함수를 호출해버리는 거죠.

 

결국 42(); 라는 이상한 형태가 되며 42는 숫자이지 함수가 아니므로 'number is not a function'이라는 에러가 발생하게 됩니다.

 

참고로 구글의 자바스크립트 스타일 가이드에 이와 관련된 내용이 있습니다.

 

구글이 쓰는데, 저희도 써야죠.


Function() 생성자 함수를 통한 함수 생성하기

이 장의 뒷부분에서 설명하겠지만 자바스크립트 함수도 Function ()이라는 기본 내장 생성자 함수로부터 생성된 객체라고 볼 수 있습니다.

var add = new Function('x', 'y', 'return x + y');
console.log(add(3, 4)); // 7

하지만 Function () 생성자 함수를 사용한 함수 생성 방법은 자주 사용되지 않으니 상식 수준으로 알아두도록 합시다.

아는 척 할 때 써야죠

함수 호이스팅

지금까지 함수를 생성하는 3가지 방법을 살펴봤습니다. 코드는 약간씩 다르지만 서로 모두 같은 기능의 함수를 생성함을 확인 했습니다.

 

하지만, 이들 사이에는 동작 방식이 약간 차이가 있는데, 그 중의 하나가 바로 함수 호이스팅입니다.

 

함수 선언문, 표현식 중 표현식만을 사용할 것을 권하고 있는데 이가 바로 함수 호이스팅 때문입니다.

 

예를 보도록 하죠

add(2, 3); // 5

function add(x, y) {
	return x + y;
}

add(3, 4); // 7

함수 호이스팅은 함수를 사용하기 전에 반드시 선언해야 한다는 규칙을 무시하므로 코드의 구조를 엉성하게 만들 수도 있다고 지적하며, 함수 표현식을 권장하고 있습니다.

add(2, 3); // uncaught type error

var add = function (x, y) {
	return x + y;
};

add(3, 4); // 7

이러한 함수 호이스팅이 발생하는 원인은 자바스크립트의 변수 생성초기화의 작업이 분리돼서 진행되기 때문입니다. 이에 대해선 추후에 알아보도록 해요.


이상 JavaScript 함수와 프로토타입 체이닝 (1) 였습니다. ^_^

반응형
LIST