스터디 4회차
스터디 4회차(모던 자바스크립트 딥다이브 12강 함수)
함수
- 함수 리터럴 :
리터럴 : 사람이 이해할 수 있는 문자 또는 약속된 기호를 통해 값을 생성하는 표기방식
리터럴은 객체이므로 함수는 객체이다.(이는 자바스크립트 언어 고유한 특성)
일반 객체는 호출 불가, but 함수는 호출 가능 and 고유한 프로퍼티를 가짐
-
함수 정의법 4가지
-
함수 선언문
-
함수 표현식
-
Function 생성자 함수
-
화살표 함수(ES6에서 도입됨)
1) 함수 선언문
function add(x, y) {
return x + y;
}
//함수 참조(dir은 함수객체의 프로퍼티까지 출력, 단 node.js는 console.log와 같은 결과 출력)
console.dir(add); // f add(x, y);
//함수 호출
console.log(add(2, 5)); // 7
함수 리터럴과 형태가 동일하다.
but 함수 이름 생략 불가(리터럴은 가능)
선언문은 표현식이 아니라 ‘문’이다.(따라서 변수 할당 불가)
- 표현식과 문 차이점
- 표현식 : (값으로 평가될 수 있는 문)은 모두 표현식이다.
표현식과 문 구별방법은 변수에 할당해 보는 것
var x; //변수 선언문은 표현식이 아닌 문이다. x = 100; //할당문은 그 자체가 표현식이지만 문이기도 하다. 즉 할당문은 표현식인 문이다. var foo = var x; //SyntaxError 표현시이 아닌 문은 값처럼 사용할 수 없다.
-
문 : 프로그램 구성하는 기본단위이자 최초실행 단위(토큰들로 구성)
-
토큰 : 문법적으로 더이상 나눌수 없는 상태
var sum = 1 + 2 ; //문, 밑줄 각각 토큰
표현식이 아닌 문은 변수에 할당할 수 없다.
함수 선언문도 문이므로 변수 할당할 수 없다. 그런데 가능한 것 처럼 보이는 이유?
선언문 실제 실행 과정 :
var add = function add(x, y) {
return x + y;
}
자바스크립트는 { }가 상황에 따라 다르게 해석된다.
기명 함수 리터럴을 단독으로 쓰면 함수 선언문으로 해석됨
/* 기명 함수 (foo)*/
function foo() {
console.log('foo');
}
foo(); // foo
함수 리터럴 피연산자로 쓰면 선언문이 아니라 리터럴로 해석됨
(function bar() { console.log('bar');})
bar(); // ReferenceError : bar is not defined
2) 함수 표현식
자바스크립트 함수는 값의 성질을 갖는 객체이다.(이를 일급 객체라고 부른다.)
값은 자유롭게 사용이 가능 ‘
따라서 함수 리터럴로 생성한 객체는 변수 할당이 가능
/* 익명함수를 객체변수에 할당했다. */
var add = function(x, y){
return x+y;
}
/* 기명함수지만 foo는 함수 내부에서만 사용할 수 있다. */
var add = function foo(x, y){
return x+y;
}
함수선언문과 함수표현식은 유사해보이지만 다름
선언문 : 표현식이 아닌 문(선언전에 호출 가능) → 함수호이스팅
표현식 : 표현식인 문(선언전에 호출 불가) →변수호이스팅
why? 생성 시점이 다름
자바스크립트 호이스팅 : 읽기전에 식별자와 같은 부분을 읽어들이는 것
함수 호이스팅과 변수 호이스팅은 다름
함수 호이스팅 : 암묵적 식별자는 함수객체로 초기화됨, 런타임시 평가 // f add(x, y)
변수 호이스팅 : 값처럼 취급, 런타임 이전에 평가 //undefined
함수 호이스팅은 당연한 규칙을 무시하므로 함수 표현식을 권장함(JSON 창시자)
3) function 생성자 함수(객체를 생성하는 함수)
var add = new Function('x', 'y', 'return x+y');
console.log(add(2,5)); // 7
new 연산자와 함께 호출시 함수 객체 생성 반환(없이 호출해도 결과는 동일)
클로저를 생성하지 않는 등 1),2)와 다르게 작동하므로
일반적이지 않음, 바람직하지 않음
4) 화살표함수
항상 익명함수로 정의
const add = (x, y) => x + y;
console.log(add(2,5)); // 7
기존함수와 this 바인딩 방식이 다름
prototype 프로퍼티가 없고, argument 객체를 생성하지 않음
- 함수 호출
인수가 모자라면 undefined
인수가 넘치면 무시됨
타입과 갯수를 확인 안하므로 확인하는 코드를 가지면 좋다.
function(x, y){
return x+y;
}
console.log(add(2)); // y가 undefined되어 NaN
console.log(add(2,5, 10)); // 7
매개변수 갯수는 적을 수록 좋고 (많을 수록 많은 기능을 한다고 봄)
많이 필요시 인수(ajax로 바인딩)로 전달하는 방법을 추천