• 제어문은 조건에 따라 코드 블록을 실행(조건문)하거나 반복 실행(반복문)에 사용하여 코드의 실행 흐름을 인위적으로 제어
  • 코드의 실행 순서가 변경된다는 것은 직관성이 떨어짐. forEach, map, filter, reduce 같은 고차 함수를 사용하여 복잡성을 해결하려고 하기도 함

블록문

  • 블록문 block statement / compound statement은 0개 이상의 문을 중괄호로 묶은 것, 코드 블록 또는 블록이라고 부름
  • 자바스크립트는 블록문을 하나의 실행 단위로 취급
  • 문의 끝에는 일반적으로 세미콜론을 붙이나, 블록문은 언제나 문의 종료를 의미하는 자체 종결성을 갖기 때문에 블록문의 끝에는 세미콜론을 붙이지 않음
// 블록문
{
  var foo = 10;
}

// 제어문
var x = 1;
if (x < 10) {
  x++;
}

// 함수 선언문
function sum(a, b) {
  return a + b;
}

조건문

  • 조건문 conditional statement은 주어진 조건식 conditional expression의 평가 결과에 따라 코드 블록(블록문)의 실행을 결정
  • 조건식은 불리언 값으로 평가될 수 있는 표현식
  • 자바스크립트는 두 가지 조건문을 제공
    • if ... else 문
    • switch

if ... else 문

  • if ... else 문은 주어진 조건식(불리언 값으로 평가될 수 있는 표현식)의 평가 결과에 따라 실행할 코드 블록을 결정
  • if 문의 조건식이 블리언이 아닌 값으로 평가되면 자바스크립트 엔진에 의해 암묵적으로 불리언 값으로 강제 변환되어 실행할 코드 블록을 결정
  • 조건식을 추가하여 조건에 따라 실행될 코드 블록을 늘리고 싶을 경우 else if문 사용
  • 코드 블록 내의 문이 하나 뿐이라면 중괄호 생략 가능
  • 대부분의 if ... else 문은 삼항 조건 연산자로 바꿔 쓸 수 있음
    • 삼항 조건 연산자는 값으로 평가되는 표현식을 만들기 때문에 변수에 할당 할 수 있음
    • 조건에 따라 단순히 갑을 결정하여 변수에 할당하는 경우 if ... else문보다 가독성이 좋음
if (조건식1) {
  // 조건식1이 참이면 이 코드 블록이 실행
} else if (조건식2) {
  // 조건식2가 참이면 이 코드 블록이 실행
} else {
  // 조건식1과 조건식2가 모두 거짓이면 이 코드 블록이 실행
}
var num = 2;
var kind;

if (num > 0) kind = "양수";
else if (num < 0) kind = "음수";
else kind = "영";
var x = 2;
var result;

if (x % 2) {
  // 2 % 2 는 0이다. 이때 0은 false로 암묵적 타입 변환됨
  result = "홀수";
} else {
  result = "양수";
}

// 삼항 연산자
var xTernary = 2;
var resultTernary = x % 2 ? "홀수" : "짝수";

switch문

  • switch문은 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮김
  • case문은 상황을 의미하는 표현식을 지정하고 콜론으로 마치고, 그 뒤에 실행할 문들을 위치시킴
  • switch문의 표현식과 일치하는 case문이 없다면 실행 순서는 default문으로 이동, default문은 선택 사항
  • 폴스루 fall through: switch문에 break가 없을 경우 switch문을 탈출하지 않고, 그 이후의 모든 case문과 default문을 실행함
  • default문은 switch문의 마지막에 위치하므로 break를 생략함
  • if ... else문으로 해결할 수 있으면 switch문보다는 if ... else 문 사용 권장
switch (표현식) {
  case 표현식1:
    switch 문의 표현식과 표현식1이 일치하면 실행될 문;
    break
  case 표현식2:
    switch 문의 표현식과 표현식2가 일치하면 실행될 문;
    break
  case 표현식3:
    switch 문의 표현식과 표현식3가 일치하면 실행될 문;
    break
  default:
    switch 문의 표현식과 일치하는 case문이 없을 때 실행될 문;
}

반복문

  • 반복문 loop statement는 조건식의 평가 결과가 참인 경우 코드 블록을 실행, 그 후 조건식을 다시 평가하여 여전히 참인 경우 코드 블록을 다시 실행, 이는 조건식이 거짓일 때까지 반복
  • 자바스크립트는 세 가지 반복문 제공
    • for문
    • while문
    • do ... while문
  • 반복문을 대체할 수 있는 forEach 메서드, 객체의 프로퍼티를 열거하는 for ... in 문, ES6에 도입된 for ... of 문과 같은 반복문을 대체할 수 있는 다양한 기능이 있음

for 문

  • for문은 조건식이 거짓으로 평가될 때까지코드 블록을 반복 실행
  • for문의 변수 선언문, 조건식, 증감식은 모두 옵션이므로 반드시 사용할 필요는 없음. 어떤 식도 선언하지 않으면 무한 루프가 됨
  • for문 내에 for문을 중첩해 사용할 수 있음
// 가장 일반적으로 사용되는 for 문의 형태
for (변수 선언문 또는 할당문; 조건식; 증감식) {
  조건식이 참인 경우 반복 실행될문;
}

for (var i = 0; i < 2; i++){
  console.log(i);
  // 결과
  // 0
  // 1
}

for문의 실행 순서

// 주사위 2개를 굴렸을 경우 합이 6이 되는 모든 경우의 수 출력
for (var i = 1; i <= 6; i++) {
  for (var j = 1; j <= 6; j++) {
    if (i + j === 6) {
      console.log(i, j);
    }
  }
}

while 문

  • while문은 주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행, 조건식의 평가 결과가 거짓이 되면 코드 블록을 실행하지 않고 종료
  • 조건식의 결과가 불리언 값이 아니면 불리언 값으로 강제 변환하여 논리적 참, 거짓 구별
  • for 문은 반복 횟수가 명확할 때 주로 사용, while문은 반복 횟수가 불명확할 때 주로 사용
var count = 0;

// count가 3보다 작을 떄까지 코드 블록을 계속 반복 실행
while (count < 3) {
  console.log(count); // 0 1 2
  count++;
}
var count = 0;

while (true) {
  console.log(count);
  count++;
  // count가 3이면 코드 블록을 탈출
  if (count === 3) break;
}

do ... while 문

  • do ... while문은 코드 블록을 먼저 실행하고 조건식을 평가
  • 따라서 코드 블록은 무조건 한 번 이상 실행
var count = 0;

do {
  console.log(count);
  count++;
} while (count < 3);

break 문

  • 레이블 문 , 반복문(for, for ... in, for ... of, while, do ... while) 또는 switch 문의 코드 블록 탈출
  • 위 외에서 사용할 경우 SyntaxError 발생
  • 레이블문은 프로그램의 실행 순서를 제어하는데 사용, switch문의 case문과 defaul문도 레이블 문
  • 중첩된 for문에서 원하는 for문을 탈출할 경우 레이블 문 사용
// 레이블 문 label statement란 식별자가 붙은 문
foo: console.log('foo')
foo: {
  console.log(1);
  break foo;
  console.log(2);
}

console.log("Done!");
// 1
// Done!
// 중첩된 for문의 내부 for문에서 break문을 실행하면 내부 for문을 탈출하여 외부 for문으로 진입
// 내부 for문이 아니라 외부 for 문을 탈출하려면 레이블문 사용
outer: for (var i = 0; i < 3; i++) {
  for (var j = 0; j < 3; j++) {
    if (i + j === 3) break outer;
    console.log(i, j);
  }
}
console.log("Done!");
// 0 0
// 0 1
// 0 2
// 1 0
// 1 1
// Done!

continue문

  • continue문은 반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동시킴
// 문자열에서 특정 문자의 개수를 세는 겨우
var string = "Hello World!";
var search = "l";
var count = 0;

// 문자열은 유사 배열이므로 for문으로 순회 가능
for (var i = 0; i < string.length; i++) {
  if (string[i] !== search) continue;
  count++;
}

console.log(count); // 3

// 참고로 String.prototype.match 메서드를 사용해도 같은 동작
const regexp = new RegExp(search, "g");
console.log(string.match(regexp).length);

산술 연산자

  • 산술 연산자 arithmetic operator는 피연산자를 대상으로 수학적 계산을 수행해 새로운 숫자 값을 만듦
  • 산술 연산이 불가능할 경우 NaN을 반환
  • 피연산자의 개수에 따라 이항 산술 연산자와 단항 산술 연산자로 구분

이항 산술 연산자

  • 이항 binary 산술 연산자는 2개의 피연산자를 산술 연산
  • 부수 효과 side effect(피연산자의 값을 변경)가 없음
이항 산술 연산자 의미 부수 효과
+ 덧셈 x
- 뺄셈 x
* 곱셈 x
/ 나눗셈 x
% 나머지 x

단항 산술 연산자

  • 단항 unary 산술 연산자는 1개의 피연산자를 산술 연산하여 숫자 값을 만듦
  • 증가/감소(++/--) 연산자
    • 피연산자 값을 변경하는 부수 효과가 있음, 피연산자의 값을 변경하는 암묵적 할당이 이루어짐
      • 위치에 따라 의미가 있음
        • 피연산자 앞: 피연산자의 값을 증가/감소시킨 후 다른 연산 수행
        • 피연산자 뒤: 먼저 다른 연산을 수행한 후, 피연산자의 값을 증가/감소
단항 산술 연산자 의미 부수 효과
++ 증가 o
-- 감소 o
+ 어떠한 효과x, 음수를 양수로 반전x x
- 양수를 음수로, 음수를 양수로 반전한 값 x

문자열 연결 연산자

  • + 연산자는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작
  • 개발자의 의도와 관계없이 암묵적 타입 변환implicit coercion 또는 타입 강제 변환 type coercion이 발생하기도 함
// 문자열 연결 연산자
'1' + 2; // '12'

// 산술 연산자
1 + 2 // 3

// true는 1로 타입 변환
true + 1 // 2

// false는 0으로 타입 변환
false + 1 // 0

// null은 0으로 타입 변환
null + 1 // 0

// undefined는 숫자로 타입 변환 x
undefined + 1 // NaN

할당 연산자

  • 할당 연산자 assignment operator는 우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당
  • 좌항의 변수에 값을 할당하므로 변수 값이 변하는 부수효과 o
  • 할당문은 값으로 평가되는 표현식인 문으로서 할당된 값으로 평가
할당 연산자 동일 표현 부수 효과
= x = 5 x = 5 o
+= x += 5 x = x + 5 o
-= x -= 5 x = x - 5 o
*= x *= 5 x = x * 5 o
/= x /= 5 x = x / 5 o
%= x %= 5 x = x % 5 o
var x;

// 할당식은 표현식인 문
console.log((x = 10)); // 10

var a, b, c;

// 연쇄 할당 오른쪽에서 왼쪽으로 진행
a = b = c = 0;
console.log(a, b, c); // 0 0 0

비교 연산자

  • 비교 연산자 comparison operator는 좌항과 우항의 피연산자를 비교한 다음 그 결과를 불리언 값으로 반환
  • if문이나 for문과 같은 제어문의 조건식에서 주로 사용

동등/일치 비교 연산자

  • 좌항과 우항의 피연산자가 같은 값으로 평가되는지 비교해 불리언 값으로 반환
  • 동등 비교 loose equality 연산자: 비교 전에 암묵적 타입 변환을 통해 타입을 일치시킨 후 비교
  • 일치 비교 strict equality 연산자: 타입도 같고 값도 같은 경우에 한하여 true 반환
  • 동등 비교 연산자는 예측하기 어려운 결과를 나타내므로 일치 비교 연산자 사용 권장
  • NaN === NaN // false ; NaN은 자신과 일치하지 않는 값
  • 부동등 비교 연산자(!=)와 불일치 비교 연산자(!==)는 각각 동등 비교 연산자(==)와 일치 비교 연산자(===)의 반대 개념
비교 연산자 의미 사례 설명 부수 효과
== 동등 비교 x == y x와 y 값이 같음 x
=== 일치 비교 x === y x와 y 값과 타입이 같음 x
!= 부동등 비교 x != y x와 y 값이 다름 x
!== 불일치 비교 x !== y x와 y 값 또는 타입이 다름 x
// 동등 비교
5 == 5; // true
5 == "5"; // true
// 일치 비교
5 === 5; // true
5 === "5"; // false
// NaN은 자신과 일치하지 않은 유일한 값
NaN === NaN; // false

// Number.isNaN 함수는 지정한 값이 NaN인지 확인하고, 그 결과를 불리언 값을 반환
Number.isNaN(NaN); // true

// ES6에서 도입된 Object.is 메서드는 예측 가능한 비교 결과를 반환
1 + undefined === NaN; // false
Object.is(NaN, NaN); // True

대소 관계 비교 연산자

  • 대소 관계 비교 연산자는 피연산자의 크기를 비교하여 불리언 값을 비교
대소 관계 비교 연산자 예제 설명 부수 효과
> x > y x가 y보다 큼 x
< x < y x가 y보다 작음 x
>= x >= y x가 y보다 크거나 같음 x
<= x <= y x가 y보다 작거나 같음 x

삼항 조건 연산자

  • 삼항 조건 연산자 ternary operator는 조건식의 평가 결과에 따라 반환할 값을 결정, 부수 효과 x
  • 조건식 ? 조건식이 true일 때 반환할 값 : 조건식이 false일 때 반환할 값
  • 값으로 평가할 수 있는 표현식인 문
var score = 60;
var result = score >= 80 ? "Pass" : "Fail"; // Fail

논리 연산자

  • 논리 연산자 logical operator는 우항과 자항의 피연산자를 논리 연산
  • 논리 부정 연산자(!)는 암묵적 타입 변환을 통하여 언제나 불리언 값을 반환
논리 연산자 의미 부수 효과
|| 논리합(OR) x
&& 논리곱(AND) x
! 부정(NOT) x
// 논리합연산자(||)
true || true; // true
true || false; // true
false || false; // false

// 논리곱연산자(&&)
true || true; // true
true || false; // false
false || false; // false

// 논리부정연산자(!)
!0; // true
!'hello' // false

// 단축 평가
'Cat' || 'Dog'; // 'Cat'
'Cat' && 'Dog'; // 'Dog'

// 드모르간의 법칙
!(x || y) === (!x && !y);
!(x && y) === (!x || !y);

 

쉼표  연산자

  • 쉼표(,) 연산자는 왼쪽 피연산자부터 차례대로 피연산자를 평가하고 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가 결과를 반환
var x, y, z;

x = 1, y = 2, z = 3; // 3

그룹 연산자

  • 소괄호('( )')로 피연산자를 감싸는 그룹 연산자는 자신의 피연산자인 표현식을 가장 먼저 평가
  • 연산자의 우선순위 조절 가능
  • 그룹 연산자는 우선 순위가 가장 높음

typeof 연산자

  • 피연산자의 타입을 문자열로 반환
  • 7 가지 문자열 'string', 'number', 'boolean', 'undefined', 'symbol', 'object', 'function' 중 하나를 반환
  • null은 'object'로 반환하는 자바스크립트의 첫 번째 버전의 버그 존재
  • 선언하지 않은 식별자를 Reference Error가 아닌 undefined를 반환
typeof '' // 'string'
typeof 1 // 'number'
typeof NaN // 'number'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof new Date() // 'object'
typeof /test/gi // 'object'
typeof function() {} // 'function'

typeof neverDeclared; // 'undefined'

지수 연산자

  • ES7에 도입
  • 좌항의 피연산자를 밑 base, 우항의 피연산자를 지수 exponent로 거듭제곱하여 숫자 값을 반환
  • 지수 연산자 도입 이전에는 Math.pow 메서드를 사용
  • 이항 연산자 중에서 가장 우선 순위가 높음
3 ** 2 // 9
Math.pow(3, 2) // 9

그 외의 연산자

연산자 개요 참고
?. 옵셔널 체이닝 연산자 9장
?? null 병합 연산자 9장
delete 프로퍼티 삭제 10장
new 생성자 함수를 호출할 때 사용하여 인스턴스 생성 17장
instanceof 좌변의 객체가 우변의 생성자 함수와 연결된 인스턴스인지 판별 19장
in 프로퍼티 존재 확인 19장

연산자의 부수 효과

  • 다른 코드에 영향을 줌
  • 할당 연산자(=), 증가/감소 연산자, delete연산자
var x;

// 할당 연산자
x = 1;
console.log(x); // 1

// 증가/감소 연산자
x++;
console.log(x); // 2

// delete 연산자
var hongyeop = {
  hp: 5,
  status: "hungry",
};
console.log(hongyeop); // { hp: 5, status: 'hungry' }

delete hongyeop.status;
console.log(hongyeop); // { hp: 5 }

연산자 우선순위

  • 우선순위가 높은 그룹 연산자를 사용하여 우선순위를 명시적으로 조절 권장
우선순위 연산자
1 ()
2 new(매개변수 존재), ., [ ](프로퍼티 접근), ( )(함수호출), ?.(옵셔널 체이닝 연산자)
3 new(매개변수 미존재)
4 x++, x--
5 !x, +x, -x, ++x, --x, typeof, delete
6 **(이항 연산자 중에서 우선순위가 가장 높음)
7 *, / , %
8 +, -
9 <, <=, >, >=, in, instanceof
10 ==, !=, ===, !==
11 ??(null 병합 연산자)
12 &&
13 ||
14 ? ... : ...
15 할당 연산자(=, +=,  ...)
16 ,

연산자 결합 순서

  • 연산자의 어느 쪽(좌항 혹은 우항)부터 평가를 수행할 것인지 나타냄
결합 순서 연산자
좌항 -> 우항 +, -, /, %, <, <=, >, >=, &&, ||, ., ??, ?., in, instanceof
우항 -> 좌항 ++, --, 할당 연산자(=, +=, ...), !x, +x, -x, ++x, --x, typeof, delete, ? ... : ..., **

데이터 타입 종류

  • 데이터 타입 data type은 값의 종류를 뜻함
  • 자바스크립트의 모든 값은 데이터 타입을 갖음
  • ES6는 7개의 데이터 타입을 제공하며, 각 타입은 원시 타입 primitive type과 객체 타입 object/reference type으로 분류
구분 데이터 타입 설명 
원시 타입 숫자 number 숫자, 정수와 실수 구분 없이 하나의 숫자 타입만 존재
문자열 string 문자열
불리언 boolean 논리적 참(true)과 거짓(false)
undefined var 키워드로 선언된 변수에 암묵적으로 할당되는 값
null 값이 없다는 것을 의도적으로 명시할 때 사용되는 값
심벌 symbol 다른 값과 중복되지 않는 유일무이한 값. ES6에서 추가
객체 타입 객체, 함수 배열 등

숫자 number 타입

  • 자바스크립트는 하나의 숫자 타입만 존재 / 자바나 c는 int, long, float, double 등 정수와 실수로 타입을 구분함
  • ECMAScript 사양에 따르면 숫자 타입의 값은 배정밀도 64비트 부동소수점 형식
  • 즉, 모든 수를 실수로 처리하며, 정수만 표현하기 위한 데이터 타입 interger type이 별도로 존재 x
  • 숫자 타입은 추가적으로 세 가지 특별한 값도 표현할 수 있음
    • Infinity: 양의 무한대
    • -Infinity: 음의 무한대
    • NaN: 산술 연산 불가 not-a-number
// 숫자 타입은 모두 실수 처리
console.log(1 === 1.0); // true
// 숫자 타입의 세 가지 특별한 값
console.log(10 / 0); // Infinity
console.log(-10 / 0); // -Infinity
console.log(1 * 'String') // NaN

문자열 string 타입

  • 텍스트 데이터를 나타내는데 사용
  • 0개 이상의 16비트 유니코드 문자( UTF-16)의 집함으로 전세계의 대부분 문자 표현 가능
  • 작은따옴표(' '), 큰따옴표(" "), 백틱(` `) 사용, 일반적으로는 작은따옴표 사용
  • 자바스크립트의 문자열은 원시 타입이며, 변경 불가능한 값 immutable value

템플릿 리터럴 template literal

  • ES6부터 도입
  • 멀티라인 문자열 multi-line string, 표현식 삽입 expression interpolation, 태그드 템플릿 tagged template 등 편리한 문자열 처리 기능 제공
  • 템플릿 리터럴은 일반적인 따옴표가 아닌 백틱(` `)사용

멀티라인 문자열

  • 일반적인 문자열 내에서는 줄바꿈이 허용되지 않음
  • 일반적인 문자열 내에서 줄바꿈을 표현하기 위해서는 백슬레쉬(\)로 시작하는 이스케이프 시퀀스 escape sequence를 사용해야 함
  • 템플릿 리터럴 내에서는 이스케이프 시퀀스 사용하지 않고 줄바꿈이 허용되며, 모든 공백도 그대로 적용됨
// template1과 template2의 출력 결과는 같다
var template1 = '<ul>\n\t<li><a href="##>Home</a></li>\n</ul>';

var template2 = `<ul>
	<li><a href="##>Home</a></li>
</ul>
`

표현식 삽입

var first = "Hongyeop";
var last = "Jin";

// ES6 표현식 삽입
console.log(`My name is ${first} ${last}.`)

불리언 타입

  • 논리적 참, 거짓을 나타내는 true와 false만 존재
  • 프로그램의 흐름을 제어하는 조건문에서 많이 사용됨

undefined 타입

  • var 키워드로 선언한 변수는 암묵적으로 undefined로 초기화
  • 개발자가 의도적으로 할당을 위한 값이 아닌, 자바스크립트 엔진이 변수를 초기화할 때 사용되는 값
  • 의도적으로 갓이 없다는 것을 명시하기 위해서는 null 사용

null 타입

  • 변수에 값이 없다는 것을 의도적으로 명시(의도적 부재 intentional absence)할 때 사용
  • 함수에서 유효한 값을 반환할 수 없는 경우 명시적으로 null을 반환하기도 함
var elemnet = document.querySelector('.myClass');

console.log(element); // null

심벌 타입

  • ES6에서 추가된 7번째 타입
  • 변경 불가능한 원시 타입의 값
  • 심벌 값은 다른 값과 중복되지 않은 유일무이한 값
  • 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해서 사용
// 심벌 값 생성
var key = Symbol('key');
console.log(typeof key); // symbol

// 객체 생성
var obj = {};

// 이름이 충돌할 위험이 없는 유일무이한 값이 심벌을 프로퍼티 키로 사용
obj[key] = 'value';
console.log(obj[key]); // value

객체 타입

  • 자바스크립트는 객체 기반의 언어
  • 자바스크립트를 이루고 있는 거의 모든 것이 객체

데이터 타입의 필요성

  • 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해
  • 값을 참조할 때 한 번에 읽어 들여야 할 메모리 공간의 크기를 결정하기 위해
  • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해

동적 타이핑

정적 타입 언어 static/strong type

  • C, C++, java, kotlin, go, haskell, rust, scala
  • 변수를 선언할 때 변수에 할당할 수 있는 값의 종류, 즉 데이터 타입을 사전에 선언해야 함, 이를 명시적 타입 선언 explicit type declaration이라고 함
  • 변수의 타입을 변경할 수 없으며, 변수 선언한 타입에 맞는 값만 할당 가능
  • 컴파일 시점에 타입 체크 수행, 타입 체크를 통과 실패 시 에러 발생
  • 타입의 일관성을 강제하여 안정적인 코드의 구현을 통해, 런타임에서 발생하는 에러를 줄임

동적 타입 언어dynamic/weak type인 javascript 

  • 변수를 선언할 때 타입 선언 x, 키워드(var, let, const)를 사용해 변수 선언
  • 어떤 데이터 값이라도 자유롭게 선언 가능
  • 자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론 type inference) 됨
  • 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있음. 이를 동적 타이핑 (dynamic typing)이라고 함
  • 동적 타입 언어는 유연성은 높지만 신뢰성은 떨어짐
  • 다른 동적 타입 언어로는 python, PHP, ruby, lisp, perl

변수 사용 시 주의사항

  • 변수는 꼭 필요한 경우에 한해 제한적으로 사용하고 최소한으로 유지
  • 변수의 유효 범위(스코프)를 최대한 좁게
  • 전역 변수 사용 최대한 지양
  • 변수보다는 상수
  • 변수의 이름은 목적이나 의미를 알 수 있도록 신중히
  • 가독성이 좋은 코드가 좋은 코드

 

값 value

값 value는 식(표현식 expression)이 평가 evaluate되어 생성된 결과

다음 예제의 식은 평가되어 숫자 값 30을 생성한다

10 + 20 // 30

변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름, 즉 변수에 할당되는 것은 값

var sum = 10 + 20 // 변수에는 10 + 20이 평가되어 생성된 값 30이 할당

리터럴 literal

리터럴 literal은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법 notation을 말함

자바스크립트 엔진은 코드가 실행되는 시점인 런타임 runtime에 리터럴을 평가해 값을 생성

사람이 이해할 수 있는 아라비아 숫자를 사용해 숫자 리터럴 3을 코드에 기술하면,

자바스크립트 엔진은 이를 평가해 숫자 값 3을 생성

 

3 // 숫자 리터럴 3

리터럴은 평가되어 값을 생성

리터럴 예시 비고
정수 리터럴 100  
부동소수점 리터럴 10.5  
2진수 리터럴 0b00000000 0b로 시작
8진수 리터럴 0o0101 ES6에서 도입, 0o로 시작
16진수 리터럴 0x000000F2 Es6에서 도입, 0x로 시작
문자열 리터럴 "hello world"  
불리언 리터럴 true  
nul 리터럴 null  
undefined 리터럴 undefined  
객체 리터럴 { name: "Gildong", location: "Korea"}  
배열 리터럴 [1, 2, 3]  
함수 리터럴 function() {}  
정규 표현식 리터럴 /[A-Z]+/g  

표현식 expression

표현식 expression은 값으로 평가될 수 있는 문 statement. 즉 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조

var score = 100; // 리터럴 100은 자바스크립트 엔진에 의해 평가되어 값 생성
var score = 50 + 50; // 리터럴과 연산자로 이뤄져있음. 50 + 50도 평가되어 값 100 생성
// 식별자 참조는 값을 생성하지 않지만 값으로 평가되므로 표현식
score; // 100
// 리터럴 표현식
10
"hello"

// 식별자 표현식 (선언이 이미 존재한다고 가정)
sum
person.name
arr[1]

// 연산자 표현식
10 + 20
sum = 10
sum !== 10

// 함수/메서드 호출 표현식 (선언이 이미 존재한다고 가정)
square()
person.getName()

표현식은 값으로 평가된다. 이때 표현식과 표현식이 평가된 값은 동등한 관계, 즉 동치 equivalent다

값이 위치할 수 있는 자리에는 표현식도 위치할 수 있음을 의미

var x = 1 + 2;
// 식별자 표현식 x는 3으로 평가됨
x + 3; // 6

문 statement

문 statement: 프로그램을 구성하는 기본 단위이자 최소 실행 단위, 프로그램 =  문의 집합

토큰 token: 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소

// 변수 선언문 
var x;

// 할당문
x = 5;

// 함수 선언문
function foo() {}

// 조건문
if (x > 1) {console.log(x);}

// 반복문
for (var i = 0; i < 2, i++) {console.log(i);}

세미콜론과 자동삽입 기능

  • 세미콜론(;)은 문의 종료를 나타냄, 자바스크립트 엔진은 세미콜론으로 문의 종료 위치를 파악하고 순차적으로 실행
  • 코드 블록({}) 뒤에는 세미콜론을 붙이지 않음, 코드 블록이 문의 종료를 의미하는 자체 종결성 self closing을 갖기 때문
  • 문의 끝에 붙이는 세미콜론은 옵션, 세미콜론 자동 삽입 기능(ASI)이 암묵적으로 수행되기 때문
  • 자동 삽입 기능이 있지만 일반적으로 작성을 해주는 듯
  • Prettier의 도움을 받자
 

Prettier · Opinionated Code Formatter

Opinionated Code Formatter

prettier.io

표현식인 문과 표현식이 아닌 문

// 변수 선언문은 값으로 평가될 수 없으므로 표현식이 아닌 문이다
var x;
// 1, 2, 1 + 2, x = 1 + 2는 모두 표현식
// x = 1 + 2는 표현식이면서 완전한 문
x = 1 + 2;
// 표현식이 아닌 문은 값으로 사용할 수 없음'
var foo = var = x;
// 표현식이 아닌 문은 값처럼 사용 가능
var foo = x = 100;
console.log(foo) // 100

변수란 무엇인가? 왜 필요한가?

  • 애플리케이션은 데이터를 입력 받아 처리하고 그 결과를 출력한다
  • 변수는 프로그래밍 언어에서 데이터를 관리하는 핵심 개념
10 + 20

자바스크립트가 위 코드를 계산(평가 evaluation)하려면

  • 20, 30 ,+ 라는 기호(리터럴 literal과 연산자 operator)의 의미를 알고 있어야 함
  • 10 + 20이라는 식(표현식 expression)의 의미도 해석(파싱 pharsing)할 수 있어야 함

자바스크립트가 해당 식의 의미를 해석하면

  • + 연산을 수행하기 위해 + 연산자의 좌변과 우변의 숫자 값(피연산자 operand)를 기억
  • cpu를 사용해 연산하고 메모리를 사용해 데이터를 기억

메모리

  • 데이터를 저장할 수 있는 메모리 셀의 집합체
  • 메모리 셀 하나의 크기는 1바이트(8비트)
  • 컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장 write하거나 읽어 read 들인다
  • 각 메모리셀은 고유의 메모리 주소 memory address를 갖고, 이는 메모리 공간의 위치를 나타냄
  • 메모리 주소는 0부터 시작해서 메모리의 크기만큼 정수로 표현된다. 아래 그림은 4GB 메모리의 예시
  • 컴퓨터는 모든 데이터를 2진수로 처리. 예제의 숫자 10과 20은 메모리 상의 임의의 위치(메모리주소)에 저장되고 cpu는 이 값을 읽어서 연산을 수행. 그림에는 10과 20으로 표기했지만 실제로는 2진수로 저장

메모리

변수 variable

  • 연산 결과는 메모리에 저장되지만 해당 값을 재사용하기 위해서는 cpu에게 해당 메모리 주소를 가르쳐 (식별)시켜줘야 함
  • 변수 variable는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름
  • 값의 위치를 가리키는 상징적인 이름
  • 자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않음
  • 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름을 변수 이름이라 하고, 저장된 값을 변수 값이라고 함
  • 변수 이름을 식별자 identifier라고도 함. 식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말함
  • 식별자는 값이 아니라 메모리 주소를 기억. 식별자는 값이 저장되어 있는 메모리 주소와 매핑 관계를 맺으며 이를 저장함
  • 변수에 값을 저장하는 것을 할당 assignment (대입 ,저장)이라고 하고, 읽어들이는 것을 참조 reference라고 함
var result = 10 + 20;

값의 생성과 변수 할당

변수 선언 variable delcaration

  • 변수를 생성하는 것을 뜻함
  • 값을 저장하기 위한 메모리 공간을 확보 allocate하고 변수 이름과 확보된 메모리 공간의 주소를 연결 name binding 해서 값을 저장할 수 있게 준비
  • 확보된 메모리 공간은 해제 release 되기 전까지는 누구도 사용할 수 없도록 보호됨
  • 변수를 사용하기 위해서는 반드시 선언이 필요
  • 변수를 선언하기 위한 키워드
    • var
    • let, const: ES6 때 var 키워드의 단점을 보안하기 위해 도입
  • 자바스크립트 엔진은 변수 선언을 다음과 같은 2단계에 거쳐 수행
    • 선언 단계: 변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알림
    • 초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화
  • 변수를 사용하려면 반드시 선언이 필요. 선언하지 않은 식별자에 접근할 경우 ReferenceError 발생
var score;

변수 선언

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

  • 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임runtime이 아니라 그 이전 단계에서 먼저 실행됨
  • 자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가과정을 거치게 되는데, 해당 과정에서 변수 선언을 포함한 모든 선언문 (변수, 함수 등)을 소스 코드에서 찾아서 먼저 실행
  • 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅 variable hoisting이라고 함
  • var, let, const, function, function*, class
console.log(score); // undefined
var score;

값의 할당

  • 값의 할당에는 할당 연산자 = 를 사용
  • 할당 연산자는 우변의 값을 좌변에 할당
  • 변수 선언과 값의 할당을 하나의 문 statement로 단축 표현도 가능
  • 실행 시점이 다름
    • 변수 선언: 런타임 이전에 먼저 실행
    • 값의 할당: 소스코드가 순차적으로 실행되는 런타임 시점에 실행
var score; // 변수 선언
score = 80; // 변수 할당
var score = 80; // 변수 선언과 값의 할당

 

console.log(score); // undefined

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

console.log(score); // 80

변수 선언이 런타임 이전에 실행되기 때문에 위와 같은 코드가 정상 실행 가능함

값의 재할당

  • 재할당이란 이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것을 뜻함
  • 상수 constant: 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없음 (단 한 번만 할당)
  • 재할당할 경우 기존의 값은 어떤 식별자와도 연결되어 있지 않음. 이런 값들은 가비지 콜렉터에 의해서 메모리에서 자동 해체됨. 언제 될지는 예측할 수 없음.
  • 자바스크립트는 매니지드 언어 managed language 이며, 메모리의 할당 및 해체를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않음
var score = 80; // 변수 선언과 값의 할당
score = 90; // 값의 재할당

식별자 네이밍 규칙

  • 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러기호 ($)를 포함 가능
    • ES5부터 식별자를 만들 때 유니코드를 허용해서 한글도 사용이 가능하나 권장하지 않음
    • 자바스크립트는 대소문자를 구분함
  • 식별자의 첫 글자는 숫자로 시작할 수 없음
  • 예약어는 식별자로 사용 불가능
  • 변수 이름은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현해야 함
  • 네이밍 컨벤션
    • 카멜 케이스 (camelCase): 자바스크립트에서 일반적으로 변수나 함수의 이름에 사용
    • 파스칼 케이스 (PascalCase): 자바스크립트에서 일반적으로 생성자 함수, 클래스의 이름에 사용
    • 헝가리언 케이스 (typeHungarianCase): type + indentifier
    • 스네이크 케이스 (snake_case): 주로 파이썬에서 쓰는 듯

자바스크립트 예약어

// 카멜 케이스
var firstName;

// 파스칼 케이스
var FirstName;

// 헝가리안 케이스
var strFirstName;
var $elme = document.getElementById('myId'); // Dom 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블

// 스네이크 케이스
var first_name

자바스크립트 실행 환경

  1. 모든 브라우저와 Node.js는 자바스크립트 엔진을 내장하고 있다. 하지만 용도가 다르다
  2. 브라우저
    • 웹 페이지를 화면에 렌더링하는 것이 주된 목적
    • ECMAScript + DOM API, Alert API 등
  3. Node.js
    • 브라우저 외부에서 자바스크립트 실행 환경 제공
    • ECMAScript + 파일 생성 수정할 수 있는 파일 시스템 등
  4. ECMAScript 외에 용도에 따라 다른 기능이 제공되는 것을 확인할 수 있음
    브라우저 vs Node.js

웹 브라우저

크롬 브라우저

 

Google Chrome - Download the Fast, Secure Browser from Google

Get more done with the new Google Chrome. A more simple, secure, and faster web browser than ever, with Google’s smarts built-in. Download now.

www.google.com

크롬 브라우저는 V8 자바 스크립트 엔진을 사용한다

개발자 도구

크롬 브라우저에서 기본 내장

단축키

  • 윈도우: F12 or Ctrl + Shift + I
  • 맥: command + option + I

기능

  • Elements: 로딩된 웹페이지의 DOM과 CSS를 편집해서 랜더링된 뷰를 확인 가능. 단 편집한 내용이 저장되지는 않음. 웹 페이지가 의도된대로 렌더링되지 않았다면 이 패널을 통해서 확인 가능
  • Console: 로딩된 웹페이지의 에러를 확인하거나 자바스크립트 소스코드에 작성한 console.log 메서드의 실행 결과를 알 수 있음
  • Sources: 로딩된 웹페이지의 자바스크립트 소스를 디버깅할 수 있음
  • Network: 로딩된 웹페이지에 관련된 네트워크 요청 정보와 성능을 확인할 수 있음
  • Application: 웹 스토리지, 세션, 쿠키를 확인하고 관리할 수 있음

콘솔

  • console.log(): 소괄호 안의 코드를 평가해서 그 결과를 콘솔에 출력하는 함수
  • 자바스크립트 코드를 직접 입력하여 그 결과를 확인할 수 있는 REPL(Read Eval Print Loop: 입력 수행 출력 반복) 환경으로 사용 가능

브라우저에서 자바스크립트 실행

브라우저는 HTML 파일을 로드하면 script 태그에 포함된 자바스크립트 코드를 실행

디버깅

크롬 개발자 도구 활용 참고

 

Chrome DevTools - Chrome for Developers

Chrome DevTools is a set of web developer tools built directly into the Google Chrome browser.

developer.chrome.com

 Node.js

프레임워크나 라이브러리, 도구 등을 사용할 때, Node.js나 npm이 필요

Node.js와 npm 소개

  • Node.js: 브라우저 이외의 환경에서 동작할 수 있는 자바스크립트 실행환경
  • npm(node package manager)
    • 자바스크립트 패키지 매니저
    • 사용할 수 있는 모듈들을 패키지화해서 모아둔 저장소 역할과 패키지 설치 관리를 위한 CLI(Command Line Interface) 제공
    • npm 관련 내용 정리
 

Node.js & npm | PoiemaWeb

npm(node package manager)은 자바스크립트 패키지 매니저이다. Node.js에서 사용할 수 있는 모듈들을 패키지화하여 모아둔 저장소 역할과 패키지 설치 및 관리를 위한 CLI를 제공한다. 자신이 작성한 패

poiemaweb.com

Node.js 설치

설치 사이트

 

Node.js

 

nodejs.org

버전 확인을 위해서는 아래 코드 실행

node -v
npm -v

Node.js REPL

터미널에서 아래 커맨드로 REPL 사용 가능

node

 

REPL 관련 정보

 

REPL | Node.js v21.1.0 Documentation

REPL# Source Code: lib/repl.js The node:repl module provides a Read-Eval-Print-Loop (REPL) implementation that is available both as a standalone program or includible in other applications. It can be accessed using: const repl = require('node:repl'); copy

nodejs.org

비주얼 스튜디오 코드 VSCode

마이크로소프트에서 개발한 코드 에디터

비주얼 스튜디오 코드 설치

다운로드 링크

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

내장 터미널

index.js 파일을 생성하고 아래 코드 실행할 경우 해당 자바스크립트 파일 실행 가능

node index

Code Runner 확장 플러그인

extension 중 하나인 code runner를 실행할 경우, 현재 표시 중인 자바스크립트 파일을 실행할 수 있음

기본 단축키: Ctrl + Alt + N

Live Server 확장 플러그인

extension 중 하나인 live server를 실행할 경우, 가상 서버를 기동하여 브라우저에 HTML를 랜더링 해줌

2.1 자바스크립트의 탄생

  • 1995년 90%의 시장 점유율로 웹브라우저 시장을 점유하고 있던 넷스케이프 커뮤니케이션즈는 웹 페이지의 보조기능 을 수행하기 위해 브라우저에서 동작하는 경량 프로그래밍 언어를 도입하기로 결정, 그래서 탄생한 것이 자바스크립트다.

2.2 자바스크립트의 표준화

  • 경쟁사인 마이크로소프트 사의 JScript가 인터넷 익스플로러에 탑재되면서 표준화되지 못하고 적당히 호환되는 크로스 브라우징 이슈 발생
  • 비영리 표준화 기구인 ECMA에 자바스크립트의 표준화 요청
    ECMA Script 버전별 특징

2.3 자바스크립트 성장의 역사

초기

  • 대부분의 로직은 서버에서 실행되어 브라우저의 역할은 서버에서 전달 받은 HTML과 CSS를 렌더링하는 수준

Ajax(Asynchronous JavaScript  and XML)

  • 기존에는 완전한 HTML 코드를 받아서 웹페이지 전체를 랜더링함
  • 1999년 자바스크립트를 이용해 서버와 브라우저가 비동기(Asynchronous) 방식으로 데이터를 교환할 수 있는 통신 기능인 Ajax가 XMLHttpRequest라는 이름으로 등장
  • 웹페이지에서 변경할 필요가 없는 부분은 렌더링하지 않고, 서버로부터 필요한 데이터만 전송받아 변경해야 하는 부분만 한정적으로 렌더링하는 방식
  • 웹브라우저에서도 데스크톱 어플리케이션과 유사한 빠른 성능과 부드러운 화면 전환이 가능해짐

jQuery

  • DOM(document object model)을 더욱 쉽게 제어할 수 있게 됨
  • 배우기 쉽고 직관적인 사용으로 넓은 사용자층 확보

V8 자바스크립트 엔진

  • 더욱 빠르게 동작하는 자바스크립트 엔진의 필요성과 구글의 공급
  • 과거 웹서버에서 수행되던 로직들이 대거 클라이언트(브라우저)로 이동
  • 웹 애플리케이션 개발에서 프론트엔드 영역이 주목 받는 계기

Node.js

  • V8 자바스크립트 엔진 기반의 자바스크립트 런타임 환경
  • 자바스크립트를 브라우저 환경 외에도 동작할 수 있도록 함
  • 서버 사이드 애플리케이션에서 주로 사용
  • 비동기 I/O 지원, 단일 스레드 이벤트 루프 기반으로 동작함으로써 요청 처리 성능이 좋음
  • 따라서 데이터를 실시간으로 처리하기 위해 I/O가 빈번하게 발생하는 SPA에 적합, 하지만 CPU 사용률 높은 애플리케이션에는 권장 x
  • Node.js의 등장으로 자바스크립트는 범용 프로그래밍 언어가 됨

SPA (Single Page Application) 프레임워크

  • CBD(component based development) 방법론을 기반으로 하는 SPA 대중화
  • Angular, React, Vue.js, Svelte

2.4 자바스크립트와 ECMAScript

  • ECMAScipt는 자바스크립트의 표준 사양인 ECMA-262를 뜻함
  • 각 제조사는 해당 사양을 준수해서 브라우저에 내장되는 자바스크립트 엔진을 구현
  • 자바스크립트 = ECMAScript + 브라우저 별도 지원 클라이언트 사이트 Web API

2.5 자바스크립트의 특징

  • 웹 브라우저에서 동작하는 유일한 프로그래밍 언어
  • 개발자가 별도의 컴파일 작업을 수행하지 않는 인터프리터 언어(Interpreter language)
  • 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어
    컴파일러 언어 vs 인터프리터 언어

2.6 ES6 브라우저 지원 현황

  • 인터넷 익스플로러를 제외한 대부분 브라우저에서 ES6 지원
  • babel 같은 트랜스 파일러를 이용해 ES5 이하의 사양으로 다운그레이드 가능

1.1 프로그래밍이란?

  • 컴퓨터에게 실행을 요구하는 일종의 커뮤니케이션
  • 0과 1밖에 알지 못하는 기계가 실행할 수 있을 정도로 정확하고 상세하게 요구사항을 설명하는 작업, 그 결과물이 코드
  • 컴퓨터와 사람은 사고, 인지 방식이 다르기 때문에, 컴퓨터의 관점에서 문제를 사고할 수 있어야함

1.2 프로그래밍 언어

  • 컴퓨터가 이해할 수 있는 언어는 기계어(machine code)
  • 기계어는 직접 작성이 어렵기 때문에, 사람이 이해할 수 있는 약속된 구문(syntax) 으로 구성된 프로그래밍 언어(Programming Language)를 사용해 프로그램을 작성
  • 그것을 컴퓨터가 이해할 수 있도록 기계어로 번환하는 번역기를 사용한다. 그 번역기를 컴파일러(Compiler) 또는 인터프리터(Interpreter)라고 함

1.3 구문과 의미

  • 언어는 문법에 알맞은 문장 뿐만 아니라 적합한 의미(semantics)를 가지고 있어야 언어의 역할을 충분히 수행할 수 있다.
  • 프로그래밍의 목정은 요구 사항의 실현 (문제의 해결)이다.
  • 대부분의 프로그래밍 언어는 '변수와 값', '키워드', '연산자', '표현식과 문', '조건문', '반복문'에 의한 '흐름제어', '함수', 그리고 자료구조인 '객체', '배열' 같은 문법을 제공
  • 프로그래밍은 요구사항의 집합을 분석해서 적절한 자료구조와 함수의 집합으로 변환한 후, 그 흐름을 제어하는 것

+ Recent posts