1장 자바스크립트 기초
Updated:
처음 만나는 자바스크립트
자바스크립트가 어떤 언어이고, 어떤 목적으로 개발되었는지 알아본다.
자바스크립트는 어떤 언어인가?
인터넷 웹 페이지는 다음과 같은 세 개의 언어로 만들어 진다.
- HTML(HyperText Markup Language): 텍스트, 이미지, 버튼, 메뉴 등과 같이 웹 페이지에 나타나는 모든 요소의 배치와 내용을 기술하는 언어
- CSS(Cascading Style Sheets): 색상이나 크기처럼 웹 페이지 요소의 스타일을 정할 때 사용하는 언어
- 자바스크립트: 사람의 근육처럼 웹 페이지에 동적인(움직임이 있는) 기능을 장착할 수 있게 도와주는 언어
자바스크립트는 어떻게 실행되나?
자바스크립트는 ‘자바스크립트 엔진’이라는 프로그램이 해석해 실행한다. 자바스크립트 엔진은 기본적으로 웹 브라우저에 탑재되어 있다.
웹 에디터로 자바스크립트 편집하기
코드샌드박스는 샌드박스(sandbox) 단위로 웹 언어를 입력하고 편집할 수 있는 웹 에디터이다. 이 에디터는 코드샌드박스 사이트에 접속하면 편리하게 코딩할 수 있는 환경을 제공한다.
변수와 상수
변수
변수란 프로그램을 실행하는 과정에서 변경될 수 있는 값을 저장하는 저장소이다. 또한 변수는 어떤 값을 이름으로 가리킬 떄 사용하는 기능이기도 하다. 자바스크립트에서 변수는 다음과 같이 만든다.
let age = 25;
변수는 이름으로 구분하기 때문에 let으로 변수를 선언할 때는 이름을 중복해서 사용할 수 없다. 자바스크립트에서 키워드 var로도 변수를 선언할 수 있다.
var age = 25;
var를 이용한 변수 선언은 let과는 달리 이름을 중복해 선언해도 실핼할 수 있다. 그러나 변수를 선언하면서 같은 이름을 또 쓸 수 있도록 허용하면, 코드가 많아지고 복잡해질 때 프로그래머가 실수할 가능성이 커진다. var를 사용하면 혼란을 야기하고 코드의 복잡도를 높이는 까닭에 가급적 변수 선언 키워드로는 let을 사용해야 한다.
상수
상수 역시 변수처럼 이름을 가진 저장 공간이다. 그러나 상수는 변수와 달리 프로그램 실행 과정에서 변경할 수 없다.
const age = 25;
상수는 절대 변하지 않는 값을 저장할 때 사용하는 이름이다.
자료형
자료형과 원시 자료형
자료형(Type)이란 값을 성질에 따라 분류한 것이다. 자바스크립트는 자료형을 크게는 원시(Primitive Type) 또는 객체 자료형(Object Type, Non-Primitive Type: 비 원시 타입)으로 나누고, 작게는 8개의 세부 자료형으로 나눈다. 원시 자료형은 원시 타입 또는 기본 타입이라고 한다. 원시 자료형은 한 번에 단 하나의 값만 가질 수 있는 타입이다. 객체 자료형은 객체, 배열, 함수이다.
숫자형
자바스크립트에서 숫자형(Number Type)은 수의 종류를 구분하지 않는다. 즉, 소수, 음수, 실수와 같은 수를 모두 포함한다.
let age = 25;
let tall = 175.9;
let minus = -20;
숫자형에는 정수, 실수 말고도 일반적이지 않은 몇 가지 값이 있다.
let inf = Infinity;
let minf = -Infinity;
let nan = NaN;
Infinity는 양의 무한대, -Infinity는 음의 무한대를 의미하는 값이다. 이 값은 최솟값이나 최댓값을 구할 때 주로 사용한다. 또한 Infinity는 0으로 어떤 수를 나눈 결과이기도 하다. 자바나 C 언어에서는 0으로 어떤 수를 나누면 오류가 발생하지만, 자바스크립트는 Infinity라는 결과를 얻게 된다. NaN은 Not a Number라는 뜻으로 표현이 불가능한 숫자형의 결과를 표현할 때 사용하는 값이다. 예를들어, 숫자와 문자열을 곱하면 정상적인 연산의 결과물이 나올 수 없으므로 NaN이라는 값을 얻는다.
문자형
문자형(String Type)은 가람의 이름과 같은 문자열을 포함하는 자료형이다.
let myName = "이정환";
문자형에 덧셈 연산자를 사용하면 두 개의 문자를 이어 붙이고 벡터(``)를 이용해도 문자형을 만들 수 있다.
let name = "이정환";
let welcomeText = '님 반가워요!'; // 작은따옴표를 이용
let resultWelcomeText = name + welcomeText;
console.log(resultWelcomeText); // 이정환님 반가워요!
let guestName = `이정환`; // 벡터 사용
벡터를 이용하면 문자형 사이에 변수를 사용할 수 있어, 값이 변하는 동적인 문자열을 생성할 때 유용하다. 벡터를 이용한 문자열을 “템플릿 리터럴(Template Literal)”이라고도 한다.
let name = "이정환";
let location = "역곡";
let introduce = `${name}은 ${location}에 살고 있습니다.`;
console.log(introduce); // 이정환은 역곡에 살고 있습니다.
불리언, null, undefined
불리언 형(Boolean Type)은 참(true) 또는 거짓(false)만을 저장하는 자료형이다. null은 “아무것도 없다”라는 뜻으로, 변수에 아무런 값도 할당할 필요가 없을 때 사용한다. undefined는 “미정의 값”이라는 뜻이다. 정상정인 할당이 이루어지지 않았을 때 자동으로 할당되는 undefined는 자바스크립트 프로그래밍에서 상당히 많은 오류를 일으킨다.
형 변환
형 변환에는 프로그래머가 의도적으로 자료형을 변환하는 ‘명시적 형 변환’과 자바스크립트 엔진이 알아서 변환하는 ‘묵시적 형 변환’이 있다.
묵시적 형 변환
묵시적 형 변환은 자바스크립트 엔진이 스스로 알아서 변환하는 작업이다.
let number = 10;
let string = "20";
const result = number + string;
console.log(result); // 1020
위는 자바스크립트가 암묵적으로 숫자를 문자로 형 변환해 계산했기 때문이다.
명시적 형 변환
명시적 형 변환은 묵시적 형 변환과 반대로 내장 함수 등을 이용해 프로그래머가 의도적으로 어떤 자료형을 다른 자료형으로 변경하는 작업이다.
숫자형으로 변환
let strA = "10";
let strB = "10개";
let numA = Number(strA);
let numB = Number(strB);
console.log(numA); // 10
console.log(numB); // NaN
함수 Number는 자바스크립트가 기본적으로 제공하는 내장 함수로, 제공된 문자열을 숫자로 변환해 반환한다. 그러나 변수 strB처럼 숫자가 아닌 문자를 포함한 문자열은 정상적으로 변환되지 않기 때문에 NaN을 반환한다.
만약 숫자뿐만 아니라 문자열도 함께 포함된 문자열을 숫자로 변환하고 싶다면, 함수 parseInt를 사용한다.
let strA = "10";
let strB = "10개";
let numA = parseInt(strA, 10);
let numB = parseInt(strB, 10);
console.log(numA); // 10
console.log(numB); // NaN
함수 parseInt는 Number처럼 괄호 안에 있는 문자열을 숫자로 변환하는 자바스크립트의 내장 함수 이다. Number과 달리 괄호 안에 두 개의 값을 콤마로 구분해 전달하는데, 첫 번째 값은 변환하려는 문자열이고, 두 번째 값은 진수이다.(10진수는 안해도 됨.) 만약 문자열의 첫문자부터 숫자가 아닌 문자로 시작한다면 함수 parseInt는 NaN을 반환한다.
문자열로 변환
let num = 2022;
let str = String(num);
console.log(str); // 2022
String은 자바스크립트 내장 함수로 인수로 제공한 값을 문자열로 변환해 반환한다.
let varA;
let varB = null;
let varC = true;
let strA = String(varA);
let strB = String(varB);
let strC = String(varC);
console.log(strA); // undefined
console.log(strB); // null
console.log(strC); // true
undefined값은 문자열 undefined, null 값은 문자열 null, true 값은 문자열 true로 변환된다.
불리언으로 변환
불리언 값으로 변환하는 내장 함수는 Boolean이 있다.
let varA = "하이";
let varB = 0;
let varC = "";
let boolA = Boolean(varA);
let boolB = Boolean(varB);
let boolC = Boolean(varC);
console.log(boolA); // true
console.log(boolB); // false
console.log(boolC); // false
연산자
대입 연산자
대입 연산자(=)는 가장 기본이 되는 연산자로서 변수에 값을 할당하는 역할을 한다.
산술 연산자
산술 연산자는 덧셈(+), 뺄샘(-), 곱샘(*), 나눗셈(/), 나머지 연산(%)처럼 프로그래밍에 필요한 가장 기본적인 계산 기능을 수행하는 연산자이다.
복합 대입 연산자
복합 대입 연산자는 대입 연산자와 산술 연산자의 기능을 함께 이용할 때 사용한다. 복합 대입 연산자는 산술 연산자와 대입 연산자를 서로 이어 붙여 사용한다.
증감 연산자
증감 연산자는 값을 1씩 늘리거나 줄일 때 사용하는 연산자이다. 이 증감 연산자는 덧셈 또는 뺄셈 연산자를 두 개 연달아 붙여 사용한다.
논리 연산자
논리 연산자는 참(true)과 거짓(false)을 포함하는 불리언 값을 다룰 때 사용하는 연산자이다. 논리연산자에는 3종류가 있다.
논리 연산자 | 설명 |
---|---|
OR(||) | 둘 중 하나라도 참이면 참 |
AND(&&) | 둘 중 하나라도 거짓이면 거짓 |
NOT(!) | 참이면 거짓, 거짓이면 참 |
비교 연산자
비교 연산자는 말뜻 그대로 두 값을 비교하는 연산자이다.
비교 연산자 | 설명 |
---|---|
=== | 같다(== 연산자는 값만 비교할 뿐 자료형은 비교하지 않음) |
!== | 같지 않다(값과 자료형 중 하나라도 다르면 참, != 연산자는 자료형을 비교하지 않음) |
> | 크다 |
>= | 크거나 같다 |
< | 작다 |
<= | 작거나 같다 |
null 병합 연산자
null 병합 연산자(Nullish Coalescing Operator)는 값이 확정된 변수를 찾을 때 사용하는 연산자이다. 자바스크립트에서는 값이’없음’을 나타내는 자료형으로 null과 indefined가 있다. null이나 undefined가 있는 변수를 값이 확정되지 않은 변수라고 한다. null 병합 연산자 ??를 사용하면, 값이 확정된 변수를 쉽게 찾아 낼 수 있다.
let varA = 10;
let varB = 20;
let varC;
console.log(varA ?? varB); // 10, null 병합 연산자에서는 ?? 연산자 기준 왼쪽의 값을 연산 결과로 반환
console.log(varC ?? varB); // 20, null 병합 연산자는 값이 확정된 변수인 varB의 값을 연산 결과로 반환
실무에서 null 병합 연산자를 이용하면 다음과 같은 상황을 간단하게 해결할 수 있다.
let name;
let nickname = "Winterload";
let user = name ?? nickname;
console.log(user); // Winterload
동적 타이핑과 typeof 연산자
자바스크립트는 변수에 숫자를 저장했다가 문자로 바꿔도 오류가 발생하지 않는다. 자바스크립트 변수는 값을 저장할 때마다 자료형이 동적으로 결정되기 때문이다. 저장하는 변숫값에 따라 변수의 자료형도 함께 변경되는 특징을 ‘동적 타이핑(Dynamic Typing)’이라고 한다.
자바스크립트 자료형의 이러한 유연함은 때로는 단점이 되기도 한다. 프로그래머가 변수의 자료형이 변경되었다는 사실을 모르고 코드를 작성하면 프로그램이 의도하지 않게 동작하거나 오류가 발생할 수 있다. 이런 상황을 대비해 typeof 연산자를 이요해 변수의 자료형을 확인할 수 있다.
let varA = 1;
varA = '이정환';
console.log(typeof varA); // string
삼항 조건 연산자
삼항 조건 연산자(삼항 연산자)는 유일하게 자바스크립트에서 3개의 피연산자를 취하는 연산자이다. 삼항 연산자는 다음과 같이 ? 앞에 조건식을 작성하고 클론(:)을 기준으로 앞은 조건식이 참일 때 그리고 뒤는 조건식이 거짓일 때 수행할 명령을 작성하면 된다.
조건식 ? 참일 때 명령 수행 : 거짓일 때 명령 수행
조건문
조건문이란 특정 조건을 만족할 때 원하는 동작을 수행하게 하는 프로그래밍의 기본 문법중 하나이다. 자바스크립트의 조건문에는 if문과 switch/case 문이 있다.
if 문
if 문은 if 키워드 다음의 소괄호(())애 조건식을 입력하고, 중괄호({})에서는 해당 조건식이 참일 때 수행할 명령을 입력한다. if 문에서 else를 사용하여 거짓일 때 수행할 명령을 추가할 수 있다. else if문은 두 개 이상의 조건이 있는 경우 사용하는 조건문이다.
switch 문
switch 문은 중첩 if 문처럼 비교할 조건이 많을 때 사용하는 조건문이다. switch 문은 식이나 값을 case 문과 비교해 정확히 일치할 때만 수행한다. switch 문에서는 break 문을 사용하는데 case 문에서 수행할 명령을 작성하고, break를 입력해 “실행할 명령이 끝났다.”라고 알려주어야 한다. break 문을 작성하지 않아도 오류가 발생하지는 않는다. 그거나 break를 입력하지 않으면, 조건식과 일치해 실행한 case 문 이후의 명령까지 모두 차례로 수행한다.
반복문
프로그래밍에서 동일하거나 유사한 동작이 반복해서 나올 때는 반복문(Loop)을 사용한다.
반복문의 유용성과 for문
자바스크립트의 반복문에는 for 문, while 문, do while 문 등이 있다.
반복문 강제 종료하기, 건너뛰기
break 문을 사용하면 조건식에서 정의한 반복문의 종료 조건과 상관없이 반복을 강제로 종료할 수 있다. continue 문은 break 문과 유사하게 동작하지만, 반복을 멈추는 대신 다음 반복 과정으로 건너뛴다.
함수
자바스크립트에서는 공통으로 사용하는 유사 코드를 하나로 묶어 ‘함수’라는 이름으로 사용할 수 있다.
함수가 필요한 이유
함수를 사용하면 유사하게 동작하는 중복 코드를 하나의 블록 단위로 묶을 수 있다. 그리고 이 블록에 이름을 붙여 원할 때마다 호출해 사용할 수 있다.
함수 선언
자바스크립트에서는 기본적으로 다음과 같이 함수를 만든다.
function 함수 이름 (매개변수) {
함수가 수행하는 명령
}
함수 호출
함수는 이름을 불러 주어야 실행되는데, 이를 ‘함수 호출’이라고 한다.
함수의 인수와 매개변수
자바스크립트에서는 ‘인수’와 ‘매개변수’라는 기능을 이용해 함수를 호출하면서 값을 주고받는다. 인수는 함수를 호출하면서 넘겨주는 값이고, 매개변수는 함수에서 넘겨받은 인수를 저장하는 변수이다.
함수 반환
자바스크립트의 함수에서 값을 반환하려면 return 문을 사용한다.
중첩 함수
자바스크립트는 함수 내에서 또 다른 함수를 선언할 수 있다. 특정 함수 내부에서 선언된 함수를 ‘중첩 함수(Nested Function)’라고 한다. 중첩 함수를 많이 두면 가독성을 헤치는 단점이 있으나, 적절히 활용하면 함수 내에서 서로 역할을 분담할 수 있어 중복 코드를 방지하는 데 도움이 된다.
함수의 호이스팅
호이스팅(Hoisting)이란 프로그램에서 변수나 함수를 호출하거나 접근하는 코드가 함수 선언보다 위에 있음에도 불구하고, 마치 선언 코드가 위에 있응 것처럼 동작하는 자바스크립트만의 독튿한 기능이다.
자바스크립트에서 함수는 선언하기 전에도 호출할 수 있는데, 이런 기능을 ‘호이스팅’이라고 한다. 이런 현상이 일어나는 이유는 자바스크립트의 내부 알고리즘때문이다. 자바스크립트는 코드를 실행하기 전에 준비 단계을 거친다. 준비 단계에서 중첩 함수가 아닌 함수들은 모두 찾아 미리 생성해 둔다. 자바스크립트 코드는 이런 준비 단계를 거친 다음에 실행된다. 따라서 함수 선언 코드를 호출보다 늦게 작성해도 자연스럽게 호출할 수 있다.
함수 표현식
자바스크립트는 함수 선언 말고도 함수를 만드는 또 다른 방법이 있다. 바로 ‘함수 표현식’을 이용하는 방법이다. 함수 표현식이란 함수를 생성하고 변수에 값으로 저장하는 방법이다.
let greeting = function() {
console.log("hello");
};
greeting(); // hello
자바스크립트에서는 함수를 숫자나 문자열처럼 값으로 취급한다. 그래서 변수에 함수를 저장할 수 있다. 변수에 함수를 저장하면 변수 이름으로 호출할 수 있다. 이렇게 함수를 변수의 값으로 저장해 생성하는 방법을 함수 표현식이라고 한다.
위 코드에서 함수를 만들 때 이름을 생략했다. 이런 함수를 ‘익명 함수’라고 한다.
함수 표현식으로 만든 함수는 함수 선언으로 만든 함수와는 달리 호이스팅되지 않는다.
콜백 함수
함수는 다른 함수의 인수(= 값)로도 전달할 수 있는데, 이를 ‘콜백 함수(Callback Function)’라고 한다.
화살표 함수
화살표 함수는 익명 함수를 매우 간결하게 작성할 때 사용하는 함수 표현식의 단축 문법이다. 화살표 함수는 다음과 같은 형식으로 사용한다.
let funcA = (매개변수) => 반환값;
화살표 함수 funcA는 다음 함수와 동일하다.
let funcA = function() {
return 반환값;
};
스코프
자바스크립트의 변수와 함수는 생성과 동시게 접근하거나 호출할 때 일정한 제약을 갖는데, 이를 스코프(Scope)라고 한다. 스코프는 변수나 함수의 제약 범위를 뜻한다.
전역, 지역 스코프
변수가 전역 스코프를 갖는다는 것은 해당 변수를 코드 어디에서나 접근할 수 있다는 의미이다. 반면 변수가 지역 스코프르 갖는다는 것은 특정 영역에서만 해당 변수에 접근할 수 있다는 의미이다.
블록, 함수 스코프
자바스크립트의 변수나 함수는 중괄호로 둘러싸인 부분을 뜻하는 ‘블록(Block)’을 기준으로 지역 스코프가 결정된다. 블록 기준으로 지역 스코프를 정한다고 해서 ‘불록 스코프’리고한다. 대다수의 언어는 변수를 선언한 블록에 따라 지역 스코프가 정해진다.
그러나 자바스크립트의 지역 스코프는 블록 스코프 외에도 한가지 더 있다. 바로 함수를 기준으로 지역 스코프를 정하는 ‘함수 스코프’이다.
객체
객체는 숫자형이나 문자형과 같은 원시 자료형과 달리 다양한 값을 담는 자료형이다.
객체 생성과 프로퍼티
자바스크립트에서는 2가지 방법으로 객체를 생성할 수 있는데, 다음과 같이 ‘리터럴’ 또는 ‘생성자’ 문법을 사용한다.
let objA = {}; // '객체 리터럴' 문법
let onjB = new Object(); // '객체 생성자' 문법
객체 프로퍼티 다루기
객체는 key와 value로 이루어진 프로퍼티의 모음이다. 객체에서 프로퍼티를 찾고, 추가하고, 삭제하는 등의 모든 연산은 key를 이용해 수행한다. key를 이용하면 객체의 프로퍼티에 접근할 수 있다.
let person = {
name: "이정환",
age: 25,
"like cat": true
};
const personName = person.name;
const personAge = person["age"];
console.log(personName); // 이정환
console.log(personAge); // 25
새로운 프로퍼티를 추가하는 방법은 다음과 같이 점 표기법과 괄호 표기법을 이용해 새로운 프로퍼티를 추가할 수 있다.
let person = {
name: "이정환",
age: 25,
"like cat":true
};
person.gender = "male";
person["nickname"] = "Winterlood";
console.log(person.gender); // male
console.log(person["nickname"]); // Winterlood
다음은 객체의 프로퍼티를 수정하는 예이다.
let cat = {
name: "치삼이",
age: 4
};
cat.name = "치삼";
cat["age"] = 5;
console.log(cat); // {name: "치삼", age: 5}
다음은 프로퍼티를 삭제하는 예이다.
let cat = {
name: "치삼이",
age: 4
};
delete cat.name;
delete cat["age"];
console.log(cat); // {}
배열
배열은 순서가 있는 요소의 집합이자 여러 개의 항목을 담는 리스트이다.
배열 선언
자바스크립트에서는 두 가지 방법으로 빈 배열을 생성한다.
let arrA = new Array(); // 배열 생성자
let arrB = []; // 배열 리터럴
배열 인덱스
배열과 객체 둘 다 여러 데이터를 저장할 수 있고, 저장할 데이터릐 자료형에도 아무런 제약이 없다. 배열과 객체의 차이점은 객체는 key가 있지만 배열은 그렇지 않다는 점이다.
객체에서는 특정 데이터에 접근할 때 key를 이용하지만, 배열은 데이터의 위치를 key처럼 사용할 수 있는 인덱스가 있다. 배열에서 특정 데이터에 접근하려면 데이터의 위치를 나타내는 인덱스를 객체의 괄호 표기법처럼 사용하면 된다.
let food = ["짜장면", "피자", "치킨"];
console.log(food[0]); // 짜장면
console.log(food[1]); // 피자
console.log(food[2]); // 치킨
인덱스란 배열 요소의 위치를 0부터 시작하는 숫자로 순서대로 표현한 것이다. 배열은 인덱스 기능을 이용해 배열 food의 요소를 짜장면 0, 피자 1, 치킨 2와 같이 순서대로 번호를 매긴다.
댓글남기기