💡 18.1 일급 객체
1. 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.
2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
3. 함수의 매개변수에 전달할 수 있다.
4. 함수의 반환값으로 사용할 수 있다.
- 함수는 이를 모두 만족하는 일급객체! ⇒ 함수형 프로그래밍을 가능하게 함
- 함수형 프로그래밍 : 순수 + 보조 함수를 통해 Side effect을 최소화하여, 불변성을 지향
- 함수 또한 객체, 일반 객체와의 차이점은?
- 함수는 호출 가능, 객체는 호출불가능
- 함수 고유의 프로퍼티가 존재!
💡 18.2 함수 객체의 프로퍼티
- 함수의 모든 프로퍼티의 프로퍼티 어트리뷰트를 봅시다!
function square(number) {
return number * number;
}
console.log(Object.getOwnPropertyDescriptors(square));
- (16장) 모든 객체는 [[Prototype]]이라는 내부슬롯을 가지고, __proto__ 로 접근이 가능하다
// 즉, 해당 문법이 가능해야하나 되지 않는다.
console.log(Object.getOwnPropertyDescriptor(square, '__proto__'));
// undefined
왜 해당 코드가 안될까?
- 함수 객체 고유의 프로퍼티가 아닌, Object.prototype 객체의 프로퍼티이기 때문이다.
- Object.prototype 객체의 프로퍼티는 모든 객체가 상속받아 사용할 수 있다!
✨ 18.2.1 arguments 프로퍼티
- 인수 정보를 갖는 iterable 유사 배열 객체
- length 프로퍼티를 가진 객체로, for문으로 순회가능하다.
- 그러나 배열이 아니기에 배열메소드 X
- 함수 매개변수, 인수 개수가 일치하는지 확인 X ⇒ 에러 X
- 적게 전달할 경우 undefined, 많게 전달할 경우 무시(암묵적으로 저장되긴 함)
function multiply(x, y) {
console.log(arguments);
return x + y;
}
console.log(multiply(1, 2)); // 2
- 가변 인자 함수를 구현할 때 쓰지만, arguments[i] 번거로움
- 이를 해결하고자 ES6 Rest 파라미터 도입
function foo(...rest) {}
✨ 18.2.2 caller 프로퍼티
- 함수 자신을 호출한 함수를 가리킨다.
- ECMAScript사양에 포함되지 않는 비표준 프로퍼티. 참고만 하자!
✨ 18.2.3 length 프로퍼티
- 선언한 매개변수의 개수
- arguments에서 length는 인자의 개수, 이건 매개변수의 개수
function baz(x, y) {
return x * y;
}
console.log(baz.length); // 2
✨ 18.2.4 name 프로퍼티
- 함수 이름을 나타낸다.
- (12장) 함수 이름 <-> 식별자
- 함수는 함수 이름으로 호출하는 게 아니라, 함수 객체를 가리키는 식별자로 호출한다.
- 함수는 함수 이름으로 호출하는 게 아니라, 함수 객체를 가리키는 식별자로 호출한다.
- 익명함수 표현식의 경우, ES5는 빈 문자열로, ES6는 변수 이름으로 값이 다르다.
// 기명 함수 표현식
var namedFunc = function foo() {};
console.log(namedFunc.name); // foo
// 익명 함수 표현식
var anonymousFunc = function() {};
console.log(anonymousFunc.name); // ES6 : anonymousFunc
// 함수 선언문(Function declaration)
function bar() {}
console.log(bar.name); // bar
✨ 18.2.5 __proto__ 접근자 프로퍼티
- (16장) 모든 객체는 [[Prototype]]이라는 내부슬롯을 가지고, __proto__ 로 간접적으로 접근이 가능하다
const obj = { a: 1 };
// 객체 리터럴 방식으로 생성한 객체의 프로토타입 객체는 Object.prototype이다.
console.log(obj.__proto__ === Object.prototype); // true
// 객체 리터럴 방식으로 생성한 객체는 프로토타입 객체인 Object.prototype의 프로퍼티를 상속받는다.
// hasOwnProperty 메서드는 Object.prototype의 메서드다.
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty('__proto__')); // false
✨ 18.2.6 prototype 프로퍼티
- 생성자 함수, constructor만이 소유하는 프로퍼티 (17장)
- 어떤 함수가 constructor를 가져서 prototype 프로퍼티를 가질 것인가?
=> 모든 함수가 prototype 프로퍼티를 갖는 게 아니다!
// 함수 객체는 prototype 프로퍼티를 소유한다.
(function () {}).hasOwnProperty('prototype'); // -> true
// 일반 객체는 prototype 프로퍼티를 소유하지 않는다.
({}).hasOwnProperty('prototype'); // -> false
🎈 요약정리
일급 객체
1. 무명의 리터럴로 생성할 수 있다.
2. 변수나 자료구조에 저장할 수 있다.
3. 함수의 매개변수에 전달할 수 있다.
4. 함수의 반환값으로 사용할 수 있다.
- 함수는 이를 만족하는 일급객체!
- 함수 또한 객체, 그럼 일반 객체와의 차이점은?
- 함수는 호출 가능, 객체는 호출불가능
- 함수는 고유의 프로퍼티가 존재!
🎆 여기서 프로퍼티란?
property는 해당 object의 특징이다.
property는 보통 데이터 구조와 연관된 속성을 나타낸다. 예를 들어 문자열에는 length라는 property가 포함되어 있는데 이 프로퍼티는 문자열 안에 있는 문자의 양을 정수로 나타낸 값을 담고 있다.
property에는 2가지 종류가 있다.
- 인스턴스 프로퍼티(Instance property)는 특정 object 인스턴스의 특정한 데이터를 가지고 있다
- 정적 프로퍼티(Static Property)는 모든 object 인스턴스들에게 공유되는 데이터를 가지고 있다
property는 이름(string이나 symbol)과 값(원시함수(primitive), 메서드(method) 또는 객체 참조(object reference))을 가지고 있다
- arguments 프로퍼티
- 인수 정보를 갖는 iterable 유사 배열 객체
- caller 프로퍼티
- 함수 자신을 호출하는 함수(비표준 프로퍼티, 참고만)
- length 프로퍼티
- 선언한 매개변수의 개수
- name 프로퍼티
- 함수 이름을 나타냄 (함수 이름 <-x-> 식별자)
- 함수는 함수 이름으로 호출하는 게 아니라 함수 객체를 가리키는 식별자로 호출
- __proto__ 접근자 프로퍼티
- 모든 객체는 [[Prototype]]이라는 내부슬롯을 가지고, __proto__로 간접적으로 접근가능
- prototype 프로퍼티
- 생성자함수, constructor만이 소유하는 프로퍼티
- 모든 함수가 prototype 프로퍼티를 갖는 게 아님.
반응형
'📝 Javascript > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
[Javascript] 모던 자바스크립트 Deep Dive - 22, 23장 this, 실행컨텍스트 (1) | 2024.07.17 |
---|---|
[Javascript] 모던 자바스크립트 Deep Dive - 20장 strict mode (0) | 2024.01.08 |
[Javascript] 모던 자바스크립트 Deep Dive - 17장 생성자 함수에 의한 객체 생성 (0) | 2023.12.28 |
[Javascript] 모던 자바스크립트 Deep Dive - 16장 프로퍼티 어트리뷰트 (0) | 2023.09.09 |
[Javascript] 모던 자바스크립트 Deep Dive - 15장 let, const 키워드와 블록 레벨 스코프 (0) | 2023.08.20 |