자바슀크늜튞는 객첎 지향의 프로귞래밍 얞얎읎며 자바슀크늜튞륌 읎룚고 있는 거의 몚든 것읎 객첎닀.

자바슀크늜튞는 프로토 타입 Ʞ반의 객첎지향 프로귞래밍 ì–žì–Žë‹€.

⭐ 19.1 객첎지향 프로귞래밍

객첎지향 프로귞래밍은 싀섞계의 싀첎륌 읞식하는 철학적 사고륌 프로귞래밍에 접목하렀는 시도에서 시작된닀. 싀첎는 성질을 나타낮는 속성(attribute/property)을 가지고 있고, 닀양한 속성 쀑에서 프로귞랚에 필요한 속성만 간추렀 낮 표현하는 것을 추상화(abstraction)띌고 한닀.

속성을 통핎 여러 개의 값을 하나의 닚위로 구성한 복합적읞 자료구조륌 객첎띌 하며, 객첎지향 프로귞래밍은 독늜적읞 객첎의 집합윌로 프로귞랚을 표현하렀는 프로귞래밍 팚러닀임읎닀.

객첎지향 프로귞래밍은 객첎의 상태륌 나타낮는 데읎터와 상태 데읎터륌 조작할 수 있는 동작을 하나의 녌늬적읞 닚위로 묶얎 복합적읞 자료구조로 나타낞닀. 읎 때 객첎의 상태 데읎터륌 프로퍌티, 동작을 메서드띌 부륞닀.

⭐ 19.2 상속곌 프로토타입

객첎 지향 프로귞래밍 방식에서는 상속을 통핎 불필요한 쀑복을 방지한닀. 자바슀크늜튞는 프로토타입을 Ʞ반윌로 상속을 구현한닀.

// 생성자 핚수
function Circle(radius) {
  this.radius = radius;
}

// Circle 생성자 핚수가 생성한 몚든 읞슀턎슀가 getArea 메서드륌
// 공유핎서 사용할 수 있도록 프로토타입에 추가한닀.
// 프로토타입은 Circle 생성자 핚수의 prototype 프로퍌티에 바읞딩되얎 있닀.
Circle.prototype.getArea = function () {
  return Math.PI * this.radius ** 2;
};

// 읞슀턎슀 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);

// Circle 생성자 핚수가 생성한 몚든 읞슀턎슀는 부몚 객첎의 역할을 하는
// 프로토타입 Circle.prototype윌로부터 getArea 메서드륌 상속받는닀.
// 슉, Circle 생성자 핚수가 생성하는 몚든 읞슀턎슀는 하나의 getArea 메서드륌 공유한닀.
console.log(circle1.getArea === circle2.getArea); // true

console.log(circle1.getArea()); // 3.141592653589793
console.log(circle2.getArea()); // 12.566370614359172

⭐ 19.3 프로토타입 객첎

프로토 타입은 ì–Žë–€ 객첎의 상위(부몚) 객첎의 역할을 하는 객첎로서 닀륞 객첎에 공유 프로퍌티(메서드 포핚)을 제공한닀. 프로토타입을 상속받은 하위(자식) 객첎는 상위 객첎의 프로퍌티륌 자신의 프로퍌티처럌 자유롭게 사용할 수 있닀.

몚든 객첎는 [[Prototype]] 읎띌는 낎부 슬롯을 가지며, 읎 낎부 슬롯의 값은 프로토타입(null읞 겜우도 있닀.) [[Prototype]]에 저장되는 프로토타입은 객첎 생성 방식에 의핎 결정된닀. 슉, 객첎가 생성될 때 객첎 생성 방식에 따띌 프로토 타입읎 결정되고 [[Prototype]] 에 저장된닀.

몚든 객첎는 하나의 프로토타입을 갖는닀. 귞늬고 몚든 프로토타입은 생성자 핚수와 연결되얎 있닀.

[[Prototype]] 낎부 슬롯에는 직접 접귌할 수 없지만, 위 귞늌처럌 proto 접귌자 프로퍌티륌 통핎 자신의 프로토타입, 슉 자신의 [[Prototype]] 낎부 슬롯읎 가늬킀는 프로토타입에 간접적윌로 접귌할 수 있닀.

19.3.1 proto 접귌자 프로퍌티

몚든 객첎는proto 접귌자 프로퍌티륌 통핎 자신의 프로토타입, 슉 [[Prototype]] 낎부 슬롯에 간접적윌로 접귌할 수 있닀.

const person = { name: 'Lee' };

// person 객첎는 __proto__ 프로퍌티륌 소유하지 않는닀.
console.log(person.hasOwnProperty('__proto__')); // false

// __proto__ 프로퍌티는 몚든 객첎의 프로토타입 객첎읞 Object.prototype의 접귌자 프로퍌티닀.
console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'));
// {get: ƒ, set: ƒ, enumerable: false, configurable: true}

// 몚든 객첎는 Object.prototype의 접귌자 프로퍌티 __proto__륌 상속받아 사용할 수 있닀.
console.log({}.__proto__ === Object.prototype); // true

proto 접귌자 프로퍌티륌 통핎 프로토타입에 접귌하는 것은 권장하지 ì•Šêž° 때묞에, 프로퍌티 대신 프로토타입의 찞조륌 췚득하고 싶은 겜우에는 Object.getPrototpyeOf 메서드나 Object.setPrototypeOf 메서드륌 사용할 것을 권장한닀.

// 1. 1번 윔드
const parent = {};
const child = {};
// child의 프로토타입을 parent로 섀정
child.__proto__ = parent;
// parent의 프로토타입을 child로 섀정
parent.__proto__ = child; // TypeError: Cyclic __proto__ value

// 2. 2번 윔드 사용 권장
const obj = {};
const parent = { x: 1 };

// obj 객첎의 프로토타입을 췚득
Object.getPrototypeOf(obj); // obj.__proto__;
// obj 객첎의 프로토타입을 교첎
Object.setPrototypeOf(obj, parent); // obj.__proto__ = parent;

console.log(obj.x); // 1

19.3.2 핚수 객첎의 prototype 프로퍌티

핚수 객첎만읎 소유하는 prototype 프로퍌티는 생성자 핚수가 생성할 읞슀턎슀의 프로토타입을 가늬킚닀. prototype 프로퍌티는 생성자 핚수가 생성할 객첎(읞슀턎슀)의 프로토타입을 가늬킚닀. 따띌서 생성자 핚수로서 혞출할 수 없는 핚수, 슉 non-constructor읞 화삎표 핚수와 ES6 메서드 축앜표현윌로 정의한 메서드는 prototype 프로퍌티륌 소유하지 않윌며 프로토타입도 생성하지 않는닀.

몚든 객첎가 가지고 있는 proto 접귌자 프로퍌티와 핚수 각첎만읎 가지고 있는 prototype 프로퍌티는 ê²°êµ­ 동음한 프로토타입을 가늬킚닀.

생성자 핚수의 prototype 프로퍌티와 생성자 핚수로 찍얎낞 객첎의 proto 접귌자 프로퍌티는 동음한 프로토타입을 가늬킚닀.

19.3.3 프로토타입의 constructor 프로퍌티와 생성자 핚수

몚든 프로토타입은 constructor 프로퍌티륌 갖는닀. 읎 constructor 프로퍌티는 prototype 프로퍌티로 자신을 찞조하고 있는 생성자 핚수륌 가늬킚닀. 읎 연결은 생성자 핚수가 생성될 때, 슉 핚수 객첎가 생성될 때 읎뀄진닀.


⭐ 19.4 늬터럎 표Ʞ법에 의핎 생성된 객첎의 생성자 핚수와 프로토타입

생성자 핚수에 의핎 생성된 읞슀턎슀는 프로토타입의 constructor 프로퍌티에 의핎 생성자 핚수와 연결된닀. 늬터럎 표Ʞ법에 의핎 생성된 객첎는 추상 연산(OrdinaryObjectCreate)륌 혞출하여 빈 객첎륌 생성하고 프로퍌티륌 추가한닀.

늬터럎 표Ʞ법에 의핎 생성된 객첎도 상속을 위핎 프로토타입읎 필요하닀. 따띌서 늬터럎 표Ʞ법에 의핎 생성된 객첎도 가상적읞 생성자 핚수륌 갖는닀. 프로토타입은 생성자 핚수와 더불얎 생성되며 prototype, constructor 프로퍌티에 의핎 연결되얎 있Ʞ 때묞읎닀. 닀시 말핮, 프로토타입곌 생성자 핚수는 닚독윌로 졎재할 수 없고 얞제나 쌍윌로 졎재한닀.

🧐 추상 연산

추상 연산은 ECMAScript 사양에서 낎부 동작의 구현 알고늬슘을 표현한 것읎닀. ECMAScript 사양에서 섀명을 위핎 사용되는 핚수와 유사한 의사윔드띌고 읎핎하자.


⭐ 19.5 프로토타입의 생성 시점

객첎는 늬터럎 표Ʞ법 또는 생성자 핚수에 의핎 생성되므로 ê²°êµ­ 몚든 객첎는 생성자 핚수와 연결되얎 있닀. 프로토타입은 생성자 핚수가 생성되는 시점에 더불얎 생성된닀. 프로토타입곌 생성자 핚수는 닚독윌로 졎재할 수 없고 얞제나 쌍윌로 졎재하Ʞ 때묞읎닀.

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

생성자 핚수로서 혞출할 수 있는 핚수, 슉 constructor(핚수 선얞묞, 핚수 표현식, 큎래슀)는 핚수 정의가 평가되얎 핚수 객첎륌 생성하는 시점에 프로토타입도 더불얎 생성된닀.

생성된 프로토타입은 였직 constructor 프로퍌티만을 갖는 객첎닀. 프로토타입도 객첎읎고 몚든 객첎는 프로토타입을 가지므로 프로토타입도 자신의 프로토타입을 갖는닀. 생성된 프로토타입의 프로토타입은 Object.prototype읎닀.

19.5.2 빌튞읞 생성자 핚수와 프로토타입 생성 시점

빌튞읞 생성자 핚수도 음반 핚수와 마찬가지로 빌튞읞 생성자 핚수가 생성되는 시점에 프로토타입읎 생성된닀.

객첎가 생성되Ʞ 읎전에 생성자 핚수와 프로토타입은 읎믞 객첎화 되얎 졎재한닀. 읎후 생성자 핚수 또는 늬터럎 표Ʞ법윌로 객첎륌 생성하멎 프로토타입은 생성된 객첎의 [[Prototype]] 낎부 슬롯에 할당된닀.

⭐ 19.6 객첎 생성 방식곌 프로토타입의 결정

객첎는 닀음곌 같읎 닀양한 생성방법읎 있닀.

  • 객첎 늬터럎
  • Object 생성자 핚수
  • 생성자 핚수
  • Object.create 메서드
  • 큎래슀(ES6)

읎처럌 닀양한 방식윌로 생성된 몚든 객첎는 각 방식마닀 섞부적읞 객첎 생성 방식의 찚읎는 있윌나 추상연산 OrdinaryObjectCreate 에 의핎 생성된닀는 공통점읎 있닀.

추상 연산 OrdinaryObjectCreate는 필수적윌로 자신읎 생성할 객첎의 프로토타입을 읞수로 전달 받는닀. 귞늬고 자신읎 생성할 객첎에 추가할 프로퍌티 목록을 옵션윌로 전달할 수 있닀. 추상 연산 OrdinaryObjectCrearte는 빈 객첎륌 생성한 후, 객첎에 추가할 프로퍌티 목록읎 읞수로 전달된 겜우 프로퍌티륌 객첎에 추가한닀. 귞늬고 읞수로 전달받은 프로토타입을 자신읎 생성한 객첎의 [[Prototype]] 낎부 슬롯에 할당한 닀음, 생성한 객첎륌 반환한닀.

슉 프로토타입은 추상 연산 OrdinaryObjectCreate에 전달되는 읞수에 의핎 결정된닀. 읎 읞수는 객첎가 생성되는 시점에 객첎 생성 방식에 의핎 결정된닀.

19.6.1 객첎 늬터럎에 의핎 생성된 객첎의 프로토타입

객첎 늬터럎을 평가하여 객첎륌 생성할 때 추상연산 OrdinaryObjectCreate 에 전달되는 프로토타입은 Object.prototype읎닀. 객첎 늬터럎에 의핎 생성된 객첎는 Object.prototype을 프로토타입윌로 갖게 되며 상속받는닀.

const obj = { x : 1 };

19.6.2 Object 생성자 핚수에 의핎 생성된 객첎의 프로토타입

Object 생성자 핚수륌 사용핎 객첎륌 생성할 때 추상연산 OrdinaryObjectCreate에 전달되는 프로토타입은 Object.prototype읎닀. 객첎 늬터럎곌 Object 생성자 핚수에 의한 객첎 생성 방식의 찚읎는 프로퍌티륌 추가하는 방식에 있닀. 객첎 늬터럎 방식은 객첎 늬터럎 낎부에 프로퍌티륌 추가하지만 Object 생성자 핚수 방식은 음닚 빈 객첎륌 생성한 읎후 프로퍌티륌 추가핎알 한닀.

const obj = new Object();
obj.x = 1;

19.6.3 생성자 핚수에 의핎 생성된 객첎의 프로토타입

new 연산자와 핚께 생성자 핚수륌 **사용핎 읞슀턎슀륌 생성할 때 추상연산 OrdinaryObjectCreate가 혞출된닀. **읎 때 전달되는 프로토타입은 생성자 핚수

의 prototype 프로퍌티에 바읞딩 되얎있는 객첎읎닀. 슉, 생성자 핚수에 의핎 생성되는 객첎의 프로토타입은 생성자 핚수의 prototype 프로퍌티에 바읞딩되얎 있는 객첎읎닀. 사용자 정의 생성자 핚수 Person곌 더불얎 생성된 프로토타입 Person.prototype의 프로퍌티는 constructor뿐읎닀.

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

const me = new Person('Lee');

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

// 프로토타입 메서드
Person.prototype.sayHello = function () {
  console.log(`Hi! My name is ${this.name}`);
};

const me = new Person('Lee');
const you = new Person('Kim');

me.sayHello();  // Hi! My name is Lee
you.sayHello(); // Hi! My name is Kim

⭐ 19.7 프로토타입 첎읞

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

// 프로토타입 메서드
Person.prototype.sayHello = function () {
  console.log(`Hi! My name is ${this.name}`);
};

const me = new Person('Lee');

// hasOwnProperty는 Object.prototype의 메서드닀.
console.log(me.hasOwnProperty('name')); // true

Person 생성자 핚수에 의핎 생성된 me 객첎는 Object.prototype의 메서드읞 hasOwnProperty륌 혞출할 수 있닀. 읎것은 me 객첎가 Person.prototype뿐만 아니띌 Object.prototype도 상속받았닀는것을 의믞한닀.

Person.prototype의 프로토타입은 Object.prototype읎닀. 프로토타입의 프로토타입은 얞제나 Object.prototype읎닀.

자바슀크늜튞는 객첎의 프로퍌티(메서드 포핚)에 접귌하렀고 할 때 핎당 객첎에 접귌하렀는 프로퍌티가 없닀멎 [[Prototype]] 낎부 슬롯의 찞조륌 따띌 자신의 부몚역할을 하는 프로토타입의 프로퍌티륌 순찚적윌로 검색한닀. 읎륌 프로토타입 첎읞읎띌고 한닀.

프로토타입 첎읞의 최상위에 위치하는 객첎는 얞제나 Object.prototype읎닀. 따띌서 몚든 객첎는 Object.prototype을 상속받는닀. Object.prototype의 프로토타입 슉, [[Prototype]] 낎부슬롯의 값은 null읎닀.

프로퍌티가 아닌 식별자는 슀윔프 첎읞에서 검색한닀. 자바슀크늜튞 엔진은 핚수의 쀑첩ꎀ계로 읎룚얎진 슀윔프의 계잵적 구조에서 식별자륌 검색한닀. 따띌서 슀윔프 첎읞은 식별자 검색을 위한 메컀니슘읎띌고 할 수 있닀.

슀윔프 첎읞곌 프로토타입 첎읞은 서로 연ꎀ없읎 별도로 동작하는 것읎 아니띌 서로 협력하여 식별자와 프로퍌티륌 검색하는 데 사용된닀.

🧐 call 메서드

call 메서드는 this로 사용할 객첎륌 전달하멎서 핚수륌 혞출한닀.


⭐ 19.8 였버띌읎딩곌 프로퍌티 섀도잉

const Person = (function () {
  // 생성자 핚수
  function Person(name) {
    this.name = name;
  }

  // 프로토타입 메서드
  Person.prototype.sayHello = function () {
    console.log(`Hi! My name is ${this.name}`);
  };

  // 생성자 핚수륌 반환
  return Person;
}());

const me = new Person('Lee');

// 읞슀턎슀 메서드
me.sayHello = function () {
  console.log(`Hey! My name is ${this.name}`);
};

// 읞슀턎슀 메서드가 혞출된닀. 프로토타입 메서드는 읞슀턎슀 메서드에 의핎 가렀진닀.
me.sayHello(); // Hey! My name is Lee

프로토타입읎 소유한 프로퍌티륌 프로토타입 프로퍌티, 읞슀턎슀가 소유한 프로퍌티륌 읞슀턎슀 프로퍌티띌고 부륞닀.

프로토타입 프로퍌티와 같은 읎늄의 프로퍌티륌 읞슀턎슀에 추가하멎 프로토타입 첎읞을 따띌 프로토타입 프로퍌티륌 검색하여 프로토타입 프로퍌티륌 덮얎쓰는 것읎 아니띌 읞슀턎슀 프로퍌티로 추가한닀. 읎처럌 상속 ꎀ계에 의핎 프로퍌티가 가렀지는 현상을 프로퍌티 섀도잉읎띌 한닀.

하위 객첎륌 통핎 프토토타입의 프로퍌티륌 변겜 또는 삭제하는 것은 불가능하닀. 닀시 말핮 하위 객첎륌 통핎 프로토타입에 get 엑섞슀는 허용되나 set 엑섞슀는 허용되지 않는닀.

🧐 였버띌읎딩(overriding)

상위 큎래슀가 가지고 있는 메서드륌 하위 큎래슀가 재정의하여 사용하는 방식

🧐 였버로딩(overloading)

핚수의 읎늄은 동음하지만 맀개변수의 타입 또는 개수가 닀륞 메서드륌 구현하고 맀개변수에 의핎 메서드륌 구별하여 혞출하는 방식. 자바슀크늜튞는 였버로딩을 지원하지 않지만 arguments 객첎륌 사용하여 구현할 수는 있닀.


⭐ 19.9 프로토타입의 교첎

프로토타입은 동적윌로 변겜 가능하닀. 읎러한 특징을 활용핎 객첎 간의 상속 ꎀ계륌 동적윌로 변겜할 수 있닀. 프로토타입은 생성자 핚수 또는 읞슀턎슀에 의핎 교첎할 수 있닀.

19.9.1 생성자 핚수에 의한 프로토타입의 교첎

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

  // ① 생성자 핚수의 prototype 프로퍌티륌 통핎 프로토타입을 교첎
  Person.prototype = {
    sayHello() {
      console.log(`Hi! My name is ${this.name}`);
    }
  };

  return Person;
}());

const me = new Person('Lee');

위와 같읎 프로토타입을 교첎하게 되멎 **me 의 생성자 핚수는 Person읎 아닌 Object로 바뀐닀. 읎처럌 프로토타입을 교첎하게 되멎 `constructor프로퍌티와 생성자 핚수간의 연결읎 파ꎎ**되는데,constructor프로퍌티륌 추가하여 프로토타입의constructor` 프로퍌티륌 되삎늎 수 있닀.

19.9.2 읞슀턎슀에 의한 프로토타입의 교첎

읞슀턎슀의 proto 접귌자 프로퍌티륌 통핎 접귌할 수 있닀. 생성자 핚수의 prototype 프로퍌티에 닀륞 임의의 객첎륌 바읞딩 하는 것은 믞래에 생성할 읞슀턎슀의 프로토타입을 교첎하는 것읎닀.

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

const me = new Person("Lee");

// 프로토타입윌로 교첎할 객첎
const parent = {
  // constructor 프로퍌티와 생성자 핚수 간의 연결을 섀정
  constructor: Person,
  sayHello() {
    console.log(`Hi! My name is ${this.name}`);
  },
};

// 생성자 핚수의 prototype 프로퍌티와 프로토타입 간의 연결을 섀정
Person.prototype = parent;

// me 객첎의 프로토타입을 parent 객첎로 교첎한닀.
Object.setPrototypeOf(me, parent);
// 위 윔드는 아래의 윔드와 동음하게 동작한닀.
// me.__proto__ = parent;

me.sayHello(); // Hi! My name is Lee

// constructor 프로퍌티가 생성자 핚수륌 가늬킚닀.
console.log(me.constructor === Person); // true
console.log(me.constructor === Object); // false

// 생성자 핚수의 prototype 프로퍌티가 교첎된 프로토타입을 가늬킚닀.
console.log(Person.prototype === Object.getPrototypeOf(me)); // true

⭐ 19.10 instanceof 연산자

instanceof 연산자는 읎항 연산자로서 좌변에 객첎륌 가늬킀는 식별자, 우변에 생성자 핚수륌 가늬킀는 식별자륌 플연산자로 받는닀. 만앜 우변의 플연산자가 핚수가 아닐 겜우 Typeerror가 발생한닀.

우변의 생성자 핚수의 prototype에 바읞딩된 객첎가 좌변의 객첎의 프로토타입 첎읞 상에 졎재하멎 true로 평가되고, 귞렇지 않은 겜우에는 false로 평가된닀.

instanceof 연산자는 생성자 핚수의 prototype에 바읞딩된 객첎가 프로토타입 첎읞 상에 졎재하는지 확읞한닀.

⭐ 19.11 직접 상속

19.11.1 Object.create에 의한 직접 상속

Object.create 메서드는 명시적윌로 프로토타입을 지정하여 새로욎 객첎륌 생성한닀. 닀륞 객첎와 마찬가지로 추상 연산 OrdinaryObjectCreate륌 혞출한닀.

Object.create 메서드의 첫 번짞 맀개변수에는 생성할 객첎의 프로토타입윌로 지정할 객첎륌 전달한닀. 두 번짞 맀개변수에는 생성할 객첎의 프로퍌티 킀와 프로퍌티 디슀크늜터 객첎로 읎뀄진 객첎륌 전달한닀. 두 번짞 읞수는 옵션읎므로 생략 가능하닀.

// 프로토타입읎 null읞 객첎륌 생성한닀. 생성된 객첎는 프로토타입 첎읞의 종점에 위치한닀.
// obj → null
let obj = Object.create(null);
console.log(Object.getPrototypeOf(obj) === null); // true
// Object.prototype을 상속받지 못한닀.
console.log(obj.toString()); // TypeError: obj.toString is not a function

// obj → Object.prototype → null
// obj = {};와 동음하닀.
obj = Object.create(Object.prototype);
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

// obj → Object.prototype → null
// obj = { x: 1 };와 동음하닀.
obj = Object.create(Object.prototype, {
  x: { value: 1, writable: true, enumerable: true, configurable: true }
});
// 위 윔드는 닀음곌 동음하닀.
// obj = Object.create(Object.prototype);
// obj.x = 1;
console.log(obj.x); // 1
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

const myProto = { x: 10 };
// 임의의 객첎륌 직접 상속받는닀.
// obj → myProto → Object.prototype → null
obj = Object.create(myProto);
console.log(obj.x); // 10
console.log(Object.getPrototypeOf(obj) === myProto); // true

// 생성자 핚수
function Person(name) {
  this.name = name;
}

// obj → Person.prototype → Object.prototype → null
// obj = new Person('Lee')와 동음하닀.
obj = Object.create(Person.prototype);
obj.name = 'Lee';
console.log(obj.name); // Lee
console.log(Object.getPrototypeOf(obj) === Person.prototype); // true

Object.create 메서드는 첫 번짞 맀개변수에 전달된 객첎의 프로토타입 첎읞에 속하는 객첎륌 생성한닀. 읎 메서드의 장점은 닀음곌 같닀.

  • new 연산자가 없읎도 객첎륌 생성할 수 있닀.
  • 프로토타입을 지정하멎서 객첎륌 생성할 수 있닀.
  • 객첎 늬터럎에 의핎 생성된 객첎도 상속받을 수 있닀.

19.11.2 객첎 늬터럎 낎부에서 proto에 의한 직접 상속

ES6에서는 객첎 늬터럎 낎부에서 proto 접귌자 프로퍌티륌 사용하여 직접 상속을 구현할 수 있닀.

const myProto = { x: 10 };

// 객첎 늬터럎에 의핎 객첎륌 생성하멎서 프로토타입을 지정하여 직접 상속받을 수 있닀.
const obj = {
  y: 20,
  // 객첎륌 직접 상속받는닀.
  // obj → myProto → Object.prototype → null
  __proto__: myProto
};
/* 위 윔드는 아래와 동음하닀.
const obj = Object.create(myProto, {
  y: { value: 20, writable: true, enumerable: true, configurable: true }
});
*/

console.log(obj.x, obj.y); // 10 20
console.log(Object.getPrototypeOf(obj) === myProto); // true

⭐ 19.12 정적 프로퍌티/메서드

// 생성자 핚수
function Person(name) {
  this.name = name;
}

// 프로토타입 메서드
Person.prototype.sayHello = function () {
  console.log(`Hi! My name is ${this.name}`);
};

// 정적 프로퍌티
Person.staticProp = 'static prop';

// 정적 메서드
Person.staticMethod = function () {
  console.log('staticMethod');
};

const me = new Person('Lee');

// 생성자 핚수에 추가한 정적 프로퍌티/메서드는 생성자 핚수로 ì°žì¡°/혞출한닀.
Person.staticMethod(); // staticMethod

// 정적 프로퍌티/메서드는 생성자 핚수가 생성한 읞슀턎슀로 ì°žì¡°/혞출할 수 없닀.
// 읞슀턎슀로 ì°žì¡°/혞출할 수 있는 프로퍌티/메서드는 프로토타입 첎읞 상에 졎재핎알 한닀.
me.staticMethod(); // TypeError: me.staticMethod is not a function

⭐ 19.13 프로퍌티 졎재 확읞

19.13.1 in 연산자

in 연산자는 객첎 낎에 특정 프로퍌티가 졎재하는지 여부륌 확읞한닀. in 연산자는 프로토타입 첎읞 상에 졎재하는 몚든 프로토타입에서 프로퍌티륌 검색한닀.

const person = {
  name: 'Lee',
  address: 'Seoul'
};

// person 객첎에 name 프로퍌티가 졎재한닀.
console.log('name' in person);    // true
// person 객첎에 address 프로퍌티가 졎재한닀.
console.log('address' in person); // true
// person 객첎에 age 프로퍌티가 졎재하지 않는닀.
console.log('age' in person);     // false

19.13.2 Object.prototype.hasOwnProperty 메서드

Object.prototype.hasOwnProperty 메서드륌 사용핎도 객첎에 특정 프로퍌티가 졎재하는지 확읞할 수 있닀. 읞수로 전달받은 프로퍌티 킀가 객첎 고유의 프로퍌티 킀읞 겜우에만 true륌 반환하고 상속받은 프로토타입의 프로퍌티읞 겜우 false륌 반환한닀.

⭐ 19.14 프로퍌티 ì—Žê±°

19.14.1 for .. in 묞

for ... in 묞은 객첎의 프로토타입 첎읞 상에 졎재하는 몚든 프로토타입의 프로퍌티 쀑에서 프로퍌티 얎튞늬뷰튞 [[Enumerable]]의 값읎 true읞 프로퍌티륌 순회하며 엎거한닀.

const person = {
  name: 'Lee',
  address: 'Seoul',
  __proto__: { age: 20 }
};

for (const key in person) {
  // 객첎 자신의 프로퍌티읞지 확읞한닀.
  if (!person.hasOwnProperty(key)) continue;
  console.log(key + ': ' + person[key]);
}
// name: Lee
// address: Seoul

19.14.2 Object.keys/values/entries 메서드

Object.keys와 Object.values 메서드는 객첎 자신의 ì—Žê±° 가능한 프로퍌티 킀와 값을 ë°°ì—Žë¡œ 반환한닀. ES8에서 도입된 Object.entries 메서드는 객첎 자신의 ì—Žê±° 가능한 킀와 값의 쌍의 배엎을 배엎에 ë‹Žì•„ 반환한닀.

const person = {
  name: 'Lee',
  address: 'Seoul',
  __proto__: { age: 20 }
};

console.log(Object.keys(person)); // ["name", "address"]
console.log(Object.values(person)); // ["Lee", "Seoul"]
console.log(Object.entries(person)); // [["name", "Lee"], ["address", "Seoul"]]

Object.entries(person).forEach(([key, value]) => console.log(key, value));
/*
name Lee
address Seoul
*/

후Ʞ
너묎 얎렀워서 욞고싶었닀

profile
읎사쀑입니닀!🌟https://velog.io/@devkyoung2

0개의 댓Ꞁ

ꎀ렚 채용 정볎