javascript function

박재성·2021년 12월 31일
0

함수란?

수학에서 함수

학교를 다닐 때 함수를 처음 접하면, 함수를 이렇게 정의합니다.

어떤 값의 입력에 따라 출력값이 정해지는 것

중학교 수업시간에 배운 정의입니다. 수학을 더 공부했거나, 해석학을 공부하셨다면 위 정의를 아니꼽게 생각할 수 있지만, 함수의 기본 원리만 이해하고 프로그래밍에서, 혹은 자바스크립트에서 함수가 어떤 것인가 살펴봅시다.

자바스크립트에서 함수

함수 선언문

처음 언어를 접하거나 c, java와 같은 언어를 먼저 배웠던 사람들은 자바스크립트 함수가 이상하게 보일 것입니다.

function add(a, b){
	return a + b;
}

보통 함수는 이렇게 '정의'합니다.

하지만 자바스크립트는 함수를 정의하는 방법이 몇 가지 더 있습니다.

그 중에 사용하지 않는 생성자를 이용한 함수 정의는 생략하겠습니다.

자바스크립트 공식 문서로 많은 사람들이 보고 있는 'MDN'에 따르면 함수 정의는

let f = function add(a, b){
	return a+ b;
}

같이 함수 리터럴을 사용해서 정의하는 것을 더 올바른 방법이라고 설명합니다.

이유는 '함수 호이스팅' 때문입니다.

함수 호이스팅

앞서 'var'를 이용한 변수 선언은 변수 호이스팅 문제가 발생해 프로그래밍의 복잡성을 높일 수 있다고 설명했습니다.

함수 호이스팅도 마찬가지입니다.

함수 선언문을 통해 함수를 정의하면, 런타임에 들어가기 전 자바스크립트 엔진이 먼저 평가과정을 거치면서, 선언문들이 먼저 할당이 이뤄집니다.

먼저 할당이 이뤄지면 당연히 우리가 함수를 정의했다 하는 부분 전에 함수를 호출해도 정상적으로 동작을 하기 때문에 실수가 더 많이 일어날 수 있습니다.

이를 방지한 함수 정의 방식이 함수 리터럴을 이용한 함수 표현식입니다.

함수 표현식

자바스크립트에서 함수는 '객체'입니다. 따라서 리터럴을 통해 함수를 정의할 수 있습니다.

리터럴이란 알다시피 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기를 뜻합니다.

함수 리터럴은 function키워드를 통해 '값'을 생성하고, 함수 이름, 매개변수목록, 내용들로 구성되어 있습니다.

let f = function test(){...}

test() --- 1
f()    --- 2

함수 표현식을 통해 함수를 정의할 때 꼭 알아야 하는 특징들이 있습니다.

위 예시에서 함수를 호출하려면 어떤 식별자를 써야할까요?

리터럴은 몸체 내부에서만 참조할 수 있다.

이 점을 꼭 기억해야 합니다.

따라서 test() 가 아니라 f()를 통해 함수를 호출할 수 있습니다.

f라는 식별자를 통해 함수를 호출하는 것입니다. 만약에 test함수 내에 함수가 있을 때는 함수 이름인 test를 사용해 함수를 호출할 수 있습니다.

다시 말해, 자바스크립트에서 함수는 객체입니다. 객체를 메모리에 저장하는 그림을 떠올려 보면 함수가 어떻게 저장되고, 불리는지 알 수 있습니다.

따라서 함수 표현식을 통한 함수 정의에서 식별자(변수)를 통한 함수 호출은 어찌보면 당연하게 생각해야 합니다.

변수에 함수 리터럴로 정의한 함수 표현식을 할당하는 것이 객체를 변수에 할당한 것과 근본적으로 다르지 않다는 것을 알 수 있습니다.

외부 상태 변경

함수는 어떤 값을 대입해 값을 출력하는 것입니다. 함수에 값을 대입한다는 의미는 매개변수를 의미합니다.

자바스크립트에서 매개변수는 어떤 데이터 타입을 넣어도 상관이 없습니다. 원시 값을 넣을 수도 있고, 객체를 넣을 수도 있습니다. 객체라 하면, 함수를 넣을 수도 있고, 배열을 넣을 수도 있습니다.

매개변수에 값을 전달해 새로운 값을 리턴했습니다. 매개변수로 입력한 값은 어떻게 될까요?

값을 전달하는 방식은 값에 의한 전달, 참조에 의한 전달이 있습니다. 어떤 타입이건 결국에는 참조에 의한 전달이 이뤄진다는 것을 공부했습니다.

let num = 100;
let obj = {
	name: 'park',
}
f(num)
f(obj)

num은 원시타입이기 때문에 값을 변경할 수 없습니다. 매개변수로 사용된 num은 재할당을 통해 새로운 원시 값으로 교체되어 실행됩니다.

반대로 객체를 매개변수로 전달하면, 객체를 변경 가능한 값으로 참조에 의한 전달이 일어나 함수를 통해 객체의 값을 변경할 수 있게 됩니다.

다시말해, 원시 타입을 할당한 변수를 매개변수로 전달하면 원본 값이 훼손되지 않지만, 객체 타입을 할당한 변수를 매개변수로 전달하면, 원본 값이 훼손될 수 있습니다.

외부에서 함수로 전달한 값의 원본 값이 변경되는 현상으로 부수효과 라고 합니다.

그래서 스코프에 대한 개념이 정말 중요합니다!

스코프는 다음 장에서 다룹니다!

profile
개발, 정복

0개의 댓글