λͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Dive λμμ 17μ₯μ μ 리νμμ΅λλ€.
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}
μμ±μ ν¨μλ new μ°μ°μμ ν¨κ» νΈμΆνμ¬ κ°μ²΄λ₯Ό μμ±νλ ν¨μλ₯Ό λ§νλ€. μμ±μ ν¨μμ μν΄ μμ±λ κ°μ²΄λ₯Ό μΈμ€ν΄μ€λΌ νλ€.
Object μμ±μ ν¨μ μ΄μΈμλ String, Number, Boolean, Function, Array, Date, RegExp, Promise λ±
μ λΉνΈμΈ μμ±μ ν¨μλ₯Ό μ 곡νλ€.
ex) Function μμ±μ ν¨μ
const func = new Function ('x', 'return x * x');
console.log(typeof func); //function
console.dir(func); // f anonymous(x)
Object μμ±μ ν¨μλ₯Ό μ¬μ©ν΄μ κ°μ²΄ μμ±νλ λ°©μμ νΉλ³ν μ΄μ κ° μμΌλ©΄ κ·Έλ€μ§ μ μ©ν΄ 보μ΄μ§ μλλ€.
κ°μ²΄ 리ν°λ΄μ μν κ°μ²΄ μμ± λ°©μμ λ¨ νλμ κ°μ²΄λ§μ μμ±νλ€. λμΌν νλ‘νΌν°λ₯Ό κ°λ κ°μ²΄λ₯Ό μ¬λ¬ κ° μμ±ν΄μΌ νλ κ²½μ° λ§€λ² κ°μ νλ‘νΌν°λ₯Ό κΈ°μ ν΄μΌ νκΈ° λλ¬Έμ λΉν¨μ¨μ μ΄λ€.
λ§μΉ κ°μ²΄(μΈμ€ν΄μ€)λ₯Ό μμ±νκΈ° μν ν νλ¦Ώ(ν΄λμ€)μ²λΌ μμ±μ ν¨μλ₯Ό μ¬μ©νμ¬ νλ‘νΌν° κ΅¬μ‘°κ° λμΌν κ°μ²΄ μ¬λ¬ κ°λ₯Ό κ°νΈνκ² μμ±ν μ μλ€.
functon Circle(radius){
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
}
}
// μΈμ€ν΄μ€μ μμ±
const circle1 = new Circle(5);
const circle2 = new circle(10);
console.log(circle1.getDiaameter()); //10
console.log(circle2.getDiaameter()); //20
μμ±μ ν¨μλ μ΄λ¦ κ·Έλλ‘ κ°μ²΄λ₯Ό μμ±νλ ν¨μλ€. μΌλ° ν¨μμ λμΌν λ°©λ²μΌλ‘ μμ±μ ν¨μλ₯Ό μ μνκ³ new μ°μ°μμ ν¨κ» νΈμΆνλ©΄ ν΄λΉ ν¨μλ μμ±μ ν¨μλ‘ λμνλ€. new μ°μμμ ν¨κ» νΈμΆνμ§ μμΌλ©΄ μΌλ° ν¨μλ‘ λμνλ€.
// new μ°μ°μμ€ ν¨κ» νΈμΆνμ§ μμΌλ©΄ μμ±μ ν¨μλ‘ λμνμ§ μλλ€. => μΌλ° ν¨μλ‘μ λμ
const circle3 = Circle(15);
console.log(circle3); // undefined : λ°νλ¬Έμ΄ μμΌλ―λ‘
console.log(radius); // μΌλ° ν¨μλ‘μ νΈμΆλ Circle λ΄μ thisλ μ μ κ°μ²΄λ₯Ό κ°λ¦¬ν¨λ€.
ππ» thisλ?
thisλ κ°μ²΄ μμ μ νλ‘νΌν°λ λ©μλλ₯Ό μ°Έμ‘°νκΈ° μν μκΈ° μ°Έμ‘° λ³μ
λ€. thisκ° κ°λ¦¬ν€λ κ°, μ¦ this λ°μΈλ©μ ν¨μ νΈμΆ λ°©μμ λ°λΌ λμ μΌλ‘ κ²°μ λλ€.
ν¨μ νΈμΆ λ°©μ | thisκ° κ°λ¦¬ν€λ κ°(this λ°μΈλ©) |
---|---|
μΌλ° ν¨μλ‘μ νΈμΆ | μ μ κ°μ²΄ |
λ©μλλ‘μ νΈμΆ | λ©μλλ₯Ό νΈμΆν κ°μ²΄(λ§μΉ¨ν μμ κ°μ²΄) |
μμ±μ ν¨μλ‘μ νΈμΆ | μμ±μ ν¨μκ° (λ―Έλμ) μμ±ν μΈμ€ν΄μ€ |
function foo(){
console.log(this);
}
// μΌλ°μ μΈ ν¨μλ‘μ νΈμΆ
// μ μ κ°μ²΄λ λΈλΌμ°μ νκ²½μμλ window, Node.js νκ²½μμλ globalμ κ°λ¦¬ν¨λ€.
foo(); // window
// λ©μλλ‘μ νΈμΆ
const obj = { foo }; // ES6 νλ‘νΌν° μΆμ½ νν
obj.foo(); // obj
// μμ±μ ν¨μλ‘μ νΈμΆ
const inst = new foo(); //inst
μμ±μ ν¨μμ μν μ νλ‘νΌν° κ΅¬μ‘°κ° λμΌν μΈμ€ν΄μ€λ₯Ό μμ±νκΈ° μν ν νλ¦Ώ(ν΄λμ€)μΌλ‘μ λμνμ¬ μΈμ€ν΄μ€λ₯Ό μμ±νλ κ²κ³Ό μμ±λ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννλ κ²μ΄λ€.
μμ±μ ν¨μκ° μΈμ€ν΄μ€λ₯Ό μμ±νλ κ²μ νμμ΄κ³ μμ±λ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννλ κ²μ μ΅μ μ΄λ€.
1. μΈμ€ν΄μ€ μμ±κ³Ό this λ°μΈλ©
μ묡μ μΌλ‘ λΉ κ°μ²΄κ° μμ±λλ€. μ΄ κ°μ²΄κ° λ°λ‘ μμ±μ ν¨μκ° μμ±ν μΈμ€ν΄μ€
μ΄λ€. κ·Έλ¦¬κ³ μ묡μ μΌλ‘ μμ±λ λΉ κ°μ²΄, μ¦ μΈμ€ν΄μ€λ thisμ λ°μΈλ©(μλ³μλ κ°μ μ°κ²°νλ κ³Όμ )λλ€.
2. μΈμ€ν΄μ€ μ΄κΈ°ν
μμ±μ ν¨μμ κΈ°μ λμ΄ μλ μ½λκ° ν μ€μ© μ€νλμ΄ thisμ λ°μΈλ©λμ΄ μλ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ν
νλ€. μ¦, thisμ λ°μΈλ©λμ΄ μλ μΈμ€ν΄μ€μ νλ‘νΌν°λ λ©μλλ₯Ό μΆκ°νκ³ μμ±μ ν¨μκ° μΈμλ‘ μ λ¬λ°μ μ΄κΈ°κ°μ μΈμ€ν΄μ€ νλ‘νΌν°μ ν λΉνμ¬ μ΄κΈ°ννκ±°λ κ³ μ κ°μ ν λΉνλ€.
3. μΈμ€ν΄μ€ λ°ν
μμ±μ ν¨μ λ΄λΆμ λͺ¨λ μ²λ¦¬κ° λλλ©΄ μμ±λ μΈμ€ν΄μ€κ° λ°μΈλ©λ thisκ° μ묡μ μΌλ‘ λ°ν
λλ€.
function Circle(radius){
// 1. μ묡μ μΌλ‘ μΈμ€ν΄μ€κ° μμ±λκ³ thisμ λ°μΈλ©λλ€.
console.log(this); // Circle{}
// 2. thisμ λ°μΈλ© λμ΄ μλ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννλ€.
this.radius = radius;
this.getDiagmeter = function(){
return 2 * this.radius;
}
// 3. μμ±λ μΈμ€ν΄μ€κ° λ°μΈλ©λ thisκ° μ묡μ μΌλ‘ λ°νλλ€.
}
// μΈμ€ν΄μ€ μμ±. Circle μμ±μ ν¨μλ μ묡μ μΌλ‘ thisλ₯Ό λ°ννλ€.
const circle = new Circle(1);
console.log(circle); // Circle {radius: 1, getDiameter: f}
λ§μ½ thisκ° μλ λ€λ₯Έ κ°μ²΄
λ₯Ό λͺ
μμ μΌλ‘ λ°ννλ©΄ thisκ° λ°νλμ§ λͺ»νκ³ return λ¬Έμ λͺ
μν κ°μ²΄κ° λ°ν
λλ€. νμ§λ§ λͺ
μμ μΌλ‘ μμ κ°μ λ°ννλ©΄ μμ κ° λ°νμ 무μλκ³ μ묡μ μΌλ‘ thisκ° λ°ν
λλ€.
function Circle(radius){
...
return 100
};
const circle = new Circle(1);
console.log(circle); // Circle {radius: 1, getDiameter: f}
λ°λΌμ μμ±μ ν¨μ λ΄λΆμμ return λ¬Έμ λ°λμ μλ΅
ν΄μΌ νλ€.
ν¨μλ κ°μ²΄μ΄λ―λ‘ μΌλ° κ°μ²΄μ λμΌνκ² λμν μ μλ€. ν¨μ κ°μ²΄λ μΌλ° κ°μ²΄κ° κ°μ§κ³ μλ λ΄λΆ μ¬λ‘―κ³Ό λ΄λΆ λ©μλλ₯Ό λͺ¨λ κ°μ§κ³ μκΈ° λλ¬Έ
μ΄λ€.
ν¨μλ κ°μ²΄μ΄μ§λ§ μΌλ° κ°μ²΄μλ λ€λ₯΄λ€. μΌλ° κ°μ²΄λ νΈμΆν μ μμ§λ§ ν¨μλ νΈμΆν μ μλ€. λ°λΌμ ν¨μ κ°μ²΄λ μΌλ° κ°μ²΄κ° κ°μ§κ³ μλ λ΄λΆ μ¬λ‘―κ³Ό λ΄λΆ λ©μλλ λ¬Όλ‘ , ν¨μλ‘μ λμνκΈ° μν΄ ν¨μ κ°μ²΄λ§μ μν [[Environment]], [[FormalParameters]]
λ±μ λ΄λΆ μ¬λ‘―κ³Ό [[Call]]κ³Ό [[Construct]]
κ°μ λ΄λΆ λ©μλλ₯Ό μΆκ°λ‘ κ°μ§κ³ μλ€.
ν¨μκ° μΌλ° ν¨μλ‘μ νΈμΆ
- ν¨μ κ°μ²΄ λ΄λΆμ λ©μλ
[[Call]]
μ΄ νΈμΆλλ€.new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ‘μ νΈμΆ
- λ΄λΆ λ¨ΈμΈλ
[[Construct]]
κ° νΈμΆλλ€.
callable
λ‘ λΆλ₯Έλ€. callableμ νΈμΆν μ μλ κ°μ²΄, μ¦ ν¨μ
λ₯Ό λ§ν¨constructor
λ‘ λΆλ₯΄κ³ μμ±μ ν¨μλ‘μ νΈμΆ ν μ μλ ν¨μ
λ₯Ό μλ―Ένλ€.non-constructor
λ‘ λΆλ₯΄κ³ κ°μ²΄λ₯Ό μμ±μ ν¨μλ‘μ νΈμΆν μ μλ ν¨μ
λ₯Ό μλ―Έμλ°μ€ν¬λ¦½νΈ μμ§μ ν¨μ μ μ λ°©μμ λ°λΌ ν¨μλ₯Ό constructorμ non-constructorλ‘ κ΅¬λΆνλ€.
// μΌλ° ν¨μ μ μ(ν¨μ μ μΈλ¬Έ, ν¨μ ννμ)
function foo(){}
const bar = function () {};
// νλ‘νΌν° 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 contstructor
β οΈ μ£Όμν μ
μμ±μ ν¨μλ‘μ νΈμΆλ κ²μ κΈ°λνκ³ μ μνμ§ μμ μΌλ° ν¨μ(callableμ΄λ©΄μ constructor)μ new μ°μ°μλ₯Ό λΆμ¬ νΈμΆνλ©΄ μμ±μ ν¨μμ²λΌ λμν μ μλ€λ κ²
function() {}
foo(); // μΌλ° ν¨μλ‘μ νΈμΆ => [[Call]]μ΄ νΈμΆλ¨
new foo(); // μμ±μ ν¨μλ‘μ νΈμΆ => [[Construct]]κ° νΈμΆ
new μ°μ°μμ ν¨κ» ν¨μλ₯Ό νΈμΆνλ©΄ [[Construct]]
κ° νΈμΆλλ€. λ¨, new μ°μ°μμ ν¨κ» νΈμΆνλ ν¨μλ non-constructorκ° μλ constructorμ΄μ΄μΌ νλ€.
new μ°μ°μ μμ΄ μμ±μ ν¨μλ₯Ό νΈμΆνλ©΄ μΌλ° ν¨μλ‘ νΈμΆ
λλ€. μ¦ ν¨μ κ°μ²΄μ λ΄λΆ λ©μλκ° [[Call]]
μ΄ νΈμΆλλ€.
function Circle(radius){
this.radius = radius;
this.getDiagmeter = function(){
return 2 * this.radius;
}
}
const circle = Circle(5); //new μ°μ°μ μμ΄ μμ±μ ν¨μ νΈμΆ
console.log(circle); // undefined
// μΌλ° ν¨μ λ΄λΆμ thisλ μ μ κ°μ²΄ windowλ₯Ό κ°λ¦¬ν¨λ€. (new μμ΄ μμ±νκΈ° λλ¬Έμ)
// λ°λΌμ radiusμ getDiameter λ©μλλ μ μ κ°μ²΄μ νλ‘νΌν°μ λ©μλκ° λλ€.
console.log(radius); //5
console.log(getDiameter()); // 10
circle.getDiameter();
// TypeError: Cannot read property 'getDiameter' of undefined
μΌλ° ν¨μμ μμ±μ ν¨μμ νΉλ³ν νμμ μ°¨μ΄λ μλ€. λ°λΌμ μμ±μ ν¨μλ μΌλ°μ μΌλ‘ 첫 λ¬Έμλ₯Ό λλ¬Έμλ‘ κΈ°μ νλ νμ€μΉΌ μΌμ΄μ€λ‘ λͺ λͺ νμ¬ μΌλ° ν¨μμ ꡬλ³ν μ μλλ‘ λ Έλ ₯νλ€.
μμ±μ ν¨μκ° new μ°μ°μ μμ΄ νΈμΆλλ κ²μ λ°©μ§νκΈ° μν΄ νμ€μΉΌ μΌμ΄μ€ 컨벀μ
μ μ¬μ©νλ€ νλλΌλ μ€μλ μΈμ λ λ°μν μ μλ€. μ΄λ¬ν μνμ±μ ννΌνκΈ° μν΄ ES6μμλ new.target
μ μ§μνλ€.
function Circle(radius){
// λ°©μ΄μ½λ(μ¬κ· νΈμΆμ ν΅ν΄ μμ±μ ν¨μλ‘μ νΈμΆ)
if(!new.target){
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());
new.targetμ μ¬μ©ν μ μλ μν©μ μ¬μ©νλ€.
function Circle(radius){
if(!(this instancef Circle)){
return new Circle(radius);
}
...
}
μ΄ ν¨μκ° new μ°μ°μμ ν¨κ² νΈμΆλμ§ μμλ€λ©΄ thisλ μ μ κ°μ²΄ windowλ₯Ό κ°λ¦¬ν€κ³ thisμ Circleμ νλ‘ν νμ μ μν΄ μ°κ²°λμ§ μλλ€. λ°λΌμ instanceof μ°μ°μλ₯Ό μ΄μ©ν΄μ νλ³ νμ new μ°μ°μμ ν¨κ» νΈμΆνμ¬ μμ±λ μΈμ€ν΄μ€λ₯Ό λ°νν΄μΌ νλ€.
instanceof μ°μ°μ
λΉνΈμΈ μμ±μ ν¨μ(Object.String, Number, Boolean, Function, array, Date, RegExp, Promise λ±)λ new μ°μ°μμ ν¨κ» νΈμΆλμλμ§λ₯Ό νμΈν ν μ μ ν κ°μ λ°ννλ€.
μλ₯Ό λ€μ΄ Objectμ Function μμ±μ ν¨μλ new μ°μ°μ μμ΄ νΈμΆν΄λ 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
μ΄λ²κ³Όμ μμ μ¬μ©λ¬λ
new.target
μ΄ 17μ₯μ λμμκ΅°μ