Skip to content

[week3_NAEUN] 22장, 24장 퀴즈#9

Open
eunkr82 wants to merge 1 commit intomainfrom
week3_NAEUN
Open

[week3_NAEUN] 22장, 24장 퀴즈#9
eunkr82 wants to merge 1 commit intomainfrom
week3_NAEUN

Conversation

@eunkr82
Copy link
Collaborator

@eunkr82 eunkr82 commented Nov 10, 2025

Q1. 다음 코드를 보고, 예상 출력 결과와 이유를 작성하세요.

<button id="btn">Click</button>
<script>
        const btn = document.getElementById('btn');

        btn.addEventListener('click', function() {
            console.log('A', this.id);
        });

        btn.addEventListener('click', () => {
            console.log('B', this && this.id);
        });
</script>

Q2. 빈칸 채우기

  • call은 인자를 ( )로 전달한다.
  • apply 는 인자를 ( )로 전달한다.
  • bindapplycall 메서드와 달리 ( )를 호출하지 않으며, ( )를 반환한다.

Q3. 문제에 답하고, 답변에 대한 해설을 적어 주세요.

function outer() {
	var x=1; 
	function inner() {
		console.log(x);
	}
	x=2;
	return inner;
}

const fn = outer();
fn();

innerouter의 렉시컬 환경을 기억하는 클로저다. innerouter 의 지역 변수 x 를 사용하므로, outer 의 렉시컬 환경을 기억하고 있다. 여기서 inner 가 기억하는 것은 지역변수 x 의 값 그 자체다. 따라서, outer 가 끝나면 그 바인딩은 가비지 컬렉션으로 함께 들어간다. (O/X)

Q4. 클로저란 무엇이고, 실무에서 어떤 이점을 가져갈 수 있는지 적어 주세요.

필수 포함 키워드: 은닉, 캡슐화

@mimizae
Copy link
Collaborator

mimizae commented Nov 11, 2025

ㅁㅊ!! 잘못 닫았습니다... 죄송합니다 😅😅😅

Q1. 다음 코드를 보고, 예상 출력 결과와 이유를 작성하세요.

출력 결과는 아래와 같다.

A btn
B undefined

첫 번째 핸들러는 일반 함수로 정의되어 있고, 두 번째 핸들러는 화살표 함수로 정의되어 있다. 이 두 함수는 this 바인딩 방식이 다르기 때문에 서로 다른 결과를 출력한다.

먼저, btn.addEventListener('click', function() { ... }) 형태로 등록된 첫 번째 핸들러의 경우, 이벤트 리스너 내부의 this는 이벤트를 발생시킨 요소, 즉 요소를 가리킨다.

addEventListener 메서드는 일반 함수가 콜백으로 전달될 때 자동으로 this를 해당 DOM 요소에 바인딩하기 때문이다.
따라서 첫 번째 로그에서는 'A btn'이 출력된다!!!

반면 두 번째 핸들러인 btn.addEventListener('click', () => { ... })의 경우, 화살표 함수는 자신만의 this를 가지지 않고 정의된 시점의 상위 스코프(this)를 그대로 가져온다.

이 코드에서는 화살표 함수가 전역 스코프에서 정의되었기 때문에, 상위 스코프의 this는 브라우저 환경에서 window 객체가 된다.

즉!!!! 화살표 함수 내부에서는 이벤트를 발생시킨 버튼이 아니라 전역 객체를 가리키게 된다.
그 결과 this && this.id의 값은 undefined가 되어 'B undefined'가 출력된다.

Q2. 빈칸 채우기

  • call은 인자를 (콤마)로 구분하여 전달한다.
  • apply는 인자를 (배열)로 전달한다.
  • bind는 apply와 call 메서드와 달리 (함수)를 호출하지 않으며, (새로운 함수)를 반환한다.

Q3. 문제에 답하고, 답변에 대한 해설을 적어 주세요.

function outer() {
	var x=1; 
	function inner() {
		console.log(x);
	}
	x=2;
	return inner;
}

const fn = outer();
fn();

inner는 outer의 렉시컬 환경을 기억하는 클로저다. inner는 outer 의 지역 변수 x 를 사용하므로, outer 의 렉시컬 환경을 기억하고 있다. 여기서 inner 가 기억하는 것은 지역변수 x 의 값 그 자체다. 따라서, outer가 끝나면 그 바인딩은 가비지 컬렉션으로 함께 들어간다. (X)

아니다!! inner는 outer의 렉시컬 환경을 기억하는 클로저이라고 했다. 즉!!

outer 함수가 한 번 호출된 후 종료되더라도, 그 안에서 정의된 inner 함수가 반환되어 외부에서 계속 참조되고 있기 때문에,
outer의 실행 컨텍스트 자체는 스택에서 제거되더라도 그 렉시컬 환경 객체는 가비지 컬렉션의 대상이 되지 않는다.
(가비지 컬레션은 참조되고 있는 것의 메모리를 함부로 해제하지 않는다.)

따라서 outer가 종료된 뒤에도, inner가 여전히 x에 접근할 수 있고, 그 렉시컬 환경은 fn이 존재하는 한 메모리에서 해제되지 않는다.
(클로저가 살아 있는 한 참조되고 있는 해당 변수도 함께 살아 있는 상태라는 의미)

Q4. 클로저란 무엇이고, 실무에서 어떤 이점을 가져갈 수 있는지 적어 주세요.

클로저는 상태를 안전하게 변경하고 유지하기 위해 사용되는 개념이다. 클로저를 이용하면 외부에서 직접 접근할 필요가 없는 내부 상태를 은닉하고, 특정 함수에게만 그 상태의 변경을 허용함으로써 캡슐화를 구현할 수 있다!!

즉, 상태가 의도치 않게 변경되지 않도록 보호하고, 외부에서는 접근할 수 없지만 내부 함수는 그 상태를 계속 기억하고 사용할 수 있게 하는 것이다.

@mimizae mimizae closed this Nov 11, 2025
@mimizae mimizae reopened this Nov 11, 2025
@Tnalxmsk
Copy link
Collaborator

Q1. 다음 코드를 보고, 예상 출력 결과와 이유를 작성하세요.

<button id="btn">Click</button>
<script>
        const btn = document.getElementById('btn');

        btn.addEventListener('click', function() {
            console.log('A', this.id);
        });

        btn.addEventListener('click', () => {
            console.log('B', this && this.id);
        });
</script>

A btn
B undefined

첫 번째는 리스너로 일반 함수를 넘기고 있음. 일반 함수의 this는 브라우저가 이벤트 타깃을 바인딩해줌
두 번째눈 화살표 함수로 넘기고 있음. 화살표 함수는 자신만의 this를 가지지 않고 정의될 당시의 렉시컬 환경의 this를 캡처. 즉 상위 스코프에서 받기 때문에블라우저 환경의 window 객체가 this 바인딩됨. 만약 strict면 this === undefiend. 아니라면 this는 window

Q2. 빈칸 채우기

쉼표
배열
함수, this가 바인딩된 새로운 함수

Q3. 문제에 답하고, 답변에 대한 해설을 적어 주세요.

function outer() {
	var x=1; 
	function inner() {
		console.log(x);
	}
	x=2;
	return inner;
}

const fn = outer();
fn();

X
클로저는 변수에 대한 참조를 기억하고 있음. 그러면 상위 스코프의 렉시컬 환경은 유지된 채로 있는 것임.
여기서 innner는 상위 스코프 outer의 렉시컬 환경의 x를 참조하고 있으므로 otuer의 실행이 끝나도 가비지 컬렉션 대상이 되지 않음

Q4. 클로저란 무엇이고, 실무에서 어떤 이점을 가져갈 수 있는지 적어 주세요.

'클로저는 함수가 선언될 당시의 렉시컬 환경의 조합'
함수가 선언될 당시의 렉시컬 환경을 기억하고, 그 환경 밖에서 호출되더라도 그 변수들에 접근할 수 있는 함수
내부 함수가 외부 함수의 변수와 환경을 은닉 한 채로 캡슐화하여 유지하고 있음

첫 번째 이점은 캡슐화가 가느함. 데이터와 데이터를 조작하는 함수를 하나의 단위로 묶어 관리하여 불필요한 외부 노출 방지.
두 번째는 데이터 은닉으로 캡슐화를 통해 하나의 단위로 묶인 객체의 상태를 외부에서 직접 접근할 수 없도록 하여 외부에서 임의로 상태를 직접 변경할 수 없게 됨

@sonnnnhe
Copy link
Collaborator

Q1. 다음 코드를 보고, 예상 출력 결과와 이유를 작성하세요.

<button id="btn">Click</button>
<script>
        const btn = document.getElementById('btn');

        btn.addEventListener('click', function() {
            console.log('A', this.id);
        });

        btn.addEventListener('click', () => {
            console.log('B', this && this.id);
        });
</script>

출력 결과

A btn
B 

이유
리스너의 this 바인딩은 함수 호출 방식에 따라 달라진다.
함수 리터럴 방식을 사용해 리스너를 등록한 경우 this는 이벤트를 발생시킨 DOM 요소에 바인딩되므로 첫 번째 리스너의 this는 btn으로 바인딩된다. 따라서 btn.id가 참조되어 A btn이 출력되는 것이다.
화살표 함수로 리스너를 등록한 경우 자신만의 this를 가지지 않아 상위 스코프로부터 this를 물려받는다. 이 화살표 함수의 상위 스코프는 global scope이므로 this에 바인딩된 값은 window 객체이다. window.id의 기본값은 빈 문자열 이므로 B 가 출력된다.


Q2. 빈칸 채우기

  • call은 인자를 ( ,로 구분한 리스트 형식 )로 전달한다.
  • apply 는 인자를 ( 배열 )로 전달한다.
  • bind 는 apply와 call 메서드와 달리 ( 함수 )를 호출하지 않으며, ( 새롭게 생성한 this 바인딩이 교체된 함수 )를 반환한다.

Q3. 문제에 답하고, 답변에 대한 해설을 적어 주세요.

function outer() {
	var x=1; 
	function inner() {
		console.log(x);
	}
	x=2;
	return inner;
}

const fn = outer();
fn();

innerouter의 렉시컬 환경을 기억하는 클로저다. innerouter 의 지역 변수 x 를 사용하므로, outer 의 렉시컬 환경을 기억하고 있다. 여기서 inner 가 기억하는 것은 지역변수 x 의 값 그 자체다. 따라서, outer 가 끝나면 그 바인딩은 가비지 컬렉션으로 함께 들어간다. (O/X)

X, inner가 기억하는 것은 자신의 상위 스코프인 outer의 렉시컬 환경으로 outer가 끝나도 inner 함수가 outer의 렉시컬 환경을 참조하고 있기 때문에 가비지 컬렉션의 대상이 되지 않는다.


Q4. 클로저란 무엇이고, 실무에서 어떤 이점을 가져갈 수 있는지 적어 주세요.

필수 포함 키워드: 은닉, 캡슐화

일반적으로 중첩 함수가 상위 스코프의 식별자를 참조하고 있고 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에 한정하여 클로저 라고 부른다.
객체의 특정 프로퍼티나 메서드를 감출 목적으로 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 캡슐화를 사용하기도 하는데 이를 정보 은닉이라고 한다. 정보 은닉은 적절치 못한 접근으로부터 객체의 상태가 변경되는 것을 방지해 정보를 보호하고 객체 간의 상호 의존성, 즉 결합도를 낮추는 효과가 있으며 예상치 못한 오류를 사전에 방지할 수 있다는 이점이 있다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants