함수

Noob·2022년 10월 25일

함수

함수의 기본은 입력을 받아 출력을 내보내는 과정을 정의한 것이다.

그림에 있는 함수를 코드로 작성

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

add(1,2)	// 3

그럼 굳이 이렇게 함수의 형태를 안만들고도 연산을 할 수 있지 않나 싶지만
함수를 사용 시 코드의 재사용성, 1+2, 3+4, 1+6등 같은 코드를 중복 사용 시 함수를 이용하면 수정 시 시간이 줄어 유지 보수의 편의성이 높고 코드를 보기가 편해진다.

함수 리터럴

자바스크립트에서 함수는 객체 타입의 값이다. 함수 리터럴도 평가되어 값을 생성한다.

함수 정의법 4가지

함수 선언문 
function add(x,y) {
	return x + y
} // 함수 선언문은 표현식이 아닌 문이다. 즉 변수에 할당 할 수 없다..

함수 표현식
const add = funtion(x,y) {
	return x+y
}

Function 생성자 함수
const add = new Function('x' , 'y', 'return x + y')

화살표 함수
const add = (x,y) => x + y

함수의 선언

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

함수명 add는 몸체 내부에서만 유효한 식별자인 함수 이름이다. 따라서 add로 함수는 본래라면 호출 할 수 없어야 한다. 함수를 호출 하려면 add가 함수 객체를 가리키는 식별자여야 한다.
그럼에도 add로 함수는 호출이 된다 왤까.

자바스크립트 엔진이 암묵적으로 생성한 식별자로 add를 만들었기 때문이다. 함수 객체를 가리키는 식별자가 없으면 함수 객체를 참조, 호출이 불가능하다 그래서 자바스크립트 엔진이 함수 이름과 동일한 식별자를 생성한 후 함수 객체를 할당한다.

결론 add는 함수 이름으로 호출하는게 아니라 함수 객체를 나타내는 add를 가리키는 식별자로 호출한다.

함수 표현식

표현식이기에 식별자에 함수를 할당 할 수 있다.
자바스크립트에서 함수는 일급 객체이기때문에 값으로써 자유롭게 사용 가능하다.

함수와 호이스팅

console.log(add(1,2))	// 3 함수 선언이 아래에 있는데도 콘솔찍힘 호이스팅임
console.log(add2(1,2))	// 타입에러 함수 표현식이라 함수 선언식과 생성 시점이 다름

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

var add2 = function(x, y) {	// 함수 표현식으로 정의한 함수는 이후에 호출해야 한다.
	return x + y
}

근데 함수를 호출하기 전에 함수를 선언해야 한다는 규칙때문에 함수 선언문보단 함수 표현식을 사용하는걸 권장한다.

Function 생성자 함수

빌트인 함수인 Function(대문자 주의) 생성자 함수에 매개변수, 함수 몸체를 "문자열"로 전달하면서 new 연산자와 함께 호출하면 함수 객체를 생성한다. 근데 new 연산자의 차이는 잘 모르겠다.
생성자 함수는 클로저를 생성하지 않는 등 다르게 동작한다.

클로저?

const add = (function () {
	const a = 1
    return function(x,y){
        return x + y+ a
    }	
    // 함수 표현식의 반환값으로 함수를 리턴했다. 이런걸 클로저라 한다
}())
add(1,2)	// 4 정상적으로 리턴 함수에 접근한다
const add2 = (function () {
	const a = 1
    return new Function('x','y','return x + y + a')	
    // 함수 표현식의 반환값으로 생성자 함수를 리턴했다.
}())
add2(1,2)	//	레퍼런스에러 클로저를 생성하지 못한다;

화살표 함수

function 키워드 없이 화살표를 "=>" 사용하여 간략한 방법으로 함수를 선언한다.

const add = (x,y) => x+y
add(1,2)	// 3

단순히 함수 표현식을 간략화 한게 아니라 내부 동작 또한 다르다. 생성자 함수로는 사용 불가능 하고 기본 함수와 this 바인딩 방식이 다르다. prototype프로퍼티가 없고 인수 객체를 생성 안한다.

인수 확인

매개변수보다 더 많은 인수를 전달했을 시.

function add(x,y) {		// 매개변수는 x와 y 뿐인데 인수를 더 넘겨주면 어찌될까
    console.log(arguments)	// arguments 객체안에 저장된다, 인덱스로 접근 가능
	return x + y
}
add(1,2,3,4)

매개변수보다 더 적은 인수를 전달했을 시.

function add(x,y) {		
	x = x || 0		
    y = y || 0		// 원래 매겨변수 y는 아무런 인수를 받은게 없어 undefined지만 단축평가로 오류 내지 않고 결과 값을 얻을 수 있다
	return x + y
}
add(1)	// 1

function add(x = 0,y = 0) {	// 또는 매개변수 기본 값을 이용하는 방법도 있다		
	return x + y
}
add(1)	// 1

매개변수는 최대 개수의 제한은 없지만 함수의 이해를 힘들게 하고 유지보수가 힘들다.
이상적인 매개변수는 0이며 함수는 한가지 일만 한다
.

즉시 실행 함수

함수 정의와 동시에 즉시 호출되는 함수다. 재 호출이 불가능하다.

(function () {	// 함수 식별자가 없다. 넣어도 되지만 그릅 연산자내의 함수 리터럴로 평가되어 함수 몸체에서만 참조 가능한 식별자가 되어 호출은 마찬가지로 불가능하다.
	return 1 + 2
}())

const add = (function (x,y) {	// 즉시 실행 함수도 값을 반환 할 수 있고 인수 전달도 가능하다.
	return x + y
}(1,2))
console.log(add)	// 3

재귀 함수

함수가 자기 자신을 호출하는 걸 재귀 호출이라 한다. 코딩 테스트할때 시간 복잡도를 낮추기 위해 자주 사용한다.

	function count(n){	// 반복문으로 0이 될때까지 카운트하는 함수
    	for(let i = n; i >= 0; i--){
        	console.log(i)
        }
    }
    count(5)	// 5 4 3 2 1 0
    
    function count(n){	// 재귀로 0이 될때까지 카운트하는 함수
    	if(n < 0){	// 만약 0이 된다면 멈추라는 조건문
        	return
        }
        console.log(n)
        count(n-1)	// count 함수안에 count 호출이 있다.
    }
    count(5)	// 5 4 3 2 1 0

중첩 함수

함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라 한다. 중첩 함수의 호출은 외부 함수 내부에서만 가능하다.

function out() {		
	const x = 1
    function inn() {
    	const y = 2
        console.log(x + y)
    }
    inn()
}
out()	// 3
inn()	// 레퍼런스 에러

if문이나 for문 등에서도 함수 선언이 가능하지만 호이스팅에 의한 혼란이 있을 수 있으므로 안하는게 좋다.

콜백 함수

함수의 배개변수를 통해 함수의 내부로 전달되는 함수를 콜백 함수라 한다. 그리고 전달 받아진 외부 함수를 고차 함수라 한다.

function result(x, y, f){	// 매개변수 f는 함수를 추상화 시킨다. 고차함수
	return f(x,y)
}

const add = function (x, y){	// 콜백 함수로 매개변수를 더해준다
	return x + y
}

const multiple = function (x, y){	
	return x * y
}

result(1,2,add)		// 3
result(1,2,multiple)	// 2

비동기 처리에서도 많이 쓰인다.

document.getElementById('button').addEventListener('click', function () {console.log('button click')})

배열 고차함수에서의 콜백 함수

const arr = [0,1,2].map(function (x) {	// map 함수는 배열 0부터 끝까지 순회한다
	return x + 1	// 순회할때 해당 인덱스 배열에 접근해 +1을 해준다
})
console.log(arr) //[1, 2, 3]

순수 함수

외부 상태를 변경하지 않는 함수는 순수함수, 그 반대는 비순수 함수라 한다.

function add (x){	// 순수함수
	return x + 1
}

const count = 0
function add (){	// 비순수 함수
	return count + 1
}

비순수 함수가 외부 상태의 변경을 하면 쉽게 추적하기 힘드므로 최대한 순수 함수를 이용하는것이 옳다.

profile
나의 기록

0개의 댓글