μμ μμ±νλ κ°μ²΄ 리ν°λ΄ ν¬μ€ν μμ κ°μ²΄λ¦¬ν°λ΄λ‘ κ°μ²΄λ₯Ό μμ±νλ λ°©λ²μ λν΄ μμ보μλ€.
μ΄λ² ν¬μ€ν μμλ κ°μ²΄λ₯Ό μμ±νλ λ λ€λ₯Έ λ°©μμΈ μμ±μ ν¨μμ object μμ±μ ν¨μμ μν κ°μ²΄ μμ± λ°©μμ μ΄ν΄λ³΄μ.
μ΄ ν¬μ€ν μ μ΄μ λͺ¨ λμ Javascript deepdive 17μ₯μ μ°Έκ³ νμ¬ μμ±νμμ΅λλ€.
μμ±μ ν¨μλ, β¨newβ¨ μ°μ°μμ ν¨κ» νΈμΆνμ¬ κ°μ²΄λ₯Ό μμ±νλ ν¨μμ΄λ€.
첫λ²μ§Έλ‘ μ΄ν΄λ³Ό μμ±μλ 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: Ζ}
person.sayHello(); // Hi! My name is Lee
Object μμ±μλ₯Ό μ§μ μ΄μ©ν΄μ κ°μ²΄λ₯Ό μμ±νλ κ² λ³΄λ€λ, κ°μ²΄ 리ν°λ΄μ μ΄μ©ν΄ κ°μ²΄λ₯Ό μμ±νλ λ°©μμ΄ λ μΌλ°μ μ΄λ€.
λλ²μ§Έλ‘ μ΄ν΄λ³Ό μμ±μλ Objectκ° μ 곡νλ μμ±μ ν¨μκ° μλ, μΌλ° μμ±μ ν¨μλ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό μ μνλ λ°©μμ΄λ€.
κ°μ²΄ 리ν°λ΄μ μν κ°μ²΄ μμ± λ°©μμ κ°νΈνμ§λ§ λ¨μ λν κ°μ§κ³ μλ€. λ¨μ μ λ°λ‘ λμΌν κ°μ²΄λ₯Ό μ¬λ¬κ° μμ±νκΈ° μν΄μλ λμΌν μ½λλ₯Ό μμ±νλ €κ³ νλ κ°μ²΄μ κ°μλ§νΌ μμ±ν΄μΌ νλ€λ κ²μ΄λ€!
λ°λ©΄ μμ±μ ν¨μμ μν κ°μ²΄μμ± λ°©μμ κ°μ²΄λ₯Ό μμ±νκΈ° μν ν νλ¦Ώμ²λΌ μμ±μ ν¨μλ₯Ό μ¬μ©νκΈ° λλ¬Έμ, ν¨μ νλλ‘ κ΅¬μ‘°κ° λμΌν κ°μ²΄λ₯Ό μ¬λ¬ κ° μμ±ν μ μλ€!
μ½λλ₯Ό ν΅ν΄ μ΄ν΄λ³΄μ.
// μμ±μ ν¨μ
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 κ°μ²΄λ₯Ό μμ±
const circle3 = new Circle(20); // λ°μ§λ¦μ΄ 20μΈ Circle κ°μ²΄λ₯Ό μμ±
const circle4 = new Circle(30); // λ°μ§λ¦μ΄ 30μΈ Circle κ°μ²΄λ₯Ό μμ±
κ°μ²΄ 리ν°λ΄λ‘ μμ±νλ κ²λ³΄λ€ ν¨μ¬ μ½λκ° κΉλνκ³ μ§§μ κ²μ νμΈν μ μλ€. ππ
μ¬μ€ μμ κ°μ΄ κ°μ²΄λ₯Ό μμ±ν λ λ§λ€ λ©μλλ₯Ό κ³μ λ§λλ κ² λ³΄λ€λ νλ‘ν νμ μ μ΄μ©ν΄μ κ³΅ν΅ λ©μλλ‘ μΆμΆ νλκ²μ΄ λ°λμ§νλ€. μμΈν λ΄μ©μ μΆν νλ‘ν νμ κ΄λ ¨ ν¬μ€ν μμ λ€λ£¨μ΄ 보λλ‘ νκ² λ€.
κ·Έλ λ€λ©΄ new ν€μλλ₯Ό μ΄μ©ν΄μ κ°μ²΄λ₯Ό μμ±νλ©΄ μ΄λ€ κ³Όμ μ κ±°μ³ μλ‘μ΄ κ°μ²΄κ° μμ±λλ κ²μΌκΉ? μμ μ½λλ₯Ό μ°Έκ³ ν΄μ μ€ν λ³λ‘ μ΄ν΄λ³΄μ.
new μ°μ°μ λ€μ μμ±μ ν¨μλ₯Ό νΈμΆνλ©΄ μ묡μ μΌλ‘ λΉ κ°μ²΄κ° μμ±λλ€. κ·Έλ¦¬κ³ μ묡μ μΌλ‘ μμ±λ λΉ κ°μ²΄λ thisμ λ°μΈλ©λλ€.
π‘ λ°μΈλ©μ΄λ μλ³μκ³Ό κ°μ μ°κ²°νλ κ³Όμ μΌλ‘, this λ°μΈλ©μ΄λ thisμ thisκ° κ°λ¦¬ν¬ κ°μ²΄λ₯Ό μ°κ²°νλ κ²μ μλ―Έν©λλ€.
μΌλ¨μ new μ°μ°μ λ€μ μμ±μ ν¨μλ₯Ό νΈμΆνλ©΄ μμ±λ κ°μ²΄λ μλμΌλ‘ thisμ λ°μΈλ© λλ€λ μ¬μ€λ§ κΈ°μ΅νμ!
μΈμ€ν΄μ€ μμ± ν μμ±μ ν¨μλ΄λΆμ μ½λκ° νμ€μ© μ€νλμ΄ thisμ λ°μΈλ©λμ΄ μλ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννκ±°λ κ°μ ν λΉνλ€.
μμ±μ ν¨μ λ΄λΆμ λͺ¨λ μ²λ¦¬κ° λλλ©΄ μμ±λΒ μΈμ€ν΄μ€κ° λ°μΈλ©λ thisκ° μ묡μ μΌλ‘ λ°νλλ€.
function Circle(radius) {
// 1. μ묡μ μΌλ‘ μΈμ€ν΄μ€κ° μμ±λκ³ thisμ λ°μΈλ©λλ€.
console.log(this); // Circle {}
// 2. thisμ λ°μΈλ©λμ΄ μλ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννλ€.
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
// 3. return νμ§ μμλ μλμΌλ‘ thisλ₯Ό returnνλ€!
return this;
}
// μΈμ€ν΄μ€ μμ±. Circle μμ±μ ν¨μλ λͺ
μμ μΌλ‘ λ°νν κ°μ²΄λ₯Ό λ°ννλ€.
const circle = new Circle(1);
console.log(circle); // Circle {radius: 1, getDiameter: Ζ}
ν¨μλ κ°μ²΄μ΄κΈ° λλ¬Έμ, κΈ°λ³Έμ μΌλ‘ κ°μ²΄κ° κ°μ§κ³ μλ λ΄λΆ μ¬λ‘―μ λͺ¨λ κ°μ§κ³ μλ€. (λ΄λΆ λ©μλκ° λ¬΄μμΈμ§ λͺ¨λ₯΄μλ λΆλ€μ λ΄λΆ λ©μλ ν¬μ€ν μ μ°Έμ‘°νμΈμ!)
μ¬κΈ°μ λν΄ ν¨μκ°μ²΄λ ν¨μλ‘ λμνκΈ° μν΄ [[Environment]], [[Formal Parameters]]λ±μ λ΄λΆ μ¬λ‘―κ³Ό, [[Call]], [[Construct]] κ°μ λ΄λΆλ©μλλ₯Ό μΆκ°λ‘ κ°μ§κ³ μλ€.
κΈ°μ΅ν΄μΌ ν μ¬μ€μ μΌλ°ν¨μλ‘ νΈμΆλ λμ new ν€μλλ₯Ό ν΅ν΄ μμ±μ ν¨μλ‘ νΈμΆλ λ νΈμΆλλ λ΄λΆ λ©μλκ° λ€λ₯΄λ¨ κ²μ΄λ€.
μΌλ°ν¨μλ‘ νΈμΆλλ©΄ λ΄λΆλ©μλ [[Call]]μ΄ νΈμΆλκ³ , new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ‘ νΈμΆλλ©΄ λ΄λΆλ©μλ [[Construct]]κ° νΈμΆλλ€.
κ·Έλ λ€λ©΄ μμ λ³Έ Circle ν¨μλ‘ newλ₯Ό μ΄μ©ν΄μ μμ±μ ν¨μλ‘ νΈμΆνμ§ μκ³ μΌλ° ν¨μλ‘ νΈμΆνκ² λλ©΄ μ΄λ€ μΌμ΄ λ°μν κΉ?
// μμ±μ ν¨μ
function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle = Circle(5); // newλ₯Ό μ¬μ©νμ§ μκ³ μΌλ°ν¨μλ‘ νΈμΆ
console.log(circle); // undefined(ν¨μ λ΄λΆμ returnνλ κ°μ΄ μμ)
// μΌλ° ν¨μ λ΄λΆμ thisλ μ μ κ°μ²΄ windowλ₯Ό κ°λ¦¬ν€λ―λ‘, windowκ°μ²΄μ propertyλ‘ μΆκ°λλ€.
console.log(radius); // 5
console.log(getDiameter()); // 10
circle.getDiameter();
// TypeError: Cannot read property 'getDiameter' of undefined
newλ₯Ό λΆμ΄μ§ μκ³ νΈμΆ ν μ μλ‘μ΄ κ°μ²΄κ° μμ±λμ§ μκ³ (μ묡μ μΈ returnμ΄ μΌμ΄λμ§ μκΈ° λλ¬Έμ circleμ undefinedμ΄λ€),
μΌλ° ν¨μ λ΄λΆμ thisλ μ μ κ°μ²΄μΈ windowμ΄λ―λ‘ window κ°μ²΄μ νλ‘νΌν°λ‘ μΆκ°λλ κ²μ λ³Ό μ μλ€.
μ΄λ μμμ μ€λͺ νλ― new ν€μλλ₯Ό λΆμ΄μ§ μκ³ ν¨μ κ°μ²΄λ₯Ό μμ±νκ² λλ©΄ λ΄λΆλ©μλ [[Construct]] λμ [[Call]]μ΄ μ€νλκΈ° λλ¬Έμ΄λ€.
μ 리ν΄λ³΄λ©΄, μμ κ°μ΄ [[construct]] λ΄λΆ λ©μλλ₯Ό κ°μ§κ³ μλ ν¨μλ§ μμ±μλ‘μ λμν μ μλ€λ μ¬μ€μ μ μ μλ€.
κ·Έλ¬λ©΄ λͺ¨λ ν¨μλ new ν€μλμ ν¨κ» νΈμΆν μ μμκΉ?
κ²°λ‘ λΆν° λ§νλ©΄, new ν€μλλ‘ νΈμΆν μ μλ ν¨μμ μλ ν¨μκ° μ‘΄μ¬νλ€.
μλ°μ€ν¬λ¦½νΈ μμ§μ ν¨μ μ μ λ°©μμ λ°λΌ ν¨μλ₯Ό constructorμ non-constructorλ‘ κ΅¬λΆνλ€.
- constructor : ν¨μ μ μΈλ¬Έ, ν¨μ ννμ, ν΄λμ€
- non-constructor : λ©μλ(ES6 λ©μλ μΆμ½ νν), νμ΄ν ν¨μ
μ½λλ₯Ό 보며 μ§μ μ΄ν΄λ³΄μ.
function foo(){};
const bar = function(){};
const baz = {
x: function (){}
}
const bzy = {
x(){}
}
const arrow = () => {};
new foo(); // foo {}
new bar(); // bar {}
new baz.x(); // x {}
new bzy.x(); // TypeError : bay.y is not a constructor
new arrow(); // TypeError : arrow is not a constructor
κ²°κ³Όλ₯Ό 보면 foo(ν¨μ μ μΈλ¬Έ), bar(ν¨μ ννμ), baz.x(μΌλ° λ©μλ)λ μμ±μ ν¨μλ‘ μ¬μ©ν μ μμ§λ§,
bzy(λ©μλ μΆμ½νν)μ arrow(νμ΄ν ν¨μ)λ μμ±μ ν¨μλ‘μ¨ μ¬μ©ν μ μλκ²μ νμΈν μ μλ€.
ES6μμ μΆκ°λ κΈ°λ₯μΌλ‘, new μ°μ°μμ ν¨κ» νΈμΆλμλμ§ μ¬λΆλ₯Ό νλ¨ν μ μλ λ©μλμ΄λ€. new.targetμ μ΄μ©νλ©΄ μμ±μ ν¨μκ° new μ°μ°μ μμ΄ νΈμΆνμλ μμ±λλ λ¬Έμ λ₯Ό λ―Έμ°μ λ°©μ§ν μ μλ€.
// μμ±μ ν¨μ
function Circle(radius) {
if (!new.target) {
// new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ₯Ό μ¬κ· νΈμΆνμ¬ μμ±λ μΈμ€ν΄μ€λ₯Ό λ°ννλ€.
return new Circle(radius);
}
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle = Circle(5);
console.log(circle.getDiameter()); // 10
μ μ©νκ² μ¬μ©ν μ μμ κ² κ°λ€. νμ§λ§ μμ IEμμλ μ§μνμ§ μλλ€.
https://caniuse.com/ μμ νΉμ κΈ°λ₯μ λΈλΌμ°μ λ³ μ¬μ© κ°λ₯ μ¬λΆλ₯Ό 체ν¬ν μ μλ€.