다시 처음부터 JavaScript || 함수 (1) ⭐️

문규찬·2021년 11월 10일
0
post-thumbnail

✅ 출처 : 다시 처음부터 자바스크립트 게시글은 이웅모(님) '모던 자바스크립트 Deep Dive' 를 기록합니다

•함수란?

함수는 자바스크립트에서 가장 중요한 핵심 개념입니다! 스코프, 실행 컨텍스트, 클로저, 생성자 함수에 의한 객체 생성, 메서드, this, 프로토타입, 모듈화 등이 모든 함수와 깊은 관련이 있어 함수를 정확히 이해하고 넘어가야 합니다!

프로그래밍 언어의 함수도 수학의 함수와 같은 개념입니다. f(x,y) = x+y 를 자바스크립트 함수로 표현하면

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

add(2,5) // 7

프로그래밍 언어의 함수는 일련의 과정을 문(statement)으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것입니다.

-함수를 사용하는 이유

함수는 몇 번이든 호출할 수 있으므로 코드의 재사용이라는 측면에서 매우 유용
코드의 중복을 억제하고 재사용성을 높이는 함수는
유지보수의 편의성을 높이고
실수를 줄여 코드의 신뢰성을 높입니다.

함수는 객체지만 일반 객체와는 다릅니다. 일반 객체는 호출할 수 없지만 함수는 호출이 가능하지요. 그리고 일반 객체에는 없는 함수 객채만!의 고유한 프 로 퍼 티 를 갖습니다.

-함수선언문

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

함수 선언문은 함수 이름을 생략할수 없! 습! 니다. (add)
함수 선언문은 표현식이 아닌 문입니다. 콘솔에서 선언문을 실행하면 완료 값 undefined가 출력됩니다.
(*표현식은 값으로 평가될 수 있는 문(statement)입니다)

자바스크립트 엔진은 함수 선언문을 해석해 함수 객체를 생성합니다. 이때 함수 이름은 함수 몸체 내부에서만 유효한 식별자이므로 함수 이름과는 별도로 생성된 함수 객체를 가리키는 식별자가 필요합니다.
따라서 자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당합니다.

-함수표현식

자바스크립트의 함수는 객체 타입의 '값'입니다.
이처럼 값의 성질을 갖는 객체를 일급 객체라 하는데 자바스크립트의 함수는 일급 객체입니다.
함수가 일급 객체라는 것은 함수를 값처럼 자유롭게 사용할 수 있다는 의미입니다.

함수선언문으로 정의한 add함수를 함수표현식으로 바꿔서 정의하면

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

console.log(add(2,5)) // 7

함수 선언문에서 살펴본 바와 같이 함수를 호출할 때는 함수 이름이 아니라 함수 객체를 가리키는!!! 식별자를 사용해야 합니다. 함수 이름은 함수 내부에서만 유효한 식별자이므로 함수 이름으로 함수를 호출할 수 없습니다.

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

//함수 객체를 가리키는 식별자로 호출
console.log(add(2,5)) // 7

//함수 이름은 함수 몸체 내부에서만 유효한 식별자이므로 에러!
console.log(foo(2,5)) // ReferenceError

함수 선언문과 함수 표현식에 대한 차이는 따로 정리하겠지만

함수 선언문은 "표현식이 아닌 문" 이고 함수 표현식은 "표현식인 문"입니다. 미묘하지만 중요한 차이가 있습니다.

-함수 생성 시점과 함수 호이스팅

//함수 참조
console.dir(add) // f add (x,y)
console.dir(sub) // undefined

//함수 호출
console.log(add(2,5)) // 7
console.log(sub(2,5)) // TypeError

//함수 선언문
function add(x,y){
return x+y;
}

//함수 표현식
var sub = function(x,y){
return x-y;
};

예제와 같이 '함수 선언문' 으로 정의한 함수는 함수 선언문 이전에 호출할 수 있지만 함수 표현식을 그렇지 않습니다 (TMI...이부분 좀 신기했음...)
함수 생성 시점이 다르기 때문인데요

모~든 선언문이 그렇듯 함수 선언문도 코드가 한 줄씩 순차적으로 실행되는 시점인 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행됩니다. 함수선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼서 생성됩니다. 그리고 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당합니다.

따라서 함수 선언문 이전에 함수를 참조할 수 있으며 이를 자바스크립트 고유의 특징인 함수 호이스팅(function hoisting) 이라 합니다.

간략하게 함수호이스팅과 변수호이스팅의 미묘한 차이점

  • 둘다 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되어 식별자를 생성한다는 점은 동일!
  • var는 선언과 동시에 undefined로 초기화 -> 선언문 이전에 참조하면 undefined
  • 함수호이스팅은 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화 -> 호출 가능

함수표현식은 변수에 할당되는 값이 함수 리터럴 문인데 따라서 변수 선언문과 변수 할당문을 한번에 기술한 축약 표현과 동일합니다.

즉 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 됩니다.

함수 표현식으로 함수를 정의하면 함수 호이스팅이 아닌 변수 호이스팅이 발생하는것!!!!

• Function 생성자 함수

자바스크립트가 기본 제공하는 빌트인 함수 Function 생성자 함수에 매개변수 목록과 함수 몸체를 문자열로 전달하면서 new 연산자와 함께 호출하면 함수 객체를 생성해서 반환합니다

var add = new Function('x', 'y', 'return x+y');

console.log(add(2,6)) // 8

Function 생성자 함수로 생성하는 방식은 일반적이지 않지!!
클로저를 생성하지 않는 둥, 함수선언문, 표현식과는 다르게 동작합니다.
(클로저는 이후에 포스팅!!)

• 화살표함수 (Arrow function)

더 간략한 방법으로 함수를 선언할 수 있습니다.

const add = (x,y) => x+y;
console.log(add(2,5)) // 7

화살표 함수는 기존의 함수보다 표현만 간략한 것이 아니라 내부 동작 또한 간략화되어 있습니다.
화살표 함수는 생성자 함수로 사용할 수 없으며, 기존 함수와 this 바인딩 방식이 다르고,
prototype 프로퍼티가 없으며 arguments 객체를 생성하지 않습니다. 이후 자세히 포스팅!!!

0개의 댓글