개발 도구 (Development Tools)/JavaScript

#8. 자바스크립트 고급 주제

BiCute 2023. 5. 19. 08:00
반응형

 

# let 및 const를 사용한 코드 구성 및 모듈성


"let" 및 "const"는 자바스크립트에서 변수를 선언하는 데 사용되는 키워드입니다.

"let"은 재할당이 가능한 변수를 선언할 때 사용됩니다. 예를 들어:

let myVariable = 10;
myVariable = 20; // 가능

 

"const"는 재할당이 불가능한 상수를 선언할 때 사용됩니다. 예를 들어:

const myConstant = 10;
myConstant = 20; // 불가능

 

이러한 키워드를 사용하여 코드를 작성할 때, 모듈성을 높일 수 있습니다.

모듈성이란 코드를 작은 논리적 단위로 분리하여 이해하기 쉽고 유지 보수하기 쉽게 만드는 것입니다.

예를 들어, 변수를 전역 범위에서 선언하면 다른 함수에서도 그 변수를 사용할 수 있으므로 코드의 복잡성이 증가할 수 있습니다.

하지만, 함수 내에서 "let"이나 "const"를 사용하여 변수를 선언하면 그 함수 내에서만 사용할 수 있으므로 코드를 분리하고 모듈성을 높일 수 있습니다.

또한, 상수를 사용하여 변경되지 않을 값을 정의하면 코드의 가독성을 높일 수 있습니다.

코드에서 상수를 사용하면, 상수 이름을 사용하는 것만으로도 값을 이해할 수 있습니다.

 

예를 들어:

const MAX_COUNT = 10;

이러한 방식으로 변수와 상수를 사용하여 코드를 구성하면, 코드를 이해하기 쉽고 유지 보수하기 쉬운 모듈화된 코드를 작성할 수 있습니다.

 

 

 

# 구조 분해 할당(Destructuring)

 

구조 분해 할당은 JavaScript에서 배열이나 객체와 같은 데이터 구조에서 값을 추출하여 변수에 할당하는 방법입니다.

 

배열에서 구조 분해 할당을 사용하면 다음과 같이 배열의 값들을 변수에 할당할 수 있습니다:

const array = [1, 2, 3];
const [a, b, c] = array;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

 

객체에서 구조 분해 할당을 사용하면 다음과 같이 객체의 속성값을 변수에 할당할 수 있습니다:

const obj = { x: 1, y: 2 };
const { x, y } = obj;
console.log(x); // 1
console.log(y); // 2

 

배열과 객체에서는 할당할 변수의 개수가 데이터의 원소 수나 속성 수보다 적거나 많을 수 있습니다. 이때 할당할 변수 개수가 적을 경우, 나머지 값은 무시됩니다. 할당할 변수 개수가 많을 경우, 나머지 변수에는 undefined가 할당됩니다.

const array = [1, 2, 3];
const [a, b] = array;
console.log(a); // 1
console.log(b); // 2

const obj = { x: 1, y: 2 };
const { x, y, z } = obj;
console.log(x); // 1
console.log(y); // 2
console.log(z); // undefined

구조 분해 할당은 코드를 더 간결하고 가독성 있게 만들 수 있으며, 객체나 배열에서 필요한 값을 쉽게 추출할 수 있습니다.

 

 

 

# 템플릿 리터럴(Template Literal)

 

템플릿 리터럴(Template Literal)은 ES6(ECMAScript 2015)부터 도입된 JavaScript의 새로운 문자열 표기법입니다.

일반적인 문자열과는 다르게, 백틱(backtick) 기호()로 문자열을 감싸며, 내부에 변수나 표현식을 쉽게 삽입할 수 있습니다. 이를 위해 ${}` 문법을 사용합니다.

예를 들어, 기존의 문자열 표기법에서는 변수를 삽입하기 위해 문자열과 변수를 더하거나 복잡한 문자열 연결 방법을 사용해야 했지만, 템플릿 리터럴에서는 간단하게 변수를 삽입할 수 있습니다.

const name = "BiCute";
const message = `Hello, ${name}!`;
console.log(message); // 출력 결과: "Hello, BiCute!"

 

또한, 여러 줄의 문자열을 작성할 때도 유용하게 사용됩니다.

const multiLine = `
  Hello,
  World!
`;
console.log(multiLine); 
// 출력 결과: 
// "
//   Hello,
//   World!
// "

템플릿 리터럴은 가독성이 좋고 편리한 문자열 표기법으로, 문자열 처리가 필요한 JavaScript 코드에서 매우 유용하게 사용됩니다.

 

 

 

# 화살표 함수(Arrow function)

 

화살표 함수(arrow function)는 ES6(ES2015)에서 추가된 함수 정의 방식 중 하나입니다.

일반 함수 표현식과 다르게 함수 선언문이나 function 키워드를 사용하지 않고 화살표 연산자(=>)를 사용하여 함수를 정의합니다.

 

예를 들어, 기존의 함수를 화살표 함수로 바꾸면 다음과 같습니다.

// 일반 함수 표현식
function double(num) {
  return num * 2;
}

// 화살표 함수
const double = num => num * 2;

화살표 함수의 주요 특징은 다음과 같습니다.

  1. 함수 선언 시 function 키워드 대신 화살표 연산자(=>)를 사용합니다.
  2. 함수의 매개변수가 하나인 경우 괄호(())를 생략할 수 있습니다.
  3. 함수 내부에서 한 줄의 코드만 있는 경우 중괄호({})를 생략할 수 있습니다.
  4. 함수 내부에서 반환값을 바로 반환할 경우 return 키워드를 생략할 수 있습니다.
  5. 함수 내부에서 this 키워드가 함수 자체를 가리키며, 바깥쪽 스코프의 this와 달리 this의 값이 바뀌지 않습니다.

화살표 함수는 주로 콜백 함수나 배열의 map, filter, reduce와 같은 함수에서 사용됩니다. 이를 통해 코드의 가독성을 높일 수 있습니다.

 

 

 

# 프로미스(Promise)

 

프로미스(Promise)는 자바스크립트에서 비동기 처리를 위한 객체입니다. 비동기 처리란, 어떤 작업을 실행하고 그 결과를 기다리는 동안 다른 작업을 수행하는 것을 말합니다.

프로미스는 주로 네트워크 요청이나 파일 읽기 등 시간이 오래 걸리는 작업을 처리할 때 사용됩니다. 프로미스는 세 가지 상태를 가지며, 대기 상태(pending), 이행 상태(fulfilled), 거부 상태(rejected) 중 하나의 상태를 가집니다. 프로미스가 대기 상태일 때는 작업이 실행 중인 상태이며, 작업이 성공적으로 완료되면 이행 상태가 되고, 작업이 실패하면 거부 상태가 됩니다.

프로미스는 then()과 catch() 메서드를 제공하여 이행 상태와 거부 상태에 대한 처리를 할 수 있습니다. then() 메서드는 프로미스가 이행 상태일 때 실행되며, 프로미스의 결과를 전달받습니다. catch() 메서드는 프로미스가 거부 상태일 때 실행되며, 에러를 처리합니다.

최근에는 async/await 문법이 도입되면서 프로미스의 사용이 더욱 편리해졌습니다. async/await 문법을 사용하면 프로미스를 좀 더 직관적으로 사용할 수 있습니다.


# 비동기/대기(Async/Await)

 

비동기/대기(Async/Await)는 자바스크립트에서 비동기 처리를 더욱 직관적이고 간결하게 작성할 수 있도록 해주는 문법입니다.

비동기/대기는 ES2017(ES8)에서 도입되었으며, async 함수와 await 키워드를 사용하여 비동기 처리를 수행합니다. async 함수는 내부에 프로미스를 반환하는 함수입니다. async 함수 내부에서 await 키워드를 사용하면, 프로미스가 이행되거나 거부될 때까지 함수의 실행을 일시 중지하고, 해당 프로미스가 처리될 때까지 대기합니다. 이후, 처리 결과를 반환합니다.

예를 들어, 다음과 같은 코드가 있다고 가정해봅시다.

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => resolve('data'), 2000);
  });
}

async function main() {
  const data = await fetchData();
  console.log(data);
}

main();

 

위 코드에서 fetchData 함수는 2초 후 'data' 문자열을 반환하는 프로미스를 생성합니다. 이후, main 함수에서 fetchData 함수를 호출하고, await 키워드를 사용하여 fetchData 함수의 처리를 대기하고 있습니다. fetchData 함수가 프로미스를 반환할 때까지 main 함수의 실행이 일시 중지되며, fetchData 함수가 처리된 후에는 data 변수에 해당 결과를 저장하고, 이후의 코드를 실행합니다.

비동기/대기는 콜백 지옥(callback hell)이나 프로미스 체이닝(promise chaining)에서 벗어나, 비동기 처리를 보다 간결하고 직관적으로 작성할 수 있도록 도와줍니다.

 

 


# 클래스와 상속

 

자바스크립트에서 클래스는 ES6에서 도입된 개념으로, 객체 지향 프로그래밍을 지원하기 위한 문법적인 구조를 제공합니다. 클래스를 사용하여 유사한 속성과 메서드를 가진 객체를 생성할 수 있습니다.

클래스는 class 키워드를 사용하여 선언하며, 클래스 내부에는 속성과 메서드를 정의할 수 있습니다. 클래스의 인스턴스는 new 연산자를 사용하여 생성하며, 생성된 인스턴스는 클래스의 속성과 메서드에 접근할 수 있습니다.

상속은 클래스의 기능 중 하나로, 이미 존재하는 클래스에서 일부 기능을 물려받아 새로운 클래스를 만드는 것입니다. 자바스크립트에서는 상속을 구현하기 위해 extends 키워드를 사용합니다. 자식 클래스는 부모 클래스의 속성과 메서드를 상속받아 사용할 수 있으며, 필요한 경우 오버라이딩하여 재정의할 수도 있습니다.

예를 들어, 다음과 같이 Animal 클래스를 정의하고, Cat 클래스가 Animal 클래스를 상속받는 예시를 들 수 있습니다.

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Cat extends Animal {
  speak() {
    console.log(this.name + ' meows.');
  }
}

let cat = new Cat('Tom');
cat.speak(); // 출력값: "Tom meows."

이 예시에서 Cat 클래스는 Animal 클래스를 상속받았으며, speak() 메서드를 재정의하여 오버라이딩하였습니다. 따라서 cat.speak() 메서드를 호출하면 "Tom meows." 라는 결과가 출력됩니다.

 

 


# 자바스크립트 모듈

 

자바스크립트 모듈은 코드를 여러 개의 파일로 나누어 관리하고 재사용성을 높이기 위한 기술입니다. ES6(ECMAScript 2015)에서 도입되었으며, 모듈화를 위해 export와 import 키워드를 사용합니다.

모듈은 기본적으로 파일 하나에 해당하며, 파일 내부에서 export 키워드를 사용하여 해당 모듈에서 외부에 노출시킬 변수, 함수, 클래스 등을 지정합니다. 다른 파일에서는 import 키워드를 사용하여 해당 모듈에서 노출한 항목들을 가져와 사용할 수 있습니다.

모듈은 기본적으로 strict mode로 실행되며, import 구문은 해당 모듈 내부에서 가장 먼저 실행됩니다. 또한, 모듈 간의 순환 참조를 허용하지 않습니다.

자바스크립트 모듈은 브라우저에서도 사용할 수 있으며, Node.js에서는 CommonJS와 AMD 형식의 모듈 시스템을 사용하던 예전에는 별도의 라이브러리가 필요했지만, 현재는 ES6 모듈을 지원합니다.

// 모듈 내보내기 (export)
export const PI = 3.141592;  // 상수
export function add(x, y) {  // 함수
  return x + y;
}
export class Person {  // 클래스
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    console.log(`Hello, ${this.name}!`);
  }
}

// 모듈 가져오기 (import)
import { PI, add, Person } from './example.js';

console.log(PI);          // 3.141592
console.log(add(1, 2));   // 3
const person = new Person('John');
person.sayHello();        // "Hello, John!"

 

위의 코드에서 example.js 파일은 모듈로서 PI, add, Person 세 가지 항목을 외부에 노출하고 있습니다. import 구문에서는 해당 모듈에서 사용할 항목들을 중괄호로 감싸서 가져옵니다.

example.js 파일과 import 구문이 있는 파일은 같은 디렉토리에 있어야 합니다. 만약 다른 디렉토리에 있다면, 상대 경로나 절대 경로를 이용하여 파일 경로를 지정해주어야 합니다.

 

// 같은 디렉토리에 있을 경우
import { PI } from './example.js';

// 다른 디렉토리에 있을 경우 (상대 경로)
import { PI } from '../path/to/example.js';

// 다른 디렉토리에 있을 경우 (절대 경로)
import { PI } from '/path/to/example.js';

 

 

 

# 클로저

 

클로저(closure)는 함수와 그 함수가 선언된 어휘적 환경(lexical environment)의 조합입니다.

자바스크립트에서 함수는 자신이 선언될 때의 환경(변수, 함수 등의 정보)을 기억하며, 이 정보를 바탕으로 함수가 실행될 때 참조할 수 있습니다. 이때, 함수가 자신의 스코프 외부에서 선언된 변수에 접근할 수 있도록 하는 것이 클로저입니다.

예를 들어, 아래의 코드에서 outer 함수가 실행될 때 inner 함수가 반환됩니다. 이때 inner 함수는 outer 함수가 실행된 환경에서 선언된 변수 x에 접근할 수 있으므로, inner 함수를 호출하면 x 값이 출력됩니다.

function outer() {
  var x = 10;
  function inner() {
    console.log(x);
  }
  return inner;
}

var closure = outer();
closure(); // 10

클로저는 함수형 프로그래밍에서 매우 중요한 개념 중 하나이며, 상태를 기억하고 상태 변경을 추적하는 등의 다양한 용도로 활용됩니다. 하지만 과도한 클로저 사용은 메모리 누수(memory leak)를 발생시키는 원인이 될 수 있으므로, 적절하게 사용하는 것이 중요합니다.

 

 

# 정규식

 

정규식은 문자열에서 패턴을 찾거나 대체하는 데 사용되는 패턴 매칭 도구입니다. 자바스크립트에서는 정규식 객체를 만들어 문자열 메소드와 함께 사용할 수 있습니다.

정규식을 만드는 방법은 /pattern/flags 형식으로 슬래시(/)로 패턴을 감싸고, 옵션인 플래그(flags)를 추가합니다.

일반적으로 사용하는 플래그로는 g (전체 일치), i (대소문자 구분 없는 일치), m (여러 줄 일치) 등이 있습니다.

정규식 패턴은 문자열의 특정 부분과 일치하도록 설계됩니다. 예를 들어, /hello/ 는 "hello"라는 문자열과 일치합니다.

정규식 메소드로는 test(), exec(), match(), replace() 등이 있습니다. 이러한 메소드를 사용하여 문자열 내에서 패턴을 찾거나 대체할 수 있습니다.


다음은 자주 사용되는 정규식 메소드에 대한 간단한 예시 코드입니다

test(): 문자열이 정규식 패턴과 일치하는지 여부를 불리언 값으로 반환합니다.

const pattern = /hello/;
const str = "Hello, world!";
const result = pattern.test(str);
console.log(result); // false

 

exec(): 문자열에서 정규식 패턴과 일치하는 부분을 찾아 일치하는 문자열, 인덱스 등의 정보를 배열로 반환합니다. 찾지 못하면 null을 반환합니다.

const pattern = /hello/;
const str = "Hello, world!";
const result = pattern.exec(str);
console.log(result); // null

 

match(): 문자열에서 정규식 패턴과 일치하는 부분을 찾아 배열로 반환합니다. 찾지 못하면 null을 반환합니다.

const pattern = /hello/;
const str = "Hello, world!";
const result = str.match(pattern);
console.log(result); // null

 

replace(): 문자열에서 정규식 패턴과 일치하는 부분을 찾아 지정한 문자열로 대체합니다.

const pattern = /hello/;
const str = "Hello, world!";
const result = str.replace(pattern, "Hi");
console.log(result); // "Hi, world!"

이외에도 다양한 정규식 메소드가 있으며, 이를 활용하여 문자열을 처리할 수 있습니다.

 

 

 

반응형