- Published on
Javascript - Closure
- Author
- Name
- yceffort
ν΄λ‘μ
μλ°μ€ν¬λ¦½νΈλ μ΄λ»κ² λ³μμ μ ν¨ λ²μλ₯Ό μ νλκ°?
function hello() {
var name = 'yceffort'
// λ΄λΆν¨μμ΄λ©°, ν΄λ‘μ λ€.
function showName() {
// λΆλͺ¨ν¨μκ° μ μΈν λ³μλ₯Ό μ¬μ©νλ€.
alert(`hello, ${name}`)
}
showName()
}
hello()
μ¬κΈ°μμ hello()
λ μ§μλ³μ name
κ³Ό ν¨μ showName()
μ μμ±νλ€. showName()
μ λ΄λΆν¨μμ΄λ―λ‘, hello()
μμλ§ μ¬μ©μ΄ κ°λ₯νλ€. showName()
μ λ³λμ μ§μλ³μκ° μμ§λ§ λ΄λΆν¨μλ μΈλΆν¨μμ μ κ·Όν κΆνμ κ°μ§κ³ μμΌλ―λ‘, name
μ΄ μ μμ μΌλ‘ μΆλ ₯λ κ²μ΄λ€. λ§μ½ nameμ΄λΌλ λ€λ₯Έ λ³μκ° λ΄λΆ ν¨μμ μλ€λ©΄, κ·Έ λ³μλ₯Ό μ°μ μ μΌλ‘ μ¬μ©ν κ²μ΄λ€.
Lexical
μ λ³μκ° μ¬μ©κ°λ₯ν λ²μλ₯Ό κ²°μ νκΈ° μν΄ μμ€μ½λ λ΄μμ λ³μκ° μ μΈλ μμΉλ₯Ό μ¬μ©νλ€λ κ²μ λ§νλ€. λ°λΌμ λ΄λΆ ν¨μλ€μ κ·Έλ€μ μΈλΆ μ ν¨ λ²μ λ΄μμ μ μΈλ λ³μλ€μ μ κ·Όν κΆνμ κ°μ§λ€.
ν΄λ‘μ λ 무μμΈκ°
function hello() {
var name = 'yceffort'
function showName() {
alert(`hello, ${name}`)
}
return showName
}
let sayHello = hello()
sayHello()
μ΄ μ κ³Ό μμ ν λκ°μ κ²°κ³Όλ₯Ό λ³΄μΌ κ²μ΄λ€. μ°¨μ΄μ μ, hello()
κ° λ΄λΆ ν¨μ showName
λ₯Ό 리ν΄νλ€λ κ², κ·Έλ¦¬κ³ κ·Έλ κ² λ¦¬ν΄ν μ 보λ₯Ό sayHello
λ³μμ μ μ₯νλ€λ κ²μ΄λ€. μΌν보면 μ μ΄ν΄κ° λμ§ μλ λͺ¨μ΅μ΄λ€. hello()
λ showName()
λ§μ 리ν΄νλλ°, κ³μν΄μ name
λ³μμ μ κ·Όνκ³ μκΈ° λλ¬Έμ΄λ€.
κ·Έ μ΄μ λ, μλ°μ€ν¬λ¦½νΈκ° ν¨μλ₯Ό 리ν΄ν λ, 리ν΄νλ ν¨μκ° ν΄λ‘μ λ₯Ό μμ±νκΈ° λλ¬Έμ΄λ€. ν΄λ‘μ λ ν¨μμ ν¨μκ° μ μΈλ μ΄νμ νκ²½μ μ‘°ν©μ΄λ€. (ν¨μκ° μ μΈλ νκ²½μ κΈ°μ΅νλ€.) μ¬κΈ°μμ νκ²½μ, ν΄λ‘μ κ° μμ±λ μμ μ μ ν¨λ²μλ΄μ μλ λͺ¨λ μ§μλ³μλ‘ κ΅¬μ±λλ€. (λ΄λΆ ν¨μκ° μΈλΆ ν¨μμ λ³μμ μ κ·Όν μ μμκΈ° λλ¬Έμ κ·Έ λ³μλ€μ κΈ°μ΅νλ κ²)
function add(x) {
var y = 1
return function (z) {
y = 100
return x + y + z
}
}
// ν΄λ‘μ μ μΈ
let add5 = add(5)
let add10 = add(10)
console.log(add5(2))
console.log(add10(2))
add
ν¨μλ, x
λ₯Ό μΈμλ‘ λ°μμ μλ‘μ΄ λ΄λΆ ν¨μλ₯Ό λ°ννλ€. μ΄ λ΄λΆ ν¨μλ z
λ₯Ό λ°μμ x+y+z
λ₯Ό λ°ννλ€. add5
μ add10
μ λͺ¨λ ν΄λ‘μ λ€. μ΄ λ ν¨μμ κ²°κ³Όλ μ΄λ»κ² λ κΉ?
첫λ²μ§Έ μ μΈ let add5 = add(5)
μμ μΌλ¨ xκ° 5λ‘ ν λΉμ΄ λμλ€. κ·Έλ¦¬κ³ λλ²μ§Έ add5(2)
μμλ zκ° 2λ‘ ν λΉμ΄ λμλ€. κ·Έλ¦¬κ³ yκ° λκ΅°λ° ν λΉμ΄ λμ΄μμΌλ―λ‘, λ΄λΆλ₯Ό μ°μ μνμ¬ yλ 100μ΄λ€. λ°λΌμ μ΄ λλ€. λ§μ°¬κ°μ§λ‘, add10
μ κ° λλ€.
λ³Έμ§μ μΌλ‘, μ΄ λκ°λ κ°μ ν¨μμ λ³Έλ¬Έμ μ μνμ§λ§, μλ‘ λ€λ₯Έ νκ²½μ μ μ₯νλ€. μ΄λ ν΄λ‘μ κ° λ¦¬ν΄λ νμλ μΈλΆ ν¨μμ λ³μμ μ κ·Όμ΄ κ°λ₯νλ€λ κ²μ 보μ¬μ£Όλ©°, λ¨μν κ° ννλ‘ μ λ¬λλ κ²μ΄ μλλΌλ κ²μ μλ―Ένλ€.
μ΄λλ€ μΈκΉ
ν΄λ‘μ λ μ΄νμ μΈ νκ²½κ³Ό λ°μ΄ν°λ₯Ό μ‘°μνλ ν¨μλ₯Ό μ°κ΄μμΌ μ£ΌκΈ° λλ¬Έμ μ μ©νλ€. μ΄λ κ°μ²΄κ° μ΄λ€ λ°μ΄ν° (μμ±)κ³Ό κ·Έ λ©μλλ₯Ό μ°κ΄μν¨ λ€λ μ μμ κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°κ³Ό κ°μ λ§₯λ½μ μλ€. λ°λΌμ, λ¨ νλμ λ©μλ λ§μ κ°μ§κ³ μλ κ°μ²΄λ₯Ό μΌλ°μ μΌλ‘ μ¬μ©νλ λͺ¨λ κ³³μ ν΄λ‘μ λ₯Ό μ¬μ©ν μ μλ€.
μ΄λ νλ‘ νΈμλ μλ°μ€ν¬λ¦½νΈ μ΄λ²€νΈμμ νν λ³Ό μ μλ€. μ¬μ μ λͺκ°μ§ λμμ μ μν νμ, μ¬μ©μκ° μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±° νλ©΄ μ΄ λμλ€μ μ°κ²°νλλ° μ΄λ μ΄λ²€νΈμ μλ΅νμ¬ μ€νλλ λ¨μΌ ν¨μλ€.
function makeFontSize(size) {
return function () {
document.body.style.fontSize = size + 'px'
}
}
let size12 = makeFontSize(12)
let size14 = makeFontSize(14)
let size16 = makeFontSize(16)
document.getElementById('size-12').onclick = size12
document.getElementById('size-14').onclick = size14
document.getElementById('size-16').onclick = size16
νλΌμ΄λΉ λ©μλλ₯Ό νλ΄λ΄λ κ²λ κ°λ₯νλ€. νλΌμ΄λΉ λ©μλλ μ½λμ μ νμ μΈ μ κ·Όλ§ νμ©ν μ μκ³ , μ μ λ€μμ€νμ΄μ€λ₯Ό κ΄λ¦¬νλ λ°©λ²μ μ 곡νμ¬ λΆνμν λ©μλκ° κ³΅μ© μΈν°νμ΄μ€λ₯Ό νΌλμ€λ½κ² λ§λ€μ§ μλλ‘ ν μ μλ€.
let counter = (function () {
let privateCounter = 0
function change(val) {
privateCounter += val
}
return {
increment: function () {
change(1)
},
decrement: function () {
change(-1)
},
value: function () {
return privateCounter
},
}
})()
counter.increment()
counter.value()
counter.increment()
counter.increment()
counter.decrement()
counter.value()
change()
privateCounter
λ λͺ¨λ μ΅λͺ
ν¨μ λ΄λΆμμ μμ±λμκΈ° λλ¬Έμ μ κ·Όν μ μλ€. μ΄ μ΅λͺ
ν¨μμμ μ κ·Όν μ μλ건 μ΅λͺ
λνΌμμ λ°νλ μΈκ°μ νΌλΈλ¦ν¨μ increment()
decrement()
value()
λΏμ΄λ€. μ μ²λΌ μ¦μμ€νμ΅λͺ
ν¨μκ° μλλΌ λ³λμ ν¨μλ‘ λ§λ€μ΄μ λ°λ‘ μ΄λ€λ©΄, κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ μλκ³Ό μΊ‘μν κ°μ μ΄μ λ€μ μ»μ μ μλ€.
루νμμμ ν΄λ‘μ
μ΄ ν¨μλ μκ°μ²λΌ μλνμ§ μλλ€. κ·Έ μ΄μ λ onfcus
μ μ°κ²°λ ν¨μκ° ν΄λ‘μ μ΄κΈ° λλ¬Έμ΄λ€. μ΄ ν΄λ‘μ λ setupHelp()
ν¨μλ²μμμ μΊ‘μ³λ νκ²½μΌλ‘ ꡬμ±λλ€. 루νμμ μΈκ°μ μΈκ°μ ν΄λ‘μ κ° λ§λ€μ΄μ‘μ§λ§, κ° ν΄λ‘μ λ κ°μ΄ λ³νλ λ³μ item.help
κ° μλ λ¨μΌ νκ²½μ 곡μ νλ€. λ°λΌμ κ³μν΄μ λ§μ§λ§ λ³μλ₯Ό κ°λ₯΄ν€κ² λλ κ²μ΄λ€.
첫λ²μ§Έ ν΄κ²°λ°©μμ showHelp()
λ₯Ό κ°μΈλ ν΄λ‘μ λ₯Ό λ§λλ κ²μ΄λ€.
showHelp()
λ μ¬μ ν λ¨μΌ νκ²½μμ μλνμ§λ§, makeHelpCallback()
λ λ§€λ² μλ‘μ΄ ν΄λ‘μ λ₯Ό λ§λ€μ΄μ μλ‘μ΄ νκ²½μ νμ±νλ€.
μλλ©΄ μ¦μμ€νμ΅λͺ ν¨μλ₯Ό λ§λ€μ΄μ for ꡬ문λ΄μ νκ²½μ΄ λ³λ‘ μ¦μλ‘ μ€νλκ² νλ λ°©λ²λ μμ μ μλ€.
λ°λμ for ꡬ문 λ΄μ λ‘μ§μ μ¦μμ€νν¨μλ‘ κ°μΈμ λ³λμ νκ²½μΌλ‘ ꡬμ±λκ² ν΄μΌ νλ€.
μλλ©΄ letμ μ¬μ©νμ¬ item
λ³μμ λ²μμ체λ₯Ό forλ¬Έ λ΄λ‘ μ νν μλ μλ€.
μ±λ₯
ν΄λ‘μ κ° νμνμ§ μμ μμ μ λ€λ₯Έ ν¨μλ΄μμ ν¨μλ₯Ό λΆνμνκ² κ³μ μ μΈνκ³ μμ±νλ κ²μ μ±λ₯μ μ μν₯μ λ―ΈμΉλ€. μλ₯Ό λ€μ΄, μλ‘μ΄ κ°μ²΄λ ν΄λμ€λ₯Ό μμ±ν λ λ©μλλ₯Ό κ°μ²΄ μμ±μμ μ μνλ κ² λ³΄λ€λ κ°μ²΄μ νλ‘ν νμ μ μ°κ²°ν΄μΌ νλ€.
μμ’μ μ
function MyObject(name, message) {
this.name = name.toString()
this.message = message.toString()
this.getName = function () {
return this.name
}
this.getMessage = function () {
return this.message
}
}
μ΄λ κ² ν기보λ€λ prototypeμ μ μνλ κ²μ΄ ν¨μ¬ λ«λ€.
function MyObject(name, message) {
this.name = name.toString()
this.message = message.toString()
}
MyObject.prototype.getName = function () {
return this.name
}
MyObject.prototype.getMessage = function () {
return this.message
}
function MyObject(name, message) {
this.name = name.toString()
this.message = message.toString()
}
;(function () {
this.getName = function () {
return this.name
}
this.getMessage = function () {
return this.message
}
}).call(MyObject.prototype)
μ΄λ κ² μ΄λ€λ©΄ μ’λ μΉμν΄ λ³΄μΌ κ²μ΄λ€.