코드노트

자바스크립트 함수 정의 방법에 대하여 알고 시작하자 본문

Code note/자바스크립트

자바스크립트 함수 정의 방법에 대하여 알고 시작하자

코드노트 2022. 12. 5. 21:13

함수를 사용하면서 몰랐던 부분들을 기초부터 하나하나 정리하고자 한다.

알았지만 그냥 넘어갔던부분들까지..

자바스크립트를 공부하면서 처음에는 대충 넘어갔었고,

코드를 작성하면서 모르는부분들을 검색했었다.

 

함수 자체의 용어, 네이밍, 스코프, 호이스팅들을 모두 이해하지 않고 사용하니

에러가 너무 많이 발생하는것 같다.

 

에러를 발생시키면서 공부를 한다?

에러가 생기지 않게 기초지식을 다시 공부를한다?

 

무엇이 맞는지는 모르겠다.

그러나 알고있는 부분들을 다시한번 상기시키고

모르는 부분들은 다시 배우면서 정리를 해놓는게 좋을것 같다는 생각이 들었다.

 

자바스크립트를 처음시작하는사람이 있다면 지루하고 시간이 조금은 들지만 기초를 탄탄하게 쌓아가는게 좋을거라고 말하고 싶다.

 

자바스크립트에서는 다른 언어들과는 다르게 함수가 객체로 되어있다.

이 특징을 이해해야한다!

여기서 조금의 지식이 틀어지면 객체에 대한 정의가 모두 다르게 해석된다.

 

그 외에도 다른 코드를 해석할때에도 정확히 알아야 코드해석에 있어 유용하다.


함수 리터럴

- 자바스크립트 함수는 객체 타입의 값

- 숫자값을 숫자 리터럴, 객체를 객체 리터럴로 생성하는 것처럼 함수도 함수 리터럴로 생성할 수 있다.

- function 키워드, 함수이름, 매개변수, 함수몸체 로 이루어져 있다.

 

함수 이름

- 함수 이름은 식별자이다, 따라서 식별자 네이밍 규칙을 준수 해야함.

- * 함수 몸체 내에서만 참조할 수 있는 식별자

- 함수 이름은 생략 가능

- 함수는 객체 타입의 값, 따라서 변수와 마찬가지로 재사용하기 위해 이름을 붙힐 수 있다.

- 기명함수, 익명함수로 나누어진다.

 

매개변수

- 0개 이상의 매개변수를 소괄호로 감싸고 쉼표로 구분

- 매개변수에는 함수 호출문의 인수가 순서대로 할당, 즉 매개변수 목록은 순서의 의미가 있다.

- 매개변수는 함수 몸채 내에서 변수와 동일하게 취급, 식별자 네이밍 규칙을 준수하여 작성

 

함수몸체

- 함수가 호출되었을 때 일괄적으로 실행도리 문들을 하나의 실행 단위로 정의한 코드 블록

- 함수 몸체는 함수 호출에 의해 실행



함수 정의

- 함수를 정의하는 방식은 미묘하지만 중요한 차이들이 있다.

- 자바스크립트 함수는 1급 객체이다. 일급객체라는 것은 함수 를 값처럼 사용할 수 있다.


 

▶ 함수 선언문

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

- 함수 리터럴과 형태가 동일하다. 그러나 함수 선언문에서는 함수 이름을 생략할 수 없다.

- 함수 선언문은 표현식이 아닌 문이다. 값으로 평가될 수 없다.

* 그러나 함수선언문은 변수에 할당하게 되면 error가 발생하지 않는다.

  자바스크립트 엔진이 상황에 따라서 함수 리터럴로 해석하는 경우가 있다. 형태가 동일하기 때문이다.

 

ex)

// 이름이 있는 함수 리터럴을 단독으로 사용하면 함수 선언문으로 해석
// 함수 선언문은 함수 이름을 생략할 수 없다.
function name() {
  console.log("name");
}

name(); // foo


// 함수 리터럴을 피연산자로 사용하면 함수 선언문이 아닌 함수 리터럴 표현식으로 해석
// 함수 리터럴은 함수 이름을 생략할 수 있다.
(function name() {
  console.log("name");
});
name(); // ReferenceError: name is not defined

첫번째 함수 선언문

- 함수 선언문은 실행되면서 함수 객체를 생성한다.

두번째 함수 리터럴

- 함수 리터럴에서는 피연산자로 사용된 함수를 식별할 수 있는 식별자가 없기 때문에 referenceError가 나오는걸 알 수 있다.

 

 

- 함수 리터럴, 함수 선언문 둘 다 함수 객체를 만드는것은 동일하다

- 그러나 둘다 호출을 했을 때 다른걸 알 수 있다.

- 함수 이름은 식별자이다. 함수 내부에서만 식별할 수 있다.

- 함수 선언문 에서는 출력이 잘되는것이 보인다.

 

- 자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당한다.

 

 

* 여기서 알 수 있듯이 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가르키고 있는 식별자로 호출한다.

 


▶ 함수 표현식

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

- 함수 표현식에서는 함수 이름을 생략하는것이 일반적이다. ( 재귀함수, 디버깅 등 이름이 필요없으면 생략한다)

 

ex)

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

// 함수 객체를 가리키는 식별자로 호출
console.log(add(2, 5)); // 7

// 함수 이름으로 호출하게 되면 ReferenceError가 발생
// 함수 이름은 함수 몸체 내부에서만 유효한 식별자
console.log(foo(2, 5)); // ReferenceError: foo is not defined

- 이렇게 알 수 있듯 함수 식별자를 통해서 호출해야한다.

- 함수 이름으로 호출하게 되면 에러가 발생한다.

- 함수 이름은 함수 내부에서 호출할때만 사용!

* foo의 스코프는 함수 객체 내이다.


▶ 화살표 함수

let name = (x, y) => x + y;

- 화살표 함수는 언제든지 익명함수로 정의한다.

- function키워드 대신 화살표 => 를 사용하여 간략한 방법으로 함수를 선언

- 생성자 함수로 사용할 수 없다.

- 기존의 함수와 this바인딩 방식이 다르다.

- prototype 프로퍼티가 없으며, arguments객체를 생성하지 않는다.

 


▶ 함수 호이스팅

- 변수 호이스팅과 같이 함수도 호이스팅이 발생한다.

- 함수 선언문은 선언하기 이전에 호출할 수 있다.

- 함수 표현식은 선언하기 이전에 호출할 수 없다.

// 함수 참조
console.dir(add) // f 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; }

// 함수 표현식
let sub = function(x, y) { return x - y; }

- 함수 선언문은 함수가 호출되기 런타임 이전에 선언문이 먼저 함수 객체가 생성된다.

- 함수 표현식은 변수 호이스팅이 발생된다. 변수에 선언되기 때문에 런타임 이전에는 변수 선언이 되고, 런타임 이후에 할당이 이루어진다.


▶ 생성자 함수 /     이 방법으로는 함수를 만들지 않는게 좋다.

생성자 함수는 객체를 생성하는 함수를 말한다.

객체를 생성하는 방식은 객체 리터럴 이외에 다양한 방법이 있다.

new 연산자와 함께 호출하면 함수 객체를 생성하여 반환한다.

let add = new Func("x", "y", 'return x + y");

console.log(add(2, 5); // 7

- 생성자 함수로 함수를 생성하는 방식은 일반적이지 않으며 바람직하지도 않다.

- 클로저(closure)를 생성하지 않는 등, 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작한다.

* 클로저 알아보기

 

 

자바스크립트 클로저(Closure) 정리

클로저(Closure) - 함수와 함수가 선언된 어휘적 환경(렉시컬 환경)의 조합 -> 내부함수가 외부함수 변수에 접근 가능 function init() { // name은 init에 의해 생성된 지역 변수 var name = "Mozilla"; // displayName

codeno-te.tistory.com