|
17 | 17 | 그런데, 일급 객체가 뭐죠? |
18 | 18 |
|
19 | 19 | ### 일급 객체 |
| 20 | +> 함수는 일반 객체가 아니라 **일급 객체(First-Class Object)** 로 취급됩니다. |
| 21 | +
|
| 22 | +- 아래와 같은 조건을 만족하면 일급 객체라고 해요. |
| 23 | + 1. 무명 리터럴로 생성(런타임에 생성이 가능하다는 이야기에요)할 수 있습니다. |
| 24 | + 2. 변수, 각종 자료구조(Object, Array, Set, Map 등)에 저장할 수 있습니다. |
| 25 | + 3. 함수의 매개변수(Parameter)로 전달할 수 있습니다. |
| 26 | + 4. 함수의 반환(return) 값으로 사용할 수 있습니다. |
| 27 | +- 예제 코드를 보면 더 정확히 알겠죠? |
| 28 | + ```js |
| 29 | + // 1번, 2번 조건에 충족됩니다. |
| 30 | + const increase = function (num) { |
| 31 | + return ++num; |
| 32 | + } |
| 33 | + console.log(increase); // ƒ (num) { return ++num; } |
| 34 | + console.log(increase(3)); // 4 |
| 35 | + |
| 36 | + |
| 37 | + // 3번 조건에 충족됩니다. |
| 38 | + const predicates = { increase }; |
| 39 | + console.log(predicates); // {increase: ƒ} |
| 40 | + console.log(predicates.increase(3)); // 4 |
| 41 | + |
| 42 | + // 3번, 4번 조건에 충족됩니다. |
| 43 | + function makeCounter(predicates) { |
| 44 | + let num = 0; |
| 45 | + |
| 46 | + return function() { |
| 47 | + num = predicates(num); |
| 48 | + return num; |
| 49 | + }; |
| 50 | + } |
| 51 | + |
| 52 | + const increaser = makeCounter(predicates.increase); |
| 53 | + console.log(increaser()); // 1 |
| 54 | + console.log(increaser()); // 2 |
| 55 | + ``` |
| 56 | + |
| 57 | +`함수는 일급 객체`라는 것은 함수를 객체와 동일하게 사용할 수 있다는 의미입니다. 즉, 함수는 값을 가용할 수 있는 곳이라면 리터럴로 정의할 수 있고 런타임에 함수 객체로 평가되는 것이죠. |
| 58 | + |
| 59 | +함수 객체와 일반 객체는 아래와 같은 차이가 있습니다. |
| 60 | +1. 소괄호(`()`)를 사용한 **호출**인데, 일반 객체는 호출이 불가능하지만 함수 객체는 호출할 수 있습니다. |
| 61 | +2. 함수 객체에는 일반 객체에 없는 함수 고유 프로퍼티가 존재합니다. |
| 62 | + |
| 63 | +함수도 일반 객체처럼 프로퍼티를 소유할 수 있습니다. 즉, Object.getOwnPropertyDescriptors를 사용할 수 있죠. 함수 객체가 소유한 프로퍼티를 살펴볼까요? |
| 64 | + |
| 65 | +- **arguments** 프로퍼티 |
| 66 | + - arguments 객체는 함수 호출 시 전달된 인수(argument)들의 정보를 담고 있는 순회 가능(Iterable)한 유사 배열 객체입니다. |
| 67 | + - 함수 내부에서 지역 변수처럼 사용되며 외부에서는 참조할 수 없습니다. |
| 68 | + - ES3부터 표준에서 폐지되어 사용이 권장되지 않습니다. |
| 69 | + - 자바스크립트는 함수의 매개변수와 인수의 개수가 일치하는지 확인하지 않아 에러가 발생하지 않습니다. |
| 70 | + - 지정된 개수보다 적은 경우 : 매개변수는 undefined로 초기화됩니다. |
| 71 | + - 지정된 개수보다 많은 경우 : 암묵적으로 arguments 객체에 순서대로 저장(순회 가능한 유사 배열 객체이므로)됩니다. |
| 72 | + - 이러한 이유로 `가변 인자 함수`를 구현할 때 유용합니다. |
| 73 | + - 단, 유사 배열 객체는 배열이 아니므로 배열 메서드를 사용할 수 없으나 아래의 방법으로 간접 호출할 수 있습니다. |
| 74 | + 1. `Function.prototype.call, Function.prototype.apply` 사용하기 |
| 75 | + ```js |
| 76 | + function sum(){ |
| 77 | + // const array = Array.prototype.slice.apply(arguments); |
| 78 | + const array = Array.prototype.slice.call(arguments); |
| 79 | + return array.reduce(function (pre, cur){ |
| 80 | + return pre + cur; |
| 81 | + }, 0); |
| 82 | + } |
| 83 | + console.log(sum(1, 2, 3, 4, 5)); // 15 |
| 84 | + ``` |
| 85 | + 2. ES6의 Rest 파라미터 |
| 86 | + ```js |
| 87 | + function sum(...args){ |
| 88 | + return args.reduce((pre, cur) => pre + cur, 0); |
| 89 | + } |
| 90 | + console.log(sum(1, 2, 3, 4, 5)); // 15 |
| 91 | + ``` |
| 92 | + |
| 93 | +<br> |
| 94 | + |
| 95 | +- **caller** 프로퍼티 |
| 96 | + - 비표준 프로퍼티로 함수 자신을 호출한 함수를 가리킵니다. |
| 97 | + |
| 98 | +<br> |
| 99 | + |
| 100 | +- **length** 프로퍼티 |
| 101 | + - 함수를 정의할 때 선언한 매개변수의 개수를 가리킵니다. |
| 102 | + - `arguments 객체의 length 프로퍼티`와 `함수 객체의 length 프로퍼티`의 값은 다를 수 있습니다. |
| 103 | + - 전자의 경우 인자(argument)의 개수, 후자의 경우 매개변수(parameter)의 개수를 가리키기 떄문이지요. |
| 104 | + |
| 105 | +<br> |
| 106 | + |
| 107 | +- **name** 프로퍼티 |
| 108 | + - ES6에서 표준이 되었으며 함수 이름을 나타냅니다. ES5와 ES6의 동작이 서로 다릅니다. |
| 109 | + - 익명 함수 표현식의 경우 `ES5는 빈 문자열`을, `ES6는 함수 객체를 가리키는 식별자`를 값으로 갖습니다. |
| 110 | + |
| 111 | +<br> |
| 112 | + |
| 113 | +- **__proto__** 접근자 프로퍼티 |
| 114 | + - `[[Prototype]]` 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용합니다. |
| 115 | + |
| 116 | +<br> |
| 117 | + |
| 118 | +- **prototype** 프로퍼티 |
| 119 | + - 생성자 함수로 호출할 수 있는 객체로 constructor만이 소유합니다. |
| 120 | + - 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor는 prototype 프로퍼티가 존재하지 않습니다. |
| 121 | + - 즉, 함수가 객체를 생성하는 생성자 함수로 호출될 때, 생성자 함수가 생성할 인스턴스의 프로토타입 객체를 가리키는 거죠. |
20 | 122 |
|
| 123 | +`__proto__`와 `[[Prototype]]`에 대해서는 [프로토타입 페이지](https://github.com/FECrash/JavascriptCrash/blob/main/Javascript/prototype.md)를 참고해주세요. |
21 | 124 |
|
22 | 125 | <br> |
23 | 126 |
|
|
0 commit comments