함수 객체

2019. 7. 19. 16:01javascript

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

add.result = add(2,5;
add.status = "ok"

console.log(add.result); // 5
console.log(add.status); // "ok"

위의 코드를 보면 함수가 일반 객체 처럼 프로퍼티를 추가하는 게 가능하다는 것을 보여준디.

함수 코드는 [[Code]] 내부 프로퍼티에 자동으로 저장된다.

 

 ※add() 함수 객체

[[Code]]     ======> return x+y

  result       ======> 5

  status       ======> "ok"

 

자바스크립트에서 함수도 일반 객체 처럼 취급 될수 있고 다음과 같은 동작이 가능한 일급 객체이다.

(일급 객체란 나열한 기능이 모두 가능한 객체를 말한다.

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

함수가 일반 객체처럼 이용되는 예제를 살펴 보자

 

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

// 변수에 할수 할당
var foo = 100;
var bar = function () {return 100; };
console.log(bar()); // 100

// 프로퍼티에 함수 할당
var obj = {};
obj.baz = function () {return 200;}
console.log(obj.baz()); // 200

 

2) 함수 인자로 전달

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

//foo() 함수 실행
foo(function() {
	console.log("Function can be used as the arguments.");
});

// "Function can be used as the arguments."

익명 함수를 func 인자로 넘겨서 함수를 호출 하고 있다, 

 

3) 리턴값으로 활용

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

var bar = foo();
bar();

//"this function is the return value."

bar에 foo()를 실행하면 나오는 내부함수를 할당 해주고 bar 함수를 즉 foo의 내부함수를 실행 시켜 console.log를 출력하고 있다.

 

함수 객체의 기본 프로퍼티

함수는 객체다. 이 말은 함수 역시 일반적인 객체의 기능에 추가로 호출 됐을 때 전의된 코드를실행하는 기능을 가지고 있다. 또한 일반 객체와는 다르게 추가로 함수 객체만의 표준 프로퍼티가 정의되어 있다.

 

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

console.dir(add);

function add(x,y) { return x + y; }
  arguments: null
  caller: null
  length: 2
  name: "add"
prototype: {constructor: ƒ} // (add)
__proto__: ƒ ()
  apply: ƒ apply()
  arguments: null
  bind: ƒ bind()
  call: ƒ call()
  caller: null
  constructor: ƒ Function()
  length: 0
  name: ""                 // Empty()
  toString: ƒ toString()
  Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]()
  get arguments: ƒ ()
  set arguments: ƒ ()
  get caller: ƒ ()
  set caller: ƒ ()
  __proto__: Object
  [[FunctionLocation]]: <unknown>
  [[Scopes]]: Scopes[0]
  [[FunctionLocation]]: VM432:1
[[Scopes]]: Scopes[1]

ECMA5 스크립트 명세서에는 모든 함수가 lengthprototype 프로퍼티를 가져야 한다고 기술하고 있다. 위의 결과를 확인해 보면 length 와  prototype 프로퍼티를 가지고 있다.

 

length 와 prototype 프로퍼티 이외의 프로퍼티들을 살펴보자, 이 프로퍼티들은 ECMA 표준이 아니다. 

  • name 프로퍼티는 함수의 이름을 나타낸다. 이름이 없는 익명 함수라면 빈 문자열이 된다.
  • caller 프로퍼티는 자신을 호출한 함수를 나타낸다. 함수를 호출 하지 않았으므로 null 값을 나타내고 있다.
  • arguments 프로퍼티는 함수를 호출할 때 전달한 인자값을 나타 낸다. 현재 함수를 호출한 상태가 아니므로 null 값이 출력됐다.
  • __proto__ 프로퍼티 : 모든 자바스크립트 객체는 자신의 프로토 타입을 가리키는 [[Prototype]]라는 내부 프로퍼티를 가진다.  즉[[Prototype]] 와  __proto__ 는 같은 개념이라고 생각하면 된다.

add() 함수 역시 객체이므로 [[Prototype]] 프로퍼티를 가지고 있고 이를 통해 자신의 부모 역활을 하는 프로토타입 객체를 가리킨다.  이를 ECMA 표준에서는 Function.prototype 객체라고 말하고 있으며 이것을 함수 객체라고 정의하고 있다. 

실제로 위의 결과를 보면 Function Prototype 객체를 Empty() 함수라고 명하고 있으며 이 함수 역시 name, caller, arguments 등과 같은 프로퍼티가 있음을 확인할 수 있다.

length 프로퍼티

length 프로퍼티는 모든 함수가 가져야 하는 표준 프로퍼티로서 함수가 정상적으로 실행될 때 기대되는 인자의 개수를 나타낸다.

function func0() {

}

function func1(x) {
	return x;
}

function func2 (x, y) {
	reutnr x + y;
} 

function func3 (x, y, z) {
	reuturn x + y + z;
}

console.log("func0.length = " + func0.length); // func0.length = 0
console.log("func1.length = " + func1.length); // func1.length = 1
console.log("func2.length = " + func2.length); // func2.length = 2
console.log("func3.length = " + func3.length); // func3.length = 3

 

Prototype 프로퍼티 

모든 함수는 객체로서 prototype 프로퍼티를가지고 있지만 주의해야 할 점은 함수 객체의 prototype 프로퍼티와 모든 객체의 부모를 나타내는 내부 프로퍼티[[Prototype]]과 혼동하지 말아야 한다.

prototype 프로퍼티느 함수가 생성될 때 만들어지며 constructor 프로퍼티 하나만 있는 객체를 가리킨다. 그리고 constructor 프로퍼티는 자신과 연결된 함수를 가리킨다. 즉 자바스크립트에서는 함수를 생성할 때 함수 자신과 연결된 프로토 타입 객체를 동시에 생성하며 각각 prototype과 constructor라는 프로퍼티로 서로 참조하게  된다. 

function myFunction() {
	return true;
}

console.dir(myFunction.prototype); 
console.dir(myFunction.prototype.constructor);

// myFunction.prototype
Object
  constructor: ƒ myFunction()
  __proto__: Object

// myFunction.prototype.constructor
ƒ myFunction()

실행 결과를 보면 myFunction.prototype 객체는 constructor__proto__라는 두개의 프로퍼티가 있다.

 

 

 

'javascript' 카테고리의 다른 글

비동기 처리 방법  (0) 2019.10.23
Prototype, __proto__, constructor 의 관계  (0) 2019.07.29
함수  (0) 2019.07.18
배열  (0) 2019.07.17
객체  (0) 2019.07.15