함수는 가장 중요한 핵심 개념이다.다른 핵심 개념인 스코프, 실행 컨텍스트, 클로저, 생성자 함수에 의한 객체생성, 메서드, this, 프로토타입, 모듈화 등이 모두 함수와 깊은 관련이 있다.
function add(num1,num2){
return num1+num2; //표현식인 문
}
console.log(add(1,2));
let add = add(10,20); //자바스크립트 함수는 일급객체이기에 변수에 할당이 가능하다.
코드의 재사용성을 대폭 증가시켜 준다. 유지보수의 편의성을 준다. 코드의 신뢰성, 가독성을 증가시켜 준다.
자바스크립트 함수는 객체 타입의 값이다. 함수도 리터럴로 생성이 가능하다. 또한 변수에 할당도 가능하다. 함수 리터럴은 function 키워드로 생성이 가능하다.
var f = function add(num1, num2){
return num1 + num2;
}
리터럴이란 사람이 이해할 수 있는 문자를 사용해 값을 생성하는 표기 방식을 말한다. 즉, 리터럴은 값을 생성하는 표기법이다. 따라서 함수 리터럴도 평가되어 값을 생성하며, 이 값은 객체다, 즉 함수는 객체다.
함수는 일반 객체와 다르게 호출이 가능하다. 그리고 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티를 갖는다.
함수가 객체라는 사실은 다른 언어와 구별되는 자바스크립트만의 특징이다.
//함수 선언
//함수명 생략 불가능
//표현식이 아닌 문
function add(x,y){
return x + y;
}
//함수 표현식인 문
var f = function(x,y){
return x + y;
}
//Function 생성자 함수
var add = new Function('x','y','return x + y');
//화살표 함수
var add = (x,y) => x + y;
/*
화살표 함수는 ES6에서 추가된 함수 표기법이고 원래는 {}가 있으나
위와같이 return 값이 한개이고 한줄안에 끝낼 수 있다면 {} 생략가능
*/
변수는 선언, 함수는 정의 함수 선언문이 평가되면 식별자가 암묵적으로 생성되고 함수 객체가 할당된다.
자바스크립트의 함수는 일급 객체이다. 즉,표현식으로 사용하여 값으로 쓸 수 있다는 말.
값처럼 변수에 할당 가능, 프로퍼티 값으로 사용 가능, 배열의 요소도 될 수 있다. 이처럼 값의 성질을 갖는 객체를 일급 객체라 한다.
위에 함수표현식인문처럼 함수를 사용할 수 있는 이유도 자바스크립트 함수는 일급 객체이기 때문이어서 가능한것이다.
함수의 호이스팅은 변수의 호이스팅과는 미묘하게 다른점이 있으니 꼭 알고넘어가자.
//함수 참조
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;
}
위에 왜 저런 결과가 나온것인가. 원래 우리가 알고있던 호이스팅이라 함은 자바스크립트 런타임 이전에 선언문을 모두 찾아서 가장 앞에서 실행하는 것과 같은 효과였다.
답 : 함수의 생성 시점이 다르기 때문
함수 선언문
함수 선언문은 일반적으로 우리가 알고있듯이 호이스팅이 되어서 참조도 가능하고 호출도 가능하다.
함수 표현식
함수 표현식은 변수에 함수를 할당하는 것과 같다. 함수 표현식에서 선언문은 무엇인가. var sub 가 되시겠다. 여기서 호이스팅 되는것은 var sub 이기때문에 참조시에는 undefined 가 호출시에는 아직 선언되지 않았기 때문에 TypeError 를 내뿜는다.
그렇다면 function은?? 바로 런타임에서 생성되고 실행된다.
- 함수 선언문을 사용하면 일반적인 함수 호이스팅
- 함수 표현식을 사용하면 변수호이스팅이 발생하고, 함수는 런타임에서 생성, 평가 되어지므로 주의가 필요하다.
- 함수 표현식으로 정의한 함수는 반드시 표현식 이후에 참조, 호출해야한다.
JSON을 창안한 더글라스 크락포드는 함수 선언문 대신 함수 표현식을 사용할것을 권장한다.
var, let, const 와 같은 맥락인거같다. 째금 다르긴하지만^^..
사용하지말자.. 클로저를 생성하지도 않고 일반적인 선언문과 다르게 동작한다...
ES6에서 도입된 화살표 함수(arrow function)은 function 키워드 대신 => 를 사용하여 좀 더 간략한 표현을 할 수 있게 해준다.
화살표 함수는 항상 익명으로 정의한다.
const add = (x,y) => x + y;
console.log(add) // 7
화살표 함수는 생성자 함수로 사용 불가능, this 바인딩 기존과 다름, prototype 프로퍼티가 없음, arguments 객체 생성안함 등 차이가 있으니 추후에 자세히 알아보자.