this μ this binding
π this
μμ μ΄ μν κ°μ²΄ λλ μμ μ΄ μμ±ν μΈμ€ν΄μ€λ₯Ό κ°λ¦¬ν€λ μκΈ° μ°Έμ‘° λ³μ self-referencing-variable μ΄λ€.
this λ₯Ό ν΅ν΄ μμ μ΄ μν κ°μ²΄ λλ μμ μ΄ μμ±ν μΈμ€ν΄μ€μ property λ method λ₯Ό μ°Έμ‘°ν μ μλ€.
λ¨, this κ° κ°λ¦¬ν€λ κ° (this λ°μΈλ©) μ ν¨μ νΈμΆ λ°©μμ μν΄ λμ μΌλ‘ κ²°μ λλ€.
1. μΌλ° ν¨μ νΈμΆ
2. λ©μλ νΈμΆ
3. μμ±μ ν¨μ νΈμΆ
4. Function.prototype.apply/call/bind λ©μλμ μν (κ°μ ) νΈμΆ
π μΌλ° ν¨μ νΈμΆ
κΈ°λ³Έμ μΌλ‘ this μλ μ μ κ°μ²΄(global object)κ° λ°μΈλ©λλ€.
(μ΄λ ν ν¨μ[μ€μ²© ν¨μ, μ½λ°± ν¨μ ν¬ν¨]λΌλ μΌλ° ν¨μλ‘ νΈμΆλλ©΄ this μ μ μ κ°μ²΄κ° λ°μΈλ©λλ€.)
strict mode κ° μ μ©λλ©΄, this μλ undefined κ° λ°μΈλ©λλ€.
console.log(this) // μ μ κ°μ²΄ window
function foo(){
console.log("foo's this: ", this); // window
function bar(){
console.log("bar's this: ", this); // window
}
bar();
}
foo();
> this μ λͺ©μ μμ²΄κ° κ°μ²΄μ νλ‘νΌν°λ λ©μλλ₯Ό μν μκΈ° μ°Έμ‘° λ³μμ΄κΈ° λλ¬Έμ΄λ€.
μΌλ°μ μΌλ‘λ κ°μ²΄μ λ©μλ λ΄λΆ λλ μμ±μ ν¨μ λ΄λΆμμλ§ μλ―Έκ° μκΈ°μ strict mode μμλ μ μ©λμ§ μλλ€ !-!
π μ€μ²© ν¨μ, μΌλ° ν¨μλ‘ νΈμΆνκΈ°
var value = 1;
// var ν€μλλ‘ μ μΈν μ μ λ³μ valueλ μ μ κ°μ²΄μ νλ‘νΌν°μ΄λ€.
// const ν€μλλ‘ μ μΈν μ μ λ³μ valueλ μ μ κ°μ²΄μ νλ‘νΌν°κ° μλλ€.
// const value = 1;
const obj = {
value: 100,
foo(){
console.log("foo's this: ", this); // {value: 100, foo: β¨}
console.log("foo's this.value: ". this.value); // 100
// λ©μλ λ΄μμ μ μν μ€μ²© ν¨μ
function bar(){
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
// λ©μλ λ΄μμ μ μν μ€μ²© ν¨μλ μΌλ° ν¨μλ‘ νΈμΆνλ©΄ λ΄λΆμ this μλ μ μ κ°μ²΄κ° λ°μΈλ©λλ€.
bar();
}
};
obj.foo();
π μ½λ°± ν¨μ, μΌλ° ν¨μλ‘ νΈμΆνκΈ°
var value = 1;
const obj = {
value: 100,
foo(){
console.log("foo's this: ", this); // {value: 100, foo: β¨}
// μ½λ°± ν¨μ λ΄λΆμ this μλ μ μ κ°μ²΄κ° λ°μΈλ©λλ€.
setTimeout(function(){
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}. 100);
}
};
obj.foo();
> κ·Έλ μ§λ§ μΈλΆ ν¨μμΈ λ©μλμ μ€μ²© ν¨μ/μ½λ°± ν¨μμ this κ° μΌμΉνμ§ μλλ€λ κ²μ
μ€μ²© ν¨μ/μ½λ°± ν¨μκ° ν¬νΌ ν¨μλ‘ λμνκΈ° μ΄λ ΅κ² λ§λ λ€.
> κ·Έλμ λ©μλ λ΄λΆμ μ€μ²© ν¨μ/μ½λ°± ν¨μμ this λ°μΈλ©κ³Ό λ©μλμ this λ°μΈλ©μ μΌμΉμν€λ λ°©λ²μ΄ μ‘΄μ¬νλ€.
• 1. λ³μ ν λΉ
var value = 1;
const obj = {
value: 100,
foo(){
// this λ°μΈλ©(obj)μ λ³μ that μ ν λΉ
const that = this;
// μ½λ°± ν¨μ λ΄λΆμμ this λμ that μ μ°Έμ‘°
setTimeout(function(){
console.log(that.value); // 100
}, 100);
}
};
obj.foo();
• 2. apply, call, bind λ©μλ μ¬μ©ν΄ μ§μ λ°μΈλ©
var value = 1;
const obj = {
value: 100,
foo(){
// μ½λ°± ν¨μμ λͺ
μμ μΌλ‘ thisλ₯Ό λ°μΈλ©νλ€.
setTimeout(function(){
console.log(this.value); // 100
}.bind(this),100);
}
};
obj.foo();
• 3. νμ΄ν ν¨μ μ¬μ©
var value = 1;
const obj = {
value: 100,
foo(){
// νμ΄ν ν¨μ λ΄λΆμ thisλ μμ μ€μ½νμ thisλ₯Ό κ°λ¦¬ν¨λ€ ββ
setTimeout(() => console.log(this.value), 100); // 100
}
};
obj.foo();
π λ©μλ νΈμΆ
λ©μλ λ΄λΆμ this μλ λ©μλλ₯Ό νΈμΆν κ°μ²΄κ° λ°μΈλ©λλ€.
β» λ©μλ λ΄λΆμ this λ λ©μλλ₯Ό μμ ν κ°μ²΄κ° μλβ λ©μλλ₯Ό νΈμΆν κ°μ²΄μ λ°μΈλ©λλ€.
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
};
const me = new Person('Lee');
// getName λ©μλλ₯Ό νΈμΆν κ°μ²΄λ meλ€.
console.log(me.getName()); // Lee
Person.prototype.name = 'Kim';
// getName λ©μλλ₯Ό νΈμΆν κ°μ²΄λ Person.prototypeμ΄λ€.
console.log(Person.prototype.getName()); // Kim
// λΈλΌμ°μ νκ²½μμ window.name μ λΈλΌμ°μ μ°½μ μ΄λ¦μ λνλ΄λ λΉνΈμΈ νλ‘νΌν°μ΄κ³ , κΈ°λ³Έκ°μ ''μ΄λ€.
// Node.js νκ²½μμ window.name μ undefined μ΄λ€.
π μμ±μ ν¨μ νΈμΆ
function Circle(){
// μμ±μ ν¨μ λ΄λΆμ this λ μμ±μ ν¨μκ° μμ±ν μΈμ€ν΄μ€λ₯Ό κ°λ¦¬ν¨λ€.
this.radius = radius;
this.getDiameter = function(){
return 2 * this.radius;
};
}
// λ°μ§λ¦μ΄ 5μΈ Circle κ°μ²΄λ₯Ό μμ±
const circle_5 = new Circle(5);
// λ°μ§λ¦μ΄ 10μΈ Circle κ°μ²΄λ₯Ό μμ±
const circle_10 = new Circle(10);
console.log(circle_5.getDiameter());
console.log(circle_10.getDiameter());
π Function.prototype.apply/call/bind λ©μλμ μν (κ°μ ) νΈμΆ
apply, call, bind λ©μλλ Function.prototype μ λ©μλμ΄λ€.
apply, call λ©μλλ ν¨μλ₯Ό νΈμΆνλ©΄μ 첫 λ²μ§Έ μΈμλ‘ μ λ¬ν νΉμ κ°μ²΄λ₯Ό νΈμΆν ν¨μμ this μ λ°μΈλ©νλ€.
bind λ©μλλ ν¨μλ₯Ό νΈμΆνμ§ μκ³ this λ‘ μ¬μ©ν κ°μ²΄λ§ μ λ¬νλ€.
(κ·Έλμ bind λ©μλλ‘ apply, call λ©μλμ κ°μ ν¨κ³Όλ₯Ό λ΄λ €λ©΄ λͺ μμ μΌλ‘ νΈμΆν΄μ€μΌνλ€.)
function getThisBinding(){
console.log(arguments);
return this;
}
const thisArg = {a: 1}; // thisλ‘ μ¬μ©ν κ°μ²΄
// apply λ©μλλ νΈμΆν ν¨μμ μΈμλ₯Ό λ°°μ΄λ‘ λ¬Άμ΄ μ λ¬νλ€.(λ°°μ΄ λλ μ μ¬ λ°°μ΄ κ°μ²΄)
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: β¨, Symbol(Symbol.iterator): β¨]
// {a: 1}
// call λ©μλλ νΈμΆν ν¨μμ μΈμλ₯Ό μΌνλ‘ κ΅¬λΆν 리μ€νΈ νμμΌλ‘ μ λ¬νλ€.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: β¨, Symbol(Symbol.iterator): β¨]
// {a: 1}
function getThisBinding(){
return this;
}
// this λ‘ μ¬μ©ν κ°μ²΄
const thisArg = {a: 1};
// bind λ©μλλ ν¨μμ thisλ‘ μ¬μ©ν κ°μ²΄λ₯Ό μ λ¬νλ€.
// bind λ©μλλ ν¨μλ₯Ό νΈμΆνμ§λ μλλ€. κ·Έλμ λͺ
μμ μΌλ‘ νΈμΆν΄μ€μΌνλ€ !
console.log(getThisBinding.bind(thisArg)); // getThisBinding
console.log(getThisBinding.bind(thisArg)()); // {a: 1}
πLexical Scope μ this λ°μΈλ©
Lexical Scope λ ν¨μ μ μκ° νκ°λμ΄ ν¨μ κ°μ²΄κ° μμ±λλ μμ μ μμ μ€μ½νλ₯Ό κ²°μ νλ€.
this λ°μΈλ©μ ν¨μ νΈμΆ μμ μ κ²°μ λλ€.
π μ 리
ν¨μ νΈμΆ λ°©μ | this λ°μΈλ© |
μΌλ° ν¨μ νΈμΆ | μ μ κ°μ²΄ |
λ©μλ νΈμΆ | λ©μλλ₯Ό νΈμΆν κ°μ²΄ |
μμ±μ ν¨μ νΈμΆ | μμ±μ ν¨μκ° λ―Έλμ μμ±ν μΈμ€ν΄μ€ |
Function.prototype.apply/call/bind λ©μλμ μν κ°μ νΈμΆ | Function.prototype.apply/call/bind λ©μλμ 첫 λ²μ§Έ μΈμλ‘ μ λ¬ν κ°μ²΄ |
• μ°Έκ³ μλ£
λͺ¨λ μλ°μ€ν¬λ¦½νΈ DEEP DIVE - μ΄μ λͺ¨