[Modern JS] #4. 변수

wonnie1224·2022년 7월 24일
0

Modern JS

목록 보기
1/7

📌 4.1 변수란?

💡 (js를 해석하고 실행하는)자바스크립트 엔진이 10 + 20을 어떻게 계산할까?

컴퓨터에선 CPU - 연산, 메모리 - 데이터 기억 이렇게 역할이 나누어져있다
(+) 연산을 하기 위해 10과 20(피연산자)를 메모리에 저장함(2진수로 저장됨)
연산 후 결과값인 30도 메모리에 저장함

그치만 문제 : 연산해서 만든 값인 30을 재사용할 수 없음!
-> 재사용하고 싶다면 30이 저장돼있는 메모리 주소를 통해 30이저장된 메모리 공간에 직접 접근 해야함
-> but 이건 오류 발생 가능성 높음 위험함
& 동일한 코드를 실행해도 실행될 때마다 값이 저장될 메모리 주소는 변함
=> js는 개발자의 직접적인 메모리 제어를 허용 x

변수 : 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 / 그 메모리 공간을 식별하기 위해 붙인 이름

  • 즉 값의 위치를 가리키는 상징적인 이름
  • 컴파일러/인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환돼서 실행됨
    => 개발자가 변수를 통해 안전하게 값에 접근 가능!
// 변수는 하나의 값을 저장하기 위한 수단임
var userId = 1;
var userName = 'Lee';

// 객체/배열 같은 자료구조를 사용하면 #개의 값을 하나로 그룹화해서 하나의 값처럼 사용 가능
var user = { id: 1, name: 'Lee' };

var users = [// 객체로 이루어진 배열
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' }
  ];
  • 변수 이름(=변수명) : 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름
  • 변수 값 : 변수에 저장된 값
  • 할당(assignment) : 변수에 값을 저장하는 것
  • 참조(reference) : 변수에 저장된 값을 읽어 들이는 것

📌 4.2 식별자

식별자 : 어떤 값을 구별해서 식별할 수 있는 고유한 이름, 어떤 값이 저장돼있는 메모리 주소에 붙인 이름

-> 식별자 - 메모리 공간에 저장돼있는 어떤 값을 구별해서 식별할 수 있어야 함
-> 식별자 - 어떤 값이 저장돼 있는 메모리 주소를 기억(저장)해야 함
=> 즉, 식별자 - 값이 저장돼 있는 메모리 주소와 매핑 관계를 맺음 & 이 매핑 정보도 메모리에 저장돼야 함

식별자 - 값이 아니라 메모리 주소를 기억함!!

  • 변수, 함수, 클래스 등의 이름은 모두 식별자임(네이밍 규칙을 준수해야 함)
    선언(declaration)에 의해 자바스크립트 엔진에 식별자의 존재를 알림

💡✏️ 변수 이름은 어디에 등록되는가?
모든 식별자 : 실행 컨텍스트에 등록됨
*) 실행 컨텍스트(execution context) : JS 엔진이 소스코드 평가 & 실행하기 위해 필요한 환경 제공 , 코드의 실행 결과를 실제로 관리하는 영역
변수 이름 & 변수 값 : key/value 형식인 객체로 등록됨


📌 4.3 변수 선언

변수 선언 = 변수 생성
값 저장하기 위한 메모리 공간 확보 & 확보된 메모리 공간의 주소를 연결 -> 값을 저장할 수 있게 준비하는 것

변수 선언할 땐 var, let, const 키워드 사용!

var 키워드 : 뒤에 오는 변수 이름으로 새로운 변수를 선언할 것을 지시함
*) var 키워드의 단점 : 블록 레벨 스코프 지원 X, 함수 레벨 스코프 지원 -> 의도치 않게 전역 변수 선언될 수 O

var score;	// 변수 선언

변수 선언문 - 변수 이름 등록 & 값 저장할 메모리 공간 확보
-> 아직 변수에 값 할당 안 함
=> 자바스크립트 엔진에 의해 undefined 라는 값이 암묵적으로 할당돼서 초기화됨

undefined : JS에서 제공하는 원시 타입의 값

자바스크립트 엔진의 변수 선언 단계

1) 선언 단계 : 변수 이름을 등록해서 js 엔진에 변수의 존재를 알림
2) 초기화 단계 : 값 저장하기 위한 메모리 공간 확보 & 암묵적으로 undefined 할당하여 초기화

선언하지 않은 식별자에 접근 -> ReferenceError(참조 에러) 발생

📌 4.4 변수 선언의 실행 시점과 변수 호이스팅

console.log(score);	//undefined 출력

var score; // 변수 선언문

❓ 위의 코드에서 Reference Error가 발생할 것 같지만, undefined가 출력됨
🔍 why?
변수 선언이 런타임(= 소스코드가 1줄씩 순차적으로 실행되는 시점)이 아니라, 그 이전 단계에서 먼저 실행되기 때문

1) JS 엔진 - 소스코드 1줄씩 순차적으로 실행하기 전 소스코드 평가 과정 거침
-> 모든 선언문(변수 선언문, 함수 선언문...)을 소스코드에서 찾아내서 먼저 실행함
2) 소스코드 평가 과정 끝나면 모든 선언문을 제외하고 소스코드를 1줄씩 순차적으로 실행함

변수 호이스팅(variable hoisting) : 변수 선언문이 코드의 맨 위로 끌어 올려진 것처럼 동작하는 JS 고유 특징


📌 4.5 값의 할당

변수에 값을 할당할 땐 할당 연산자 = 을 사용함
-> 우변의 값을 좌변의 변수에 할당함

var score;	// 변수 선언
score = 80; // 값의 할당

var score = 80; // 변수 선언 & 값의 할당을 한 번에 단축 표현함

이 두 코드는 동일하게 동작함
단축 표현해도 변수 선언 & 값의 할당을 2개의 문으로 나누어 각각 실행함

  • 변수 선언 - 런타임 이전에 먼저 실행됨
  • 값의 할당 - 런타임에 실행됨
console.log(score);	// undefined

var score;	// 1) 변수 선언 -> undefined로 초기화됨
score = 80; // 2) 값의 할당

console.log(score);	// 80

1), 2)의 순서가 바뀌어도 실행 결과는 같음


📌 4.6 값의 재할당

재할당 : 이미 값이 할당돼 있는 변수에 새로운 값을 다시 할당하는 것
var 키워드로 선언한 변수는 값 재할당 가능
값을 재할당 할 수 X -> 변수가 아니라 상수임

💡 const 키워드로 선언한 변수는 값 재할당 불가능

var score = 80;
score = 90;

-> 80이 저장돼 있던 메모리 공간을 지우고 거기에 90 저장하는게 아니라, 새로운 메모리 공간 확보하고 거기에 90 저장

score 변수의 이전 값인 undefined, 80은 어떤 식별자와도 연결돼 있지 X
이런 불필요한 값 -> 가비지 콜렉터(garbage collector)에 의해 메모리에서 자동 해제됨

💡 garbage collector : 애플리케이션이 할당한 메모리 공간을 주기적으로 검사해 더 이상 사용되지 않는 메모리(어떤 식별자도 참조하지 않는 메모리 공간)를 해제하는 기능

📌 4.7 식별자 네이밍 규칙

네이밍 규칙

  • 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어( _ ), $를 포함 가능
  • 단, 특수문자를 제외한 문자, 언더스코어( _ ), $로 시작해야함 -> 즉 숫자로 시작하면 안 됨
  • 예약어는 식별자로 사용 불가능

<예약어>

awaitbreakcasecatchclassconst
continuedebuggerdefaultdeletedoelse
enumexportextendsfalsefinallyfor
functionifimplementsimportininstanceof
interfaceletnewnullpackageprivate
protetedpublicreturnsuperstaticswitch
thisthrowtruetrytypeofvar
voidwhilewithyield
var person, $elem, _name, first_name, val1;	// 이렇게 변수 #개를 한 번에 선언 가능하지만 가독성 bad
  • 알파벳 외의 유니코드 문자로 명명 권장 X
  • 대소문자 구별함
  • 변수 이름 - 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현해야 함
  • 네이밍 컨벤션(naming convention) : #개 영단어로 구성된 식별자의 가독성을 좋게하려고 규정한 명명 규칙
    ✅ 변수 & 함수 : 카멜 케이스
    ✅ 생성자 함수 & 클래스의 이름 : 파스칼 케이스
// 카멜 케이스(camelCase)
var firstName;

// 스네이크 케이스(snake_case)
var first_name;

// 파스칼 케이스(PascalCase)
var FirstName;

// 헝가리언 케이스(typeHungarianCase)
var strFirstName;	// type + identifier
var $elem = document.getElementById('myId');	// DOM 노드
var obserable$ = fromEvent(document, 'click');	// RxJS 옵저버블
profile
안녕하세요😊 인공지능을 공부하고 있는 대학생입니다 🙌

0개의 댓글