본문 바로가기

Web + APP/JavaScript

JavaScript 함수와 프로토타입 체이닝 (2)

반응형
SMALL

시간이 없어요 !! 바로 시작합시다.

 

출발


함수 객체 : 함수도 객체다

자바스크립트에서는 함수도 객체다

자바스크립트에서는 함수도 객체입니다. 즉, 함수의 기본 기능인 코드 실행 뿐만 아니라, 함수 자체가 일반 객체처럼 프로퍼티들을 가질 수 있다는 것입니다.

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

add.result = add(3, 2);
add.status = 'OK';

console.log(add.result); // '5'
console.log(add.status); // 'OK'

앞서 설명한 것처럼 자바스크립트는 일반 객체처럼 취급될 수 있단 점을 알고가야합니다.

 

  • 리터럴에 의해 생성
  • 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
  • 함수의 인자로 전달 가능
  • 함수의 리턴값으로 리턴 가능
  • 동적으로 프로퍼티를 생성 및 할당 가능

이와 같은 특징을 가지고 있는 자바스크립트의 함수를 일급 객체라고 부릅니다. 이는 후에 더 다뤄보도록 합시다.

일급 객체는 다음에 ㅎㅎ

위에서 조금 어렵게 설명 드린거 같은데 함수가 일급 객체라는 건 그냥 값으로 취급된다는 것으로 이해하면 됩니다. 따라서 함수를 변수나 객체, 배열 등에 값으로도 저장할 수 있고, 리턴값으로도 활용이 가능합니다.

 

사실 C 언어 쓰는 사람이라면 굉장히 생소하게 느껴집니다. 저 역시 그랬어요 ㅎㅎ;;

 

변수나 프로퍼티의 값으로 할당

var foo = 100;
var bar = function () { return 100; };
console.log(bar()); // 100

var obj = {};
obj.baz = function() { return 200; };
console.log(obj.baz()); // 200

함수 인자로 전달

var foo = function(func) {
	func(); // 인자로 받은 func() 함수 호출
};

foo(function() {
	console.log('Function can be used as the argument.');
});

리턴값으로 활용

var foo = function() {
	return function () {
    	console.log('this function is the return value.')
	};
};

var bar = foo();
bar();

여기까지가 자바스크립트 함수가 사용되는 전반적인 범위를 알려드린 코드입니다. 실제로 제가 프로젝트를 진행하면서도 위와 같은 특성을 자주 사용하면서 플젝을 하는데, 이가 가능한 이유가 함수가 일급 객체이기 때문임을 한 번 더 알려드립니다.

함수 객체의 기본 프로퍼티

계속 강조했는데 자바스크립트에서 함수는 객체입니다. (계속 말하는 이유는 읽으시는 구독자분들 머리에 집어넣으려고 하는겁니다 !!!)

또 할거에요 !

함수는 객체이지만 일반 객체와는 다르게 추가로 함수 객체만의 표준 프로퍼티가 정의되어 있습니다.

크롬 브라우저에서 실행한 결과 화면

결과를 보면 add() 함수는 저희가 정의하지 않은 다양한 프로퍼티가 기본적으로 생성된 것을 확인할 수 있습니다. (arguments, caller, length)

 

ECMA5 스크립트 명세서에는 모든 함수가 length와 prototype 프로퍼티를 가져야 한다고 말합니다. 실제로 가지고 있죠??

 

name 프로퍼티도 있는데 함수의 이름을 나타냅니다. 익명 함수면 빈 문자열이겠죠.

 

caller 프로퍼티는 자신을 호출한 함수를 나타냅니다. 

 

arguments 프로퍼티는 함수를 호출할 때 전달된 인자값을 나타냅니다.

 

마지막으로 __proto__ 프로퍼티를 알아봅시다.

 

참고로 모든 자바스크립트 객체는 자신의 프로토타입을 가지는 [[Prototype]]이라는 내부 프로퍼티를 가집니다. 크롬에서는 이를 __proto__로 나타냅니다.

 

add() 역시 객체이므로 __proto__를 가지고 있죠?? add()와 같이 함수 객체의 부모 역할을 하는 프로토타입 객체를 Function.prototype 객체라고 명명하고 있으며 이것 역시 함수 객체라고 정의합니다.

 

?

함수 객체의 부모 역할을 하는 프로토타입 객체를 Function.prototype 객체라고 명명하고 이도 역시 함수 객체입니다.

 

뭔가 이상한 점이 있지 않나요..?

 

함수 부모인 프로토타입 객체 역시 함수 객체이라는 건.. 자기 부모가 자기 자신인건지 의문이 생기기 시작합니다.

 

ECMAScript 명세서에는 예외적으로 Function.prototype 함수 객체의 부모는 Object.prototype 객체라고 설명합니다.

 

Function.prototype 객체는 모든 함수들의 부모 역할입니다. 그렇기 때문에 constructor 프로퍼티, toString() 메서드, apply() 메서드, call() 메서드, bind() 메서드을 사용할 수 있습니다.

 

Prototype 프로퍼티

모든 함수는 객체로서 prototype 프로퍼티를 가지고 있습니다. 근데 얘는 방금 말한 __proto__와 다르다는 걸 인지해야합니다.

 

왤케 헷갈리게 했는지 모르겠네요 !? 추후에 이 두 프로토타입에서 자세히 알아봅시다.

 

prototype 프로퍼티는 함수가 생성될 때 만들어지며, constructor 프로퍼티 하나만 있는 객체를 가리킵니다. 이 constructor 프로퍼티는 자신과 연결된 함수를 가리킵니다.

 

아니... 하다 못해 함수도 짝이 있는데.. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

커플 out

실행결과를 보면 알 수 있듯 constructor __proto__라는 두 개의 프로퍼티가 있습니다. 앞서 설명했듯이 이 객체는 func() 함수의 프로토타입 객체이므로 constructor 프로퍼티가 있음을 확인가능하고, 또한, 프로토타입 객체 역시 자바스크립트 객체이므로 예외 없이 __proto__ 프로퍼티를 가지고 있습니다.

 

보시다시피 constructor도 함수를 가리키고 있죠??

 

이렇듯 함수 객체와 프로토타입 객체는 서로 밀접하게 연결되어 있음을 다시 강조합니다.

 

왜냐면 이후 프로토타입과 프로토타입 체이닝을 이해하는 기본 지식이거든요 !!


이상 JavaScript 함수와 프로토타입 체이닝 (2) 였습니다 !

반응형
LIST