๐Ÿ’ก ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ

  1. ๋‹ค์–‘ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹ ์ค‘์—์„œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹
  2. ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹๊ณผ์˜ ์žฅ๋‹จ์ 

1. 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

โ˜‘๏ธŽ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ (constructor): new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜

โ˜‘๏ธŽ ์ธ์Šคํ„ด์Šค (instance): ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด

โœข ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ด์™ธ์—๋„ String, Number, Boolean, Function, Array, Date, RegExp, Promise ๋“ฑ ๋นŒํŠธ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๋ฐ˜๋“œ์‹œ Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ฐ„ํŽธํ•˜๋‹ค.

2. ์ƒ์„ฑ์ž ํ•จ์ˆ˜

2-1. ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ 

๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์€ ์ง๊ด€์ ์ด๊ณ  ํŽธํ•˜๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์€ ๋‹จ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ์ƒ์„ฑํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋™์ผํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋งค๋ฒˆ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ธฐ์ˆ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„ํšจ์œจ์ ์ด๋‹ค.

โœ”๏ธŽ ๊ฐ์ฒด๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด ๊ณ ์œ ์˜ ์ƒํƒœ๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค.

โœ”๏ธŽ ๊ฐ์ฒด๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒํƒœ ๋ฐ์ดํ„ฐ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์กฐ์ž‘ํ•˜๋Š” ๋™์ž‘์„ ํ‘œํ˜„ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ, ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด๋งˆ๋‹ค ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฉ”์„œ๋“œ๋Š” ๋‚ด์šฉ์ด ๋™์ผํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ผ๋ฐ˜์ ์ด๋‹ค.

2-2. ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์˜ ์žฅ์ 

์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์€ ๋งˆ์น˜ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ(ํด๋ž˜์Šค)์ฒ˜๋Ÿผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœํผํ‹ฐ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•œ ๊ฐ์ฒด ์–ด๋Ÿฌ ๊ฐœ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

function Circle(radius) {
	// ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
	this.radius = radius;
	this.getDiameter = function () {
		return 2 * this.radius;
	};
}

// ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ
const circle1 = new Circle(5);
const circle2 = new Circle(10);

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

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋‹ค. ํ•˜์ง€๋งŒ ์ž๋ฐ”์™€ ๊ฐ™์€ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์˜ ์ƒ์„ฑ์ž์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๊ทธ ํ˜•์‹์ด ์ •ํ•ด์ ธ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•œ๋‹ค. ๋งŒ์•ฝ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•œ๋‹ค.

const circle3 = Circle(15);

console.log(circle3); // undefined

// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ Circle ๋‚ด์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(radius); // 15

2-3. ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๊ณผ์ •

์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์—ญํ• ์€ ํ”„๋กœํผํ‹ฐ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์œผ๋กœ์„œ ๋™์ž‘ํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”(์ธ์Šคํ„ด์Šค ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ ๋ฐ ์ดˆ๊ธฐ๊ฐ’ ํ• ๋‹น)ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ํ•„์ˆ˜์ด๊ณ , ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์€ ์˜ต์…˜์ด๋‹ค.

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius) {
	// ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”
	this.radius = radius;
	this.getDiameter = function () {
		return 2 * this.radius;
	};
}

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const circle1 = new Circle(5);

์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ์—์„œ this์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ์ „๋‹ฌ๋œ ์ธ์ˆ˜๋ฅผ ํ”„๋กœํผํ‹ฐ์˜ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ์„œ ํ• ๋‹นํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ’ก ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์•”๋ฌต์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•œ๋‹ค. new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์ณ ์•”๋ฌต์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ํ›„ ์•”๋ฌต์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1๏ธโƒฃ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๊ณผ this ๋ฐ”์ธ๋”ฉ

์•”๋ฌต์ ์œผ๋กœ ๋นˆ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

์ด ๋นˆ ๊ฐ์ฒด๊ฐ€ ๋ฐ”๋กœ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค์ด๋‹ค.

์ด ์ธ์Šคํ„ด์Šค๋Š” this์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

โ†’ ์ƒ์„ฑ์ž ๋‚ด๋ถ€ ํ•จ์ˆ˜์˜ this๊ฐ€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์ด๊ฒƒ์ด๋‹ค.

์ด ์ฒ˜๋ฆฌ๋Š” ํ•จ์ˆ˜ ๋ชธ์ฒด์˜ ์ฝ”๋“œ๊ฐ€ ํ•œ ์ค„์”ฉ ์‹คํ–‰๋˜๋Š” ๋Ÿฐํƒ€์ž„ ์ด์ „์— ์‹คํ–‰๋œ๋‹ค.

โœ ๋ฐ”์ธ๋”ฉ (name binding) - ์‹๋ณ„์ž์™€ ๊ฐ’์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •

ex) ๋ณ€์ˆ˜ ์„ ์–ธ์€ ๋ณ€์ˆ˜ ์ด๋ฆ„(์‹๋ณ„์ž)๊ณผ ํ™•๋ณด๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ.

this ๋ฐ”์ธ๋”ฉ์€ this(ํ‚ค์›Œ๋“œ๋กœ ๋ถ„๋ฅ˜๋˜์ง€๋งŒ ์‹๋ณ„์ž ์—ญํ• ์„ ํ•จ.)์™€ this๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

2๏ธโƒฃ ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”

์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ๊ธฐ์ˆ ๋˜์–ด ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ํ•œ ์ค„์”ฉ ์‹คํ–‰๋˜์–ด this์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

this์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ๋Š” ์ธ์Šคํ„ด์Šค์— ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์ดˆ๊ธฐ๊ฐ’์„ ์ธ์Šคํ„ด์Šค ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ•˜๊ฑฐ๋‚˜ ๊ณ ์ •๊ฐ’์„ ํ• ๋‹นํ•œ๋‹ค.

3๏ธโƒฃย ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜

์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๋ชจ๋“  ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด ์™„์„ฑ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ this๊ฐ€ ์•”๋ฌต์ ์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

function Circle(radius) {
	// 1๏ธโƒฃ ์•”๋ฌต์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  this์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
	console.log(this); // Circle {}
	
	// 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 }

์œ„ ์ฝ”๋“œ์˜ 3๏ธโƒฃย ์—์„œ ๋งŒ์•ฝ ๋ช…์‹œ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด this๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€ ๋ชปํ•˜๊ณ  return ๋ฌธ์— ๋ช…์‹œํ•œ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€๋งŒ, ์›์‹œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์›์‹œ ๊ฐ’ ๋ฐ˜ํ™˜์€ ๋ฌด์‹œ๋˜๊ณ  ์•”๋ฌต์ ์œผ๋กœ this๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

2-4. ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Call]]๊ณผ [[Construct]]

ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ ๋˜๋Š” ํ•จ์ˆ˜ ํ‘œํ˜„์‹์œผ๋กœ ์ •์˜ํ•œ ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๋ฌผ๋ก  ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ๊ฒƒ์€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ด๋ฏ€๋กœ ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

// ํ•จ์ˆ˜ == ๊ฐ์ฒด
function foo() {}

// ํ•จ์ˆ˜ == ๊ฐ์ฒด -> ํ”„๋กœํผํ‹ฐ ์†Œ์œ  ๊ฐ€๋Šฅ
foo.prop = 10;

// ํ•จ์ˆ˜ === ๊ฐ์ฒด -> ๋ฉ”์„œ๋“œ ์†Œ์œ  ๊ฐ€๋Šฅ
foo.method = function () {
	console.log(this.prop);
}

foo.method(); // 10

ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ด์ง€๋งŒ ์ผ๋ฐ˜ ๊ฐ์ฒด์™€๋Š” ๋‹ค๋ฅด๋‹ค.

โ†’ ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์ง€๋งŒ ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ, ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์€ ๋ฌผ๋ก  ํ•จ์ˆ˜๋กœ์„œ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ ๊ฐ์ฒด๋งŒ์„ ์œ„ํ•œ [[Call]], [[Construct]] ๊ฐ™์€ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

โœ”๏ธ ํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋˜๋ฉด ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Call]] ํ˜ธ์ถœ

โœ”๏ธ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋˜๋ฉด ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Construct]] ํ˜ธ์ถœ

function foo() {}

foo(); // [[Call]] ํ˜ธ์ถœ

new foo(); // [[Construct]] ํ˜ธ์ถœ
  • callable: ํ•จ์ˆ˜ (ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด)
  • constructor: ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜
  • non-constructor: ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ํ•จ์ˆ˜

ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ํ•จ์ˆ˜๋กœ์„œ ๊ธฐ๋Šฅํ•˜๋Š” ๊ฐ์ฒด, ์ฆ‰ ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋ฐ˜๋“œ์‹œ callable์ด์–ด์•ผ ํ•œ๋‹ค.

โ†’ ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Call]]์„ ๊ฐ–๊ณ  ์žˆ์œผ๋ฏ€๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ [[Construct]]๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

โ†’ ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” constructor์ผ ์ˆ˜๋„ ์žˆ๊ณ  non-constructor์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

โ†’ ์ฆ‰, ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

(p.243 ๊ทธ๋ฆผ ์ฐธ๊ณ ํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€)

2-5. constructor์™€ non-contructor์˜ ๊ตฌ๋ถ„

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ํ‰๊ฐ€ํ•˜์—ฌ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ•จ์ˆ˜ ์ •์˜ ๋ฐฉ์‹์— ๋”ฐ๋ผ ํ•จ์ˆ˜๋ฅผ constructor์™€ non-constructor๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป constructor: ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹, ํด๋ž˜์Šค

๐Ÿ‘‰๐Ÿปย non-constructor: ๋ฉ”์„œ๋“œ(ES6), ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

์ด ๋•Œ ์ฃผ์˜ํ•  ๊ฒƒ์€ ECMAScript ์‚ฌ์–‘์—์„œ ๋ฉ”์„œ๋“œ๋กœ ์ธ์ •ํ•˜๋Š” ๋ฒ”์œ„๊ฐ€ ์ผ๋ฐ˜์ ์ธ ์˜๋ฏธ์˜ ๋ฉ”์„œ๋“œ๋ณด๋‹ค ์ข๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

// ์ผ๋ฐ˜ ํ•จ์ˆ˜ ์ •์˜: ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹
function foo() {}
const bar = function () {};
// ํ”„๋กœํผํ‹ฐ x์˜ ๊ฐ’์œผ๋กœ ํ• ๋‹น๋œ ๊ฒƒ์€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ์ •์˜๋œ ํ•จ์ˆ˜. (๋ฉ”์„œ๋“œ๋กœ ์ธ์ • x)
const baz = {
	x: function () {}
};

// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ์ •์˜๋œ ํ•จ์ˆ˜๋งŒ์ด constructor์ด๋‹ค.
new foo(); // -> foo {}
new bar(); // -> bar {}
new baz.x(); // -> x {}

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์ •์˜ 
const arrow = () => {};

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

// ๋ฉ”์„œ๋“œ ์ •์˜ - ES6์˜ ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„๋งŒ ๋ฉ”์„œ๋“œ๋กœ ์ธ์ •
const obj = {
	x() {}
};

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

ํ•จ์ˆ˜๋ฅผ ํ”„๋กœํผํ‹ฐ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”์„œ๋“œ๋กœ ํ†ต์นญํ•˜์ง€๋งŒ, ECMAScript ์‚ฌ์–‘์—์„œ ๋ฉ”์„œ๋“œ๋ž€ ES6์˜ ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„๋งŒ์„ ์˜๋ฏธํ•œ๋‹ค.

โ†’ ํ•จ์ˆ˜๊ฐ€ ์–ด๋””์— ํ• ๋‹น๋˜์–ด ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ์ธ์ง€๋ฅผ ํŒ๋‹จํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•จ์ˆ˜ ์ •์˜ ๋ฐฉ์‹์— ๋”ฐ๋ผ constructor์™€ non-contructor๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Call]]์ด ํ˜ธ์ถœ๋˜๊ณ  new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Construct]]๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. non-constructor์ธ ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Construct]]๋ฅผ ๊ฐ–์ง€ ์•Š๋Š”๋‹ค.

โ†’ non-constructor์ธ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

2-6. new ์—ฐ์‚ฐ์ž

์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ํŠน๋ณ„ํ•œ ํ˜•์‹์  ์ฐจ์ด๋Š” ์—†๋‹ค.

new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•œ๋‹ค.

โ†’ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Call]]์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ [[Contruct]]๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. (๋‹จ, new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๋Š” non-constructor๊ฐ€ ์•„๋‹Œ constructor์ด์–ด์•ผ ํ•œ๋‹ค.)

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ์ •์˜ํ•˜์ง€ ์•Š์€ ์ผ๋ฐ˜ ํ•จ์ˆ˜
function add(x, y) {
	return x + y;
}

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ์ •์˜ํ•˜์ง€ ์•Š์€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ
let inst = new add();

// ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฐ˜ํ™˜๋ฌธ์ด ๋ฌด์‹œ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋นˆ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์–ด ๋ฐ˜ํ™˜๋œ๋‹ค.
console.log(isnt); // {}

// ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜
function createUser(name, role) {
	return { name, role };
}

// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ
inst = new createUser('Lee', 'admin');
// ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
console.log(inst); // {name: 'Lee', role: 'admin'}

๋ฐ˜๋Œ€๋กœ new ์—ฐ์‚ฐ์ž ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋œ๋‹ค.

โ†’ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[Construct]]๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ [[Call]]์ด ํ˜ธ์ถœ๋œ๋‹ค.

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

// new ์—ฐ์‚ฐ์ž ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜๋ฉด ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ๋‹ค.
const circle = Circle(5);
console.log(circle); // undefined

// ์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(radius); // 5
console.log(getDiameter()); // 10

circle.getDiameter(); // TypeError: Cannot read property 'getDiameter' of undefined

Circle ํ•จ์ˆ˜๋ฅผ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

์œ„ ์˜ˆ์ œ์˜ Circle ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— Circle ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

โ†’ radius ํ”„๋กœํผํ‹ฐ์™€ getDiameter ๋ฉ”์„œ๋“œ๋Š” ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ๋œ๋‹ค.

2-7. new.target

์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž ์—†์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ์Šค์นผ ์ผ€์ด์Šค ์ปจ๋ฒค์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค ํ•˜๋”๋ผ๋„ ์‹ค์ˆ˜๋Š” ์–ธ์ œ๋‚˜ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์œ„ํ—˜์„ฑ์„ ํšŒํ”ผํ•˜๊ธฐ ์œ„ํ•ด ES6์—์„œ๋Š” new.target์„ ์ง€์›ํ•œ๋‹ค.

new.target์€ this์™€ ์œ ์‚ฌํ•˜๊ฒŒ constructor์ธ ๋ชจ๋“  ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์•”๋ฌต์ ์ธ ์ง€์—ญ ๋ณ€์ˆ˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ฉ”ํƒ€ ํ”„๋กœํผํ‹ฐ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ new.target์„ ์‚ฌ์šฉํ•˜๋ฉด new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋˜๋ฉด ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ new.target์€ ํ•จ์ˆ˜ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. new ์—ฐ์‚ฐ์ž ์—†์ด ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ new.target์€ undefined๋‹ค.

โ†’ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ new.target์„ ์‚ฌ์šฉํ•˜์—ฌ new ์—ฐ์‚ฐ์ž์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์žฌ๊ท€ ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius) {
	// ์ด ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด new.target์€ undefined๋‹ค.
	if (!new.target) {
		// new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
		return new Circle(radius);
	}
	this.radius = radius;
	this.getDiameter = function () {
		return 2 * this.radius;
	};
}

// new ์—ฐ์‚ฐ์ž ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ๋„ new.target์„ ํ†ตํ•ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ๋‹ค.
const circle = Circle(5);
console.log(circle.getDiameter()); // 10
// Scope-Safe Constructor Pattern
function Circle(radius) {
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜๋ฉด ํ•จ์ˆ˜์˜ ์„ ๋‘์—์„œ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  this์— ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.
  // ์ด ๋•Œ this์™€ Circle์€ ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ•ด ์—ฐ๊ฒฐ๋œ๋‹ค.

  // ์ด ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์ด ์‹œ์ ์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  // ์ฆ‰, this์™€ Circle์€ ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ•ด ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๋Š”๋‹ค.
  if (!(this instanceof Circle)) {
    // new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    return new Circle(radius);
  }

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

// new ์—ฐ์‚ฐ์ž ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ๋„ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ๋‹ค.
const circle = Circle(5);
console.log(circle.getDiameter()); // 10

new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋Š” ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ•ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ์—ฐ๊ฒฐ๋œ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

(ํ”„๋กœํ† ํƒ€์ž…๊ณผ instanceof ์—ฐ์‚ฐ์ž์— ๋Œ€ํ•ด์„œ๋Š” 19์žฅ ํ”„๋กœํ† ํƒ€์ž…์— ์ž์„ธํžˆ ๋‚˜์˜จ๋‹ค.)

Object์™€ Function ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” new ์—ฐ์‚ฐ์ž ์—†์ด ํ˜ธ์ถœํ•ด๋„ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

let obj = new Object();
console.log(obj); // {}

obj = Object();
console.log(obj); // {}

let f = new Function('x', 'return x ** x');
console.log(f); // f anonymous(x) { return x ** x }

f = Function('x', 'return x ** x');
console.log(f); // f anonymous(x) { return x ** x

ํ•˜์ง€๋งŒ String, Number, Boolean ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ String, Number, Boolean ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ new ์—ฐ์‚ฐ์ž ์—†์ด ํ˜ธ์ถœํ•˜๋ฉด ๋ฌธ์ž์—ด, ์ˆซ์ž, ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋ณ€ํ™˜ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

const str = String(123);
console.log(str, typeof str); // 123 string

const num = Number(123);
console.log(num, typeof num); // 123 number

const bool = Boolean('true');
console.log(bool, typeof bool); // true boolean