Understanding the "this" keyword, call, apply, and bind in JavaScript - Lee-hyuna/33-js-concepts-kr GitHub Wiki
μ΄κ±΄ μ°λ¦¬ κ³ κΈ μλ°μ€ν¬λ¦½νΈ μ½μ€μ μΌλΆμ λλ€. μ΄ κ²μλ¬Όμ΄ λ§μμ λ€λ©΄ νμΈλ³΄μΈμ.
μλ°μ€ν¬λ¦½νΈμ κ°μ₯ μ€ν΄ λ λΆλΆ μ€ νλλ this ν€μλμ λλ€. μ΄ κΈμμλ this ν€μλκ° μ°Έμ‘°νκ³ μλ κ²μ μμλ΄λ λ€μ― κ°μ§ κ·μΉμ λ°°μλλ€. Implicit Binding, Explicit Binding, new binding, window binding, Lexical Binding. μ΄ κΈ°μ μ λ€λ£¨λ λ°μμ΄ .call, .apply, .bind λ° new ν€μλμ κ°μ μλ°μ€ν¬λ¦½νΈμ λ€λ₯Έ λΆλΆλ λ°°μ°κ²λ©λλ€.
<iframe width="864" height="486" src="https://www.youtube.com/embed/zE9iro4r918" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>μλ°μ€ν¬λ¦½νΈμμ `this`ν€μλμ μΈλΆμ¬νμ μ΄ν΄λ³΄κΈ° μ μ ν κ±Έμ λ¬Όλ¬μμ `this`ν€μλκ° μ μ‘΄μ¬νλμ§ λ¨Όμ μ΄ν΄λ³΄λ κ²μ΄ μ€μν©λλ€. `this`ν€μλλ μλ‘ λ€λ₯Έ 컨ν μ€νΈλ‘ ν¨μλ₯Ό μ¬μ¬μ© ν μ μμ΅λλ€. λ€λ₯΄κ² λ§νλ©΄, `this`ν€μλλ ν¨μ λ λ©μλλ₯Ό νΈμΆν λ μ΄λ€ κ°μ²΄κ° μ΄μ μ΄ λμ΄μΌνλμ§ κ²°μ ν μ μμ΅λλ€. μ΄ ν μ°λ¦¬κ° μ΄μΌκΈ°νλ λͺ¨λ κ²μ κ·Έ μμ΄λμ΄λ₯Ό λ°νμΌλ‘ λ§λ€μ΄μ§ κ²μ λλ€. μ°λ¦¬λ λ€λ₯Έ 컨ν μ€νΈ λλ λ€λ₯Έ κ°μ²΄μμ ν¨μ λ λ©μλλ₯Ό μ¬μ¬μ© ν μ μκΈ°λ₯Ό μν©λλ€.
κ°μ₯ λ¨Όμ μ΄ν΄λ³Ό κ²μ this
ν€μλκ° λ¬΄μμ μ°Έμ‘°νλμ§ μλ €μ£Όλ κ²μ
λλ€.
μ΄ μ§λ¬Έμ λ΅νλ €κ³ ν λ μμ μκ² κ°μ₯ λ¨Όμ λ¬»κ³ μΆμ μ€μν μ§λ¬Έμ βμ΄ ν¨μλ μ΄λμ νΈμΆλ©λκΉ?β μ
λλ€.
this
ν€μλκ° μ°Έμ‘°νλ κ²μ μ μ μλ μ μΌν λ°©λ²μ this
ν€μλλ₯Ό μ¬μ©νλ ν¨μκ° νΈμΆ λ κ³³μ μ°Ύλ κ²μ
λλ€.
μ΄λ―Έ μ΅μν μλ‘ μ΄κ²μ μ¦λͺ
νκΈ° μν΄, μ°λ¦¬κ° νμνλ λ©μμ§λ₯Ό μ리λ μ΄λ¦μ κ°μ§ greet
ν¨μλ₯Ό κ°μ§κ³ μλ€κ³ ν©μλ€.
function greet (name) {
alert(`Hello, my name is ${name}`)
}
greet
κ° λ¬΄μμ κ²½κ³ ν κ²μΈμ§ μ ννκ² λ¬»λλ€λ©΄, λΉμ μ λλ΅μ 무μμ
λκΉ?
ν¨μ μ μλ§ μ£Όμ΄μ§λ€λ©΄ μ μ μμ΅λλ€. name
μ΄ λ¬΄μμΈμ§ μμ λ³΄λ €λ©΄ greet
μ ν¨μ νΈμΆμ μ΄ν΄ λ΄μΌν©λλ€.
greet('Tyler')
this
ν€μλκ° λ¬΄μμ μ°Έμ‘°νκ³ μλμ§ μμλ΄λ κ²λ μ νν κ°μ μκ°μ
λλ€.
this
ν€μλλ ν¨μμ λν μΌλ°μ μΈ μΈμμ²λΌ μκ°ν μλ μμ΅λλ€. ν¨μκ° νΈμΆλλ λ°©μμ λ°λΌ λ³κ²½ λ κ²μ
λλ€.
μ΄μ this
ν€μλκ° μ°Έμ‘°νλ κ²μ΄ 무μμΈμ§ μμλ΄λ 첫 λ²μ§Έ λ¨κ³λ ν¨μκ° νΈμΆλλ μμΉλ₯Ό νμΈνλ κ²μ
λλ€.
λ€μ λ¨κ³λ 무μμ
λκΉ? λ€μ λ¨κ³μμ μ°λ¦¬λ₯Ό λκΈ° μν΄ 5κ°μ§ κ·μΉμ΄λ μ§μΉ¨μ μ ν κ²μ
λλ€.
- Implicit Binding
- Explicit Binding
- new Binding
- Lexical Binding
- window Binding
μ¬κΈ°μ λͺ©νλ this
ν€μλλ₯Ό μ¬μ©νμ¬ ν¨μ μ μλ₯Ό λ³΄κ³ this
λ₯Ό μ°Έμ‘°νλ κ²μ λ§ν μ μλ κ²μ
λλ€.
μ΄λ₯Ό μν 첫 λ²μ§Έμ΄μ κ°μ₯ μΌλ°μ μΈ κ·μΉμ Implicit Binding
μ΄λΌκ³ λΆλ¦½λλ€.
this
ν€μλκ° μ½ 80%λ₯Ό μ°Έμ‘°νλ κ²μ΄ 무μμΈμ§ λ§ν΄ μ€ κ²μ΄λΌκ³ λλ λ§νκ³ μΆμ΅λλ€.
μ΄λ κ² μκΈ΄ κ°μ²΄κ° μλ€κ³ ν΄λ΄ μλ€.
const user = {
name: 'Tyler',
age: 27,
greet() {
alert(`Hello, my name is ${this.name}`)
}
}
μ΄μ user
κ°μ²΄μ greet
λ©μλλ₯Ό νΈμΆνλ €λ©΄ λνΈ νκΈ°λ²μ μ¬μ©ν΄μΌν©λλ€.
user.greet()
μ΄κ²μ μ°λ¦¬λ₯Ό 'μμ μ λ°μΈλ©'κ·μΉμ μ£Ό μμ μΌλ‘ μΈλν©λλ€.
this
ν€μλκ° μ°Έμ‘°νκ³ μλ κ²μ νμ
νλ €λ©΄ λ¨Όμ ν¨μκ° νΈμΆ λ λ μ μ μΌμͺ½μ 보μμμ€. "μ "μ΄μλ κ²½μ° ν΄λΉ μ μ μΌμͺ½μλ³΄κ³ this
ν€μλκ° μ°Έμ‘°νλ κ°μ²΄λ₯Ό μ°Ύμ΅λλ€.
μμ μμμ user
λ 'μ 'μ μΌμͺ½μΌλ‘, this
ν€μλκ° user
κ°μ²΄λ₯Ό μ°Έμ‘°νκ³ μμμ μλ―Έν©λλ€. λ°λΌμ greet
λ©μλμμ μλ°μ€ν¬λ¦½νΈ μΈν°ν리ν°κ° this
λ₯Ό user
λ‘ λ³κ²½νλ κ²μ²λΌ 보μ
λλ€.
greet() {
// alert(`Hello, my name is ${this.name}`)
alert(`Hello, my name is ${user.name}`) // Tyler
}
λΉμ·νμ§λ§ μ’ λ κ³ κΈ μλ₯Ό μ΄ν΄ λ³΄κ² μ΅λλ€.
μ΄μ name
,age
,greet property
λμ μ user
κ°μ²΄μname
κ³Όgreet property
λ₯Ό κ°μ§mother property
μ λΆμ¬νκ² μ΅λλ€.
const user = {
name: 'Tyler',
age: 27,
greet() {
alert(`Hello, my name is ${this.name}`)
},
mother: {
name: 'Stacey',
greet() {
alert(`Hello, my name is ${this.name}`)
}
}
}
μ΄μ μ§λ¬Έμ λ€μκ³Ό κ°μ΅λλ€. μλμ μλ κ°κ°μ νΈμΆμ 무μμ κ²½κ³ ν κ²μΈκ°?
user.greet()
user.mother.greet()
this
ν€μλκ° μ°Έμ‘°νλ κ²μ μμ λ΄λ €κ³ ν λλ§λ€ νΈμΆμλ³΄κ³ "μ μ μΌμͺ½"μ 무μμ΄ μλμ§ μμμΌν©λλ€. 첫 λ²μ§Έ νΈμΆμμ user
λ μ μ μΌμͺ½μ μμΌλ©° this
λ user
λ₯Ό μ°Έμ‘° ν κ²μμ μλ―Έν©λλ€.
λ λ²μ§Έ νΈμΆμμ mother
λ μ μ μΌμͺ½μμλ κ²μ΄κ³ this
λ mother
λ₯Ό λνλΌ κ²μμ μλ―Έν©λλ€.
user.greet() // Tyler
user.mother.greet() // Stacey
μμμ μΈκΈνλ―μ΄, μ½ 80%λ "μ μ μΌμͺ½"μ λμμ΄μμ κ²μ
λλ€. κ·Έλμ this
ν€μλκ° μ°Έμ‘°νκ³ μλ κ²μ μμλΌ λ 첫 λ²μ§Έ λ¨κ³λ "μ μ μΌμͺ½μ 보λ κ²"μ
λλ€. κ·Έλ¬λ, μ μ΄ μλ€λ©΄ μ΄λ¨κΉμ? μ΄κ²μ μ°λ¦¬λ₯Ό λ€μ κ·μΉμΌλ‘ μΈλν©λλ€.
μ,greet
ν¨μ λμ μ user
κ°μ²΄μ λν λ©μλκ° μλ€λ©΄ κ·Έκ²μ λ¨μ§ λ
μμ μΈ λ
립 ν¨μ μμ κ²μ
λλ€.
function greet () {
alert(`Hello, my name is ${this.name}`)
}
const user = {
name: 'Tyler',
age: 27,
}
μ°λ¦¬λthis
ν€μλκ° λ¬΄μμ κ°λ¦¬ν€κ³ μλμ§ μκΈ° μν΄ λ¨Όμ ν¨μκ° μ΄λμμ νΈμΆλλμ§ μ΄ν΄ λ΄μΌν©λλ€. μ΄μ , greet
λ₯Ό μ΄λ»κ² νΈμΆ ν μ μμ΅λκΉ? user
κ°μ²΄λ₯Ό μ°Έμ‘°νλ this
ν€μλλ‘ μ΄λ»κ² νΈμΆ ν μ μμ΅λκΉ? user
λ greet
λ©μλλ₯Ό κ°μ§κ³ μμ§ μκΈ° λλ¬Έμ μ΄μ μ²λΌ user.greet()
λ₯Ό ν μ μμ΅λλ€. μλ°μ€ν¬λ¦½νΈμμ λͺ¨λ ν¨μλ μ¬λ¬λΆμ΄ μ ννκ² μ΄κ²μ ν μμκ² ν΄μ£Όλ λ©μλλ₯Ό ν¬ν¨νκ³ μμΌλ©° κ·Έ λ©μλμ μ΄λ¦μ call
μ
λλ€.
"call"μ νΈμΆ λ 컨ν
μ€νΈλ₯Ό μ§μ νλ ν¨μλ₯Ό νΈμΆ ν μμκ² νλ λͺ¨λ ν¨μμ λ©μλμ
λλ€.
μ΄λ₯Ό μΌλν΄ λκ³ λ€μ μ½λλ₯Ό μ¬μ©νμ¬ user
컨ν
μ€νΈμμ greet
μ νΈμΆ ν μ μμ΅λλ€.
greet.call(user)
λ€μ λ§νμ§λ§,call
μ λͺ¨λ ν¨μμ μμ±μ΄κ³ , λΉμ μ΄ μ λ¬νλ 첫 λ²μ§Έ μΈμλ ν¨μκ° νΈμΆλλ 컨ν
μ€νΈ (λλ μ΄μ κ°μ²΄)κ° λ κ²μ
λλ€. μ¦, νΈμΆνκΈ° μν΄ μ λ¬νλ 첫 λ²μ§Έ μΈμλ ν΄λΉ ν¨μ λ΄λΆμ this
ν€μλκ° μ°Έμ‘°νλ κ²μ
λλ€.
μ°λ¦¬κ° λͺ
μ μ μΌλ‘ (.call
μ μ¬μ©νκ³ μκΈ° λλ¬Έμ) this
ν€μλκ° μ°Έμ‘°νκ³ μλ κ²μ μ§μ νκΈ° λλ¬Έμ μ΄κ²μ΄ κ·μΉ #2 (Explicit Binding)μ κΈ°μ΄μ
λλ€.
μ΄μ , βgreetβ functionμ μ‘°κΈ μμ ν΄λ΄ μλ€. λ§μ½ μ°λ¦¬κ° λͺ κ°μ κ°μ²΄λ₯Ό μ λ¬νλ€κ³ κ°μ ν΄λ³Έλ€λ©΄ μ΄λ»κ² λ κΉμ? κ·Έλ€μ μ΄λ¦μ κ°μ§κ³ , μ°λ¦¬λ λν κ·Έλ€μ΄ μλ μΈμ΄λ‘ μλ €μ£ΌκΈ°λ₯Ό μνμ΅λλ€ μλμ κ°μ΄ λ§μ λλ€.
function greet (l1, l2, l3) {
alert(
`Hello, my name is ${this.name} and I know ${l1}, ${l2}, and ${l3}`
)
}
μ΄μ .call
μ μ¬μ©νμ¬ νΈμΆλλ ν¨μμ μΈμλ₯Ό μ λ¬νκΈ° μν΄ μ²« λ²μ§Έ μΈμλ₯Ό λ¬Έλ§₯μΌλ‘ μ§μ ν νμ νλμ© μ λ¬ν©λλ€.
function greet (l1, l2, l3) {
alert(
`Hello, my name is ${this.name} and I know ${l1}, ${l2}, and ${l3}`
)
}
const user = {
name: 'Tyler',
age: 27,
}
const languages = ['JavaScript', 'Ruby', 'Python']
greet.call(user, languages[0], languages[1], languages[2])
μ΄κ²μ ν¨κ³Όκ° μμΌλ©° .call
μ μ¬μ©νμ¬ νΈμΆλλ ν¨μμ μΈμλ₯Ό μ λ¬νλ λ°©λ²μ 보μ¬μ€λλ€. κ·Έλ¬λ μ¬λ¬λΆμ΄ λμΉμ±μμ§ λͺ¨λ₯΄κ² μ§λ§, μ°λ¦¬μ languages
λ°°μ΄μμ νλμ© μΈμλ₯Ό μ λ¬ν΄μΌνλ κ²μ μ§μ¦λλ μΌμ
λλ€. μ 체 λ°°μ΄μ λ λ²μ§Έ μΈμλ‘ μ λ¬ν μ μμΌλ©΄ μλ°μ€ν¬λ¦½νΈκ° μ΄λ₯Ό νμ°μν¬ μ μλ€λ©΄ μ’μ κ²μ
λλ€. μ°λ¦¬μκ² μ’μ μμμ
λλ€. μ΄κ²μ μ νν .apply
κ° νλ κ²μ
λλ€. .apply
λ .call
κ³Ό μμ ν λκ°μ§λ§ μΈμ νλ νλλ₯Ό μ λ¬νλ λμ μ νλμ λ°°μ΄μ μ λ¬ν μ μμΌλ©° λ°°μ΄μ κ° μμλ₯Ό ν¨μμ μΈμλ‘ μ λ¬ν©λλ€.
κ·Έλμ μ΄μ λ .apply
λ₯Ό μ¬μ©νλ©΄, μ°λ¦¬μ μ½λλ λ€λ₯Έ κ²λ€μ΄ κ·Έλλ‘ μ μ§λλ©΄μ (μλ)μ½λλ‘ λ°λ μ μμ΅λλ€.
const languages = ['JavaScript', 'Ruby', 'Python']
// greet.call(user, languages[0], languages[1], languages[2])
greet.apply(user, languages)
μ§κΈκΉμ§ "Explicit Binding"κ·μΉμ λ°λΌ .call
κ³Ό .apply
μ λν΄ λ°°μ μ΅λλ€. λ λ€ ν¨μ νΈμΆμ νμ©νκ³ , this
ν€μλκ° κ·Έ λ΄λΆμμ μ°Έμ‘° ν κ²μμ μ§μ ν©λλ€. μ΄ κ·μΉμ λ§μ§λ§ λΆλΆμ.bind
μ
λλ€. .bind
λ .call
κ³Ό λκ°μ§ λ§ μ¦μ ν¨μλ₯Ό νΈμΆνλ λμ λμ€μ νΈμΆ ν μμλ μλ‘μ΄ ν¨μλ₯Ό λ°νν©λλ€. κ·Έλμ μ΄μ μ½λμ .bind
λ₯Ό μ¬μ©νμ¬ μ½λλ₯Ό μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ λ³΄μΌ κ²μ
λλ€.
function greet (l1, l2, l3) {
alert(
`Hello, my name is ${this.name} and I know ${l1}, ${l2}, and ${l3}`
)
}
const user = {
name: 'Tyler',
age: 27,
}
const languages = ['JavaScript', 'Ruby', 'Python']
const newFn = greet.bind(user, languages[0], languages[1], languages[2])
newFn() // alerts "Hello, my name is Tyler and I know JavaScript, Ruby, and Python"
this
ν€μλκ° μ°Έμ‘°νκ³ μλ κ²μ μμλ΄λ μΈ λ²μ§Έ κ·μΉμ new Binding
μ
λλ€. λ§μ½ new
ν€μλμ ν¨κ» ν¨μ νΈμΆμ ν λλ§λ€ λΉμ μ΄ μλ°μ€ν¬λ¦½νΈμ new
ν€μλμ μ΅μνμ§ μλ€λ©΄, μλ°μ€ν¬λ¦½νΈ μΈν°ν리ν°λ λΉμ μ μν this
λΌ λΆλ¦¬λ μλ‘μ΄ κ°μ²΄λ₯Ό μμ±ν κ²μ
λλ€.
κ·Έλ¬λ―λ‘ μμ°μ€λ½κ², new
μ ν¨κ» ν¨μκ° νΈμΆλλ€λ©΄, μ΄ this
ν€μλλ μΈν°ν리ν°κ° λ§λ μλ‘μ΄ κ°μ²΄λ₯Ό μ°Έμ‘°ν©λλ€.
function User (name, age) {
/*
Under the hood, JavaScript creates a new object called `this`
which delegates to the User's prototype on failed lookups. If a
function is called with the new keyword, then it's this new object
that interpretor created that the this keyword is referencing.
*/
this.name = name
this.age = age
}
const me = new User('Tyler', 27)
μ΄ μμ μμ μ°λ¦¬λ 4λ²μ§Έ κ·μΉμ λ°λ₯΄κ³ μμΌλ©° μ½κ° μλ λΉν μλ μμ΅λλ€. 그건 곡νν©λλ€. μλ°μ€ν¬λ¦½νΈμ this
ν€μλλ νλ¦Όμμ΄ λ λ³΅μ‘ ν κ²μ
λλ€. μ’μ μμμ λ€μ κ·μΉμ΄ κ°μ₯ μ§κ΄μ μΈ κ²μ
λλ€.
λΉμ μ΄ μ μ λ€μ΄λ³Έ μ μ΄ μκ³ arrow functionμ μ¬μ©νμ κ°λ₯μ±μ΄ μλ€. ES6μ μλ‘μ΄ κ²μ λλ€. μ΄ ν¨μλ λΉμ μ΄ λ κ°κ²°ν νμμΌλ‘ ν¨μλ₯Ό μμ±ν μ μμ΅λλ€.
friends.map((friend) => friend.name)
κ°κ²°ν¨λ³΄λ€ arrow functionλ this
ν€μλμ κ΄ν΄μ ν¨μ¬ λ μ§κ΄μ μΈ μ κ·Όλ²μ κ°μ§κ³ μλ€. arrow functionμ μΌλ° ν¨μμ λ¬λ¦¬ this
κ° μμ΅λλ€. λμ this
λ lexically
λ‘ κ²°μ λ©λλ€.
μ΄λ μ μμ μΈ λ³μ μ‘°ν κ·μΉμ λ°λΌ μ΄λ»κ² μμν μ§ κ²°μ λλ λ©μ§ λ°©μμ
λλ€. μμ μ¬μ©νλ μμλ₯Ό κ³μν΄λ΄
μλ€. μ΄μ , language
μgreet
μ κ°μ²΄μ λΆλ¦¬νμ¬ μ¬μ©νμ§ μκ³ κ²°ν©ν΄ λ΄
μλ€.
const user = {
name: 'Tyler',
age: 27,
languages: ['JavaScript', 'Ruby', 'Python'],
greet() {}
}
μμμ μ°λ¦¬λ languages
λ°°μ΄μ κΈΈμ΄κ° νμ 3μ΄λΌκ³ κ°μ νμ΅λλ€. κ·Έλ κ²ν¨μΌλ‘μ¨, μ°λ¦¬λl1
,l2
,l3
κ³Ό κ°μ νλμ½λλ λ³μλ₯Ό μ¬μ©ν μ μμμ΅λλ€. greet
λ₯Ό μ‘°κΈ λ νλͺ
νκ² λ§λ€κ³ languages
κ° μ΄λ€ κΈΈμ΄λΌλ λ μ μλ€κ³ κ°μ ν©μλ€. μ΄λ κ²νκΈ° μν΄ μ°λ¦¬λ λ¬Έμμ΄μ λ§λ€κΈ° μν΄ .reduce
λ₯Ό μ¬μ©ν κ²μ
λλ€.
const user = {
name: 'Tyler',
age: 27,
languages: ['JavaScript', 'Ruby', 'Python'],
greet(){
const hello = `Hello, my name is ${this.name} and I know`
const langs = this.languages.reduce(function(str, lang, i){
if (i === this.languages.length - 1) {
return `${str} and ${lang}.`
}
return `${str} ${lang},`
}, '')
alert(hello + langs)
}
}
ν¨μ¬ λ λ§μ μ½λμ§λ§ μ΅μ’
κ²°κ³Όλ κ°μμΌ ν©λλ€.
μ°λ¦¬κ°user.greet()
λ₯Ό νΈμΆ ν λ Hello, my name is Tyler and I know JavaScript, Ruby, and Python..
λΌκ³ κΈ°λν κ²μ
λλ€. μ¬νκ²λ μ€λ₯κ° μμ΅λλ€. κ·Έκ²μ λ°κ²¬ ν μ μμ΅λκΉ?
μμ μ½λλ₯Ό μ‘κ³ μ½μμμ μ€ννμμμ€. Uncaught TypeError: Cannot read property 'length' of undefined
μ€λ₯κ° λ°μνλ κ²μ μ μ μμ΅λλ€. .length
λ₯Ό μ¬μ©νλ μ μΌν κ³³μ 9λ²μ€μ μμΌλ―λ‘ μ°λ¦¬λ μ°λ¦¬μ μ€λ₯κ° μλ€λ κ²μ μλλ€.
if (i === this.languages.length - 1) {}
μ°λ¦¬μ μλͺ»μ λ°λ₯΄λ©΄,this.langauges
λ μ μλμ§ μμμ΅λλ€. this
ν€μλκ° μ°Έμ‘°νλκ² λ¬΄μμΈμ§ λΆλͺ
ν λ°ν λ΄κΈ° μν΄ user
λ₯Ό μ°Έμ‘°νμ§ μλ λ¨κ³λ₯Ό μ°Ύμ λ³΄κ² μ΅λλ€. λ¨Όμ ν¨μκ° νΈμΆλλ μμΉλ₯Ό μ΄ν΄λ³Ό νμκ° μμ΅λλ€. ν¨μκ° νΈμΆλλ μμΉλ μ΄λμ
λκΉ? μ΄ ν¨μλ.reduce
μ μ λ¬λμ΄μ μ°λ¦¬λ μ ν λͺ¨λ¦
λλ€. μλ°μ€ν¬λ¦½νΈλ .reduce
ꡬνμμ κ·Έ μμ²΄λ‘ λμνκΈ° λλ¬Έμ μ°λ¦¬λ μ΅λͺ
μ ν¨μ νΈμΆμ μ€μ λ‘ λ³΄μ§ λͺ»ν©λλ€. κ·Έκ² λ¬Έμ μ
λλ€. μ°λ¦¬λ.reduce
μ μ λ¬ λ μ΅λͺ
μ ν¨μκ° user
컨ν
μ€νΈμμ νΈμΆλλλ‘ μ§μ ν΄μΌν©λλ€. κ·Έλ κ²νλ©΄ this.languages
λ user.languages
λ₯Ό μ°Έμ‘° ν κ²μ
λλ€. μμμ λ°°μ΄ κ²μ²λΌ .bind
λ₯Ό μ¬μ©ν μ μμ΅λλ€.
const user = {
name: 'Tyler',
age: 27,
languages: ['JavaScript', 'Ruby', 'Python'],
greet() {
const hello = `Hello, my name is ${this.name} and I know`
const langs = this.languages.reduce(function (str, lang, i) {
if (i === this.languages.length - 1) {
return `${str} and ${lang}.`
}
return `${str} ${lang},`
}.bind(this), "")
alert(hello + langs)
}
}
κ·Έλμ μ°λ¦¬λ .bind
κ° μ΄λ»κ² μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλμ§λ₯Ό 보μμΌλ©°, μ΄κ²μ΄ arrow functionμ μ΄λ€ κ΄λ ¨μ΄ μλμ§λ₯Ό 보μμ΅λλ€. μμ arrow functionλ‘ "this
κ° lexically
λ‘ κ²°μ λμμ΅λλ€. μ΄κ²μ μ μμ μΈ λ³μ μ‘°ν κ·μΉμ λ°λΌ this
κ° μ΄λ»κ² κΈ°λλλμ§ κ²°μ νλ λ©μ§ λ°©λ²μ
λλ€. "
μμ μ½λμμ μμ°μ€λ¬μ΄ μ§κ°μ λ°λΌ μ΅λͺ
ν¨μ λ΄λΆμμ this
ν€μλ μ°Έμ‘°λ 무μμ μλ―Έν©λκΉ? λμκ²λ user
λ₯Ό μ°Έμ‘°ν΄μΌ ν©λλ€. .reduce
μ μλ‘μ΄ ν¨μλ₯Ό μ λ¬ν΄μΌλ§νκΈ° λλ¬Έμ μλ‘μ΄ μ»¨ν
μ€νΈλ₯Ό λ§λ€ μ΄μ κ° μμ΅λλ€. κ·Έλ¦¬κ³ κ·Έ μ§κ°μΌλ‘ arrow functionμ κ°μΉλ₯Ό μ’
μ’
κ°κ³Όν©λλ€. μμ μ½λλ₯Ό λ€μ μμ±νκ³ μ΅λͺ
μ ν¨μ μ μΈ λμ μ΅λͺ
μ arrow functionλ₯Ό μ¬μ©νλ©΄ λͺ¨λ κ²μ΄ "μ μλν©λλ€".
const user = {
name: 'Tyler',
age: 27,
languages: ['JavaScript', 'Ruby', 'Python'],
greet() {
const hello = `Hello, my name is ${this.name} and I know`
const langs = this.languages.reduce((str, lang, i) => {
if (i === this.languages.length - 1) {
return `${str} and ${lang}.`
}
return `${str} ${lang},`
}, "")
alert(hello + langs)
}
}
arrow functionμΌλ‘ μΈν΄ this
κ° lexically
λ‘ κ²°μ λλ€λ μ΄μ λ λ€μ νλ² μ κΈ°λ©λλ€. arrow functionμλ this
κ° μμ΅λλ€. λμ λ³μ μ‘°νμ λ§μ°¬κ°μ§λ‘ μλ°μ€ν¬λ¦½νΈ μΈν°ν리ν°λ this
κ° μ°Έμ‘°νλ κ²μ νλ³νκΈ° μν΄ λλ¬μΈλ (λΆλͺ¨)λ²μλ₯Ό μ‘°μ¬ν©λλ€.
λ§μ§λ§μΌλ‘ "catch-all"μ κ²½μ° μΈ window Bindingμ λλ€. λ€μ μ½λκ° μλ€κ³ κ°μ ν΄ λ΄ μλ€.
function sayAge () {
console.log(`My age is ${this.age}`)
}
const user = {
name: 'Tyler',
age: 27
}
μμμ λ€λ€λ κ²μ²λΌ,sayAge
λ₯Ό user
컨ν
μ€νΈμμ νΈμΆνκ³ μΆλ€λ©΄ .call
, .apply
λλ .bind
λ₯Ό μ¬μ©ν μ μμ΅λλ€. μ°λ¦¬κ° κ·Έ μ€ νλλ₯Ό μ¬μ©νμ§ μκ³ νμμ²λΌ sayAge
λ₯Ό νΈμΆνλ©΄ μ΄λ»κ² λ κΉμ?
sayAge() // My age is undefined
this.age
κ° μ μλμ§ μμκΈ° λλ¬Έμ λΉμ μ΄ μ»λ κ²μ λλμ§λ μμ§λ§, My age is undefined
μ
λλ€. μ¬κΈ°κ° μ’ μ΄μν μ μ΄ μμ΅λλ€. μ¬κΈ°μμ μ€μ λ‘ μΌμ΄λκ³ μλ κ²μ μ μ μΌμͺ½μ μ무κ²λ μκΈ° λλ¬Έμ .call
, .apply
, .bind
λλ new
ν€μλλ₯Ό μ¬μ©νμ§ μκΈ° λλ¬Έμ μλ°μ€ν¬λ¦½νΈλ window
κ°μ²΄λ₯Ό μ°Έμ‘°νκΈ° μν΄ this
λ₯Ό κΈ°λ³ΈμΌλ‘ νκ³ μμ΅λλ€. μ¦, window
κ°μ²΄μ age property
λ₯Ό μΆκ°νλ©΄ sayAge
ν¨μλ₯Ό λ€μ νΈμΆ ν λ this.age
λ λ μ΄μ μ μλμ§ μμ§λ§ λμ age property
λ window
κ°μ²΄μ μμ΅λλ€. λ λ―Ώμ§ μλ? μ΄ μ½λλ₯Ό μ€ννμμμ€.
window.age = 27
function sayAge () {
console.log(`My age is ${this.age}`)
}
κ½€ κ·μ½μ§? μ΄κ²μ΄ λ°λ‘ 5λ²μ§Έ κ·μΉμΈ window Bindingμ΄λΌλ μ΄μ μ
λλ€. λ€λ₯Έ κ·μΉλ€ μ€ μ΄λ κ²λ μΆ©μ‘±λμ§ μμΌλ©΄ μλ°μ€ν¬λ¦½νΈλ window
κ°μ²΄λ₯Ό μ°Έμ‘°νκΈ° μν΄ this
ν€μλλ₯Ό κΈ°λ³Έκ°μΌλ‘ μ¬μ©ν©λλ€.
ES5μμ "strict mode"κ° νμ±ν λ κ²½μ° μλ°μ€ν¬λ¦½νΈλ μ¬λ°λ₯Έ μμ
μ μννκ³ windowκ°μ²΄λ₯Ό κΈ°λ³Έκ°μΌλ‘ μ€μ νλ λμ "this"λ₯Ό undefined μνλ‘ μ μ§ν©λλ€.
'use strict'
window.age = 27
function sayAge () {
console.log(`My age is ${this.age}`)
}
sayAge() // TypeError: Cannot read property 'age' of undefined
λ°λΌμ λͺ¨λ κ·μΉμ μ€μ λ‘ μ μ©νλ©΄ ν¨μ λ΄λΆμ this
ν€μλκ° νμ λ λλ§λ€ μ΄λ¬ν ν€μλκ° μ°Έμ‘°νλ νλͺ©μ νμ
νκΈ° μν΄ μνν΄μΌνλ λ¨κ³μ
λλ€.
- ν¨μ νΈμΆμ΄ μ΄λμ μΌμ΄λ¬λμ§ νμΈνλ€.
- μ μ κΈ°μ€μΌλ‘ μΌμͺ½μ κ°μ²΄κ° μλμ§ νμΈνκ³ , κ·Έκ²μ΄ μλ€λ©΄ κ·Έκ² λ°λ‘
this
ν€μλκ° μ°Έμ‘°νλ κ²μ΄λ€. λ§μ½μ μλ€λ©΄ 3λ²μΌλ‘ κ°λΌ. - βcallβ, βapplyβ, νΉμ βbindβμ ν¨μκ° νΈμΆλμλκ°? λ§μ½μ κ·Έλ λ€λ©΄
this
ν€μλκ° μ°Έμ‘°νλ κ²μ λͺ μμ μΌλ‘ μ μΈν κ²μ΄λ€. κ·Έλ μ§ μλ€λ©΄ 4λ²μΌλ‘ κ°λΌ - ν¨μκ° new ν€μλμ νΈμΆμ΄ λμλκ°? κ·Έλ λ€λ©΄,
this
ν€μλλ μλ‘κ² μ°½μ‘°λ κ°μ²΄κ³ μλ°μ€ν¬λ¦½νΈ μΈν°ν리ν°μ μν΄ μμ±λ κ²μ΄λ€. μ΄κ²λ€κ³Ό νΈμΆλ κ² μλλΌλ©΄ 5λ²μΌλ‘ κ°λΌ. - νμ΄ν ν¨μ μμ
this
κ° μλκ°? κ·Έλ λ€λ©΄ μλ§λ κ·Όμ²μ (λΆλͺ¨)μ€μ½νμμ Lexically - μ΄νμ μΌλ‘? - μ°Ύμ μ μμ κ²μ΄λ€. κ·Έλ μ§ μλ€λ©΄ 6λ²μΌλ‘ κ°λΌ. - Strict modeλ₯Ό μ¬μ©μ€μΈκ°? κ·Έλ λ€λ©΄
this
ν€μλλ undefinedμ΄λ€. κ·Έλ μ§ μλ€λ©΄ 7λ²μΌλ‘ κ°λΌ. - μλ°μ€ν¬λ¦½νΈλ μ΄μν μ λ€.
this
λ window κ°μ²΄λ₯Ό μ°Έμ‘°νλ€.