[JavaScript] 함수

zmin·2022년 4월 23일
0
post-thumbnail

모던 자바스크립트 Deep Dive, 이웅모

함수 정의

  • Function 생성자 함수 : 다른 함수 선언과 다르게 동작 → 잘 쓰이지 X
    const f = new Function();
  • 함수 선언문 : 컨텍스트 생성시 함수 선언까지 호이스팅 → 앞쪽 코드에서 사용 가능
    function 함수이름(매개변수){
      console.log('함수이름 생략불가');
    }
  • 함수 표현식 : 변수 선언부만 호이스팅 → 앞쪽 코드에서 사용 불가
    const func = function 함수이름(매개변수){
      console.log('보통 함수이름을 생략한 익명함수로 씀');
    }; //'표현식'이기 때문에 일반적으로 세미콜론을 붙여서 표현

함수를 호출할 때는 식별자를 이용하여 호출
함수이름은 해당 함수 내부에서만 사용 가능 (재귀함수 등) → 근데 이것도 식별자로 가능
함수 선언문의 경우 식별자를 함수이름으로 암묵적으로 생성

표현식이라는 건... 함수가 값...?

함수 객체

자바스크립트는 함수도 객체이지만 일반적인 객체와 다른 프로퍼티를 소유하고 있기 때문에 호출이 가능

  • arguments : 호출시 전달된 인수를 유사배열객체로 저장
  • length : 정의시 사용한 매개변수 갯수 (Rest 매개변수는 포함X)
  • prototype : 생성자 함수로 호출할 때 생성할 인스턴스의 프로토타입으로 쓸 함수 객체를 가리킴, 그래서 non-constructor 함수에는 이 프로퍼티가 없음

일급 객체

아래 조건을 전부 만족하는 객체가 일급객체

  1. 무명의 리터럴로 생성
  2. 변수나 자료구조에 저장
  3. 함수의 매개변수에 전달
  4. 함수의 반환값으로 사용

따라서 자바스크립트 함수는 일급 객체이고 으로서 사용이 가능함

함수와 this

this

const a = 50;

const obj = {
    a : 5,
    getA(){  // ES6의 메서드
        return a;
    }
} 

console.log(obj.getA());	// 50

객체 내부의 프로퍼티에 접근하려면 해당 객체를 가리키는 식별자를 참조해야함 객체.프로퍼티
그렇지 않으면 가장 가깝게 있는 식별자를 참조하게 됨 → 은 우리가 바라는 것이 아님

const a = 50;

const obj = {
    a : 5,
    getA(){  // ES6의 메서드
        return this.a;
    }
} 

console.log(obj.getA());	// 5

이럴 때 사용하는 것이 자기 참조 변수 this

this 의 경우 함수 호출 방식에 따라 동적으로 결정, 함수의 정의 위치와는 상관 X
+) 렉시컬 스코프의 경우 정의 위치에 따라 달라짐

this 바인딩

  • 일반 함수 호출 : 전역 객체
  • 메서드 호출 : 해당 메서드를 호출한 객체, ~~~.@@@.메서드()의 경우 ~~~.@@@
  • 생성자 함수 호출(new 이용) : 함수가 생성 인스턴스

this를 다른 변수에 저장하여 해당 변수의 식별자를 콜백함수나 중첩함수 내부에서 this처럼 사용하는 방법과

Function.prototype.apply()/call()/bind()등을 이용하여 this를 직접 명시하여 호출하는 방법도 있음

ES6에서 추가된 부분들

화살표 함수

non-constructor → 인스턴스 생성 못하고, 따라서 property프로퍼티도 없음
생긴 것도, 기능도 간소화 된 함수
콜백함수로 많이 쓰임
무조건 익명 함수 표현식으로 작성

const func = (매개변수) => {함수 몸체};

this, arguments, super, new.target(non-constructor라 어차피 의미X) 바인딩을 갖지 않음(비어있는 거 아님)
참조하려하면 스코프 체인을 통해 가장 가까운 상위 함수의 해당 값을 참조

특히 this 바인딩을 하지 않는 것이 콜백함수로 많이 쓰이는 이유가 됨


콜백함수 내부에서 this를 사용할 때

  • 일반 함수로 정의 : this가 해당 고차 함수와 달라져(전역)
    Function.prototype.apply()/call()/bind()등을 이용하여 this를 명시해 주어야 함
  • 화살표 함수로 정의 : 어차피 해당 함수에는 this가 없어 스코프 체인을 통해 화살표 콜백함수를 호출한 고차함수의 this를 참고하게 되므로 일반적으로 생각하는 this

메서드 함수

이전에는 객체의 프로퍼티 값으로 함수를 사용하는 것을 메서드라부름
→ 문제는 이런 메서드는 해당 객체에 얽매인 상태여야 의미가 있는데 결국 이 함수도 일반 함수를 사용한 것이기 때문에 일반함수로서도 호출할 수 있고, 생성자 함수로서도 호출할 수 있음
→ 😇

ES6에서는 메서드 축약 표현으로 정의된 함수만 메서드로 인정

const obj = {
    method(){  // 메서드 축약 표현
        return 9;
    }
}
  • non-constructor(prototype 없음)
  • 일반 함수로 호출 불가(caller 없음)

매개변수 기본값 지정

ES6 이전

// 단축 평가를 이용하여 함수 내부에서 기본값을 지정해주어야 함
// 인수를 전달하지 않으면 undefined 값을 할당하고 이는 false로 평가
function f(a, b){
  a = a || 0;	
  b = b || 0;
  return a+b;
}

ES6

// 매개변수 명시하면서 기본값 지정
function f(a = 0, b = 0){
  return a+b;
}
profile
308 Permanent Redirect

0개의 댓글