TIL 23-10-12
자바스크립트의 역사 & 변수(Variable)
내일배움캠프 React 3기 JavaScript 문법 학습 기간이 시작되었다. JavaScript 기본 문법은 이미 알고 있지만 나의 언어로 설명할 수 있을 정도로 복습하고자 했다.
“설명할 수 없다면 제대로 아는 것이 아니다”
나만의 방식으로 정리해 확실히 이해하고 정보를 공유하기까지를 목표로. (너무 Deep하게 파고들어서 시간을 뺏기지 않도록 주의하기) 실패했다.
오늘 공부한 내용
-
자바스크립트의 역사와 특징
-
변수, 식별자, 변수 선언, 변수 선언의 실행 시점과 호이스팅, 할당, 네이밍 규칙
1. 자바스크립트의 역사와 특징
「모던 자바스크립트 Deep Dive」 2장을 학습하며 정리했던 TIL을 다시 읽어보았다. 그 때 이해하지 못했던 자바스크립트의 특징에 대해 다시 학습했다.
자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어
객체지향 프로그래밍
먼저 다른 개념인 절차지향 프로그래밍은 위에서부터 아래로 차례대로 프로그램을 만드는 것.
객체지향 프로그래밍 역시 위에서 아래로 실행하지만 역할을 가진 그룹(객체)로 묶어서 그룹 단위로 실행된다. 재사용이 가능하다.
“객체지향 프로그래밍도 차례대로 실행되잖아?” 차이점이 뭐지… ➡ 찾아봤는데 아직 설명하기 힘들다.
동적 타이핑 언어
변수를 선언할 때 타입을 지정하지 않는다. 런타임 시점에 변수에 할당되는 값에 따라 데이터 타입이 결정된다. ➡ Typescript 개념 공부할 때 이해했었다. TypeScript 등장의 이유.
함수형, 명령형, 비동기, 클라이언트 & 서버 개발 가능 등………
💬 일단 KEEP. 지금은 이해가 어렵다. 나중에 다시 보자
2. 변수
변수란 무엇인가? 왜 필요한가?
애플리케이션은 데이터를 입력받아 처리하고 그 결과를 출력하는 것이 전부이다.
예를 들어 10과 20을 더하는 자바스크립트 코드를 실행한다고 하자.
10 + 20
위 코드를 계산하려면 10, 20, +
라는 기호의 의미를 알고, 10 + 20
이라는 식의 의미도 해석할 수 있어야 한다. 그래서, 자바스크립트 엔진이 10 + 20
이라는 식의 의미를 해석한다. + 연산을 수행하기 위해 피연산자(10, 20)를 메모리에 저장한다.
컴퓨터는 CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다. 역할이 나뉘어 있다. 숫자 10과 20은 메모리 상의 임의의 위치에 저장되고 CPU는 이 값을 읽어 연산을 수행한다.
메모리(memory)는 데이터를 저장할 수 있는 공간으로, 1바이트 단위의 2진수로 데이터를 저장하거나 읽는다.
자바스크립트는 메모리의 직접 접근을 허용하지 않는다. 그 이유는 운영체제가 사용하고 있는 값을 변경하면 시스템이 멈추는 오류가 발생할 수 있다. 게다가 메모리 상의 ‘임의의’ 위치에 저장되므로 매번 값이 저장될 메모리 주소가 변경된다. 미리 알 수도 없다.
➡ 안전하게 메모리에 접근하기 위해 변수라는 메커니즘을 제공한다
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름
💬 내가 그의 이름을 불러주기 전에는 그는 다만 하나의 몸짓에 지나지 않았다. 내가 그의 이름을 불러주었을 때, 그는 나에게로 와서 꽃이 되었다. - 꽃(김춘수)
이름을 안다는 것, 그 대상을 안다는 것
-
변수 이름: 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름
-
변수 값: 변수에 저장된 값
-
할당: 변수에 값을 저장하는 것
-
참조: 변수에 저장된 값을 읽어 들이는 것
식별자
식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다. 변수 이름도 식별자다.
구별하다: 성질이나 종류에 따라 갈라놓다.
식별하다: 분별(구별)하여 알아보다. (인식까지 포함)
e.g. 사람을 이름으로 구별해서 식별하다.
메모리 공간에 저장된 값을 구별해서 식별해낼 수 있으려면 값이 저장된 메모리 주소를 기억해야 한다. 식별자는 메모리 주소에 붙인 이름이라고 할 수 있다.
식별자는 값이 저장되어 있는 메모리 주소와 매핑 관계를 맺으며, 이 매핑 정보도 메모리에 저장되어야 한다.
💬 학부생 때 배운 컴퓨터 구조
식별자(변수)의 메모리 주소에 접근하면 값이 저장된 메모리 주소를 가리킨다!
변수 선언
변수 선언이란 값을 저장하기 위한 메모리 공간을 확보(allocate) 하고 변수 이름과 확보된 메모리 공간의 주소를 연결(name binding) 해서 값을 저장할 수 있게 준비하는 것이다.
변수를 사용하려면 선언이 필요하다. 변수 선언할 떄는 var, let, const
키워드를 사용한다.
var score; // 변수 선언
자바스크립트 엔진은 변수 선언을 2단계에 거쳐 수행한다.
-
선언 단계: 변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다
-
초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다. 초기화란 변수가 선언된 이후 최초로 값을 할당하는 것
초기화 단계를 거치지 않으면 확보된 메모리 공간에 이전에 다른 애플리케이션에서 사용했던 값이 남아 있을 수 있다. 하지만, 자바스크립트는 초기화 단계에서 암묵적으로 undefined를 할당해 초기화하기 때문에 이로부터 안전하다.
💬 var, const, let 차이는 추후 학습 예정
변수 선언의 실행 시점과 변수 호이스팅
console.log(score); // undefined
var score; // 변수 선언문
변수 선언문보다 변수를 참조하는 코드가 앞에 있다. 자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행된다. 선언되지 않은 변수에 접근하면 참조 에러가 발생한다. 변수 선언이 되지 않았는데 console.log(score);
의 결과로 undefined
이 출력된다.
➡ 변수 선언이 이미 되었다는 것.
자바스크립트 엔진은 소스코드 실행을 위한 준비 단계인 소스코드 평과 과정을 거친다. 변수 선언을 포함한 ‘모든 선언문’을 소스코드에서 찾아내 먼저 실행한다. 소스코드 평과 과정이 끝나면 선언문을 제외하고 소스코드를 순차적으로 실행.
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 한다.
모든 선언문은 런타임 이전 단계에서 먼저 실행된다.
var
키워드를 사용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행된다. let
은 선언과 초기화를 각각 진행한다. 변수를 사용한다고 알리긴 했으나 메모리를 할당받지 못해 접근이 불가능하다.
console.log(score); // ReferenceError: score is not defined
let score = 80;
💬 변수 선언 과정은 실행 컨텍스트에서 자세히 다룰 예정
값의 할당
변수에 값을 할당할 때는 할당 연산자 =
를 사용한다. 할당 한산자는 우변의 값을 좌변의 변수에 할당한다.
var score; // 변수 선언
score = 80; // 값의 할당
var score = 80; // 변수 선언과 값의 할
위의 두 코드는 정확히 동일하게 동작한다. 변수 선언과 값의 할당을 하나의 문(statement)로 단축 표현해도 2개의 문으로 나누어 각각 실행한다.
단, 변수 선언과 값의 할당의 실행 시점은 다르다.
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전, 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.
console.log(score); // undefined
var score = 80;
console.log(score); // 80
변수에 값을 할당할 떄는 이전 값 undefined가 저장되어 있던 메모리 공간에 80을 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그곳에 80을 저장한다.
💬 ‘모든 선언문’은 런타임 이전에!
값의 재할당
이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것을 재할당이라고 한다.
var score = 80;
score = 90;
var 키워드로 선언한 변수는 선언과 동시에 undefined로 초기화되기 때문에 사실 처음으로 값을 할당하는 것도 재할당이다.
위의 코드도 마찬가지로 새로운 메모리 공간을 확보하고 그 메모리 공간에 숫자 값 90을 저장한다.
💬 score의 메모리 주소가 가리키고 있는 주소만 변경되는 거겠지?
undefined과 80은 이제 어떤 식별자와도 연결되어 있지 않다. 즉, 더 이상 필요하지 않다는 것을 의미. 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동으로 해제된다.
값을 재할당할 수 없다면 변수가 아니라 상수(constant)이다.
식별자 네이밍 규칙
식별자는 어떤 값을 구별해서 식별해낼 수 있는 고유한 이름이라고 했다. 식별자는 네이밍 규칙을 준수해야 한다.
-
특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다
-
특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다 (왜?)
-
c++ - Why can’t variable names start with numbers? - Stack Overflow
-
컴파일러가 숫자 뒤의 알파벳에 도달할 때까지 컴파일러가 숫자인지 식별자인지 알 수 없기 때문에?
-
var 1 = 3;
-> 1은 숫자 1인가 3인가? 숫자로만 변수명을 사용하지 못한다는 것은 알았다. 그렇지만 숫자 뒤에 알파벳이 오면? -
var 1a = 3;
컴파일러가 a에 도달하면 식별자임을 알 수 있지 않나..? 정확한 이유는 모르겠다 -
추측하자면 식별자가 ‘구별’해서 ‘식별’해내기 위해서는 유일하고 명확해야하기 떄문이 아닐까
-
-
-
예약어는 식별자로 사용할 수 없다
식별자를 만들 때 유니코드 문자를 허용하지만 알파벳 외의 유니코드 문자로 명명된 식별자를 사용하는 것은 바람직하지 않다.
💬 이유를 찾아봤다.
ASCII가 아닌 유니코드 문자는 키보드 레이아웃에 따라 입력하기 어렵다. 가독성을 해친다. 모르는 언어로 변수명을 지정했다면.. 아찔하다
변수 이름은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현해야 한다.
네이밍 컨벤션은 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙이다. 4가지 유형의 네이밍 컨벤션이 자주 사용된다. 링크로 대체한다.
부족한 내용 / 궁금한 내용
- 자바스크립트의 특징 이해
- 식별자 네이밍 규칙 중 숫자+알파벳 으로 변수명을 짓지 않아야 하는 이유
느낀점
“다 아는 내용이지”라고 학습 진도가 쭉쭉 나갈 것 같았지만 변수부터 발목을 잡았다. 단순히 변수를 메모리 주소, 가리키는 이름 정도로만 이해했었는데 메모리 참조를 안전하게 하기 위함이라는 개념을 배웠다.
메모리 관점에서 변수 선언과 할당을 이해하고자 시간이 꽤 소요됐다. 그렇지만 추후 학습에 분명 도움이 될 것이라 생각한다.
학습한 내용을 간추리고 요약하는데 그치는 것이 아니라 여러 참고 자료를 바탕으로 다른 사람이 이해하기 쉽게 ‘나의 언어로’ 작성하기 ➡ 글로 작성하면서 설명할 수 있기까지의 이해가 되니까 ‘나의 지식’이 되는 듯