현인

19장 프로토타입 본문

기술 학습/JavaScript

19장 프로토타입

현인(Hyeon In) 2023. 7. 31. 20:38

자바스크립트는 멀티 패러다임 프로그래밍 언어이다.

  • 명령형
  • 함수형
  • 프로토타입 기반 객체지향 프로그래밍

클래스 기반 객체지향 프로그래밍 언어

  • C++, Java 등

프로토타입 기반 객체지향 프로그래밍

  • 클래스 기반 객체지향 프로그래밍 언어보다 효율적이며 더 강력하다.

자바스크립트는 객체 기반의 프로그래밍 언어이며 자바스크립트를 이루고 있는 거의 모든 것이 객체다. 원시 타입의 값을 제외한 나머지 값들은 모두 객체이다.

객체지향 프로그래밍

전통적인 명령형 프로그래밍의 절차지향적 관점에서 벗어나 여러 개의 독립적 단위, 즉 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임

실제 세상의 실체를 인식하는 철학적 사고를 프로그래밍에 접목하려는 시도에서 시작.

실체는 특징이나 성질을 나타내는 속성을 가지고 있고, 이를 통해 실체를 인식하거나 구별할 수 있다.

예시로, 사람의 경우 나이, 이름, 성별, 주소 등등..

추상화란 실체의 다양한 속성 중에서 프로그램에 필요한 속성만 간추려 표현하는 것을 말한다.

객체 : 속성을 통해 여러 개의 값을 하나의 단위로 구성한 복합적인 자료구조

  • 프로퍼티 : 상태를 나타내는 데이터
  • 메서드 : 상태를 조작할 수 있는 동작

객체지향 프로그래밍 : 독립적인 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임.

각 객체는 고유의 기능을 갖는 독립적인 부품으로 볼 수 있지만 자신의 고유한 기능을 수행하면서 다른 객체와 관계성을 가질 수 있다. 다른 객체와 메시지를 주고 받거나 데이터를 처리할 수도 있다. 또는 다른 객체의 상태 데이터나 동작을 상속 받아 사용하기도 한다.

상속과 프로토타입

상속

  • 어떤 객체의 프로퍼티 또는 메서드를 다른 객체가 상속 받아 그대로 사용할 수 있는 것

자바스크립트의 상속

  • 프로토타입 기반
  • 불필요한 중복 제거
  • 기존의 코드 재사용
    • 코드 재사용은 개발 비용을 현저히 줄일 수 있는 잠재력이 있으므로 매우 중요함

동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메서드를 중복 소유하는 것은 메모리를 불필요하게 낭비한다. 객체를 생성할 때마다 메서드를 생성하기 때문에 만약 10개의 인스턴스를 생성하면 동일한 함수가 10개 생성된다.

이때 자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 메서드 중복을 막는다.

생성자 함수가 생성한 모든 인스턴ㅅ는 자신의 프로토타입, 즉 상위 객체 역할을 하는 프로토타입의 모든 프로퍼티와 메서드를 상속받는다.

따라서 프로토타입에 메서드를 할당하면 이후 생성자 함수가 생성하는 모든 인스턴스가 해당 메서드를 상속 받아 사용할 수 있다.

상속은 코드의 재사용이란 관점에서 매우 유용하다. 생성자 함수가 생성할 모든 인스턴스가 공통적으로 사용할 프로퍼티나 메서드를 프로토타입에 미리 구현해 두면 생성자 함수가 생성할 모든 인스턴스는 별도의 구현 없이 상위 객체인 프로토타입의 자산을 공유하여 사용할 수 있다.

프로토타입 객체

프로토타입 객체(또는 줄여서 프로토타입)란 객체지향 프로그래밍의 근간을 이루는 객체 간 상속을 구현하기 위해 사용된다.

프로토타입은 어떤 객체의 상위 객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티를 제공한다. 상속받은 하위 객체는 상위 객체의 프로퍼티를 자유롭게 사용할 수 있다.

모든 객체는 [[Prototype]]이라는 내부 슬롯을 가지며, 이 내부 슬롯의 값은 프로토타입의 참조다.

  • 저장되는 프로토타입은 객체 생성 방식에 의해 결정된다.

모든 객체는 하나의 프로토타입을 갖는다. 모든 프로토타입은 생성자 함수와 연결되어 있다.

__proto__ 접근자 프로퍼티

모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.

__proto__ 는 접근자 프로퍼티다.

자바스크립트는 원칙적으로 내부 슬롯과 내부 메서드에 직접적으로 접근하거나 호출할 수 있는 방법을 제공하지 않는다. 단, 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하기는 한다.

프로토타입 내부 슬롯에도 직접 접근할 수 없으며 __proto__ 접근자 프로퍼티를 통해 간접적으로 내부 슬롯의 값, 즉 프로토타입에 접근할 수 있다.

접근자 프로퍼티

  • 자체적인 값을 갖지 않는다.
  • 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수, 즉 getter, setter 프로퍼티 어트리뷰트로 구성된 프로퍼티다.

getter, setter 함수를 통해 프로토타입의 내부 슬롯의 값, 즉 프로토타입을 취득하거나 할당한다.

__proto__ 접근자 프로퍼티는 상속을 통해 사용된다.

__proto__접근자 프로퍼티는 객체가 직접 소유하는 프로퍼티가 아니라, Object.prototype의 프로퍼티다. 따라서 모든 객체는 상속을 통해 Object.prototype.__proto__ 접근자 프로퍼티를 사용할 수 있다.

모든 객체는 프로토타입의 계층 구조인 프로토타입 체인에 묶여 있다. 자바스크립트 엔진은 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 __proto__ 접근자 프로퍼티가 가리키는 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다.

__proto__ 접근자 프로퍼티를 통해 프로토타입에 접근하는 이유

상호 참조에 의해 프로토타입 체인이 생성되는 것을 방지하기 위함

  • 상호 참조가 될 경우 비정상적인 프로토타입 체인이 만들어지기 때문에 에러가 발생한다.

프로토타입 체인은 단방향 링크드리스트로 구현되어야 한다.

  • 순환 참조가 생기면 프로토타입 체인의 종점이 없기 때문에 무한 루프에 빠진다.

__proto__ 접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다.

  • ES5까지 ECMAScript 사양에 포함되지 않는 비표준이었다.
  • 일부는 __proto__를 지원하고 있어서 호환성을 고려하여 ES6에서 __proto__를 표준으로 채택했다.
  • 직접 상속을 통해 Object.prototype을 상속 받지 않는 객체를 생성할 수도 있기 때문에 __proto__ 접근자 프로퍼티를 사용할 수 없는 경우가 있다.
  • 따라서 __proto__ 접근자 프로퍼티 대신 사용할 수 있는 메서드는 다음과 같다.
    • Object.getPrototypeOf : 프로토타입의 참조 취득
    • Object.setPrototypeOf : 프로토타입을 교체하고 싶을 때

함수 객체의 prototype 프로퍼티

함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.

prototype 프로퍼티는 생성자 함수가 생성할 객체의 프로토타입을 가리킨다. 따라서 생성자 함수로서 호출할 수 없는 함수, 즉 non-constructor 인 화살표 함수와 ES6 메서드 축약 표현으로 정의한 메서드는 prototype 프로퍼티를 소유하지 않으며 프로토타입도 생성하지 않는다.

생성자 함수로 호출하기 위해 정의하지 않은 일반 함수도 prototype 프로퍼티를 갖긴 하나, 객체를 생성하지 않기에 아무런 의미가 없는 프로퍼티다.

모든 객체가 가지고 있는  __proto__ 접근자 프로퍼티와 함수 객체만이 가지고 있는 prototype 프로퍼티는 결국 동일한 프로토타입을 가리킨다. 하지만 이들 프로퍼티를 사용하는 주체가 다르다.

  •  __proto__ 접근자 프로퍼티 : 모든 객체가 자신의 프로토타입에 접근 또는 교체하기 위해 사용
  • prototype 프로퍼티 : 생성자 함수가 자신이 생성할 인스턴스의 프로토타입을 할당하기 위해 사용

프로토타입의 constructor 프로퍼티와 생성자 함수

constructor 프로퍼티

  • prototype의 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킨다.
    • 이 연결은 생성자 함수가 생성될 때, 즉 함수 객체가 생성될 때 이뤄진다.

리터럴 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입

리터럴 표기법에 의한 객체 생성 방식과 같이 명시적으로 new 연산자와 함께 생성자 함수를 호출하여 인스턴스를 생성하지 않는 객체 생성 방식도 있다.

리터럴 표기법에 의해 생성된 객체도 물론 프로토타입이 존재한다. 하지만 리터럴 표기법에 의해 생성된 객체의 경우 프로토타입의 constructor 프로퍼티가 가리키는 생성자 함수가 반드시 객체를 생성한 생정자 함수라고 단정할 수 없다.

리터럴 표기법에 의해 생성된 객체도 상속을 위해 프로토타입이 필요하다. 따라서 리터럴 표기법에 의해 생성된 객체도 가상적인 생성자 함수를 갖는다. 프로토타입은 생성자 함수와 더불어 생성되며 prototype, constructor 프로퍼티에 의해 연결되어 있기 때문이다. 다시 말해, 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재한다.

리터럴 표기법에 의해 생성된 객체는 생성자 함수에 의해 생성된 객체는 아니다. 하지만 큰 틀에서 생각해 보면 리터럴 표기법으로 생성한 객체도 생성자 함수로 생성한 객체와 본질적으로 큰 차이는 없다.

따라서 프로토타입의 constructor 프로퍼티를 통해 연결되어 있는 생성자 함수를 리터럴 표기법으로 생성한 객체를 생성한 생성자 함수로 생각해도 크게 무리는 없다. 리터러 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입은 다음과 같다.

리터럴 표기법  생성자 함수 프로토타입
객체 리터럴 Object Object.prototype
함수 리터럴 Function Function.prototype
배열 리터럴 Array Array.prototype
정규 표현식 리터럴 RegExp RegExp.prototype

프로토타입의 생성 시점

모든 객체는 생성자 함수와 연결되어 있다.

프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성된다.

생성자 함수

  • 사용자가 직접 정의한 생성자 함수
  • 빌트인 생성자 함수

사용자 정의 생성자 함수와 프로토타입 생성 시점

생성자 함수로서 호출할 수 있는 함수, 즉 constructor는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성된다.

함수 선언문은 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행된다. 따라서 함수 선언문으로 정의된 생성자 함수는 어떤 코드보다 먼저 평가되어 함수 객체가 된다. 이때 프로토타입도 더불어 생성된다. 생성된 프로토타입은 생성자 함수 객체의 prototype 프로퍼티에 바인딩 된다.

이 때 생성된 prototype은 오직 constructor 프로퍼티만 갖는 객체이며 Object.prototype을 프로토타입으로 가진다.

빌트인 생성자 함수와 프로토타입 생성 시점

Object, String, Number, Function, Array, RegExp, Date, Promise 등과 같은 빌트인 생성자 함수도 일반 함수와 마찬가지로 빌트인 생성자 함수가 생성되는 시점에 프로토타입이 생성된다.

모든 빌트인 생성자 함수는 전역 객체가 생성되는 시점에 생성된다. 이 때 함께 생성되는 프로토타입은 빌트인 생성자 함수의 prototype 프로퍼티에 바인딩 된다.

이처럼 객체가 생성되기 이전에 생성자 함수와 프로토타입은 이미 객체화되어 존재한다. 이후 생성자 함수 또는 리터럴 표기법으로 객체를 생성하면 프로토타입은 생성된 객체의 [[Prototype]] 내부 슬롯에 할당된다. 이로써 생성된 객체는 프로토타입을 상속받는다.

객체 생성 방식과 프로토타입의 결정

객체 생성 방식

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create 메서드
  • 클래스(ES6)

이처럼 다양한 방식으로 생성된 모든 객체는 각 방식마다 세부적인 객체 생성 방식의 차이는 있으나 추상연산 OrdinaryObjectCreate에 의해 생성된다는 공통점이 있다.

OrdinaryObjectCreate

  • 필수 인수 : 자신이 생성할 객체의 프로토타입
  • 선택 인수 : 자신이 생성할 객체에 추가할 프로퍼티 목록

연산 과정

  1. 빈 객체 생성
  2. 객체에 추가할 프로퍼티 목록이 인수로 전달된 경우 프로퍼티를 객체에 추가
  3. 인수로 전달 받은 프로토타입을 자신이 생성한 객체의 [[Prototype]] 내부 슬롯에 할당
  4. 생성된 객체 반환

즉, 프로토타입은 추상 연산 OrdinaryObjectCreate 에 전달되는 인수에 의해 결정된다. 이 인수는 객체가 생성되는 시점에 객체 생성 방식에 의해 결정된다.

객체 리터럴에 의해 생성된 객체의 프로토타입

OrdinaryObjectCreate 전달 프로토타입 : Object.prototype

Object 생성자 함수에 의해 생성된 객체의 프로토타입

OrdinaryObjectCreate 전달 프로토타입 : Object.prototype

객체 리터럴에 의해 생성된 객체와 동일한 구조를 갖는다.

차이점은?

  • 프로퍼티 추가 방식
    • 객체 리터럴 방식 : 리터럴 내부에 프로퍼티를 추가
    • Object 생성자 방식 : 빈 객체를 생성한 이후 프로퍼티를 추가

프로토타입 체인

자바스크립트는 객체의 프로퍼티에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라 한다. 프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 메커니즘이다.

프로토타입 체인의 최상위에 위치하는 객체는 언제나 Object.prototype이다. 따라서 모든 객체는 Object.prototype을 상속받는다. Object.prototype을 프로토타입 체인의 종점이라 한다.

종점의 [[Prototype]] 내부 슬롯의 값은 null이다.

종점인 Object.prototype까지 올라갔음에도 프로퍼티를 찾지 못하였을 경우, undefined를 반환한다. 이때 에러가 발생하지 않는 것에 주의한다.

프로토타입 체인은 상속과 프로퍼티 검색을 위한 메커니즘이라고 할 수 있다.

스코프 체인은 식별자 검색을 위한 메커니즘이다.

스코프 체인과 프로토타입 체인은 서로 연관 없이 별도로 동작하는 것이 아니라 서로 협력하여 식별자와 프로퍼티를 검색하는 데 사용한다.

오버라이딩과 프로퍼티 섀도잉

프로토타입 프로퍼티 : 프로토타입이 소유한 프로퍼티(메서드 포함)

인스턴스 프로퍼티 : 인스턴스가 소유한 프로퍼티

프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면, 프로토타입 체인을 따라 프로토타입 프로퍼티를 덮어쓰지 않고 인스턴스 프로퍼티로 추가한다.

  • 오버라이딩 : 프로토타입 메서드를 인스턴스 메서드에 재정의
  • 프로퍼티 섀도잉 : 상속 관계에 의해 프로퍼티가 가려지는 현상

프로퍼티 삭제 또한 마찬가지로 인스턴스에 있는 프로퍼티만 삭제된다.

인스턴스에 없는 프로퍼티를 삭제하면, 상위 프로토타입의 프로퍼티를 삭제하지 않는다.

다시 말해, 하위 객체를 통해 프로토타입에 get 접근은 가능하나 set 접근은 안된다.

프로토타입 프로퍼티를 변경하기 위해서는 프로토타입에 직접 접근해야 한다.

프로토타입의 교체

프로토타입은 임의의 다른 객체로 변경할 수 있다. 이것은 부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미한다. 이러한 특징을 활용하여 객체 간의 상속 관계를 동적으로 변경할 수 있다. 프로토타입은 생성자 함수 또는 인스턴스에 의해 교체할 수 있다.

생성자 함수에 의한 프로토타입의 교체

프로토타입을 교체하면 constructor 프로퍼티와 생성자 함수 간의 연결이 파괴된다. 파괴된 constructor 프로퍼티와 생성자 함수 간의 연결을 되살리기 위해선 프로토타입으로 교체한 객체 리터럴에 constructor 프로퍼티를 추가하여 프로토타입의 constructor 프로퍼티를 되살린다.

function Person(name) {
	this.name = name;
}

Person.prototype = { 
	constructor : Person,
	kind : 'human' 
};

const me = new Person('Choi');

인스턴스에 의한 프로토타입의 교체

프로토타입은 생성자 함수의 prototype 프로퍼티 뿐만 아니라 인스턴스의 __proto__ 접근자 프로퍼티를 통해 접근할 수 있다. 인스턴스의 __proto__ 접근자 프로퍼티를 통해 프로토타입을 교체할 수 있다.

생성자 함수에 의한 프로토타입 교체는 미래에 생성할 인스턴스의 프로토타입을 교체하는 것이며,

__proto__ 접근자 프로퍼티를 통해 프로토타입을 교체하는 것은 이미 생성된 객체의 프로토타입을 교체하는 것이다.

역시 프로퍼티와 생성자 함수 간의 연결을 살리기 위해 프로토타입으로 교체할 객체에 constructor 프로퍼티에 생성자 함수를 연결하고 생성자 함수의 prototype 프로퍼티를 재설정한다.

이처럼 프로토타입 교체를 통해 객체 간의 상속을 동적으로 변경하는 것은 꽤나 번거롭다. 따라서 프로토타입은 직접 교체하지 않는 것이 좋다. 상속 관계를 인위적으로 설정하려면 직접 상속이 더 편리하고 안전한다. 혹은 ES6 부터 도입된 클래스를 사용하면 간편하고 직관적으로 상속 관계를 구현할 수 있다.

function Person(name) {
	this.name = name;
}

const me = new Person('Choi');

const parent = { 
	constructor : Person,
	kind : 'human' 
};

Person.prototype = parent;

Object.setPrototypeOf(me, parent);

instanceof 연산자

instanceof 연산자는 이항 연산자로서 좌변에 객체를 가리키는 식별자, 우변에 생성자 함수를 가리키는 식별자를 피연산자로 받는다. 만약 우변의 피연산자가 함수가 아닌 경우 TypeError가 발생한다.

우변의 생성자 함수의 prototype에 바인딩된 객체가 좌변의 객체의 프로토타입 체인 상의 존재하면 true로 평가되고, 그렇지 않은 경우 false로 평가된다.

const obj = new Object();

console.log(obj instanceof Object); // true

const arr = new Array();

console.log(arr instanceof Object);

생성자 함수의 prototype에 바인딩 된 객체가 프로토타입 체인 상에 존재하는지 확인한다.

따라서 생성자 함수에 의해 프로토타입이 교체되어 constructor 프로퍼티와 생성자 함수 간의 연결이 파괴되어도 생성자 함수의 prototype 프로퍼티와 프로토타입 간의 연결은 파괴되지 않으므로 instanceof는 아무런 영향을 받지 않는다.

직접 상속

Object.create에 의한 직접 상속

Object.create 메서드는 명시적으로 프로토타입을 지정하여 새로운 객체를 생성한다. 다른 객체 생성 방식과 마찬가지로 추상 연산 OrdinaryObjectCreate를 호출한다.

매개변수

  1. 생성할 객체의 프로토타입
  2. 프로퍼티 키와 프로퍼티 디스크립터 객체로 이뤄진 객체 (생략가능)

첫 번째 매개변수에 전달한 객체의 프로토타입 체인에 속하는 객체를 생성한다. 즉, 객체를 생성하면서 직접적으로 상속을 구현하는 것이다.

장점

  • new 연산자가 없이도 객체를 생성할 수 있다.
  • 프로토타입을 지정하면서 객체를 생성할 수 있다.
  • 객체 리터럴에 의해 생성된 객체도 상속 받을 수 있다.

Object.prototype의 빌트인 메서드는 모든 객체가 상속받아 호출할 수 있다. ESLint 에서는 Object.prototype의 빌트인 메서드를 객체가 직접 호출하는 것을 권장하지 않는다. 그 이유는 Object.create 메서드를 통해 프로토타입 체인의 종점에 위치하는 객체를 생성할 수 있기 때문이다. 따라서 간접적으로 호출하는 것이 좋다.

const parent = { x : 10 };

const child = Object.create(parent, {
	y : { value : 4, writable : true, enumerable : true, configurable : true}
});

const obj = Object.create(null);
obj.a = 1;

console.log(obj.hasOwnProperty('a'));
// error : Object.prototype을 상속받지 않았으므로 hasOwnProperty가 없다

console.log(Object.prototype.hasOwnProperty.call(obj, 'a'));

객체 리터럴 내부에서 __proto__에 의한 직접 상속

ES6부터는 객체 리터럴 내부에서 __proto__ 접근자 프로퍼티를 사용하여 직접 상속을 구현할 수 있다.

const myProto = { x: 10 };

const obj = {
	y: 20;
	__proto__: myProto
};

정적 프로퍼티/메서드

생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메서드

가능한 이유 : 생성자 함수 역시 객체이므로 프로퍼티/메서드를 가질 수 있다.

이렇듯 생성자가 소유한 프로퍼티/메서드르르 정적 프로퍼티/메서드라고 한다.

정적 프로퍼티/메서드는 생성자 함수가 생성한 인스턴스로 참조/호출 할 수 없다.

프로퍼티 존재 확인

in 연산자

in 연산자는 객체 내의 특정 프로퍼티가 존재하는지 여부를 확인한다. in 연산자의 사용법은 다음과 같다.

/**
 * key : 프로퍼티 키를 나타내는 문자열
 * object : 객체로 평가되는 표현식
 */
key in object

in 연산자는 확인 대상 객체 뿐만 아니라 상속 받는 모든 프로토타입의 프로퍼티를 확인하므로 주의한다.

ES6에서 도입된 Reflect.has 메서드로 대체 가능

Object.prototype.hasOwnProperty 메서드

이름에서 알 수 있듯이 인수로 전달 받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환한다.

프로퍼티 열거

for … in 문

  • 객체의 모든 프로퍼티를 순회하며 열거
  • in 연산자처럼 상속 받은 프로토타입의 프로퍼티까지 열거한다.
  • 프로퍼티 어트리뷰트 [[Enumerable]] 값이 true인 값만 순회한다.
  • 키가 심벌인 프로퍼티는 열거하지 않는다.
  • 자신의 프로퍼티만 열거하려면 hasOwnProperty 메서드 활용
  • 순서 보장 하지 않음
    • 하지만 대부분의 모던 브라우저는 순서를 보장하고 숫자인 프로퍼티 키에 대해서는 정렬을 실시한다.
  • 따라서 배열에서는 for … in 문을 사용하지 말고 일반적인 for 문이나 for … of 문 또는 Array.prototype.forEach 메서드를 사용하기 바란다.
    • 상속 받은 프로퍼티가 포함될 수 있기 때문!

Object.keys/values/entries 메서드

객체 고유의 프로퍼티만 열거하기 위해서 사용

  • Object.keys
    • 객체 자신의 열거 가능한 프로퍼티 키를 배열로 반환
  • Object.values
    • 객체 자신의 열거 가능한 프로퍼티 값을 배열로 반환
    • ES8 이후 도입
  • Object.entries
    • 객체 자신의 열거 가능한 프로퍼티 키와 값의 쌍의 배열을 배열에 담아 반환
    • ES8 이후 도입

마치며

자바스크립트로 개발을 했지만 프로토타입을 제대로 사용해 본 경험도 없었고 개념에 대해서도 잘 이해하지 못했었다. 앞으로도 프론트엔드 개발을 하면서 많이 사용할지는 잘 모르겠다. 하지만 라이브러리를 사용할 때 라이브러리 구현 내용을 이해하는데 많은 도움을 받을 수 있을 것 같다.

참고 문헌

- 이웅모. 『모던 자바스크립트 Deep Dive』. 위키북스, 2020.

반응형

'기술 학습 > JavaScript' 카테고리의 다른 글

23장 실행 컨텍스트  (0) 2023.07.31
22장 this  (0) 2023.07.31
16장 프로퍼티 어트리뷰트  (0) 2023.07.20
15장 let, const 키워드와 블록 레벨 스코프  (0) 2023.07.20
8장 제어문  (0) 2023.06.28