Study/JavaScript

[JavaScript] 함수의 기초

2022. 1. 12. 13:56

함수란?

  • 일련의 과정을 문(statement)으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것
  • 입력을 받아서 출력을 내보낼 때, 함수 내부로 전달 받은 변수를 매개변수(parameter), 입력을 인수=인자(argument), 출력을 **반환값(return value)**라고 한다.
  • 함수 선언을 위해서는 Keyword, name, parameter, body 가 필요하다.
// keyword -> function
// name -> hello
// parameter -> ()
// body -> {}

function hello() {

}

 

함수의 특징

  • 함수는 function 키워드로 시작하고, 실제로는 객체이다.
  • 함수는 정의/생성할 수 있으며, 출력도 할 수 있다.
  • 객체의 특성 덕분에 함수를 변수나 배열에 배정할 수 있다.
  • 다른 함수를 호출할 때, 인자를 넘겨 줄 수 있다.

 

매개변수(parameter)와 인수(argument)

함수를 선언할 때 외부로부터 받고자 하는 임의의 값을 매개변수라 하며,

실제로 함수를 호출할 때 사용되는 구체적인 값을 인수라고 부른다.

function javascriptHello(name) {
	console.log(`Hi, ${name}!`);
}

javascriptHello('youbin'); // Hi, youbin

위 코드에서 name이라는 매개변수를 받는 함수를 만들고 함수를 호출할 때 ‘youbin’이라는 인수를 전달해주었더니, Hi, youbin 이라는 값이 출력 된 것을 확인 할 수 있다.

 

함수의 결과물 return

자바스크립트의 함수는 언제나 return값을 가진다.

함수를 선언할 때 return 을 명시하지 않으면 기본값은 undefined다.

function plus(number1, number2) {
	var result = number1 + number2;
}

console.log(plus(1, 2)); // undefined

result의 값을 가져오려면 return 을 적어줘야 한다.

function plus(number1, number2) {
	var result = number1 + number2;
	return result;
}

// or

function plus(number1, number2) {
	return number1 + number2;
}

console.log(plus(1, 2)); // 3

 

참조에 의한 호출과 값에 의한 호출

함수는 원시 값을 인수로 넘겼을 때와 객체를 인수로 넘겼을 때 다르게 동작한다.

  • 인수가 원시 값일 때(값에 의한 전달)

원시 타입은 값으로 전달된다. 객체는 참조에 의해 전달되는 것과는 달리 값을 복사하여 전달한다.

같은 주소를 가리키게 하는 것과 달리 아예 새로운 주소의 같은 값으로 복사를 하는 것이다.

원시 타입은 값이 한번 정해지면 변경할 수 없고, 고정된 메모리를 가지고 있다.

function plus(x) {
	return x = x + 1;
}

var a = 1;
var b = plus(a);
	
console.log(b);
// 같은 1을 참조하는 것이 아닌, 값이 복사되어 주소가 서로 다른 1을 가리킨다.

변수 a는 원시타입 1을 가지고 있다. 이때 b에 a를 할당하면 변수 a의 값인 1이 복사되어 변수 b에 저장된다. 깊은 복사가 되었다고 할 수 있다.

 

  • 인수가 객체일 때(참조에 의한 전달)

객체의 타입은 객체 타입 또는 참조 타입이라 한다. 참조 타입이란 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리됨을 의미한다. 원시 타입은 값이 한번 정해지면 변경할 수 없지만 객체는 프로퍼티를 변경, 추가, 삭제가 가능하다.

function plus(p) {
	p.x = p.x + 1;
	p.y = p.y + 1;
	return p;
}

var a = {
	x: 1,
	y: 2
}

var b = plus(a);

console.log(a, b); // {x: 2, y: 3} {x: 2, y: 3}

변수 a에 b 값을 할당했다. 변수 a와 b는 같은 주소를 가리킨다. 즉, 변수 a와 b는 동일한 객체를 참조하고 있다.

 

인수 여러개를 우아하게 전달하는 방법

함수에 넘겨야 하는 인수 개수가 많아지면 다음과 같은 문제가 발생한다.

  • 인수의 순서를 착각하기 쉽다.
  • 함수가 받는 인수 개수를 바꾸면 함수의 호출 방법이 바뀌므로 프로그램 전체를 수정해야 한다.
function setBallPropeties(x, y, vx, vy, radius) {...}

setBallPropeties(0, 0, 10, 15, 5);

객체의 프로퍼티에 인수를 담아서 넘기면 위와 같은 문제를 해결할 수 있다.

var parameters = {
	x: 0,
	y: 0,
	vx: 10,
	vy: 15,
	radius: 5
}

function setBallPropeties(params) {...}

setBallPropeties(parameters);

이때 함수 안에서 프로퍼티를 읽는 코드를 param.vx 처럼 표현하면 되므로 인수 순서가 바뀌는 문제가 발생하지 않는다. 또 전달하는 인수를 추가하는 경우에도 프로퍼티만 추가하면 되므로 함수를 호출하는 방법을 바꿀 필요가 없다. 단, 함수 안에서 객체의 프로퍼티를 수정하면 호출한 코드에 있는 인수 객체의 프로퍼티가 함께 바뀌므로 주의해야 한다. 객체를 인수로 넘기면 함수에는 객체의 참조가 전달되기 때문이다.

 

블록 유효 범위 : let과 const

  • let

let으로 선언한 변수의 유효 범위는 블록 안이다.

let x = 'outer x';

{
	let x = 'inner x';
	let y = 'inner y';
	console.log(x); // inner x
	console.log(y); // inner y
}
console.log(x); // outer x
console.log(y); // ReferenceError: y is not defined

중괄호 바깥에 있는 변수 x의 유효범위는 전체 프로그램이며, 블록 안에 있는 변수 x,y의 유효범위는 중괄호 안쪽이다. y의 유효 범위는 중괄호 안이므로 y를 블록 밖에서 읽으려고 하면 오류가 발생한다.

또한 let문으로 똑같은 이름을 가진 변수를 선언하면 문법 오류가 발생한다.

let x;
let x; // Uncaught SyntaxError

 

  • const

const문은 블록 유효 범위를 가지면서 한번만 할당할 수 있는 변수(상수)를 선언한다.

const c = 2;

const 문으로 선언한 변수에 다시 값을 넣으면 타입 오류가 발생한다.

c = 5; // Uncaught TypeError

const 문으로 선언한 상수 값은 수정할 수 없지만, 상수 값이 객체이거나 배열일 경우에는 프로퍼티를 수정할 수 있다.

 

함수 리터럴로 함수 정의하기

함수 리터럴은 이름이 없는 함수이므로 익명함수 또는 무명함수라고 부른다.

함수 선언문 끝에는 세미콜론을 붙일 필요가 없지만 함수 리터럴 끝에는 반드시 세미콜론을 붙여야 한다.

var square = function(x) {
	return x * x;
};

사용법은 함수 선언문으로 정의한 함수와 같다. 단, 함수 선언문으로 정의한 함수는 끌어올리지만 함수 리터럴로 정의한 함수는 끌어올리지 않는다. 함수 리터럴로 정의한 익명함수는 변수에 할당한 후에야 그 이름으로 호출할 수 있다.

console.log(square(3)); // Uncaught TypeError: square is not a function
var square = function(x) {
	return x * x;
}

var result = square(3);
result; // 9

 

객체의 메서드

객체에 저장된 값이 함수일 때 메서드라고 부른다.

var user = {
	name: 'youbin',
	age: 32,
	userName: function() {
		console.log(this.name);
	}
}

user.userName(); // youbin

함수 리터럴에서 this는 함수를 메서드로 가지고 있는 그 객체를 가르킨다.

 

함수를 활용하면 얻을 수 있는 장점

  • 재사용할 수 있다.
  • 만든 프로그램을 이해하기 쉽다.
  • 프로그램 수정이 간단해진다.