2 minute read

스터디 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로 바인딩)로 전달하는 방법을 추천