front-end/JavaScript

[JavaScript] 15. μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ 객체 생성

gaan 2023. 4. 11. 09:37

πŸ“– λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ ꡐ재) 17μž₯. μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ 객체 생성

 

λ‹€μ–‘ν•œ 객체 생성 방식 쀑, μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό μƒμ„±ν•˜λŠ” 방식을 μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜μž.

01. Object μƒμ„±μž ν•¨μˆ˜

new μ—°μ‚°μžμ™€ ν•¨κ»˜ Object μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ 빈 객체λ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•œλ‹€.

빈 객체λ₯Ό μƒμ„±ν•œ 이후 ν”„λ‘œνΌν‹° λ˜λŠ” λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ 객체λ₯Ό μ™„μ„±ν•  수 μžˆλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

// 빈 객체의 생성
const person = new Object();

// ν”„λ‘œνΌν‹° μΆ”κ°€
person.name = 'Lee';
person.sayHello = function() {
    console.log('Hi! My name is ' + this.name);
};

console.log(person); // {name: "Lee", sayHello: f}
person.sayHello(); // Hi! My name is Lee

 

⚠️ λ°˜λ“œμ‹œ Object μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ 빈 객체λ₯Ό 생성해야 ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. 객체λ₯Ό μƒμ„±ν•˜λŠ” 방법은 객체 λ¦¬ν„°λŸ΄μ„ μ‚¬μš©ν•˜λŠ” 것이 더 κ°„νŽΈν•˜λ‹€!

 

02. μƒμ„±μž ν•¨μˆ˜

μƒμ„±μž ν•¨μˆ˜λž€ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜μ—¬ 객체(μΈμŠ€ν„΄μŠ€)λ₯Ό μƒμ„±ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§ν•œλ‹€.
μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•΄ μƒμ„±λœ 객체λ₯Ό μΈμŠ€ν„΄μŠ€λΌκ³  ν•œλ‹€.

 

1) 객체 λ¦¬ν„°λŸ΄μ— μ˜ν•œ 객체 생성 λ°©μ‹μ˜ 문제점

객체 λ¦¬ν„°λŸ΄μ— μ˜ν•œ 객체 생성 방식은 단 ν•˜λ‚˜μ˜ 객체만 μƒμ„±ν•œλ‹€.

➑️ μ΄λŠ” λ™μΌν•œ ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ” 객체λ₯Ό μ—¬λŸ¬ 개 생성해야 ν•˜λŠ” 경우, λΉ„νš¨μœ¨μ μ΄λ‹€.

➑️ ν”„λ‘œνΌν‹° ꡬ쑰가 동일함에도 λΆˆκ΅¬ν•˜κ³ , 맀번 같은 ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλ₯Ό κΈ°μˆ ν•΄μ•Ό ν•œλ‹€.

 

2) μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ 객체 생성 λ°©μ‹μ˜ μž₯점

μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ 객체 생성 방식은 마치 객체(μΈμŠ€ν„΄μŠ€)λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ ν…œν”Œλ¦Ώ(클래슀)처럼 μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬, ν”„λ‘œνΌν‹° ꡬ쑰가 λ™μΌν•œ 객체 μ—¬λŸ¬ 개λ₯Ό κ°„νŽΈν•˜κ²Œ 생성할 수 μžˆλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

// μƒμ„±μž ν•¨μˆ˜
function Circle(radius) {
    // μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisλŠ” μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀.
    this.radius = radius;
    this.getDiameter = function() {
        return 2 * this.radius;
    };
}

// μΈμŠ€ν„΄μŠ€μ˜ 생성
const circle1 = new Circle(5); // λ°˜μ§€λ¦„μ΄ 5인 Circle 객체λ₯Ό 생성
const circle2 = new Circle(10); // λ°˜μ§€λ¦„μ΄ 10인 Circle 객체λ₯Ό 생성

console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20

 

3) μƒμ„±μž ν•¨μˆ˜μ˜ μΈμŠ€ν„΄μŠ€ 생성 κ³Όμ •

μƒμ„±μž ν•¨μˆ˜μ˜ ν•¨μˆ˜ λͺΈμ²΄μ—μ„œ μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” 것을 μ•Œμ•„λ³΄λ„λ‘ ν•˜μž.

μƒμ„±μž ν•¨μˆ˜λŠ” ν”„λ‘œνΌν‹° ꡬ쑰가 λ™μΌν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ ν…œν”Œλ¦Ώ(클래슀)μœΌλ‘œμ„œ λ™μž‘ν•˜μ—¬

μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”(μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹° μΆ”κ°€ 및 μ΄ˆκΈ°κ°’ ν• λ‹Ή)ν•œλ‹€.

 

1. μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩

 

μ•”λ¬΅μ μœΌλ‘œ 빈 객체가 μƒμ„±λ˜κ³ , 이 빈 κ°μ²΄λŠ” μƒμ„±μž ν•¨μˆ˜κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ‹€.

이 μΈμŠ€ν„΄μŠ€λŠ” this에 λ°”μΈλ”©λœλ‹€.

 

β€» λ°”μΈλ”©μ΄λž€?

μ‹λ³„μžμ™€ 값을 μ—°κ²°ν•˜λŠ” 과정을 μ˜λ―Έν•œλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

function Circle(radius) {
    // 1. μ•”λ¬΅μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κ³  this에 λ°”μΈλ”©λœλ‹€.
    console.log(this); // Circle {}

    this.radius = radius;
    this.getDiameter = function() {
        return 2 * this.radius;
    };
}

 

2. μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”

 

this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

즉, μΈμŠ€ν„΄μŠ€μ— ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜κ³ , μƒμ„±μž ν•¨μˆ˜κ°€ 인수둜 전달받은 μ΄ˆκΈ°κ°’μ„ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°μ— ν• λ‹Ήν•˜μ—¬ μ΄ˆκΈ°ν™”ν•˜κ±°λ‚˜ 고정값을 ν• λ‹Ήν•œλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

function Circle(radius) {
    // 1. μ•”λ¬΅μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κ³  this에 λ°”μΈλ”©λœλ‹€.

    // 2. this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.
    this.radius = radius;
    this.getDiameter = function() {
        return 2 * this.radius;
    };
}

 

3. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜

 

μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ λͺ¨λ“  μ²˜λ¦¬κ°€ λλ‚˜λ©΄ μ™„μ„±λœ μΈμŠ€ν„΄μŠ€κ°€ λ°”μΈλ”©λœ thisλ₯Ό μ•”λ¬΅μ μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

function Circle(radius) {
    // 1. μ•”λ¬΅μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κ³  this에 λ°”μΈλ”©λœλ‹€.

    // 2. this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.
    this.radius = radius;
    this.getDiameter = function() {
        return 2 * this.radius;
    };

    // 3. μ™„μ„±λœ μΈμŠ€ν„΄μŠ€κ°€ λ°”μΈλ”©λœ thisκ°€ μ•”λ¬΅μ μœΌλ‘œ λ°˜ν™˜λœλ‹€.
}

// μΈμŠ€ν„΄μŠ€ 생성. Circle μƒμ„±μž ν•¨μˆ˜λŠ” μ•”λ¬΅μ μœΌλ‘œ thisλ₯Ό λ°˜ν™˜ν•œλ‹€.
const circle = new Circle(1);
console.log(circle); // Circle {radius: 1, getDiameter: f}

 

⚠️ μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ return 문은 λ°˜λ“œμ‹œ μƒλž΅ν•΄μ•Ό ν•œλ‹€!

➑️ μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisκ°€ μ•„λ‹Œ λ‹€λ₯Έ 값을 λ°˜ν™˜ν•˜λŠ” 것은 μƒμ„±μž ν•¨μˆ˜μ˜ κΈ°λ³Έ λ™μž‘μ„ ν›Όμ†ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 


4) λ‚΄λΆ€ λ©”μ„œλ“œ [[Call]]κ³Ό [[Construct]]

ν•¨μˆ˜λŠ” κ°μ²΄μ΄μ§€λ§Œ ν˜ΈμΆœν•  수 μžˆλ‹€λŠ” μ μ—μ„œ 일반 객체와 λ‹€λ₯΄λ‹€.

➑️ λ”°λΌμ„œ, [[Call]], [[Construct]] 같은 λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό μΆ”κ°€λ‘œ κ°€μ§€κ³  μžˆλ‹€.

 

  • ν•¨μˆ˜κ°€ 일반 ν•¨μˆ˜λ‘œμ„œ 호좜 ➑️ ν•¨μˆ˜ 객체의 λ‚΄λΆ€ λ©”μ„œλ“œ [[Call]]이 호좜
  • ν•¨μˆ˜κ°€ new μ—°μ‚°μžμ™€ ν•¨κ²Œ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜 ➑️ λ‚΄λΆ€ λ©”μ„œλ“œ [[Construct]]κ°€ 호좜

 


5) constructor와 non-constructor의 ꡬ뢄

construct : [[Construct]]λ₯Ό κ°–λŠ” ν•¨μˆ˜ 객체
non-construct : [[Construct]]λ₯Ό κ°–μ§€ μ•ŠλŠ” ν•¨μˆ˜ 객체

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν•¨μˆ˜ 객체λ₯Ό 생성할 λ•Œ, ν•¨μˆ˜ μ •μ˜ 방식에 따라 이 λ‘˜μ„ κ΅¬λΆ„ν•œλ‹€.

 

construct : ν•¨μˆ˜ μ„ μ–Έλ¬Έ, ν•¨μˆ˜ ν‘œν˜„μ‹, 클래슀(ν΄λž˜μŠ€λ„ ν•¨μˆ˜!)
non-construnct : λ©”μ„œλ“œ(ES6 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„), ν™”μ‚΄ν‘œ ν•¨μˆ˜

⚠️ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜될 것을 κΈ°λŒ€ν•˜κ³  μ •μ˜ν•˜μ§€ μ•Šμ€ 일반 ν•¨μˆ˜(callableμ΄λ©΄μ„œ constructor)에 new μ—°μ‚°μžλ₯Ό λΆ™μ—¬ ν˜ΈμΆœν•˜λ©΄ μƒμ„±μž ν•¨μˆ˜μ²˜λŸΌ λ™μž‘ν•  수 μžˆλ‹€.

 


6) new μ—°μ‚°μž

일반 ν•¨μˆ˜μ™€ μƒμ„±μž ν•¨μˆ˜μ˜ νŠΉλ³„ν•œ ν˜•μ‹μ  μ°¨μ΄λŠ” μ—†λ‹€.

new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜λŠ” μƒμ„±μž ν•¨μˆ˜λ‘œ λ™μž‘ν•œλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

// μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ μ •μ˜ν•˜μ§€ μ•Šμ€ 일반 ν•¨μˆ˜
function add(x, y) {
    return x + y;
}

// μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ μ •μ˜ν•˜μ§€ μ•Šμ€ 일반 ν•¨μˆ˜λ₯Ό new μ—°μ‚°μžμ™€ ν•¨κ»˜ 호좜
let inst = new add();

// ν•¨μˆ˜κ°€ 객체λ₯Ό λ°˜ν™˜ν•˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ λ°˜ν™˜λ¬Έμ΄ λ¬΄μ‹œλœλ‹€.
// λ”°λΌμ„œ 빈 객체가 μƒμ„±λ˜μ–΄ λ°˜ν™˜λœλ‹€.
console.log(inst); // {}

// 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 일반 ν•¨μˆ˜
function createUser(name, role) {
    return { name, role };
}

// 일반 ν•¨μˆ˜λ₯Ό new μ—°μ‚°μžμ™€ ν•¨κ»˜ 호좜
inst = new createUser('Lee', 'admin');
// ν•¨μˆ˜κ°€ μƒμ„±ν•œ 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
console.log(inst); // {name: "Lee", role: "admin"}

 

new μ—°μ‚°μž 없이 μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ 일반 ν•¨μˆ˜λ‘œ ν˜ΈμΆœλœλ‹€.

 

πŸ–₯️ μ˜ˆμ‹œ μ½”λ“œ

// μƒμ„±μž ν•¨μˆ˜
function Circle(radius) {
    this.radius = radius;
    this.getDiameter = function() {
        return 2 * this.radius;
    };
}

// new μ—°μ‚°μž 없이 μƒμ„±μž ν•¨μˆ˜ ν˜ΈμΆœν•˜λ©΄ 일반 ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœλœλ‹€.
const circle = Circle(5);
console.log(circle); // undefined

 

⚠️ 일반 ν•¨μˆ˜μ™€ μƒμ„±μž ν•¨μˆ˜μ— νŠΉλ³„ν•œ 차이가 μ—†λ‹€.

➑️ λ”°λΌμ„œ μƒμ„±μž ν•¨μˆ˜λŠ” 일반적으둜 첫 문자λ₯Ό λŒ€λ¬Έμžλ‘œ κΈ°μˆ ν•˜λŠ” 파슀칼 μΌ€μ΄μŠ€λ‘œ λͺ…λͺ…ν•˜μ—¬ 일반 ν•¨μˆ˜μ™€ κ΅¬λ³„ν•˜λ„λ‘ ν•œλ‹€.

 


7) new.target

μƒμ„±μž ν•¨μˆ˜κ°€ new μ—°μ‚°μž 없이 ν˜ΈμΆœλ˜λŠ” 것을 λ°©μ§€ν•˜λ”λΌλ„, μ‹€μˆ˜κ°€ λ°œμƒν•˜λŠ” 것을 νšŒν”Όν•˜κΈ° μœ„ν•΄ ES6μ—μ„œλŠ” new.target을 μ§€μ›ν•œλ‹€.

 

new.target.은 this와 μœ μ‚¬ν•˜κ²Œ constructor인 λͺ¨λ“  ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 암묡적인 μ§€μ—­ λ³€μˆ˜μ™€ 같이 μ‚¬μš©λ˜λ©° 메타 ν”„λ‘œνΌν‹°λΌκ³  λΆ€λ₯Έλ‹€.
new μ—°μ‚°μžμ™€ ν•¨κ»˜ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜되면 ν•¨μˆ˜ λ‚΄λΆ€μ˜ new.target은 ν•¨μˆ˜ μžμ‹ μ„ 가리킨닀.

 

 

πŸ“– 참고자료

https://www.inflearn.com/course/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C/dashboard