🐸 [JavaScript] ν”„λ‘œν† νƒ€μž…

hnyoojinΒ·2024λ…„ 9μ›” 18일

🐸 JS λ§ˆμŠ€ν„° 되기

λͺ©λ‘ 보기
18/19
post-thumbnail

JavaScript

  • λ©€ν‹° νŒ¨λŸ¬λ‹€μž„ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄
    • λͺ…λ Ήν˜•, ν•¨μˆ˜ν˜•, ν”„λ‘œν† νƒ€μž… 기반 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ° 을 지원
  • 객체 기반의 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄
    • JSλ₯Ό 이루고 μžˆλŠ” 거의 "λͺ¨λ“  것"이 객체 μž„
    • μ›μ‹œ νƒ€μž…μ˜ 값을 μ œμ™Έν•œ λ‚˜λ¨Έμ§€ 값듀은 λͺ¨λ‘ 객체


객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°

  • 전톡적인 λͺ…λ Ήν˜• ν”„λ‘œκ·Έλž˜λ°
    • Program : λͺ…λ Ήμ–΄ λ˜λŠ” ν•¨μˆ˜μ˜ λͺ©λ‘ (절차 μ§€ν–₯적 관점)
  • 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°
    • Program : 객체의 μ§‘ν•©
    • ν”„λ‘œκ·Έλž˜λ°μ— μ‹€μ„Έκ³„μ˜ 싀체λ₯Ό μΈμ‹ν•˜λŠ” 철학적 사고 λ₯Ό μ ‘λͺ©
      • 싀체 : 속성을 가짐
      • μ†μ„±μœΌλ‘œ 싀체λ₯Ό ꡬ별 κ°€λŠ₯
      • 좔상화 : λ‹€μ–‘ν•œ 속성 쀑, Program에 ν•„μš”ν•œ κ²ƒλ§Œ κ°„μΆ”λ € ν‘œν˜„ν•˜λŠ” 것

// 이름과 μ£Όμ†Œ 속성을 κ°–λŠ” 객체
const person = {
    name: 'Hwang',
    address: 'Busan'
};

console.log(person);

-> 객체 : 속성을 톡해, μ—¬λŸ¬ 개의 값을 ν•˜λ‚˜μ˜ λ‹¨μœ„λ‘œ κ΅¬μ„±ν•œ 볡합적인 자료ꡬ쑰

- 원을 객체둜?

const circle = {
    radius: 5,

    getDiameter() {
        return 2 * this.radius;
    },
    getPerimeter() {
        return 2 * Math.PI * this.radius;
    },
    getArea() {
        return Math.PI * this.radius ** 2;
    }
};

console.log(circle);

console.log(circle.getDiameter());
console.log(circle.getPerimeter());
console.log(circle.getArea());

λ°˜μ§€λ¦„ : μ›μ˜ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터
지름, λ‘˜λ ˆ, 넓이 : λ™μž‘


객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ€

  • 객체 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터 (property)
  • μƒνƒœ 데이터λ₯Ό μ‘°μž‘ν•  수 μžˆλŠ” λ™μž‘ (method)

데이터와 λ™μž‘μ„ ν•˜λ‚˜μ˜ 논리적 λ‹¨μœ„λ‘œ λ¬Άμ–΄ 생각.

각 κ°μ²΄λŠ” λ…λ¦½μ μœΌλ‘œ μ‘΄μž¬ν•  수 있고, λ‹€λ₯Έ 객체와 관계성을 κ°€μ§ˆ μˆ˜λ„ μžˆλ‹€.


상속과 ν”„λ‘œν† νƒ€μž…

상속

  • 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ˜ 핡심
  • μ–΄λ–€ 객체의 property λ˜λŠ” methodλ₯Ό, λ‹€λ₯Έ 객체가 상속받아 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 μžˆλŠ” 것

ν”„λ‘œν† νƒ€μž…

  • JSλŠ” ν”„λ‘œν† νƒ€μž…μ„ 기반으둜 상속을 κ΅¬ν˜„
    -> λΆˆν•„μš”ν•œ 쀑볡을 제거
// μƒμ„±μž ν•¨μˆ˜
function Circle(radius) {
    this.radius = radius;
    this.getArea = function() {
        return Math.PI * this.radius ** 2;
    };
}

// λ°˜μ§€λ¦„μ΄ 1,2인 μΈμŠ€ν„΄μŠ€ 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);

console.log(circle1.getArea === circle2.getArea);
console.log(circle1.getArea());
console.log(circle2.getArea());

λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ λ™μΌν•œ λ‚΄μš©μ˜ methodλ₯Ό μ‚¬μš©ν•  경우?
-> methodλ₯Ό 단 ν•˜λ‚˜λ§Œ μƒμ„±ν•˜μ—¬, λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ κ³΅μœ ν•΄μ„œ μ‚¬μš©ν•˜λ„λ‘ ν•˜λŠ” 것이 λ°”λžŒμ§ν•¨

ν•˜μ§€λ§Œ μœ„μ˜ μ½”λ“œμ—μ„œ, getArea methodλŠ” λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ 쀑볡 μ†Œμœ ν•˜κ²Œ 됨
-> λΆˆν•„μš”ν•œ λ©”λͺ¨λ¦¬ λ‚­λΉ„

function Circle(radius) {
    this.radius = radius;
}

// ν”„λ‘œν† νƒ€μž…μ„ 기반으둜 상속을 κ΅¬ν˜„!!!
Circle.prototype.getArea = function () {
    return Math.PI * this.radius ** 2;
};

const circle1 = new Circle(1);
const circle2 = new Circle(2);

console.log(circle1.getArea === circle2.getArea);
console.log(circle1.getArea());
console.log(circle2.getArea());


ν”„λ‘œν† νƒ€μž… 객체 (ν”„λ‘œν† νƒ€μž…)

: 객체 κ°„ 상속을 κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ¨

prototype : μ–΄λ–€ 객체의 μƒμœ„(λΆ€λͺ¨) 객체의 역할을 ν•˜λŠ” 객체
-> λ‹€λ₯Έ 객체에 곡유 property(method 포함)λ₯Ό 제곡

prototype을 상속받은 ν•˜μœ„(μžμ‹) 객체
-> μƒμœ„ 객체의 propertyλ₯Ό μžμ‹ μ˜ property처럼 자유둭게 μ‚¬μš©ν•  수 μžˆλ‹€.


  • λͺ¨λ“  κ°μ²΄λŠ” [[Prototype]] λΌλŠ” λ‚΄λΆ€ μŠ¬λ‘―μ„ 가짐
    • λ‚΄λΆ€ 슬둯의 κ°’ : prototype의 μ°Έμ‘°
  • λͺ¨λ“  κ°μ²΄λŠ” ν•˜λ‚˜μ˜ prototype을 가짐
    • λͺ¨λ“  prototype은 μƒμ„±μž ν•¨μˆ˜μ™€ μ—°κ²°λ˜μ–΄μžˆλ‹€.

- __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°

  • λͺ¨λ“  κ°μ²΄λŠ” __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό 톡해 [[Prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ— κ°„μ ‘ μ ‘κ·Ό κ°€λŠ₯
    • [[Prototype]] : 객체 μžμ‹ μ˜ prototype

__proto__λŠ” μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‹€.

  • λ‚΄λΆ€ μŠ¬λ‘―μ€ propertyκ°€ μ•„λ‹ˆλ‹€.
    • (원칙) λ‚΄λΆ€ 슬둯과 λ‚΄λΆ€ method에 직접 μ ‘κ·Όν•˜κ±°λ‚˜ ν˜ΈμΆœν•˜λŠ” 방법은 μ œκ³΅ν•˜μ§€ X
    • 일뢀 λ‚΄λΆ€ 슬둯과 λ‚΄λΆ€ method에 ν•œν•˜μ—¬, κ°„μ ‘ μ ‘κ·Ό μˆ˜λ‹¨μ„ μ œκ³΅ν•˜κΈ°λŠ” 함
  • μ ‘κ·Όμž ν”„λ‘œνΌν‹°?
    • 자체적으둜 [[Value]] propertyλ₯Ό κ°–μ§€ μ•Šκ³ , [[Get]] [[Set]] property attribute둜 κ΅¬μ„±λœ property.
    • [[Get]] [[Set]] : λ‹€λ₯Έ data property의 값을 μ½κ±°λ‚˜ μ €μž₯ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ ‘κ·Όμž ν•¨μˆ˜

Object.property 의 μ ‘κ·Όμž ν”„λ‘œνΌν‹°μΈ __proto__

-> getter/setter ν•¨μˆ˜λΌκ³  λΆ€λ₯΄λŠ” μ ‘κ·Όμž ν•¨μˆ˜λ₯Ό 톡해
[[Property]] λ‚΄λΆ€ 슬둯의 κ°’, 즉 ν”„λ‘œν† νƒ€μž…μ„ μ·¨λ“ν•˜κ±°λ‚˜ ν• λ‹Ήν•œλ‹€.


__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό 톡해 ν”„λ‘œν† νƒ€μž…μ— μ ‘κ·Όν•˜λ©΄,
λ‚΄λΆ€μ μœΌλ‘œ __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°μ˜ getter ν•¨μˆ˜μΈ [[Get]]이 ν˜ΈμΆœλœλ‹€.

__proto__ 점근자 ν”„λ‘œνΌν‹°λ₯Ό 톡해 μƒˆλ‘œμš΄ ν”„λ‘œν† νƒ€μž…μ„ ν• λ‹Ήν•˜λ©΄,
__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°μ˜ setter ν•¨μˆ˜μΈ [[Set]]이 ν˜ΈμΆœλœλ‹€.

const obj = {};
const parent = { x: 1 };

// setter ν•¨μˆ˜μΈ set __proto__κ°€ 호좜됨
// -> obj 객체의 ν”„λ‘œν† νƒ€μž…μ„ ꡐ체
obj.__proto__ = parent;

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


__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λŠ” 상속을 톡해 μ‚¬μš©λœλ‹€.

__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λŠ” 객체가 직접 μ†Œμœ ν•˜λŠ” ν”„λ‘œνΌν‹°κ°€ μ•„λ‹ˆλ‹€.
-> Object.prototype의 ν”„λ‘œνΌν‹°μž„

λͺ¨λ“  κ°μ²΄λŠ” 상속을 톡해 Object.prototype.__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

const person = { name: 'Hwang' };

// person κ°μ²΄λŠ” __proto__ ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•˜μ§€ μ•ŠλŠ”λ‹€
console.log(Object.hasOwnProperty('__proto__'));

// __proto__ ν”„λ‘œνΌν‹° : λͺ¨λ“  객체의 ν”„λ‘œν† νƒ€μž… 객체인 Object.prototype의 μ ‘κ·Όμž ν”„λ‘œνΌν‹°
console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'));

// λͺ¨λ“  κ°μ²΄λŠ” Object.prototype의 μ ‘κ·Όμž ν”„λ‘œνΌν‹°  __proto__λ₯Ό 상속받아 μ‚¬μš©ν•  수 μžˆλ‹€.
console.log({}.__proto__ === Object.prototype);



__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό 톡해 ν”„λ‘œν† νƒ€μž…μ— μ ‘κ·Όν•˜λŠ” 이유?

[[Property]] λ‚΄λΆ€ 슬둯의 값에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜λŠ” 이유?
=> μƒν˜Έ 참쑰에 μ˜ν•΄ ν”„λ‘œν† νƒ€μž… 체인이 μƒμ„±λ˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•¨

const parent = {};
const child = {};

// child의 ν”„λ‘œν† νƒ€μž…μ„ parent둜 μ„€μ •
child.__proto__ = parent;
// parent의 ν”„λ‘œν† νƒ€μž…μ„ child둜 μ„€μ •
parent.__proto__ = child;

// 이런 μ½”λ“œκ°€ error 없이 μ •μƒμ μœΌλ‘œ 처리되면?
// -> μ„œλ‘œκ°€ μžμ‹ μ˜ ν”„λ‘œν† νƒ€μž…μ΄ λ˜λŠ” 비정상적인 ν”„λ‘œν† νƒ€μž… 체인이 λ§Œλ“€μ–΄μ§
// -> error λ°œμƒ 함

-> ν”„λ‘œν† νƒ€μž… 체인은 단방ν–₯ linked list둜 κ΅¬ν˜„λ˜μ–΄μ•Ό 함
(property 검색 λ°©ν–₯이 ν•œμͺ½ λ°©ν–₯으둜만 ν˜λŸ¬κ°€μ•Ό 함)

μˆœν™˜ μ°Έμ‘°ν•˜λŠ” ν”„λ‘œν† νƒ€μž… 체인이 λ§Œλ“€μ–΄μ§€λ©΄?
-> property κ²€μƒ‰μ‹œ, λ¬΄ν•œ 루프에 빠짐
<- ν”„λ‘œν† νƒ€μž… 체인의 쒅점이 μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έ

κ·Έλž˜μ„œ?

μ•„λ¬΄λŸ° 체크 없이 무쑰건적으둜 ν”„λ‘œν† νƒ€μž…μ„ ꡐ체할 수 없도둝 함
__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό ν†΅ν•΄μ„œ ν”„λ‘œν† νƒ€μž…μ— μ ‘κ·Όν•˜κ³  κ΅μ²΄ν•˜λ„λ‘ κ΅¬ν˜„λ˜μ–΄ 있음



__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ½”λ“œ λ‚΄μ—μ„œ 직접 μ‚¬μš©ν•˜λŠ” 것은 ꢌμž₯ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ½”λ“œ λ‚΄μ—μ„œ __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό 직접 μ‚¬μš©ν•˜λŠ” 것은 ꢌμž₯ν•˜μ§€ μ•ŠμŒ.
λͺ¨λ“  객체사 __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” 것이 μ•„λ‹ˆκΈ° λ•Œλ¬Έ

직접 상속을 톡해 Object.prototype을 상속받지 μ•ŠλŠ” 객체λ₯Ό 생성할 μˆ˜λ„ 있기 λ•Œλ¬Έμ—, __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•  수 μ—†λŠ” κ²½μš°κ°€ μžˆμ„ 수 있음

// objλŠ” prototype chain의 쒅점.
// -> Object.__proto__λ₯Ό 상속받을 수 μ—†λ‹€.
const obj = Object.create(null);

console.log(obj.__proto__);

// -> __proto__보닀 Object.getPrototypeOd λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 편이 μ’‹λ‹€.
console.log(Object.getPrototypeOf(obj));


// -----------------------------------------------------------------------

const obj = {};
const parent = { x: 1 };

// obj 객체의 prototype을 μ·¨λ“―
Object.getPrototypeOf(obj);
// obj 객체의 prototype을 ꡐ체
Object.setPrototypeOf(obj, parent);

console.log(obj.x);



- ν•¨μˆ˜ 객체의 prototype ν”„λ‘œνΌν‹°

  • ν•¨μˆ˜ 객체만이 μ†Œμœ ν•˜λŠ” prototype ν”„λ‘œνΌν‹°λŠ”, μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€μ˜ prototype을 가리킴

prototype ν”„λ‘œνΌν‹°λŠ”, μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 객체의 ν”„λ‘œν† νƒ€μž…μ„ 가리킨닀.
λ”°λΌμ„œ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  수 μ—†λŠ” ν•¨μˆ˜, 즉 non-constructor 인 ν™”μ‚΄ν‘œ ν•¨μˆ˜μ™€ ES6λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜ν•œ λ©”μ„œλ“œλŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•˜μ§€ μ•ŠμœΌλ©°, ν”„λ‘œν† νƒ€μž…λ„ μƒμ„±ν•˜μ§€ μ•ŠλŠ”λ‹€.

- ν”„λ‘œν† νƒ€μž…μ˜ constructor ν”„λ‘œνΌν‹°μ™€ μƒμ„±μž ν•¨μˆ˜


λ¦¬ν„°λŸ΄ ν‘œκΈ°λ²•μ— μ˜ν•΄ μƒμ„±λœ 객체의 μƒμ„±μž ν•¨μˆ˜μ™€ ν”„λ‘œν† νƒ€μž…


ν”„λ‘œν† νƒ€μž…μ˜ 생성 μ‹œμ 

- μ‚¬μš©μž μ •μ˜ μƒμ„±μž ν•¨μˆ˜μ™€ ν”„λ‘œν† νƒ€μž… 생성 μ‹œμ 

- 빌트인 μƒμ„±μž ν•¨μˆ˜μ™€ ν”„λ‘œν† νƒ€μž… 생성 μ‹œμ 


객체 생성 방식과 ν”„λ‘œν† νƒ€μž…μ˜ κ²°μ •

- 객체 λ¦¬ν„°λŸ΄μ— μ˜ν•΄ μƒμ„±λœ 객체의 ν”„λ‘œν† νƒ€μž…

- Object μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•΄ μƒμ„±λœ 객체의 ν”„λ‘œν† νƒ€μž…

- μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•΄ μƒμ„±λœ 객체의 ν”„λ‘œν† νƒ€μž…


ν”„λ‘œν† νƒ€μž… 체인


μ˜€λ²„λΌμ΄λ”©κ³Ό ν”„λ‘œνΌν‹° μ„€λ„μž‰


ν”„λ‘œν† νƒ€μž…μ˜ ꡐ체

- μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ ν”„λ‘œν† νƒ€μž…μ˜ ꡐ체

- μΈμŠ€ν„΄μŠ€μ— μ˜ν•œ ν”„λ‘œν† νƒ€μž…μ˜ ꡐ체


instanceof μ—°μ‚°μž


직접 상속

- Object.create에 μ˜ν•œ 직접 상속

- 객체 λ¦¬ν„°λŸ΄ λ‚΄λΆ€μ—μ„œ proto에 μ˜ν•œ 직접 상속


정적 ν”„λ‘œνΌν‹°/λ©”μ„œλ“œ


ν”„λ‘œνΌν‹° 쑴재 확인

- in μ—°μ‚°μž

- Object.prototype.hasOwnProperty λ©”μ„œλ“œ


ν”„λ‘œνΌν‹° μ—΄κ±°

- for...in λ¬Έ

- Object.keys/values/entries λ©”μ„œλ“œ







(μˆ˜μ •μ€‘)

0개의 λŒ“κΈ€