[JavaScript] 밸로퍼트 모던 자바스크립트 정리 1편

김강욱·2024년 5월 1일

JavaScript

목록 보기
4/4
post-thumbnail

😃 1장 자바스크립트 입문

자바스크립트는 웹 브라우저에서 사용하기 위해 만들어진 프로그래밍 언어입니다. 주로 웹 브라우저 상에서 UI를 동적으로 보여주기 위해 사용해왔으며 기존에는 브라우저에서만 사용했던 언어이지만, 이제는 단순히 웹 페이지에서만 국한되지 않고 Node.js 런타임을 통하여 서버 쪽에서도 사용할 수 있게 되었습니다.

✏️ 변수와 상수

변수와 상수는 특정 이름에 특정 값을 담을 때 사용됩니다. 변수를 한번 선언하면 똑같은 이름으로 선언할 수 없습니다. 단, 다른 블록 범위 내에서는 똑같은 이름으로 사용 가능합니다.

변수에는 var, let, const가 있으며 varlet의 차이점은 다음과 같습니다.

1. 범위(Scope)

var은 함수 범위(Function scope)를 가집니다. 즉, 변수가 선언된 함수 내에서 유효하며, 함수 외부에서는 접근할 수 없습니다.

반면 let은 블록 범위(Block scope)를 가집니다. 변수가 선언된 블록(예를 들어 if 문, for 문, while 문, 또는 단순 중괄호 {}로 감싼 영역) 내에서만 유효합니다.

2. 재선언

var은 같은 이름의 변수를 같은 범위 내에서 여러 번 선언할 수 있습니다.

반면 let은 같은 범위 내에서는 같은 이름의 변수를 재선언할 수 없습니다.

예시 코드

function testVar() {
  var x = 1;
  if (true) {
    var x = 2;  // 같은 변수 x 재선언
    console.log(x);  // 출력: 2
  }
  console.log(x);  // 출력: 2
}

function testLet() {
  let y = 1;
  if (true) {
    let y = 2;  // 다른 범위 내의 새로운 변수 y
    console.log(y);  // 출력: 2
  }
  console.log(y);  // 출력: 1
}

testVar();
testLet();

const는 상수이며, 한번 선언하고 값이 바뀌지 않는 값을 의미합니다. 값이 고정적이며 변수와 마찬가지로 상수를 선언할 때도 한번 선언했으면 같은 이름으로 선언할 수 없습니다.

현대 JavaScript에서는 코드의 가독성을 높이기 위해 var 대신 let 또는 const를 사용할 것을 권장하고 있습니다.


😃 참고 : 스코프란?

스코프(scope)는 변수가 접근 가능한 범위를 의미합니다. 자바스크립트에는 전역 스코프, 함수 스코프, 블록 스코프 세 가지 타입의 스코프가 존재합니다.

  1. 전역 스코프(Global Scope)

    전역 스코프에서 선언된 변수는 코드의 어디에서나 접근할 수 있습니다.

  2. 함수 스코프(Function Scope)

    함수 내에서 var 키워드로 선언된 변수는 해당 함수 내에서만 접근 가능하고, 함수 밖에서는 접근할 수 없습니다.

  3. 블록 스코프(Block Scope)

    letconst 키워드를 사용해 선언된 변수는 블록 스코프를 가집니다. 즉, 해당 변수는 선언된({}로 둘러싸인 코드 부분) 내에서만 접근이 가능합니다.

var 키워드는 함수 스코프를 가집니다. 즉, var로 선언된 변수는 선언된 함수의 내부에서 어디든지 접근할 수 있지만, 함수의 밖에서는 접근할 수 없습니다.

하지만 letconst는 블록 스코프를 가집니다. 따라서 블록 내에서 선언된 let이나 const 변수는 해당 블록 내에서만 접근할 수 있습니다.

예시 코드

function test() {
    let x = 10;
    if (true) {
        let x = 20;  // 이 "x"는 위의 "x"와는 다른 변수입니다.
        console.log(x);  // 20
    }
    console.log(x);  // 10
}
test();

😃 참고 : 변수 호이스팅이란?

변수 호이스팅이란 자바스크립트 엔진이 var 키워드로 선언된 모든 변수를 스크립트나 함수의 최상단으로 끌어올리는 현상을 말합니다.

이 때 중요한 점은 변수의 선언만 호이스팅되며, 초기화는 원래 코드에서 실행되는 위치에서 발생한다는 점입니다.

예시 코드

console.log(x); // 결과는?
var x = 5;
console.log(x); // 결과는?

위의 코드 첫 번째 결과는 undefined이고 두 번째 결과는 5가 나옵니다. 이는 자바스크립트 엔진이 스크립트를 실행하기 전에 x의 선언을 끌어올려서 스크립트의 최상단에 놓습니다. 이때 x의 초기화는 원래 그 자리에서 이루어집니다.

var로 선언된 변수를 동일한 스코프 내에서 다시 선언하면, 두 번째 선언은 사실상 무시되고, 변수의 값이 변경될 뿐입니다.

예시 코드

var x = 10;
var x = 20;
console.log(x);  // 20

위의 코드에서 두 번째 var x는 변수를 새로 선언하는 것이 아니라, 이미 선언된 x에 새 값을 할당하는 것입니다.

반면 letconst는 동일한 스코프 내에서 같은 이름의 변수를 다시 선언하려고 하면 에러를 발생시킵니다.

✏️ 데이터 타입

변수나 상수를 선언하게 될 때, 숫자 외에 다양한 타입의 값들을 할당할 수 있습니다.

1. 숫자(Number) : 숫자는 바로 값을 대입하면 됩니다.
2. 문자열(String) : 텍스트 형태의 값은 작은 따옴표 혹은 큰 따옴표로 감싸서 선언합니다.
3. 참/거짓(Boolean) : 참 혹은 거짓 두 가지 종류의 값만 나타낼 수 있습니다.
4. null과 undefined : 자바스크립트에서 없음을 의미하는 데이터 타입의 종류입니다. null은 주로 이 값이 없다! 라고 선언할 때 사용하며 고의적으로 설정하는 값입니다. 반면 undefined는 아직 값이 설정되지 않은 것을 의미합니다. 변수를 선언했지만 값을 지정해주지 않을 때 undefined라고 표시됩니다.

✏️ 연산자 순서

논리 연산자의 순서는 NOT -> AND -> OR 순으로 적용됩니다.


✏️ 비교 연산자 차이

=====의 차이에 대해서 알아봅시다.

==은 타입 검사는 하지 않고 값이 동일한지를 비교합니다. 반면 === 값과 타입 모두 동일한 지를 비교합니다.

const a = 1;
const b = '1';
const equals = a == b;
console.log(equals);  // true 반환
--------------------------------------------------------
// 0과 false도 같은 값으로 간주한다.
const a = 0;
const b = false;
const equals = a == b;
console.log(equals);  //true
--------------------------------------------------------
// undefined과 null도 같은 값으로 간주한다.
const a = null;
const b = undefined;
const equals = a == b;
console.log(equals);
--------------------------------------------------------
const value =  1 === '1';   // false 반환
const value = 'a' !== 'b';  // true 반환
// 0과 false, undefined과 null 값을 비교해도 fasle를 반환

✏️ 문자열 붙이기

두 문자열을 붙일 때에 +를 사용할 수 있습니다.

const a = '안녕';
const b = '하세요';
console.log(a + b); // 안녕하세요

✏️ switch case 문

switch (device) {
  case 'iphone' :
    console.log('아이폰!');
    break;
  case 'ipad' :
    console.log('아이패드!');
    break;
  default:
    console.log('모르겠다...');
}

✏️ 함수

  • ES6의 템플릿 리터럴 (Template Literal) 문법
function hello(name) {
  console.log(`Hello, ${name}!`);
}
hello('velopert');
  • 화살표 함수

    화살표 함수는 function 키워드 대신에 => 문자를 사용해서 함수를 구현합니다. 좌측에는 함수의 파라미터를, 화살표의 우측에는 코드 블록이 들어옵니다.

const add = (a, b) => {
  return a + b;
};

console.log(add(1, 2));

const getGrade = score => {
  if (score === 100) {
    return 'A+';
  } else if (score >= 90) {
    return 'A';
  } else if (score === 89) {
    return 'B+';
  } else if (score >= 80) {
    return 'B';
  } else if (score === 79) {
    return 'C+';
  } else if (score >= 70) {
    return 'C';
  } else if (score === 69) {
    return 'D+';
  } else if (score >= 60) {
    return 'D';
  } else {
    return 'F';
  }
};
const grade = getGrade(90);
console.log(grade);
  • 화살표 함수와 일반 function으로 만든 함수와의 주요 차이점가장 큰 차이는 this 키워드를 어떻게 처리하는지에 있습니다. 일반 함수에서는 this는 그 함수가 호출되는 컨텍스트에 따라 달리집니다. 즉, 함수가 어떻게 호출되었는지에 따라 this가 바인딩 됩니다.
let testObj = {
    name: "Test",
    showName: function() {
        console.log(this.name);
    }
};

testObj.showName();  // "Test", 여기서 `this`는 `testObj`를 가리킵니다.

---------------------------------------------------
// 같은 함수를 독립적으로 호출하면 this는 전역 객체(window나 undefined)를 가리킵니다.

let testObj = {
    name: "Test",
    showName: function() {
        console.log(this.name);
    }
};

let standaloneFunc = testObj.showName;
standaloneFunc();  // undefined, 여기서 `this`는 전역 객체를 가리킵니다.

화살표 함수에서 this 는 함수가 정의된 시점의 this 를 상속받습니다. 이를 렉시컬 바인딩(Lexical Binding)이라고 합니다. 이 경우 this 는 함수를 호출하는 방법에 관계 없이 항상 같은 값을 가리킵니다.


😃 참고 : 렉시컬 바인딩이란?

렉시컬 바인딩(Lexical Binding)은 정적 스코프(Static Scope)를 의미합니다. 즉, 변수가 선언된 위치에 따라 그 범위(scope)와 바인딩되는 값을 결정하는 방식을 의미합니다.

자바스크립트의 화살표 함수는 this를 렉시컬 바인딩 방식으로 처리합니다. 즉, 화살표 함수의 this는 함수가 정의된 시점의 this를 가리키며, 이는 함수가 어떻게 호출되었는지와는 관계가 없습니다.

let myObj = {
  value: 'Hello, World!',
  showValue: function() {
    console.log(this.value); // 이 경우 'this'는 'myObj'를 가리킵니다.
  },
  showValueDelayed: function() {
    setTimeout(() => {
      console.log(this.value); // 화살표 함수를 사용하여 'this'가 렉시컬하게 바인딩되었습니다.
    }, 1000);
  }
};

myObj.showValue(); // "Hello, World!"를 출력합니다.
myObj.showValueDelayed(); // 1초 후에 "Hello, World!"를 출력합니다.

위의 코드에서 화살표 함수의 this는 렉시컬 바인딩에 의해 myobj를 가리키므로, showValueDelayed 메서드가 호출되는 시점에서의 this를 기억하고 있습니다. 이러한 방식으로 렉시컬 바인딩은 함수의 this를 호출하는 방법과는 독립적으로 결정하게 됩니다.

😃 참고 : setTimeout()

자바스크립트에서 제공하는 타이머 함수 중 하나로, 특정 시간이 지난 후에 함수를 실행하도록 예약하는데 사용됩니다.

setTimeout 내의 콜백 함수에서 this는 전역 객체를 가리키게 됩니다. setTimeout은 콜백 함수를 독립적으로 호출하기 때문입니다.

setTimeout(function, delay, param1, param2, ...)

// 여기서
// function : 실행하고자 하는 함수를 참조하거나, 실행하고자 하는 코드를 문자열로 제공한다.
// delay : 함수가 실행되기 전에 대기할 밀리초(millisecond)를 지정한다.
// param1, param2, ... : 선택적 인자들로, 실행할 함수에 전달하고자 하는 매개변수들이다.

setTimeout(function(a, b) {
  console.log(a + b);
}, 3000, 5, 7);  // 3초 후에 "12"를 출력합니다.

✏️ 함수도 객체 취급이다!

  • 함수도 객체의 한 종류이므로 함수를 변수에 할당할 수 있고, 다른 함수의 인자로 전달하거나, 함수로부터 반환받을 수 있습니다.
  • 함수를 정의할 때, 실제로는 새로운 함수 객체를 생성합니다. 이 객체를 '함수 인스턴스'라고 부를 수 있습니다.

참고 자료
밸로퍼트 모던 자바스크립트

profile
TO BE DEVELOPER

0개의 댓글