Daehyunii's Dev-blog

[데브코스] TIL-107 자바스크립트 주요 개념 본문

✏️ 2022. TIL/October (데브코스)

[데브코스] TIL-107 자바스크립트 주요 개념

Daehyunii 2022. 10. 27. 12:41
 바닐라 자바스크립 기본역량 강화 강의 시작

  자바스크립트 기초 강의가 끝나고 바닐라 자바스크립트 기초 역량 강화관련 강의가 시작되었다. 자바스크립트 기초강의는 자바스크립트 자체에 대한 기본적인 개념들과 자료구조 & 알고리즘에 대한 내용이 굉장히 많았다면 이번 강의에서는 실질적인 자바스크립트 언어로 코드를 구현할 때의 이론들을 자세하게 배우는 강의인것 같다. 강의를 시작하기에 앞서 자바스크립트 문법과 관련된 문제들을 쪽지시험(?) 느낌으로 풀어보는 시간이 있었다. 기초적인 내용에 대해서 나름대로 잘 알거라고 생각했는데, 막상 코드를 보고  개념을 대입하려고 하니 쉽지는 않았던것 같다.  

 

문제에 대해서 요약해 보자면,

 

  1. var, let, const 키워드에 대한 개념 이해 정도
  2. this 키워드에 대한 개념 이해 정도
  3. 클로저에 대한 개념 이해 정도

를 중점적으로 물어보았던 것 같다. 오늘은 해당 내용들을 다시 한 번 상기하면서 정리해 보려고 한다.

 

var vs let vs const 키워드란?
var, let, const 키워드 모두 변수를 선언에 사용되는 키워드이다. 각 키워드 마다 차이점이 존재한다.

 

1. var 키워드

 

  • 동일 스코프 내에서 동일한 식별자 이름으로 변수의 중복선언이 가능하다.(이로인해 의도하지 않은 재할당이 이뤄질 수 있다)
var x = 10;

var x = 100;
console.log(x) // 100이 출력됨(이 경우 자바스크립트 엔진에 의해서 3번째 줄 var 키워드가 무시됨)
  • var 키워드로 선언한 변수에 재할당이 가능하다.
  • var 키워드로 선언한 변수는 전역객체의 프로퍼티가 된다.
  • var 키워드로 선언한 변수는 호이스팅 된다.(정확하게 말하면 모든 선언문은 호이스팅이 발생하지만, let과 const 키워드로 선언한 변수와의 차이점이 존재한다)

 

2. let 키워드

 

  • 동일 스코프 내에서 동일한 식별자 이름으로 변수의 중복선언이 불가능하다.(var 키워드의 단점을 방지한다)
  • let 키워드로 선언한 변수에 재할당이 가능하다.
  • let 키워드로 선언한 변수는 전역객체의 프로퍼티가 아닌 렉시컬 환경에 저장된다.
  • let 키워드로 선언한 변수는 호이스팅 되지만 변수 선언 단계와 초기화 단계가 분리되어 동작하므로 일시적 사각 지대가 발생하고, 이로 인해 호이스팅이 발생하지 않는 것처럼 동작한다.(호이스팅은 이뤄짐, 하지만 해당 선언문 이전에 참조하면 Error가 발생한다)

 

3. const 키워드

 

  • 동일 스코프 내에서 동일한 식별자 이름으로 변수의 중복선언이 불가능하다.
  • const 키워드로 선언한 변수에 재할당이 불가능하다.(상수다)
  • const 키워드로 선언한 변수는 전역객체의 프로퍼티가 아닌 렉시컬 환경에 저장된다.
  • const 키워드로 선언한 변수는 호이스팅 된다.(let 키워드로 선언한 변수와 동일하다)
  var let const
전역객체의 프로퍼티 o x x
중복선언 o x x
재할당 o o x
호이스팅 o o(일시적 사각 지대 생김) o(일시적 사각 지대 생김)

 

This 키워드란?
객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수다.

 

this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다.

 

함수 호출 방식 this가 가리키는 값(this 바인딩)
일반 함수로서 호출 전역 객체
메서드로서 호출 메서드를 호출한 객체(마침표 앞의 객체)
생성자 함수로서 호출 생성자 함수가 미래에 생성할 인스턴스
function Cat(name, age){
    this.name = name; // 생성자 함수로 Cat 함수 호출시 this는 미래에 생성할 인스턴스(객체)를 가리킴
    this.age = age; // 그냥 일반함수로 Cat 함수 호출시 this는 전역객체를 가리킴 
    this.catInfo = function(){
    	console.log(`My cat name : ${this.name}, age : ${this.age}`)
        }
}

const myCat = new Cat('leeNo', 2); 
const myNeighborCat = new Cat('kitty', 3);
console.log(myCat.name); // leeNo
console.log(myCat.age); // 2
myNeighborCat.catInfo(); //My cat name : kitty, age : 3
// 이때 catInfo 함수 내부의 this는 catInfo를 호출한 myNeighborCat 객체를 가리킴
console.log(Cat()); //이때 Cat 함수 내부의 this는 전역객체를 가리킴

 

클로저란?
외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저라고 부른다.

  함수의 경우 함수가 실행되고 함수가 종료되면 동시에 실행 컨텍스트에서 제거된다. 하지만 중첩 함수는 살아 남아 있는 경우 이미 종료된 외부 함수의 변수를 참조하는데, 그것이 가능한 이유는 외부 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거되지만 outer 함수의 렉시컬 환경까지 소멸하는 것은 아니기 때문이다. 자바스크립트는 매니지드 언어로 메모리의 관리를 가비지 컬렉터로 수행한다. 가비지 컬렉터는 참조하고 있는 메모리 공간을 정리하지 않는다. 그렇기 때문에 클로저가 가능한 것이다. 

 

클로저는 상태를 안전하게 변경하고 유지하기 위해 사용한다. 다시 말해, 상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용한다.

function Counter() {
    let count = 0;
    
    function increase() {
        count++;
    }
    function printCount() {
        console.log(`count : ${count}`);
    }
    return {
        increase,
        printCount
    }
}

const counter = Counter();
counter.increase();
counter.increase();
counter.increase();
counter.increase();
counter.printCount();

console.log(counter.count); //외부에서는 Counter 함수 내의 count에 접근 불가(스코프 때문)
//private 효과를 냄

 

오늘을 마무리 하며

 

  기존에 익히 들어 알고 있을것이라고 생각하면서 강의를 들었음에도 불구하고, 잊어버리고 있었던 내용돈 많이 있었고 생각보다 개념에 대해서 명확하게 알고 있지 못했던것 같다. 단순하게 var, let, const 키워드의 경우 중복선언 여부와 재할당 여부만을 놓고만 비교하고 있었고 클로저의 경우 개념은 알고 있었으나 클로저를 통해 정보를 은닉하는 방법에 대해서는 정확하게 모르고 있었다. 오늘 공부를 하고 보니 자바스크립트의 기본 문법과 관련하여 오늘 공부한 부분 이외에도 많은 부분에서 잊어버리고 있거나, 제대로 이해하지 못하고 넘어간 부분이 많이 있을것이라고 예상이 된다. 자바스크립트는 나에게 필수적이고 너무나도 잘 이해하고 있어야하는 언어인 만큼 반복된 학습으로 내 것으로 만들어야 겠다.