제로부터 쌓는 개발일지
article thumbnail
Published 2023. 10. 17. 15:00
자바스크립트 ES6 backend/JavaScript
반응형

ES6 문법 소개

ECMAScript 6 (ES6)는 JavaScript의 버전 중 하나로, 2015년에 발표

ES6는 이전 버전인 ES5에서 새로운 문법과 기능을 도입하여 JavaScript 개발자들이 보다 쉽고 효율적으로 코드를 작성할 수 있도록 개선

 

중복 선언과 재할당

    재선언 (중복선언) 재할당
ES6 이전 문법 var 가능 가능
변수 let 불가능 가능
상수 const 불가능 불가능

 

변수 스코프 유효범위

스코프: 유효한 참조 범위

함수 내부에서 선언된 변수는 함수 내부에서만 참조 가능

var로 선언한 변수의 스코프와 let, const로 선언한 변수의 스코프가 다름

함수 레벨 스코프(Function-level scope)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다.
즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.

블록 레벨 스코프(Block-level scope) 모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.

 

변수 호이스팅

var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성

var 키워드로 선언된 변수와는 달리 let 키워드로 선언된 변수를 선언문 이전에 참조하면 스코프의 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠져서 참조 에러(ReferenceError)가 발생

console.log(foo); // undefined
var foo;

console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;

 

선언 단계(Declaration phase)
변수를 실행 컨텍스트의 변수 객체(Variable Object)에 등록한다. 이 변수 객체는 스코프가 참조하는 대상이 됨

초기화 단계(Initialization phase)
변수 객체(Variable Object)에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 초기화

할당 단계(Assignment phase)
undefined로 초기화된 변수에 실제 값을 할당

 

var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한 번에 이루어짐

// 스코프의 선두에서 선언 단계와 초기화 단계가 실행된다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 있다.
console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
  선언단계 초기화 단계 foo === undefined
var foo;    
foo = 1; 할당 단계 foo === 1
  var 키워드로 선언된 변수의 생병주기  

 

let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행

// 스코프의 선두에서 선언 단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 없다.
console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
  선언단계 ReferenceError
  일시적 사각지대
let foo; 초기화 단계 foo === undefined
foo = 1; 할당 단계 foo === 1

 

const는 반드시 선언과 할당이 동시에 이루어지며, 재할당이 금지되고 let과 마찬가지로 블록 레벨 스코프를 가짐

// 재할당 금지
const FOO = 123;
FOO = 456; // TypeError: Assignment to constant variable.



// 선언과 동시에 할당이 이루어져야됨
const FOO; // SyntaxError: Missing initializer in const declaration



// 블록 레벨 스코프를 가짐
{
  const FOO = 10;
  console.log(FOO); //10
}
console.log(FOO); // ReferenceError: FOO is not defined

 

화살표 함수 (Arrow Function)

함수를 더 간결하게 정의할 수 있으며 익명 함수나 간단한 함수 표현식을 작성할 때 사용

// 매개변수가 없는 경우
const greet = () => {
  console.log('안녕하세요!');
};

greet(); // 출력: 안녕하세요!



// 하나의 매개변수가 있는 경우
const square = (x) => x * x;

console.log(square(5)); // 출력: 25



// 여러 매개변수가 있는 경우
const sum = (a, b) => a + b;

console.log(sum(3, 4)); // 출력: 7

// 함수의 본문이 여러 줄인 경우 중괄호로 묶어야 하며 return 키워드로 반환값 명시
const multiply = (a, b) => {
  const result = a * b;
  return result;
};

console.log(multiply(6, 7)); // 출력: 42



// 객체 리터럴을 반환하는 경우 중괄호 내부를 객체로 인식하기 위해 중괄호를 괄호로 감싸야됨
const createPerson = (name, age) => ({
  name: name,
  age: age
});

const person = createPerson('Alice', 30);
console.log(person); // 출력: { name: 'Alice', age: 30 }



// 변수에 할당해서 사용
const add = (a, b) => a + b;
console.log(add(5, 3)); // 출력: 8



// 콜백 함수로 사용
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled); // 출력: [2, 4, 6, 8, 10]



// this 바인딩
// 함수 내부에서 this를 사용할 때 외부 스코프의 this를 그대로 가져옴
// function은 호출 할 때 this가 정해지지만 화살표 함수는 선언할 때 this가 정해짐
function Counter() {
  this.count = 0;
  setInterval(() => {
    // 화살표 함수 내부에서 this는 Counter 객체를 참조
    this.count++;
    console.log(this.count);
  }, 1000);
}

const counter = new Counter();
객체 리터럴
객체를 만들기 위한 표기법으로 키(key)와 값(value)의 쌍으로 이루어져있음
간단한 객체를 생성하고 초기화할 수 있음
const person = {
  name: "Alice",
  age: 30,
  isStudent: false
};​

콜백함수
다른 함수에 전달되어 나중에 실행되는 함수
   - 함수를 인수로 전달: 다른 함수에 콜백 함수를 인수로 전달할 수 있음
   - 비동기 작업 처리: 비동기 작업이 완료되었을 때 호출됨 (파일 읽기, 데이터베이스 쿼리, 네트워크 요청 등)
   - 이벤트 처리: 이벤트 핸들러로도 사용가능
     웹페이지 버튼 클릭, 마우스 이동, 키보드 입력과 같은 이벤트에 대한 응답으로 콜백 함수가 호출됨
   - 순서 제어: 작업의 순서를 제어하거나 작업을 연결할 수 있음
     하나의 작업이 완료되면 다음 작업을 시작할 수 있음
   - 동적 동작: 함수를 실행하는 동안 콜백 함수를 사용하여 동적으로 동작을 변경할 수 있음
// 비동기 작업 처리
function fetchDataFromServer(callback) {
  // 서버에서 데이터를 비동기로 가져옴
  setTimeout(function() {
    const data = { name: "John", age: 30 };
    callback(data);
  }, 1000);
}

fetchDataFromServer(function(data) {
  console.log("데이터 받음:", data);
});



// 이벤트 처리
document.getElementById('myButton').addEventListener('click', function() {
  console.log('버튼이 클릭되었습니다.');
});



// 타이머 및 비동기 처리
console.log('시작');

setTimeout(function() {
  console.log('1초 후 실행');
}, 1000);

console.log('끝');



// 배열 처리
const numbers = [1, 2, 3, 4, 5];

function processArray(arr, callback) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i]));
  }
  return result;
}

const doubled = processArray(numbers, function(number) {
  return number * 2;
});

console.log(doubled); // 출력: [2, 4, 6, 8, 10]



// 동적 동작 변경
function calculator(a, b, operation) {
  return operation(a, b);
}

function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

console.log(calculator(5, 3, add));      // 출력: 8
console.log(calculator(5, 3, subtract)); // 출력: 2



// Promise 및 비동기 처리
function asyncTask() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('비동기 작업 완료');
    }, 1000);
  });
}

asyncTask().then(result => {
  console.log(result);
});



// 모듈 패턴
const module = (function() {
  const privateVar = '비밀 데이터';

  function privateFunction() {
    return '비밀 함수';
  }

  return {
    publicVar: '공개 데이터',
    publicFunction: function() {
      return '공개 함수';
    },
  };
})();

console.log(module.publicVar);
console.log(module.publicFunction());​


this 바인딩
함수가 실행될 때 어떤 객체에 연결되는 지를 가리킴
   - 글로벌 스코프 this: 브라우저 환경에서 this는 전역 객체인 window를 가리키며,
     Node.js 환경에서는 전역 객체를 가리킴
   - 함수 내부 this: 호출된 컨텍스트에 따라 달라짐
     함수가 객체의 메서드로 호출되면 this는 그 객체를 가리키며, 일반 함수로 호출될 때는 전역 객체를 가리킴
   - 메서드 내부 this: 객체의 메서드 내에서 this는 해당 객체를 가리킴
   - 생성자 함수 this: 생성자 함수를 사용하여 객체를 생성할 때 this는 생성된 객체를 가리킴
   - 콜백 함수 this: 콜백 함수의 this 값은 호출한 함수에 따라 달라질 수 있으며,
     이때 bind, call 또는 apply와 같은 메서드를 사용하여 명시적으로 지정할 수 있음

// 글로벌 스코프 this
// 브라우저 환경
console.log(this === window); // true (브라우저에서)

// Node.js 환경
console.log(this === global); // true (Node.js에서)



// 함수 내부 this
function greet() {
  console.log(`안녕, 나는 ${this.name}이야.`);
}

const person = { name: 'Alice' };
greet(); // 출력: 안녕, 나는 undefined이야. (전역 스코프에서 호출됨)
person.greet = greet;
person.greet(); // 출력: 안녕, 나는 Alice이야. (객체의 메서드로 호출됨)



// 메서드 내부 this
const obj = {
  name: 'Bob',
  sayName: function() {
    console.log(`내 이름은 ${this.name}입니다.`);
  }
};

obj.sayName(); // 출력: 내 이름은 Bob입니다.



// 생성자 함수 this
function Person(name) {
  this.name = name;
  this.sayHello = function() {
    console.log(`안녕, 나는 ${this.name}이야.`);
  };
}

const alice = new Person('Alice');
alice.sayHello(); // 출력: 안녕, 나는 Alice이야.



// 콜백 함수 this
function greet() {
  console.log(`안녕, 나는 ${this.name}이야.`);
}

const person = { name: 'Charlie' };

function doSomething(callback) {
  this.name = 'David';
  callback();
}

doSomething(greet); // 출력: 안녕, 나는 David이야. (명시적으로 바인딩되었음)
doSomething(greet.bind(person)); // 출력: 안녕, 나는 Charlie이야. (bind를 사용하여 명시적으로 바인딩)



// 이벤트 핸들러
document.getElementById('myButton').addEventListener('click', function() {
  console.log('버튼이 클릭되었습니다.');
  console.log(`클릭한 버튼의 텍스트: ${this.textContent}`);
});



// 함수 내부에서 this 바인딩 변경
function greet() {
  console.log(`안녕, 나는 ${this.name}이야.`);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

greet.call(person1); // 출력: 안녕, 나는 Alice이야.
greet.call(person2); // 출력: 안녕, 나는 Bob이야.



// 화살표 함수(화살표 함수는 자체적인 this를 가지지 않음)
const greet = () => {
  console.log(`안녕, 나는 ${this.name}이야.`);
};

const person = { name: 'Alice' };
greet.call(person); // 출력: 안녕, 나는 undefined이야.



// 메서드 내의 내부 함수 this (내부 함수의 this는 외부 메서드와 다름)
const obj = {
  name: 'Alice',
  outerFunction: function() {
    console.log(`outerFunction의 this.name: ${this.name}`);
    
    const innerFunction = function() {
      console.log(`innerFunction의 this.name: ${this.name}`);
    };
    
    innerFunction();
  }
};

obj.outerFunction();

 

삼항 연산자 (ternary operator)

  • condition: 조건을 평가하는 표현식
    참이면 expr1이 반환되고, 거짓이면 expr2가 반환
  • expr1: 조건이 참 일 때 반환되는 값 또는 표현식
  • expr2: 조건이 거짓일 때 반환되는 값 또는 표현식
condition ? expr1 : expr2

console.log(true ? "참" : "거짓") // 참
console.log(false ? "참" : "거짓") // 거짓

 

구조 분해 할당 (Destructuring)

배열이나 객체의 속성을 분해해서 그 값을 변수에 할당

// 객체 구조 분해 할당
// 기본구조
const person = { firstName: 'John', lastName: 'Doe' };
const { firstName, lastName } = person;
console.log(firstName); // 출력: 'John'
console.log(lastName);  // 출력: 'Doe'



// 별칭 사용
const person = { firstName: 'John', lastName: 'Doe' };
const { firstName: fName, lastName: lName } = person;
console.log(fName); // 출력: 'John'
console.log(lName);  // 출력: 'Doe'



// 기본값 설정
const person = { firstName: 'John' };
const { firstName, lastName = 'Doe' } = person;
console.log(firstName); // 출력: 'John'
console.log(lastName);  // 출력: 'Doe'



// 중첩된 객체 구조 분해
const person = { name: { firstName: 'John', lastName: 'Doe' } };
const { name: { firstName, lastName } } = person;
console.log(firstName); // 출력: 'John'
console.log(lastName);  // 출력: 'Doe'



// 배열 구조 분해 할당
// 기본 구조
const numbers = [1, 2, 3, 4, 5];
const [first, second, third] = numbers;
console.log(first);  // 출력: 1
console.log(second); // 출력: 2
console.log(third);  // 출력: 3



// 남은 요소 배열 생성
const numbers = [1, 2, 3, 4, 5];
const [first, ...rest] = numbers;
console.log(first);  // 출력: 1
console.log(rest);   // 출력: [2, 3, 4, 5]



// 요소 순서 무시
const numbers = [1, 2, 3, 4, 5];
const [, second, , fourth] = numbers;
console.log(second); // 출력: 2
console.log(fourth); // 출력: 4



// 기본값 설정
const numbers = [1, 2];
const [first, second = 0] = numbers;
console.log(first);  // 출력: 1
console.log(second); // 출력: 2

 

단축 속성명 (property shorthand)

객체의 key와 value 값이 동일한 경우(변수 이름) 변수 이름을 속성명으로 사용하여 간결하게 정의할 수 있음

const name = "Alice";
const age = 30;

// 기존 방식
const person = {
  name: name,
  age: age
};

// 단축 속성명 사용
const person = {
  name,
  age
};

 

전개 구문 (Spread)

배열, 객체, 문자열 등의 데이터를 확장하거나 결합할 때 사용

// 배열의 요소 확장
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];

console.log(arr2); // 출력: [1, 2, 3, 4, 5]



// 객체의 속성 확장
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3, d: 4 };

console.log(obj2); // 출력: { a: 1, b: 2, c: 3, d: 4 }



// 함수 인수 전달
function sum(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];
const result = sum(...numbers);

console.log(result); // 출력: 6



// 배열 복사
const originalArray = [1, 2, 3];
const copyArray = [...originalArray];

console.log(copyArray); // 출력: [1, 2, 3]



// 객체 복사
const originalObj = { a: 1, b: 2 };
const copyObj = { ...originalObj };

console.log(copyObj); // 출력: { a: 1, b: 2 }



// 문자열을 배열로 분해
const str = "Hello";
const strArray = [...str];

console.log(strArray); // 출력: ["H", "e", "l", "l", "o"]

 

나머지 매개변수(rest parameter)

함수에서 매개변수의 개수가 가변적인 경우 사용

  • param1, param2: 일반 매개변수
  • ...restParams: 나머지 매개변수로서 매개변수의 나머지 값을 수집하는 배열
function functionName(param1, param2, ...restParams) {
  // 함수 내에서 restParams는 배열로 동작
}

function sum(first, second, ...rest) {
  let result = first + second;
  for (const num of rest) {
    result += num;
  }
  return result;
}

console.log(sum(1, 2, 3, 4, 5)); // 출력: 15

 

템플릿 리터럴 (Template literals)

백틱(``) 문자로 둘러싸인 문자열 사용

  • 멀티 라인 문자열 지원: 여러 줄로 이루어진 문자열을 간편하게 작성
  • 변수 보간(Interpolation): (${}) 문법을 사용하여 변수나 표현식을 문자열 내에 삽입할 수 있음
  • 작은따옴표나 큰 따옴표 대체: 문자열을 중첩할 때 이스케이프(escape) 문자를 사용할 필요 없음
// ${} 내에 변수나 표현식을 넣고, 이를 문자열에 삽입하여 보간하는 것이 핵심 기능
const name = 'Alice';
const age = 30;

const message = `안녕, 나는 ${name}이고, 나이는 ${age}세이다.`;

console.log(message);
// 출력: "안녕, 나는 Alice이고, 나이는 30세이다."
보간 (Interpolation)
문자열 내에 변수나 표현식을 삽입하여 문자열을 동적으로 생성하는 과정

컴퓨터 과학 및 프로그래밍에서 사용되는 용어로, 주어진 데이터의 중간값을 계산하거나,
두 값 사이의 중간값을 찾는 것을 의미함

 

named export vs default export

javascript 모듈에서 다른 코드 파일로 함수, 변수 또는 객체를 내보내는 방식에 대한 용어

 

Named Export (이름 있는 내보내기)

모듈에서 여러 항목(함수, 변수, 클래스 등)을 보내는 방식

내보내려는 각 항목에 이름을 지정하고, 다른 모듈에서 해당 이름을 사용하여 그 항목에 접근할 수 있음

중괄호({})안에 내보내려는 항목의 이름을 명시해야 됨

// math.js 모듈
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// 다른 모듈에서 사용
import { add, subtract } from './math.js';
console.log(add(5, 3)); // 8
console.log(subtract(8, 4)); // 4

 

Default Export (기본 내보내기)

모듈에서 하나의 항목만 내보내는 방식

다른 모듈에서 이름을 지정하지 않고 바로 가져올 수 있음

모듈당 하나만 사용할 수 있으며 해당 항목에 이름을 부여할 필요가 없음

// math.js 모듈
const add = (a, b) => a + b;
export default add;

// 다른 모듈에서 사용
import add from './math.js';
console.log(add(5, 3)); // 8

 

 

반응형

'backend > JavaScript' 카테고리의 다른 글

자바스크립트 Map & Set  (0) 2023.10.20
자바스크립트 일급객체  (0) 2023.10.17
자바스크립트 객체와 배열  (0) 2023.10.16
자바스크립트 반복문  (0) 2023.10.13
자바스크립트 조건문  (0) 2023.10.13
profile

제로부터 쌓는 개발일지

@PachyuChepe

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...