[JS] 함수 객체: 일급 객체로써의 함수, 함수의 property, 내부함수와 스코프 체인

Jung Seo Kyung·2019년 5월 5일
1

책 인사이드 자바스크립트를 읽고 정리한 내용입니다.

  • 함수는 일급 객체 ( 변수에 값으로 할당될 수 있고, 함수의 리턴값, 함수의 매개변수로 전달, 객체이기 때문에 동적으로 프로퍼티를 생성할 수 있음)
  • 기본 property : length, prototype
  • prototype과 [[Prototype]] , proto 와의 차이
  • 내부함수와 스코프 체인, 클로져

자바스크립트 함수는 일급 객체이다.

자바스크립트에서는 함수도 객체이다. 자바스크립트의 데이터타입의 참조타입에서도 설명했 듯이 객체는 동적으로 프로퍼티를 추가할 수 있다. 함수도 마찬가지로 객체이기 때문에 동적으로 프로퍼티를 추가할 수 도 있다.

function add(x,y) { return x+y; }
add.status = "OK";
add.result = 5;

이러한 특징 때문에 함수는 다음과 같이 동작할 수 있다.

  • 함수 리터럴에 의해서 생성된다.
  • 변수에 값으로 할당되거나 배열의 값으로 사용된다.
  • 함수의 리턴값으로 사용된다.
  • 함수의 인자로도 전달된다.
  • 함수의 프로퍼티를 동적으로 생성할 수 있다.

이러한 특징이 있는 함수를 일급 객체 라고 부른다.

함수의 기본 property : length와 prototype

함수는 다른 객체들과는 다르게 함수 객체만의 표준 프로퍼티가 있다. ECMA 스크립트에는 모든 함수가 length와 prototype 프로퍼티를 가져야한다고 나와있다.

  • length -- 함수가 정상적으로 사용될 때 기대되는 인자의 개수이다.
  • prototype -- 함수가 생성자로 사용될 때 함수로 인해 만들어진 객체의 부모역할을 하는 프로토타입을 가리킨다.

prototype은 매우 중요하니 자세히 살펴보자.
먼저 헷갈릴 수 있는 요소들을 정리해보았다. 위의 add 함수를 console.dir(add)로 출력해보았다.

스크린샷 2019-05-05 오후 5.41.24.png

  • prototype과 [[Prototype]] or __proto__ 는 같은건가 ?
    NOPE! 자바스크립트 데이터 타입에서 살펴보았듯이 모든 객체에는 자신의 부모 역할을 프로토타입 객체인[[Prototype]] (크롬 브라우저에서는 __proto__ )을 내부 프로퍼티로 가지고 있다.
    add 함수의 부모역할을 하는 프로토타입 객체는 Function.prototype이라는 객체이다.
    반면 함수가 가지고 있는 ex) add.prototype 는 add 함수가 객체의 생성자로 사용이 될때, 새로 만들어진 객체의 부모 프로토타입을 가리킨다.

이 prototype 프로퍼티는 constructor 프로퍼티 하나만 있는 객체를 가리킨다. 이 객체의 constructor는 객체를 가리키고 있는 함수(즉 add 함수)를 참조한다.

function.prototype (1).png

내부 함수와 스코프 체인

함수 안에 또 다른 함수가 있는 경우 이 함수를 내부함수 (inner function)이라고 한다.

function parent(){
 var a = 100;
 var b = 200;
  
  function child(){
	var b = 300;
    console.log(a);
    console.log(b); 
	}
 child();
}
parent(); // 100 300 
child(); // Uncaught Reference error : child is not defined

🌟 중요 포인트

  • child 함수는 내부 함수이며 함수를 둘러싸고 있는 parent 함수의 변수에 접근이 가능하다. [스코프 체이닝]
  • 변수 b는 child 함수 내에 선언되어 있기 때문에 parent 함수의 변수 b가 아닌 child 변수의 a를 사용한다.
  • 함수 내부에서는 외부 함수의 변수에 접근할 수 있지만 외부에서 내부 함수의 변수로는 접근 하지 못 한다. child 함수는 parent 안에 정의되어 있기 때문에 parent 밖에서 호출했을 때 오류가 발생한다.

하지만 함수 외부에서도 특정함수 내부에 있는 함수를 호출할 수 있는 방법이 있다. 부모 함수가 내부 함수를 리턴 하면 부모 밖에서도 내부 함수를 호출할 수 있다.

function parent(){
 var a = 100;
 var b = 200;
  
  function child(){
    console.log(b); 
	}
 return child;
}
var inner = parent();
inner();
  • parent()가 child 함수의 참조값을 리턴하기 때문에 inner에도 child의 참조값이 들어간다. 이 때문에 inner 변수에 호출 연산자 ()가 붙으면 parent 함수 밖에서도 child 함수 호출이 가능하다.
    parent 처럼 실행이 끝난 함수의 변수를 참조하는 inner()와 같은 함수를 클로저 라고 한다.

0개의 댓글

관련 채용 정보