[JavaScript] closure

sunny·2022년 6월 16일
0

JavaScript

목록 보기
2/7

Closure

closure = function + environment

closure는 function이 하나 생길 때마다 하나씩 생긴다.
environment는 함수 자신을 둘러싼, 접근할 수 있는 모든 스코프를 뜻한다.

closure의 예시

function and(x) {
	return function print(y){
    	return x + ' and ' + y
    }
}

const saltAnd = and('salt')
console.log(saltAnd('pepper')) // salt and pepper
console.log(saltAnd('sugar')) // salt and sugar

and 함수로 만들어진 saltAnd의 closure는
👉 함수: print
👉 환경: x -> 'salt'

closure는 higher-order function을 만드는 데 유용 (여기서 and 함수가 higer-order fucntion)
higher-order function: 다른 함수를 내놓는 고차원 함수

function and(x) {
	return function print(y){
    	return x + ' and ' + y
    }
}

const saltAnd = and('salt')
console.log(saltAnd('pepper')) // salt and pepper
console.log(saltAnd('sugar')) // salt and sugar

const waterAnd = and('water')
console.log(waterAnd('juice')) // water and juice

❗두 개의 각각 다른 closure들이 생김❗
saltAnd와 waterAnd 모두 함수는 같은 print지만, 각각 주어진 변수가 다르다.
saltAnd는 x가 'salt', waterAnd는 x가 'water'로 바인딩 되어 있다.
👉 둘은 서로 다른 closure를 형성하고 있다

function foo() {
	function bar() {
    }
  	function baz() {
    }
}
foo()

❓ 여기서는 총 몇개의 closure ❓
foo 한 번 선언 --> closure 한 개 생김
foo 실행 한 뒤 --> bar(), baz() 각각 한 개 씩 생김
👉 총 3개의 closure 생성 (foo 1개, bar 1개, baz 1개)

function foo() {
	function bar() {
    }
  	function baz() {
    }
}
foo()
foo()

❓ 여기서는 총 몇개의 closure ❓
foo 한 번 선언 --> closure 한 개 생김
foo 실행 한 뒤 --> bar(), baz() 각각 한 개 씩 생김
foo 실행 한 뒤 --> bar(), baz() 각각 한 개 씩 생김
👉 총 5개의 closure 생성 (foo 1개, bar 2개, baz 2개)

closure의 예시 - counter

function getCounter() {
	var result = {
    	count: count,
      	total: 0
    }
    function count() {
    	result.total += 1
    }
  	return result
}

var counter = getCounter()
counter.count()
counter.count()

console.log(counter.total)

전부 실행되었을 때 어떤 결과?
getCounter는 안엥서 result라는 object 만듦
result 안에는 count(fucntion), total(숫자값)
그리고 result를 return

getCounter 실행하면--> result 객체가 만들어지고 count라는 function선언 동시에 closure 생성, closure
실행 결과 --> 2

function getCounter() {
	var result = {
    	count: count,
      	total: 0
    }
    function count() {
    	result.total += 1
    }
  	return result
}

var counterA = getCounter()
counterA.count()
counterA.count()

var counterB = getCounter()
counterB.count()

console.log(counterA.total, counterB.total)

getCounter 2개 호출
counterA에 해당하는 result 객체, counterB에 해당하는 result 객체
두 개가 서로 다른 closure
실행결과 --> 2 1

function getCounter() {
  	numCounters += 1
  
	var result = { count: count, total: 0, }
    function count() { result.total += 1 }
  	return result
}

var counterA = getCounter()
counterA.count()
counterA.count()

var counterB = getCounter()
counterB.count()

console.log(counterA.total, counterB.total, numCounters)

실행 결과 --> 2 1 2
numCounters는 getCounter 실행될 때마다 증가

VSCode에서 closure 확인하기

0개의 댓글