[240311] 12장 함수(1)

12장 함수(1)

함수란?

  • 스코프, 실행 컨텍스트, 클로저, 생성자 함수에 의한 객체 생성, 메서드, this, 프로토타입, 모듈화 등 함수와 깊은 관련 있음
  • 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것이다.

함수를 사용하는 이유

  • 코드의 재사용
  • 유지보수의 편의성
  • 코드의 신뢰성
  • 코드의 가독성 향상

함수 리터럴

  • 함수 리터럴은 function 키워드, 함수 이름, 매개 변수 목록, 함수 몸체로 구성
  • 함수는 객체지만 일반 객체와 다르다.
  • 일반 객체는 호출할 수 없지만 함수는 호출 가능
  • 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티 가짐

함수 이름

  • 함수 이름은 식별자다. 네이밍 규칙 준수
  • 함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자다.
  • 함수 이름은 생략 가능 (기명함수, 무명/익명함수)

매개변수 목록

  • 0개 이상의 매개변수를 소괄호로 감싸고 쉼표로 구분
  • 매개변수는 함수 몸체 내에서 변수와 동일하게 취급
  • 식별자 네이밍 규칙 준수

함수 몸체

  • 함수가 호출되었을 때 일괄적으로 실행될 문들을 하나의 실행 단위로 정의한 코드 블록
  • 함수 몸체는 함수 호출에 의해 실행된다

함수 정의

함수 선언문

function add(x,y) {
	return x+y;
}
  • 함수 선언문은 함수 이름을 생략할 수 없다.
  • 함수 선언문은 표현식이 아닌 문이다.
  • 크롬에서 함수 선언문을 실행하면 undefined 가 출력된다.
  • 함수 선언문도 표현식이 아닌 문이므로 변수에 할당할 수 없다.

함수 표현식

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

Function 생성자 함수

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

화살표 함수(ES6)

const add = (x,y) => x+y;
  • 모든 함수 정의 방식은 함수를 정의한다는 면에서 동일
  • 단 미묘한 차이가 있다.

함수 선언문

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

// 여기서 add는 함수이름로 아닌 식별자로 호출하는 것
// 함수 선언문을 표현식으로 변환
console.log(add(2,5)); // 7 
  • 이렇게 동작하는 이유는 자바 스크립트 엔진이 코드의 문맥에 따라 동일한 함수 리터럴ㅇ을 표현식이 아닌 문인 함수 선언문으로 해석하는 경우와 표현식인 문인 함수 리터럴 표현식으로 해석하는 경우가 있다.
  • 함수 선언문은 함수 이름을 생략할 수 없다는 점 제외하면 리터럴과 형태가 동일함
  • 함수 이름이 있는 기명 함수 리터럴은 함수 선언문 또는 리터럴 표현신으로 해석될 가능성이 있다.
  • 기명 함수 리터럴도 중의적 코드여서, 코드의 문맥에 따라 해석이 달라질 수 있다.
  • 함수 이름이 있는 함수 리터럴을 단독적으로 사용하면 함수 선언문으로 해석, 함수 리터럴이 값으로 평가 되어야 하는 문맥에서는 리터럴 표현식으로 해석
// 기명 함수 리터럴을 단독으로 사용하면 함수 선언문으로 해석
// 함수 선언문에서는 함수 이름을 생략할 수 없다.
// 자바 스크립트엔진에서 암묵적으로 생성한 식별자
function foo() { console.log('foo'); } 

foo(); // foo

// 함수 리터럴을 피연산자로 사용하면 리터럴 표현식으로 해석
// 함수 이름 생략 가능
(function bar() { console.log('bar'); });
bar(); // ReferenceError : bar is not defined
  • 함수 리터럴 표현식과 함수 선언문은 함수 객체를 생성하는 것은 동일
  • 호출에는 차이가 있다.
  • 함수 객체를 가리키는 식별자가 없으면 함수 객체 참조 할 수 없음, 자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 거기에 함수 객체 할당함

함수 표현식

  • 일급 객체 : 변수에 할당 , 프로퍼티 값, 배열의 요소가 될 수 있는 성질을 갖는 객체
  • 자바스크립트의 함수는 일급 객체다. → 값처럼 자유롭게 사용 가능
  • 함수 선언문은 “표현식이 아닌 문”
  • 함수 표현식은 “표현식인 문”

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

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

console.log(add(2,5)); // 7
console.log(sub(2,5)); // TypeError: sub is not a function

// 함수 선언문
function add(x,y) { return x+y; } 
var sub = function(x,y) { return x-y };
  • 함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출 가능
  • 함수 표현식은 불가능
  • 코드가 한 줄씩 순차적으로 실행되는 시점인 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행 (함수 선언문 객체 생성)
  • 함수 호이스팅 : 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 특징
  • 변수 호이스팅 (함수 표현식으로 정의하면)
    • 변수 선언문과 함수 선언문은 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되는 것은 동일
    • var 키워드로 선언된 변수는 undefined 로 초기화
    • 변수 할당문의 값은 할망문이 실행되는 시점, 즉 런타임에 평가
    • 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.
  • 함수 호이스팅은 함수 호출전에 반드시 함수를 선언해야 한다는 규칙을 무시한다. 이 문제로 더글라스 크락포드 (JSON) 창시자는 함수 선언문 대신 함수 표현식을 사용할 것을 권장함

Function 생성자 함수

  • JS 빌드인 생성자 함수
    • 생성자 함수는 객체를 생성하는 함수를 말함
  • 매개변수 목록과 함수 몸체를 문자열로 전달
  • new 연산자와 함께 호출하면 객체를 생성해서 반환
    • new 연산자 없이 호출해도 결과는 동일
  • 일반적이지 않으며 바람직하지 않다.
  • 클로저 생성 X (추후 살펴 볼 예정)

화살표 함수

  • 항상 익명함수로 정의
  • 함수 선언문, 함수 표현식을 완전히 대체하기 위해 디자인된 것은 아님
  • 표현도 간략하지만, 내부 동작 또한 간략화 되어 있다.
  • this 바인딩, prototype 프로퍼티 없음, arguments 객체 생성X

Categories:

Updated:

Leave a comment