[JavaScript 스터디] 2. 기초: 변수, 자료형, 연산 & 함수
웹 사이트에 JavaScript 추가하기
html 내에 .js 파일을 script 태그를 통해 가져올 수 있다.
보통 head에 지정을 해주나, html 문서가 모두 렌더링 된 다음 js 코드를 작동시키고 싶다면 body의 맨 끝에 추가해준다.
변수와 상수
변수는 let, 상수는 const로 선언 - 상수는 값을 변경할 수 없으며, 가급적 자주 사용하는 것이 좋다.
상수는 값 변경할 수 없고 용도가 제한적이기 때문에 해당 코드의 의도를 명확히 보여줄 수 있다.
코드 수명 주기 전반에 걸쳐 절대 변하지 않는 값이 있을 때 이를 명확히 함으로써, 다른 개발자가 코드를 읽을 때 이 데이터는 절대 변하지 않는다는 것을 바로 알려줄 수 있다.
→ 코드의 명확한 이해를 돕는다.
변수의 이름: 변수 내에 어떤 종류의 데이터가 저장되는지를 묘사하는 이름이 가장 좋다.
소문자로 시작하고 단어 내의 구분이 필요할 때는 대문자로 시작하는 방식이 표준적이다.
숫자를 사용할 수 있으며(숫자로 시작하는 것은 유효하지 않음), 특수문자 '$', '_'를 어느 위치에나 사용할 수 있다.
키워드(예약어)로 변수명 짓는 것은 허용되지 않는다.
세미콜론(;)을 사용하는 것은 일반적으로 선택 사항이나, 강제적으로 사용해야 하는 경우도 존재한다.
ex. 한 줄에 두 개의 표현식이 들어가는 경우
let const a = 1; let const b = 2;
일부 튜토리얼에서는 세미콜론을 사용하지 않는 것을 권장하는 경우도 있다.
본 강의에서는 세미콜론을 사용하는 것을 권장한다.
→ 개인 취향에 따라 사용해도 무방
문자열 간단한 팁
작은 따옴표나 큰 따옴표를 출력하고 싶은 경우...
" '문자열' " → 작은 따옴표를 문자열로 출력하고 싶은 경우에 큰 따옴표로 다시 감싸주면 된다.
또한 \", \'와 같은 이스케이프 문자를 사용할 수도 있다.
템플릿 리터럴
백틱(`)과 ${} 표현식을 사용하여 더 편리하게 문자열 작업을 할 수 있다.
또한 줄바꿈과 공백을 쉽게 추가할 수도 있다. (가독성 이유만으로 사용되는 것은 바람직하지 않음)
let currentValue = 10; let description = `(${currentValue} + 10) * 3 / 2 - 1` // (10 + 10) * 3 / 2 - 1 출력됨
연산자 +로 문자열을 접합하는 것도 허용된다.
단, 줄바꿈이나 공란은 무시된다. (개행 문자 '\n'을 사용하면 적용이 된다.)
String Escape Sequences
String - JavaScript | MDN
The String object is used to represent and manipulate a sequence of characters.
developer.mozilla.org
함수
Code on Demand
// 예제: 더하기 함수 만들기
const defaultResult = 0;
let currentResult = defaultResult;
let a = 1;
let b = 2;
function add(num1, num2) {
const result = num1 + num2;
//alert('The result is' + result);
return result; // result(정수) 리턴
}
currentResult = add(a, b); // add 함수의 리턴값 3이 currentResult에 할당됨
코드 순서의 (비)중요성
js, 즉 브라우저는 스크립트 로드 시 위에서부터 아래로 실행한다.
그러나 이는 전체 스크립트를 구문 분석하되, 바로 실행하는 것이 아니라 그저 위에서 아래로 읽기만 하는 것이다.
파일 내에서 함수를 찾게 되면 함수를 자동으로 맨위로 끌고 가 실행한다. - 스크립트 실행 전에 자동으로 모든 함수를 등록부터 함
함수를 맨 아래에 두더라도 위에 함수 선언을 따로 해줄 필요도 없다.
따라서 함수를 두는 위치는 상관이 없다. - 일관된 위치에 두는 것은 중요
함수를 간접적으로 실행하기
js의 어느 미래 시점에, 예를 들어 일부 이벤트가 발생할 때 해당 함수를 쓰고 싶을 경우가 있다.
이 경우에는 함수를 직접 호출하는 대신, js에 함수 이름을 제공하는 방식으로 실행한다.
someButton.addEventListener('click', add);
// 해당 버튼(someButton)이 클릭되면 add 함수를 실행해라.
// someButton.addEventListener('click', add()); 처럼 작성 않도록 주의
자료형 변환하기
(1) parseInt, parseFloat
parseInt로 문자열을 정수 형태로 변환할 수 있다. - parseFloat: 문자열을 실수 형태로 변환
const numText = '11';
const textNum = parseInt(numText);
(2) 숫자로 변환할 문자열 앞에 + 붙이기
let result = 0;
let a = 1, b = "2";
result = a + +b;
// result의 값은 3이 된다 - 앞의 +는 덧셈 기호, 뒤의 +는 문자열을 숫자로 변환하는 기호
parseInt, parseFloat가 원하는 종류의 숫자를 더 구체적으로 사용할 수 있게 해주기 때문에 권장된다.
(3) .toString
let result = 0;
let a = 1, b = "2";
result = a.toString + b;
// result는 a가 문자열로 붙으므로 12가 된다.
숫자 & 문자열 섞기 - 헷갈리는 부분
보통 다른 프로그래밍 언어에서는 정수형과 문자형을 섞으면 오류가 발생한다.
그러나 js는 생각보다 똑똑해서 정수형과 문자형이 섞여 있어도 -, / * 가 있는 간단한 연산은 해낸다.
정수 + '문자' 만 문자열 값을 반환하는데, 이는 js가 + 연산자로 텍스트를 결합할 수 있다는 특성이 있기 때문이다.
그리고 오직 +만 산술 연산자 중에서 유일하게 문자열을 지원한다. → -, /, * 은 유효하지 않음
3 + '3' == '33'
'hi' - 'i' == NaN
3 * '3' == 9
3 / '3' == 1
3 - '3' == 0
배열(Arrays)
let a = 1;
let b = 2;
let logEntries = []; // 배열 선언
// 새로운 요소를 배열에 추가 - push()
logEntries.push(a);
logEntries.push(b);
// +) js의 자체 기능: console.log() - 브라우저가 인식해 개별 콘솔로 작업 내용 출력
console.log(logEntries); // [1, 2] 출력
console.log(logEntries[1]); // 2 출력
console.log(logEntries[3]); // undefined 출력
객체(Objects)
타 프로그래밍 언어의 딕셔너리와 유사한 개념이다.
const logEntry = {
// key: value의 형태
operation: 'ADD',
prevResult: initialResult,
number: enteredNumber,
result: currentResult
};
// 배열에 객체를 넣을 수도 있고, 객체에 배열을 넣을 수도 있다.
// 자기 자신을 중첩할 수도 있다.
객체 데이터에 액세스하기
const logEntry = {
operation: 'ADD',
prevResult: initialResult,
number: enteredNumber,
result: currentResult
};
// (객체명).(키)를 통해 해당 키 값에 액세스할 수 있다.
console.log(logEntry.operation); // 'ADD' 출력
객체를 사용하는 재사용 가능한 함수 추가하기
function writeToLog( // 함수 writeToLog
operationIdentifier,
prevResult,
operationNumber,
newResult
) {
const logEntry = { // 객체 logEntry
operation: operationIdentifier,
prevResult: prevResult,
number: operationNumber,
result: newResult
};
}
// 함수를 호출하여 함수 내의 객체의 value들을 지정해줄 수 있다.
writeToLog('ADD', initialResult, enteredNumber, currentResult);
undefined, null & NaN
undefined
데이터가 없음을 나타내는 특수 데이터 유형
undefined를 직접 값으로 할당할 수 없다. - 이는 값을 할당한 적 없는 경우의 기본값일 뿐이기 때문
null
데이터가 없음을 나타내는 또 다른 데이터 유형, 객체 유형이다.
undefined와 유사하지만 null은 기본값이 될 수 없다.
null을 사용하려면 직접 설정해 주어야 함. → 변수를 재설정하거나 정리하고 싶을 때 자주 사용
undefined와 null은 빈 데이터를 관리 할 때 중요하다.
NaN
Not a Number의 약자, 일종의 오류 코드 - ex. 숫자가 포함되지 않은 무언가로 사칙연산 실행 하는 경우
undefined, null과 다르게 데이터 유형이 아닌 숫자 값 유형
숫자를 사용하는 계산에만 사용 가능하다. - NaN은 그 계산의 결과가 유효하지 않다는 의미
왜 유효하지 않은 계산을 실행할까?
js에서는 동적인 코드 작성이 가능하기 때문에 NaN인 사용자 입력으로도 계산을 실행하긴 한다.
또한 유효하지 않은 결과를 얻은 경우, 이를 비교하거나 if문을 사용해 코드를 검증할 경우에 유용하게 사용된다.
Typeof 연산자
typeof 키워드는 런타임에서 변수 유형을 평가한다.
어떤 유형의 데이터로 작업하고 있는지 이해하는데 사용한다.
let userName = 'Max';
typeof userName; // 출력: "String"
typeof 1; // "number"
typeof 1.1; // "number"
typeof true; // "boolean"
typeof [1, 2, 3]; // "object" - 배열도 객체의 한 유형
typeof {name: 'Max', age: 30} // "object"
typeof undefined; // "undefined" - 그 자체로 유형
typeof null; // "object" - null도 객체의 한 유형
typeof NaN; // "number" - 자체 유형도 가지지 않는 숫자
defer & async를 사용해 스크립트 올바르게 임포트하기
위 코드처럼 html 파일 하단(body)에 script를 임포트 하는 것은 1) html 구문 분석이 끝나고 나서 2) 스크립트가 로드되고 3) 실행된다는 것이다.
그렇게 되면 분석이 끝나기 까지 모두 기다려야 하기 때문에 html 파일과 스크립트 실행 사이에 일시 정지가 발생하게 된다.
(inspector 창의 performance 섹션 - record를 통해 실행 시간을 확인 가능하다.)
스크립트가 길어지면, 즉 파일 크기가 커지면 로드 및 실행에 더 오랜 시간이 걸리고, 구문 분석할 html 코드가 훨씬 더 많아진다. - 지연시간이 늘어나므로 실제 웹 서버에서 호스팅하는 경우 효율적이지 않다.
이 경우에는 js 파일이 html 콘텐츠에 의존하기 때문에 구문 분석 후에 실행하고자 하는 것인데, 스크립트 실행은 하지 않더라도 스크립트를 미리 로딩하거나 서버에서 다운로드 하는 것이 좋은 방법이 될 수 있다.
이상적인 시나리오에서도 불필요한 지연이 발생하지 않도록 실제 웹 서버에서 호스팅할 것을 생각해 지연을 확실하게 줄여야 한다.
전체가 구문 분석된 후에 로딩을 시작하는 것이 아니라 최대한 빨리 스크립트를 먼저 로드하고 html 구문 전체가 분석된 후에 실행하도록 해서 일석이조의 효과를 얻는 것이다.
head에 스크립트를 임포트 하는 경우, 1) html 구문 분석이 시작될 때 2) 스크립트를 다운로드하고(이 때 구문 분석이 일시정지), 3) 스크립트를 실행하고 나서 4) 다시 구문 분석을 계속 하게 된다.
하지만 이 또한 오류가 발생하므로 좋지 않은 방법이다. → 웹 페이지 버튼이 준비되지 않은 상태에서 상호작용을 시도하는 것
미리 스크립트를 다운로드 한 것은 좋지만 밥상 차려지기도 전에 너무 빨리 실행했다.
defer
script 태그에 추가할 수 있는 추가적인 속성으로, 특별한 값 없이 추가한다.
head에 임포트함과 동시에 defer 속성을 부여하면, 1) html 구문 분석을 하면서 2) 동시에 스크립트를 미리 다운로드한다.
그리고 3) html 구문 분석이 끝난 뒤에 스크립트가 실행된다.
이 때 스크립트 다운로드와 실행은 html 코드의 구문 분석과 렌더링을 차단하지 않는다.
defer는 두 가지 장점을 모두 활용하게 된다. - 1. 지연시간 감소, 2. 오류 방지
스크립트 실행 순서는 무조건 html 파일 내에 작성된 순, 즉 임포트 된 순서로 진행 된다. → 실행 순서 보장
async
가끔은 js 파일이 html 코드에 의존하지 않아서 연결을 하지 않아도 되는 경우가 있다. → html 구문 분석의 완료 여부가 중요하지 않다.
async 키워드를 사용하면 스크립트가 다운로드 되는 즉시 가능한 빠르게 실행 된다는 점이다.
defer 키워드와 유사한 점은 브라우저에 1) html 구문 분석과 동시에 2) 스크립트를 최대한 빨리 로드한다.
그 동안은 html 구문 분석이 차단되지 않고 계속 진행된다.
차이점은 3) 스크립트가 다운로드 완료되면 바로 실행되고, 스크립트가 실행되는 동안에는 html 구문 분석이 일시정지 된다.
실행이 끝나고 나서야 4) html 구문 분석은 재개 된다.
이는 html 코드가 구문 분석 되기전에 스크립트가 실행되므로 이론상 올바른 솔루션은 아니다.
하지만 스크립트가 웹 페이지와 상호작용 하지 않고 백그라운드 서버에 일부 데이터만 전송하는 경우라면 async를 사용해도 무방한 것이다.
async는 순서가 보장되지 않아서 간혹 뒤에 임포트 된 스크립트가 먼저 로드되는 경우 앞의 임포트 스크립트보다 먼저 실행될 수도 있다.
async는 html 콘텐츠에 의존하지 않는 독립 실행형 스크립트용 솔루션이다.
defer와 async는 외부 스크립트에서만 사용 가능하다. 내장된 스크립트를 defer와 함께 인라인 형식으로 임포트하는 경우 다운로드 할 파일 자체가 없으므로 렌더링 시 파일의 실행 시간만 소요된다. 이는 아무 키워드 없이 script 태그만으로 임포트하는 경우와 똑같다.
JavaScript Import Timeline

유용한 사이트
MDN JavaScript 기초
JavaScript | MDN
JavaScript (JS)는 가벼운, 인터프리터 혹은 just-in-time 컴파일 프로그래밍 언어로, 일급 함수를 지원합니다. 웹 페이지를 위한 스크립트 언어로 잘 알려져 있지만, Node.js, Apache CouchDB, Adobe Acrobat처럼
developer.mozilla.org
MDN 변수
필요한 정보를 저장하기-변수 - Web 개발 학습하기 | MDN
앞선 두 수업을 듣고, 자바스크립트에 대해(웹 기술에서 어떻게 사용되는지, 큰 범위에서의 특징) 알아보았다. 이번 수업에서는 기본중에 기본인 자바스크립트의 주된 구성중 하나인 변수가 어
developer.mozilla.org
MDN 연산자
JavaScript의 기본적인 연산 - 숫자와 연산자 - Web 개발 학습하기 | MDN
이 장은 JavaScript의 연산에 대해 다룹니다. 능숙하게 숫자를 다루기 위해 어떻게 연산자 와 그 외 기능을 사용하는지 알아봅니다.
developer.mozilla.org
MDN 함수
함수 — 코드 재사용 - Web 개발 학습하기 | MDN
코딩에 있어서 또 하나의 필수적인 개념은 함수인데, 이는 하나의 일을 하는 코드 조각을 정의된 블록 안에 저장하고, 같은 코드를 여러 번 타이핑하기보다는, 하나의 짧은 명령을 사용하여 여
developer.mozilla.org
MDN 배열
배열(Arrays) - Web 개발 학습하기 | MDN
이 모듈의 이 마지막 문서에서, 우리는 배열을 살펴볼 것입니다. 배열이란 하나의 변수명 아래에 데이터 아이템의 리스트를 저장하는 간편한 방법입니다. 여기서 우리는 왜 배열이 유용한지 보
developer.mozilla.org
MDN 객체
JavaScript 객체 기본 - Web 개발 학습하기 | MDN
이 글에서는 JavaScript 객체와 관련된 기본적인 문법을 살펴보고 이전 코스에서 학습해서 이미 알고 있는 JavaScript 의 특징들과 우리가 이미 사용하고 있는 기능들이 이미 객체와 관련되어 있다는
developer.mozilla.org