[Deepdive] 12-1 함수
함수정의
함수를 정의하는 방법은 4가지 가 있다.
- 함수 선언문
- 함수 표현식
- function 생정자 함수
- 화살표 함수
함수선언문
function add (x,y) {
return x + y;
}
함수 리터럴과 유사하지만 선언문은 함수 이름을 생략할수없고 리터럴은 생략할수있다.
또 함수 선언문은 표현식이 아닌 문으로 변수에 할당할수 없다
하지만 아래코드를 보면 의문점이 생기는데
let add = function add (x,y) {
return x + y ;
}
console.log(add(2,5)); // 7
함수 선언문이 변수에 할당되는것처럼 보이는데 이렇게 동작하는 이유는 자바스크립트 엔진이 코드의 문맥에 따라 함수 리터럴 이나 함수 선언문으로 해석하는 경우가있기때문인데 간단하게 함수리터럴을 단독으로 사용하면 함수 선언문 으로 해석하고 함수리터럴을 값으로 평가해야되는 문맥이라면 함수 리터럴로 해석하게된다.
그리고 자바스크립트 엔진은 생성된 함수를 호출하기위해 함수이름과 동일한 이름의 식별자를 암묵적으로 생성하고 함수 객체를 할당하게되기때문에 아래와 같은 코드도 호출이 가능하다.
function add (x,y) {
return x + y ;
}
console.log(add(2,5)); // 7
따라서 함수는 함수 이름으로 호출하는것이 아니라 자바스크립트 엔진이 암묵적으로 생성한 식별자 를 통해 호출하는것이다.
함수 표현식
함수는 객체 타입의 값의 성질을 가진 일급객체 이라한다. 일급객체는 함수를 값처럼 자유롭게 사용할수있다는 의미인데 이는 변수에도 할당할수있다는 얘기다
함수 표현식은 함수 리터럴로 생성한 함수 객체를 변수에 할당하는것을 얘기한다.
let add = function(x,y) {
return x+y;
};
console.log(add(2,5)); // 7
함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것이 일반적이며 , 함수 객체를 가르키는 식별자를 통해서 호출할수있다.
함수 호이스팅
// 함수 참조
console.log(add);
console.log(sub); // undefined
// 함수 호출
console.log(add(2,5)); // 7
console.log(sub(2,5)): // 타입에러
// 함수 선언문
function add(x,y) {
return x+y;
};
// 함수 표현식
var sub = function(x,y) {
return x+y;
};
함수 선언문은 선언문 이전에 호출해도 동작하게되는데 그이유는 함수 호이스팅에 있다.
모든 선언문이 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되는데 함수선언문도 마찬가지로 란타임 이전에 함수 객체가 먼저 생성되고 자바스크립트 엔진은 함수이름과 동일한 식별자를 생성하고 함수객체에 할당한다. 이렇게 함수선언문이 코드의 선두로 끌어올려지는것처럼 동작하는것이 자바스크립트의 고유의 특징인 함수 호이스팅이라고 한다.
다만 함수 호이스팅과 변수 호이스팅에는 미묘한 차이가 존재한다.
먼저 두 호이스팅의 동일한점으로는 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되고 식별자를 생성한다는점에서는 동일하다 하지만 var 키워드로 선언된 변수는 은 undefined 로 초기화 되고 함수선언문 을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다.
따라서 함수 표현식 이전에 함수 참조시 undefined 가 나오는이유는 변수 호이스팅에 의한 결과라고 볼수있다.
함수표현식은 표현식 이후에 참조 또는 호출해야한다.
function생성자 함수
자바스크립트에 기본 빌트인 함수 function 의 생성자 함수에 매개변수 목록과 함수 몸체를 문자열로 전달하면서 new 연산자와 호출하면 함수 객체를 생성해서 반환한다.
let add = new Function("x","y","return x+y");
console.log(add(2,5)) // 7
이같은 경우는 클로저를 생성하지않고, 함수선언문이나 표현식으로 생성한 함수와 다르게 동작하기때문에 일반적이지 않고 바람직하지않다.
화살표 함수
ES6 이후 도입된 함수인데 function 키워드 대신 ⇒ 를 사용해 간략한 방법으로 선언할수있다.
const add = (x,y) => x+y;
console.log(add(2,5)); // 7
화살표 함수는 항상 익명 함수로 정의한다
기존함수에서 표현만 간략하게 한것이 아니라 내부 동작도 간략화되어있다.
** 추후에 좀더 내용이 보강되어야힘 **