λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

JavaScript

[JavaScript] μƒμ„±μž ν•¨μˆ˜

λ°˜μ‘ν˜•

πŸ€ Object μƒμ„±μž ν•¨μˆ˜

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

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

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

//ν”„λ‘œνΌν‹° μΆ”κ°€
person.name = 'daniel';
person.age = 29;
person.introduce = function(){
	console.log(`μ €λŠ” ${person.name}이고, 제 λ‚˜μ΄λŠ” ${person.age}μ‚΄ μž…λ‹ˆλ‹€.`)
}

console.log(person); // {name: 'daniel', age: 29, introduce: ƒ}
person.introduce(); // μ €λŠ” daniel이고, 제 λ‚˜μ΄λŠ” 29μ‚΄ μž…λ‹ˆλ‹€.

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

 

객체λ₯Ό μƒμ„±ν•˜λŠ” λ°©μ‹μ—λŠ” μ—¬λŸ¬κ°€μ§€ 방식이 있고, μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  μ΄μœ κ°€ ꡳ이 μ—†μ–΄ 보인닀. 

μ™œ μƒμ„±μž ν•¨μˆ˜λ₯Ό μ¨μ•Όν•˜λŠ” κ²ƒμΌκΉŒ?

 

πŸ€ μƒμ„±μž ν•¨μˆ˜

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

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

그렇기에 ν”„λ‘œνΌν‹° ꡬ쑰가 동일함에도 λΆˆκ΅¬ν•˜κ³  같은 ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλ₯Ό 객체λ₯Ό 생성할 λ•Œλ§ˆλ‹€ 맀번 κΈ°μˆ ν•΄μ•Όν•œλ‹€λŠ” μ·¨μ•½ν•œ λ¬Έμ œμ μ€ μ§€λ‹Œλ‹€.

 

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

ν…œν”Œλ¦Ώ 처럼 μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν”„λ‘œνΌν‹° ꡬ쑰가 λ™μΌν•œ 객체 μ—¬λŸ¬κ°œλ₯Ό κ°„νŽΈν•˜κ²Œ 생성할 수 μžˆλ‹€.

function Person(name, age){
	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
}

const noah = new Person('noah', 100);
const daniel = new Person('daniel', 29);

console.log(noah); // Person {name: 'noah', age: 100, introduce: ƒ}
console.log(daniel); // Person {name: 'daniel', age: 29, introduce: ƒ}
this?
thisλž€ 객체 μžμ‹ μ˜ ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯΄λ₯Ό μ°Έμ‘°ν•˜κΈ° μœ„ν•œ 자기 μ°Έμ‘° λ³€μˆ˜λ‹€. thisκ°€ κ°€λ¦¬ν‚€λŠ” κ°’, 즉 this 바인딩은 ν•¨μˆ˜ 호좜 방식에 따라 λ™μ μœΌλ‘œ κ²°μ •λœλ‹€. 

ν•¨μˆ˜ 호좜 방식                               thisκ°€ κ°€λ¦¬ν‚€λŠ” κ°’(this 바인딩)
일반 ν•¨μˆ˜λ‘œμ„œ 호좜                        μ „μ—­ 객체
λ©”μ„œλ“œλ‘œμ„œ 호좜                            λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체(λ§ˆμΉ¨ν‘œ μ•žμ˜ 객체)
μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜                    μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€

μƒμ„±μž ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ μ •μ˜ν•˜κ³ , new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜λŠ” μƒμ„±μž ν•¨μˆ˜λ‘œ λ™μž‘ν•˜λŠ”λ° new μ—°μ‚°μžμ™€ ν•¨κ»˜ μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄ μƒμ„±μž ν•¨μˆ˜κ°€ μ•„λ‹ˆλΌ 일반 ν•¨μˆ˜λ‘œ λ™μž‘ν•œλ‹€. 

function Person(name, age){
	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
}
// new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄ μƒμ„±μž ν•¨μˆ˜λ‘œ λ™μž‘ν•˜μ§€ μ•ŠμŒ.
// 일반 ν•¨μˆ˜λ‘œμ„œ 호좜됨.
const noah = Person('noah', 100);

// 일반 ν•¨μˆ˜λ‘œμ„œ 호좜된 Person은 λ°˜ν™˜λ¬Έμ΄ μ—†μœΌλ―€λ‘œ μ•”λ¬΅μ μœΌλ‘œ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.
console.log(noah); // undefined

// 일반 ν•¨μˆ˜λ‘œμ„œ 호좜된 Person λ‚΄μ˜ thisλŠ” μ „μ—­ 객체λ₯Ό 가리킨닀. 
name // 'noah'
age // 100
introduce() // μ €λŠ” noah이고, 제 λ‚˜μ΄λŠ” 100μ‚΄ μž…λ‹ˆλ‹€.

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

μƒμ„±μž ν•¨μˆ˜μ˜ μ—­ν• 

  • μΈμŠ€ν„΄μŠ€λ₯Ό 생성(ν•„μˆ˜)
  • μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”(μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹° μΆ”κ°€ 및 μ΄ˆκΈ°κ°’ ν• λ‹Ή)(μ˜΅μ…˜)
// μƒμ„±μž ν•¨μˆ˜
function Person(name, age){
	// μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
}
// μΈμŠ€ν„΄μŠ€ 생성
const daniel = new Person('daniel', 29); //이름이 λ‹€λ‹ˆμ—˜μ΄κ³ , λ‚˜μ΄κ°€ 29인 Person객체λ₯Ό 생성

μƒμ„±μž ν•¨μˆ˜μ—λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  λ°˜ν™˜ν•˜λŠ” μ½”λ“œλŠ” 보이지 μ•ŠλŠ”λ°, μ΄λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 λ‹€μŒκ³Ό 같은 κ³Όμ •μœΌλ‘œ μ•”λ¬΅μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œ ν›„ μ•”λ¬΅μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 

 

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

μ•”λ¬΅μ μœΌλ‘œ 빈 객체가 μƒμ„±λ˜λ©° 이 빈 객체가 λ―Έμ™„μ„±μ΄μ§€λ§Œ μƒμ„±μž ν•¨μˆ˜κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ‹€. 그리고 이 빈 객체, 즉 μΈμŠ€ν„΄μŠ€κ°€ this에 λ°”μΈλ”©λœλ‹€. μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisκ°€ μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” μ΄μœ κ°€ 이것이닀. 이 μ²˜λ¦¬λŠ” ν•œμˆ˜ λͺΈμ²΄μ˜ μ½”λ“œκ°€ ν•œμ€„μ”© μ‹€ν–‰λ˜λŠ” λŸ°νƒ€μž„ 이전에 μ‹€ν–‰λœλ‹€. 

function Person(name, age){

    console.log(this)// Person {}

	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
}

const daniel = new Person('daniel', 29);

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

μƒμ„±μž ν•¨μˆ˜μ— 기술된 μ½”λ“œκ°€ μ‹€ν–‰λ˜λ©° this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

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

 

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

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

function Person(name, age){
	// μ•”λ¬΅μ μœΌλ‘œ 빈 객체가 μƒμ„±λ˜κ³  this에 바인딩됨.

	// this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”
    console.log(this)// Person {}

	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
    // μ™„μ„±λœ μΈμŠ€ν„΄μŠ€κ°€ λ°”μΈλ”©λœ thisκ°€ λ°˜ν™˜λœλ‹€.
}

// μΈμŠ€ν„΄μŠ€ 생성. Person μƒμ„±μž ν•¨μˆ˜λŠ” μ•”λ¬΅μ μœΌλ‘œ thisλ₯Ό λ°˜ν™˜ν•œλ‹€. 
const daniel = new Person('daniel', 29);
λ§Œμ•½ thisκ°€ μ•„λ‹Œ λ‹€λ₯Έ 객체λ₯Ό λͺ…μ‹œμ μœΌλ‘œ λ°˜ν™˜ν•˜λ©΄ thisκ°€ μ•„λ‹Œ return문에 λͺ…μ‹œν•œ 객체가 λ°˜ν™˜λ˜λ©°, μ›μ‹œ 값을 λ°˜ν™˜ν•˜λ©΄ μ›μ‹œ 값은 λ¬΄μ‹œλ˜κ³  μ•”λ¬΅μ μœΌλ‘œ thisκ°€ λ°˜ν™˜λœλ‹€. 

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

λ‚΄λΆ€ λ©”μ„œλ“œ [[call]]κ³Ό [[contruct]]

ν•¨μˆ˜λŠ” κ°μ²΄μ΄λ―€λ‘œ 일반 객체와 λ™μΌν•˜κ²Œ λ™μž‘ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ 일반 κ°μ²΄λŠ” ν˜ΈμΆœν•  수 μ—†λŠ” 반면 ν•¨μˆ˜λŠ” ν˜ΈμΆœμ„ ν•  수 μžˆλ‹€. 

ν•¨μˆ˜ κ°μ²΄λŠ” λ‹€μŒκ³Ό 같은 λ‚΄λΆ€ 슬둯과 λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€. 

  • 일반 객체가 κ°€μ§€λŠ” λ‚΄λΆ€ 슬둯 및 λ©”μ„œλ“œ
  • [[Environment]]
  • [[FormalParameters]]
  • [[Call]] : λ‚΄λΆ€ λ©”μ„œλ“œ, ν•¨μˆ˜κ°€ 일반 ν•¨μˆ˜λ‘œμ„œ 호좜되면 호좜됨.
  • [[Construct]] : λ‚΄λΆ€ λ©”μ„œλ“œ, ν•¨μˆ˜κ°€ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜되면 호좜됨.

λ‚΄λΆ€ λ©”μ„œλ“œ [[call]]을 κ°–λŠ” ν•¨μˆ˜ 객체λ₯Ό callable이라고 ν•˜λ©° μ΄λŠ” ν˜ΈμΆœν•  수 μžˆλŠ” 객체, 즉 ν•¨μˆ˜ 객체λ₯Ό λ§ν•œλ‹€. 

[[constructor]]λ₯Ό κ°–λŠ” ν•¨μˆ˜ κ°μ²΄λŠ” constructor, [[constructor]]λ₯Ό 갖지 μ•ŠλŠ” ν•¨μˆ˜ 객체λ₯Ό non-constructor라고 ν•œλ‹€. 

λͺ¨λ“  ν•¨μˆ˜ κ°μ²΄λŠ” ν˜ΈμΆœμ„ ν•  수 μžˆκΈ°μ— [[call]]을 κ°–μ§€λ§Œ λ°˜λ“œμ‹œ [[constructor]]λ₯Ό κ°€μ§€μ§€λŠ” μ•ŠλŠ”λ‹€.

constructor와 non-constructor의 ꡬ뢄

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν•¨μˆ˜ μ •μ˜λ₯Ό ν‰κ°€ν•˜μ—¬ ν•¨μˆ˜ 객체λ₯Ό 생성할 λ•Œ ν•¨μˆ˜ μ •μ˜ 방식에 따라

ν•¨μˆ˜λ₯Ό constructor, non-contructor둜 κ΅¬λΆ„ν•œλ‹€. 

  • constructor: ν•¨μˆ˜ μ„ μ–Έλ¬Έ, ν•¨μˆ˜ ν‘œν˜„μ‹, 클래슀
  • non-constructor: λ©”μ„œλ“œ(es6μ—μ„œ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„), ν™”μ‚΄ν‘œ ν•¨μˆ˜

ECMAScript μ‚¬μ–‘μ—μ„œ λ©”μ„œλ“œλ‘œ μΈμ •ν•˜λŠ” λ²”μœ„κ°€ 일반적인 의미의 λ©”μ„œλ“œλ³΄λ‹€ 쒁닀.

μ—¬κΈ°μ„œ λ©”μ„œλ“œλž€ ES6의 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„λ§Œμ„ μ˜λ―Έν•œλ‹€. 

 

μ•„λž˜μ˜ μ½”λ“œλ₯Ό 보면 쑰금 더 이해가 쉽겠닀. 

function foo(){};
const bar = function() {};
const baz = {
	x: function(){}
};

new foo(); // foo {}
new bar(); // bar {}
new baz.x(); // x {}

const arrow = () => {};

new arrow(); // Uncaught TypeError: arrow is not a constructor

const obj = {
	x(){}
}

new obj.x(); // Uncaught TypeError: obj.x is not a constructor

new μ—°μ‚°μž

μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ μ •μ˜ν•˜μ§€ μ•Šμ€ 일반 ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œλ‘œ ν˜ΈμΆœν•˜λ©΄ [[construct]]κ°€ 호좜되고,

ν•¨μˆ˜κ°€ 객체λ₯Ό λ°˜ν™˜ν•˜μ§€ μ•Šμ„ μ‹œ 빈객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

λ°˜λŒ€λ‘œ μƒμ„±μž ν•¨μˆ˜λ₯Ό new μ—°μ‚°μž 없이 ν˜ΈμΆœν•˜κ²Œ 되면 [[call]]이 호좜되고, 

μƒμ„±μž ν•¨μˆ˜μ•ˆμ— μžˆλŠ” thisλŠ” windowλ₯Ό κ°€λ¦¬ν‚€κ²Œ 되며 μƒμ„±μž ν•¨μˆ˜μ— μ •μ˜λœ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλŠ” μ „μ—­μ˜ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œκ°€ λœλ‹€. 

new.target

new μ—°μ‚°μžμ™€ ν•¨κ»˜ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜되면 ν•¨μˆ˜ λ‚΄λΆ€μ˜ new.target은 ν•¨μˆ˜ μžμ‹ μ„ 가리킨닀. new μ—°μ‚°μž 없이 일반 ν•¨μˆ˜λ‘œμ„œ 호좜된 ν•¨μˆ˜ λ‚΄λΆ€μ˜ new.target은 undefinedλ‹€. 이λ₯Ό μ΄μš©ν•˜μ—¬ μƒμ„±μž ν•¨μˆ˜κ°€ new없이 ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ  new μ—°μ‚°μžμ™€ ν•¨κ»˜ μž¬κ·€ ν˜ΈμΆœμ„ 톡해 μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœμ„ ν•  수 μžˆλ‹€. 

 

function Person(name, age){
	this.name = name;
    this.age = age;
    this.introduce = function(){
		return console.log(`μ €λŠ” ${this.name}이고, 제 λ‚˜μ΄λŠ” ${this.age}μ‚΄ μž…λ‹ˆλ‹€.`)
	}
    
    if(!new.target){
    	return new Person(name, age);
    }
}

const daniel = Person('daniel', 29);

 

좜처 : λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ λ”₯λ‹€μ΄λΈŒ

λ°˜μ‘ν˜•

'JavaScript' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[JavaScript] Webpack  (0) 2021.12.11
[JavaScript] ν•¨μˆ˜μ™€ 일급 객체  (0) 2021.11.28
[JavaScript] 빌트인 객체  (0) 2021.11.05
[JavaScript] Symbol  (0) 2021.10.23
[JavaScript]μ „μ—­ λ³€μˆ˜μ˜ 문제점  (0) 2021.10.06