본문 바로가기
Dev/문법적 설탕

JavaScript : Syntactic sugar

by 괴발짜응 2025. 2. 21.
반응형

1. 화살표 함수 (Arrow Fun

ctions)

전통적인 함수 선언 방식보다 간결하게 함수를 작성할 수 있게 해준다.

// 기존 함수 표현식
function add(a, b) {
  return a + b;
}

// 화살표 함수
const add = (a, b) => a + b;

 

2. 템플릿 리터럴 (Template Literals)

택틱 ( `` )을 사용하여 문자열 내에 변수나 표현식을 쉽게 포함할 수 있다.

const name = "Alice";
console.log(`Hello, ${name}`);

 

3. 디스트럭처링 (Destructuring Assignment)

배열이나 객체에서 필요한 값들을 간단하게 추출할 수 있다.

// 객체 디스트럭처링
const person = { name: "Bob", age: 30 };
const { name, age } = person;

//배열 디스트럭처링
const arr = [1, 2, 3];
const [first, second] = arr;

 

4. 기본 매개변수 (Default Parameters)

함수의 매개변수에 기본ㄱ밧을 지정하여, 인자가 전달되지 않았을 때도 안정적인 동작을 보장한다.

function greet(name = "Guest") {
  return `Hello, ${name}!`;
}

 

5. 스프레드 연산자 (Spread Operator)와 나머지 매개변수 ( Rest Parameters)

배열이나 객체를 확장하거나, 함수에 전달되는 인자들을 쉽게 다룰 수 있다.

// 스프레드 연산자
const arr = [1, 2, 3];
const newArr = [...arr, 4, 5];

// 나머지 매개변수
function sum(...numbers) {
  return numbers.reduce((acc, cur) => acc + cur, 0);
}

 

6. 클래스 문법 (Class Syntax)

ES6부터 도입된 클래스 문법은 기존의 프로토타입 기반 상속을 더 직관적이고 객체지향적으로 표현할 수 있도록 도와준다. 실제로 클래스는 프로토타입 기반 상속 위에 얹은 문법적 설탕임.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const bob = new Person("Bob", 30);
bob.greet();

 

 

7. 옵셔널 체이닝 ( Optional Chaining)과 널 병합 연산자 (Nullish Coalescing)

옵셔널 체이닝 (?.):

객체의 깊은 프로퍼티에 접근할 때, 해당 프로퍼티가 존재하지 않아도 에러를 발생시키지 않고 undefined를 반환.

const user = { profile: { name: "Charlie" } };
console.log(user.profile?.name); // "Charlie"
console.log(user.address?.city); // undefined

 

널 병합 연산자 (??):

값이 null 또는 undefined인 경우에만 우측의 기본값을 사용한다.

const input = null;
const value = input ?? "default value";
console.log(value); // "default value"

 

8. 객체 리터럴의 확장된 표현

객체 속성 축약 (Shorthand Property Names):

변수 이름과 객체의 속성 이름이 동일할 때, 중복 작성 없이 축약할 수 있다.

const x = 10;
const y = 20;
const point = { x, y }; // { x: 10, y: 20 }

 

객체 메서드 축약 (Method Definitions):

객체 내 함수를 정의할 때, function 키워드를 생략하고 메서드 이름만으로 작성할 수 있다.

const Person = {
  name: "Alice",
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
};
person.greet();

 

계산된 속성명 (Computed Property Names):

대괄호( [] )를 사용하여 객체 리터럴 내에서 속성 이름을 동적으로 계산할 수 있다.

const prop = "age";
const user = {
  name: "Bob",
  [prop]: 30
};
console.log(user.age); // 30

 

객체 확산 및 나머지 프로퍼티 (Object Rest/Spread):

const obj = { a: 1, b: 2, c: 3 };
const { a, ...others } = obj; // others: { b: 2, c: 3 }

 

9. 비동기 프로그래밍의 간소화

Async/Await:

Promise 기반의 비동기 코드를 동기식 코드처럼 읽기 쉽게 작성할 수 있게 해준다.

async function fetchData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    return data;
  } catch (error) {
    console.log("Error fetching data:", error);
  }
}

비록 내부적으로는 Promise를 사용하지만, 코드가 훨씬 간결해지고 예외 처리가 쉬워진다.

 

10. 지수 연산자 (Exponentiation Operator)

수학적인 지수 연산을 간결하게 표현할 수 있다.

const result = 2 ** 3; // 8
// 기존 방식: Math.pow(2, 3);

 

 

11. Tagged Template Literals

템플릿 리터럴 앞에 함수를 붙여 문자열 처리를 커스터마이징할수 있다.

function emphasize(strings, ...values) {
  return strings.reduce(
    (acc, str, i) => acc + str + (values[i] ? `<strong>${values[i]}</strong>` : ""),
    ""
  );
}
const name = "Charlie";
const message = emphasize`Hello, ${name}! Welcome to our site.`;
console.log(message);
// "Hello, <strong>Charlie</strong>! Welcome to our site."

 

 

12. 모듈 시스템 (Import/Export)

ES6 모듈 문법은 코드를 모듈 단위로 관리하고 재사용하기 쉽게 만듭니다. 이는 전동적인 IIFE나 CommonJS 방식에 비해 훨씬 간결한 표현을 제공한다.

내보내기 (Export):

// math.js
export function add(a, b) {
  return a + b;
}

 

가져오기 (Import):

// main.js
import { add } from './math.js';
console.log(add(2, 3));

 

13.for...of 루프

이터러블(iterable)한 객체를 순회할 때 사용되는 구문으로, 내부의 반복작(iterator)를 자동으로 호출해 준다.

const arr = [10, 20, 30];
for (const value of arr) {
  console.log(value);
}

 

14. Generator 함수 (함수* 구문)

상태를 유지하면서 여러 번에 걸쳐 실행할 수 있는 함수로, 내부적으로 반복자 패턴을 간결하게 구현할 수 있도록 해준다.

function* count() {
  yield 1;
  yield 2;
  yield 3;
}
const couter = count();
console.log(counter.next().value); // 1;
console.log(counter.next().value); // 2;

 

 

15. 논리 할당 연산자 (Logical Assignment Operators)

ES2021에서 도입된 이 연산자들은 기존의 논리 연산과 할당을 결합해 코드를 더욱 간결하게 만들어준다.

 

||= (논리 OR 할당):

피연산자가 falsy한 값일 때 우측 값을 할당한다.

let a = 0;
a ||= 10; // a가 falsy하므로, a는 10이 됨

 

&&= (논리 AND 할당):

피연산자가 truthy한 값일 때 우측 값을 할당한다.

let b = 5;
b &&= 20; // b가 truthy하므로, b는 20이 됨

 

??= (널 병합 할당): 위의 널 병합 연산자와는 다르다. ?? 는 널 병합 연산자 ??= 는 널 병합 할당이다.

피연산자가 null 또는 undefined일 때 우측 값을 할당한다.

let c = null;
c ??= 30; // c가 null이므로, c는 30이 됨

 

16. 선택적 Catch 바인딩 (Optional Catch Binding)

ES2019부터 catch 블록에서 에러 객체를 생략할 수 있게 되어, 에러 객체를 사용하지 않을 때 코드를 더 간결하게 작성할 수 있다.

try {
  // 에러를 발생시킬 수 있는 코드
  doSomething();
} catch {
  // 에러 객체 받지 않음
  console.log("에러가 발생했습니다.");
}

 

17. 동적 Import (Dynamic Imports)

모듈을 동적으로 불러올 수 있게 해 주는 구문으로, 정적 import와 달리 실행 시점에 모듈을 불러온기 때문에 조건에 따라 모듈을 로딩하거나 코드 분할에 유용하다.

import("./module.js")
  .then(module => {
    module.doSomething();
  })
  .catch(err => {
    console.error("모듈 로딩 중 오류 발생:", err);
  });

 

18. for-await-of 루프

비동기 이터러블 객체를 순회할 때 사용하는 구문으로, 비동기 처리를 동기식 코드처럼 작성할 수 있다.

async function processAsyncData(asyncIterable) {
  for await (const data of asyncIterable) {
    console.log(data);
  }
}

 

19. Async Generator 함수

비동기 작업을 수행하면서도 여러 값을 순차적으로 yield할 수 있는 함수다. 일반 제너레이터와 async/await를 결합한 형태

async function* asyncGenerator() {
  yield await Promise.resolve("첫번째 값");
  yield await Promise.resolve("두번째 값");
}

(async () => {
  for await (const value of asyncGeneration()) {
    cosole.log(value);
  }
})();

 

20. 클래스의 개인 필드와 메서드(Private Class Fields and Methods)

ES2022에서 도입된 기능으로, 클래스 내부에서만 접근 가능한 비공개 필드와 메서드를 # 기호를 사용해 정의할 수 있다. 이는 객체지향 프로그래밍에서 캡슐화를 강화해 준다.

class Example {
  #privateField = 42; // 비공개 필드
  
  #privateMethod() { // 비공개 메서드
    return this.#privateField;
  }
  
  getPrivate() {
    return this.#privateMethod();
  }
}

const intance = new Example();
console.log(instance.getPrivate()); // 42
// intance.#privateField; // 오류 발생: 외부 접근 불가

 

21. 후행 쉼표 (Trailing Commas)

함수 매개변수, 배열, 객체 등에서 마지막 요소 뒤에 쉼표를 허용함으로써 코드의 변경 시 diff가 깔끔해지고, 여러 줄에 걸친 선 시 가독성을 높여준다.

function example(
  a,
  b, // 마지막 매개변수 뒤에도 쉼표를 사용할 수 있음
) {
  //함수 내용
}

const arr = [
  1,
  2,
  3, // 배열의 마지막 요소 뒤에도 쉼표를 허용
]

 

22. 함수 이름 추론 (Function Name Inference)

변수나 객체 속성에 할당된 익명 함수는 자동으로 이름이 추론되어 name 프로퍼티에 할당된다. 이로인해 디버깅 시 함수의 이름을 쉽게 확인할 수 있다.

const myFunc = funcion() {};
console.log(myFunc.name);o // "myFunc"

const obj = {
  greet() {
    console.log("Hello");
  },
};
console.log(obj.greet.name); // "greet"
반응형

'Dev > 문법적 설탕' 카테고리의 다른 글

Rust: Syntactic Sugar  (0) 2025.02.21