ES6 주요 기능

he0o0nje·2024년 1월 12일
0

Javascript

목록 보기
4/15

ECMAScript 2015는 JavaScript의 두 번째 주요 개정판입니다.

✨ES6의 주요기능

1) The let keyword:

let은 블록 스코프 변수를 선언하는 키워드로, 변수를 블록 내에서만 유효하게 만듭니다. 블록 스코프를 가지기 때문에 전역 변수의 오버라이딩 문제를 방지하고 코드의 안정성을 높입니다.

const example = () => {
  if (true) {
    let x = 10;
    console.log(x); // 10
  }
  // console.log(x); // 에러! x는 블록 스코프 내에서만 유효
};

2) The const keyword:

const는 블록 스코프에서 읽기 전용 상수를 선언하는 키워드로, 한 번 할당되면 값을 변경할 수 없습니다.

const PI = 3.14;
// PI = 3.14159; // 에러! 상수를 변경할 수 없음

3) Arrow Functions:

화살표 함수는 간결한 문법을 가진 익명 함수로, function 키워드 대신 =>를 사용하여 함수를 정의합니다. 매우 간결하고 가독성이 좋으며, this의 동작이 기존 함수 표현식과 다릅니다.

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

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

4) Destructuring assignment:

구조분해할당은 배열이나 객체에서 원하는 값 또는 속성을 추출하여 변수에 할당하는 문법입니다. 이를 통해 코드의 가독성을 높일 수 있고, 필요한 값에 쉽게 접근할 수 있습니다.

// 배열 구조분해
const numbers = [1, 2, 3];
const [first, second, third] = numbers;

// 객체 구조분해
const person = { name: 'John', age: 30 };
const { name, age } = person;

5) Rest Operator / Spread Operator:

전개 연산자(...)는 배열이나 객체 등을 펼쳐서 각각의 요소로 분리시키거나 합칠 때 사용합니다. Rest는 값을 수집하고, Spread는 값을 전개합니다.

≫ Rest Operator (...): Rest 연산자는 함수의 매개변수나 배열, 객체에서 사용되어 남은 인수들을 모아서 하나의 변수로 전달하거나, 배열/객체를 합칠 때 사용됩니다.

// 함수 매개변수에서의 활용
const sum = (...numbers) => numbers.reduce((acc, num) => acc + num, 0);
console.log(sum(1, 2, 3, 4)); // 10

// 배열에서의 활용
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2];
console.log(combinedArray); // [1, 2, 3, 4, 5, 6]

≫ Spread Operator (...): Spread 연산자는 배열이나 객체를 개별 요소로 분리하여 전개하거나 복사할 때 사용됩니다.

// 배열에서의 활용
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]

// 객체에서의 활용
const person = { name: 'John', age: 30 };
const copiedPerson = { ...person, job: 'Developer' };
console.log(copiedPerson);
// { name: 'John', age: 30, job: 'Developer' }

// 함수 호출에서의 활용
const displayInfo = (name, age) => console.log(`Name: ${name}, Age: ${age}`);
const user = ['Alice', 25];
displayInfo(...user); // Name: Alice, Age: 25

spread operator를 object로 쓸 때 단점

  • 얕은 복사(shallow copy):
    Spread 연산자를 사용하여 객체를 복사할 때, 복사된 객체는 얕은 복사가 이루어집니다. 즉, 객체의 프로퍼티가 객체나 배열과 같은 참조 타입을 가지고 있으면 원본 객체와 복사본 객체가 같은 참조를 공유하게 됩니다.
const original = { key: { nestedKey: 'value' } };
const copy = { ...original };

console.log(copy.key === original.key); // true
  • 프로토타입 복사 불가:
    Spread 연산자는 객체의 프로토타입을 복사하지 않습니다. 즉, 프로토타입 체인 상의 프로퍼티들은 복사되지 않습니다.
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function () {
  console.log(`Hello, ${this.name}!`);
};

const john = new Person('John');
const copiedJohn = { ...john };

console.log(copiedJohn.sayHello); // undefined
  • 열거 불가능한 속성 복사 불가:
    Spread 연산자는 열거 불가능한 속성을 복사하지 않습니다. 열거 불가능한 속성은 Object.defineProperty나 Object.defineProperties로 설정한 속성 등이 해당됩니다.
const obj = { key: 'value' };
Object.defineProperty(obj, 'nonEnumerableKey', {
  value: 'nonEnumerableValue',
  enumerable: false,
});

const copiedObj = { ...obj };

console.log(copiedObj.nonEnumerableKey); // undefined
  • Symbol 속성 복사 불가:
    Spread 연산자는 Symbol 속성을 복사하지 않습니다.
const obj = { [Symbol('key')]: 'value' };
const copiedObj = { ...obj };

console.log(copiedObj[Symbol('key')]); // undefined

6) Promises:

Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체로, 비동기 코드를 더 효과적으로 다룰 수 있게 합니다.

const fetchData = () => {
  return new Promise((resolve, reject) => {
    // 비동기 작업 수행
    if (success) {
      resolve(data);
    } else {
      reject(error);
    }
  });
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));
// then()은 성공 시 실행되며, catch()는 실패 시 실행됩니다.

7) For/of:

for/of 루프는 이터러블 객체를 순회할 때 사용되며, 간편하게 배열이나 문자열의 값을 가져올 수 있습니다. 이터러블 컬렉션 객체 전용입니다.

  • for/in 루프는 모든 객체에서 사용이 가능하며, key값에 접근할 수 있지만 value값에 접근하는 방법은 제공하지 않습니다. 모든 열거 가능한 속성에 대해 반복합니다. 다만, Array에 사용하면 예상치 못한 동작이 발생할 수 있습니다.
  • foreach 루프는 오직 Array 객체에서만 사용가능한 메서드이며, 루프 제어가 불가능합니다.
const arr = [1, 2, 3];
for (const value of arr) {
  console.log(value); // 1, 2, 3
}

const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
  console.log(key, obj[key]); // a 1, b 2, c 3
}

const fruits = ["Apple", "Banana", "Orange"];
fruits.forEach((fruit, index) => {
  console.log(index, fruit); // 0 "Apple", 1 "Banana", 2 "Orange"
});

8) Map Objects:

Map은 키-값 쌍을 저장하는 자료구조로, 객체보다 유연하게 다양한 데이터 타입을 키로 사용할 수 있습니다.

const myMap = new Map();
myMap.set('name', 'John');
myMap.set(1, 'One');

Map 객체의 속성과 메서드

9) Set Objects:

Set은 중복을 허용하지 않는 값들의 집합을 나타내는 자료구조로, 고유한 값만을 포함합니다.

const mySet = new Set([1, 2, 3, 1, 2]);
// mySet: {1, 2, 3}

10) Classes:

클래스는 객체지향 프로그래밍을 지원하는데 사용되며, 생성자, 메서드, 상속 등을 정의할 수 있습니다.

class Person {
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    console.log(`Hello, ${this.name}!`);
  }
}

const person = new Person('Alice');
person.sayHello(); // Hello, Alice!

11) Symbol:

Symbol은 유일한 식별자를 생성하기 위한 원시 데이터 타입으로, 주로 객체 속성의 키로 사용됩니다.

const mySymbol = Symbol('description');
const obj = {
  [mySymbol]: 'This is a symbol key'
};

const person = {
  firstName: "John",
  lastName: "Doe",
  age: 50,
  eyeColor: "blue"
};

let id = Symbol('id');
person[id] = 140353;
// Now person[id] = 140353
// but person.id is still undefined

12) Default Parameters:

함수의 매개변수에 기본 값을 설정할 수 있는 기능으로, 매개변수가 전달되지 않으면 기본값이 사용됩니다.

const greet = (name = 'Guest') => console.log(`Hello, ${name}!`);
greet(); // Hello, Guest!

13) String.includes():

문자열에 특정 문자열이 포함되어 있는지를 확인하는 메서드입니다.

⇨ includes(searchElement, fromIndex)
// searchElement: 찾을 값.
// fromIndex: 검색을 시작할 0 기반 인덱스, 정수로 변환.

const str = 'Hello, World!';
console.log(str.includes('World')); // true

// fromIndex < -array.length 이거나 fromIndex가 생략되면, 0이 사용되어 전체 배열이 검색됨.
// fromIndex >= array.length 이면, 배열은 검색되지 않고 false가 반환됨.
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
// 음수 인덱스는 배열의 끝부터 거꾸로 셈. 즉, fromIndex < 0이면, fromIndex + array.length가 사용.
[1, 2, NaN].includes(NaN); // true
["1", "2", "3"].includes(3); // false

14) String.startsWith():

문자열이 특정 문자열로 시작하는지를 확인하는 메서드입니다.

const str = 'Hello, World!';
console.log(str.startsWith('Hello')); // true

15) String.endsWith():

문자열이 특정 문자열로 끝나는지를 확인하는 메서드입니다.

const str = 'Hello, World!';
console.log(str.endsWith('World!')); // true

16) Array.from():

유사 배열 객체나 이터러블 객체를 배열로 변환하는 메서드입니다.

const arrayLike = { 0: 'a', 1: 'b', length: 2 };
const arr = Array.from(arrayLike); // ['a', 'b']​

Array.from("ABCDEFG")   // Returns [A,B,C,D,E,F,G]

배열, 유사배열

17) Array keys():

배열의 각 인덱스를 가지고 있는 이터레이터 객체를 반환합니다.

const arr = ['a', 'b', 'c'];
const keys = arr.keys(); // 이터레이터 객체

let text = " ";
for(let x of keys) {
	text += x + ","
}
// 0,1,2,

18) Array find():

주어진 콜백 함수의 조건을 만족하는 첫 번째 요소를 반환합니다.

const numbers = [1, 2, 3, 4, 5];
const result = numbers.find(num => num > 2); // 3

19) Array findIndex():

주어진 콜백 함수의 조건을 만족하는 첫 번째 요소의 인덱스를 반환합니다.

const numbers = [1, 2, 3, 4, 5];
const index = numbers.findIndex(num => num > 2); // 2

20) New Math Methods:

ES6에서는 수학 연산을 위한 새로운 메서드들이 Math 객체에 추가되었습니다.

console.log(Math.trunc(3.5)) // 소수점 아래 없앰 ∴ 3, Math.trunc(-2.7)  → -2
console.log(Math.sign(-8)) // 음수, 0, 양수 구분 ∴ -1, Math.sign(0) → 0, Math.sign(4) → 1
console.log(Math.pow(2, 3)) // 제곱 ∴ 8
console.log(Math.sqrt(9)) // 루트2 ∴ 3
console.log(Math.cbrt(64)) // 루트3 ∴ 4
console.log(Math.log2(2)) // 로그2 ∴ 1
console.log(Math.log10(10)) // 로그10 ∴ 1

21) New Number Properties:

Number 객체에는 새로운 프로퍼티들이 추가되었으며, 예를 들어 Number.EPSILON은 부동 소수점 연산에서 사용되는 가장 작은 양수를 나타냅니다.

console.log(Number.EPSILON); // 2.220446049250313e-16
console.log(Number.MIN_SAFE_INTEGER;); // -9007199254740991
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

22) New Number Methods:

Number 객체에는 새로운 메서드들도 추가되었습니다.

console.log(Number.isInteger(5)); // true
console.log(Number.isSafeInteger(12345678901234567890));  // false

23) New Global Methods:

전역 객체에 추가된 새로운 메서드들로, 예를 들어 isFinite()이나 isNaN() 등이 있습니다.

isFinite(10/0); // (Infinity) returns false
isFinite(10/1); // returns true
isNaN("Hello"); // returns true
isNaN(5.0) = isNaN(5.) // returns false

24) Object entries:

entries() 메서드는 배열의 각 요소들을 [index, value] 형태의 배열로 변환하여, 이 배열들을 모아놓은 배열을 반환합니다. 하지만, 이 메서드는 바로 배열로 반환하지 않고, 이터러블한 객체를 반환합니다. 이를 배열로 바꾸려면 Array.from()이나 for...of 루프를 이용해야 합니다.

const fruits = ["Banana", "Orange", "Apple", "Mango"];
const f = fruits.entries();
Array.from(fruits.entries())
// [[0, 'Banana'], [1, 'Orange'], [2, 'Apple'], [3, 'Mango']]

// Object.entries() 메서드는 객체의 키-값 쌍을 배열로 반환합니다.
const person = { name: 'John', age: 30, job: 'Developer' };
const entries = Object.entries(person);
console.log(entries);
// [['name', 'John'], ['age', 30], ['job', 'Developer']]

25) JavaScript Modules:

모듈은 코드를 여러 파일로 나누고 재사용할 수 있도록 하는 기능으로, import와 export 키워드를 사용하여 모듈 간의 의존성을 정의합니다.

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

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

추가 정보

폴리필(Polyfill)

  • 폴리필은 기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드 (일반적으로 웹의 JavaScript)
  • 바벨은 최신 ES6+ 문법을 ES5로 바꾸어주는 것(컴파일)이고, polyfill은 브라우저가 이해할 수 없는 코드에 대하여, 이해할 수 있는 코드 소스를 제공하는 것.
  • ES5의 global namespace(window)에 존재하지 않는 것은 컴파일 하지 못하여, 폴리필이 필요함.
    • 컴파일 가능 - 새로운 “문법"인 경우
      • const, let
      • spread operator
      • arrow function
      • class
      • destructuring
    • 컴파일 불가 - 폴리필 필요
      • 새로운 객체 (Promise, IntersectionObserver, Set, Map …)
      • 기존 객체의 새로운 메서드 (Array.prototype.includes, Object.entries …)
      • 새로운 함수 (fetch)

이터러블(Iterable), 이터레이터(Iterator)

JavaScript에서 데이터를 순회하는 데 사용되는 개념입니다.

  • 이터러블: 반복 가능한 객체로, Symbol.iterator 메서드를 가지고 있습니다. 이 메서드는 이터레이터를 반환하며, 이터레이터는 next() 메서드를 갖고 있습니다.
    ex) 배열이나 문자열과 같은 데이터 구조.
  • 이터레이터: 이터러블 객체의 각 요소를 순차적으로 접근할 수 있게 해주는 객체입니다. 이터레이터는 next() 메서드를 갖고 있으며, 각 호출마다 { value, done } 형태의 결과를 반환합니다.
const iterableArray = [1, 2, 3];
const iterator = iterableArray[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Object의 key에 공백이 있을 경우 접근하는 방법

const myObject = { "hello heonje" : "hi" }
const keyAsVariable = "hello heonje"
myObject.helloWorld = "earth"
---
console.log(myObject.hello_heonje) // undefined
console.log(myObject["hello heonje"]) // hi
console.log(myObject.keyAsvariable) // undefined
console.log(myObject[keyAsVariable]) // hi
console.log(myObject.helloWorld) // earth
console.log(myObject[helloWorld]) // earth

0개의 댓글