ECMAScript
ECMAScript(European Computer Manufacturers Association Script)은 웹 브라우저에서 사용되는 스크립트 언어의 표준입니다. 즉, 자바스크립트는 ECMAScript의 구현체 중 하나입니다. ECMAScript는 스크립트 언어의 표준 규격을 정의하고, 그 규격에 따라 구현된 스크립트 언어를 통일하는 데 기여합니다.
ECMAScript의 버전은 ES1, ES2, ES3, ES5가 있으며 ES6은 ECMAScript 2015라고도 불리며 이후 새 버전의 이름은 연도를 붙여 표현합니다. ECMAScript 2015 ~ 2020까지 출시되어 가장 최신 버전은 ECMAScript 2020입니다. 각 버전마다 새로운 기능, 문법, API 등이 추가되어 개발자들이 효율적으로 작업할 수 있도록 도와줍니다. 그중에서도 ES6는 자바스크립트 개발자들에게 큰 변화를 안겨주었습니다. 어떤 중요한 변화가 있었는지 알아보겠습니다.
📜 ES5 - JS의 전통적인 버전, 2009년 출시로 대부분의 브라우저가 이 버전을 표준으로 지원함
📄 ES6 - JS의 새로운 표준, ES5와 비교하여 효율적인 문법과 기능이 추가되어 새로운 방향을 제시함
ES5와 ES6 문법
let과 const함수, 화살표 함수, 구조 분해 할당, 프로미스 등 ES6에서는 개발자들이 효율적으로 작업할 수 있도록 많은 문법과 기능이 추가되었습니다. 코드가 더욱 간결해지고 편의성을 높여주는 문법과 주요 기능들에 대해 자세히 알아보겠습니다.
- JS 변수
- 반복문 종류
- 화살표 함수
- 구조 분해 할당
- 스프레드 연산자
- 템플릿 리터럴
- 비교 연산자
- 모듈, import / export
- 클래스, Class
- 프로미스, Promise
1. Javascript 변수 ( var, let, const )
변수 | 스코프 | 재할당 | 재선언 |
var | Function Scope ( 함수 바깥에서도 접근 ) | 가능 | 가능 |
let | Block Scope ( 중괄호 블록 내 접근 ) | 가능 | 불가능 |
const | Block Scope ( 중괄호 블록 내 접근 ) | 불가능 | 불가능 |
💡 var는 선언과 동시에 초기화가 이루어지고 undefined가 할당된다. 하지만 let과 const는 선언만 될 뿐, 초기화와 메모리 할당이 되지 않는다. 이것을 변수 호이스팅 문제라고 표현하지만 엄밀히 하면 3개의 변수 모두 호이스팅 된다.
❗️ let과 const는 안정적이고 안전한 변수 선언 방식이므로 var 대신 사용하는 것이 좋다.
/* var */
console.log(apple);
var apple = 'the apple color is red';
// Output
>> undefined
/* let */
console.log(banana);
let banana = 'the banana color is yellow';
// Output
>> ReferenceError: Cannot access 'banana' before initialization
/* const */
console.log(carrot);
const carrot = 'the carrot color is orange';
// Output
>> ReferenceError: Cannot access 'carrot' before initialization
2. Array
ES5에서 단순했던 for문을, ES6에서 forEach, for ~ of 문이 추가되면서 효율적인 구현이 가능해졌습니다.
ES5, for loop
/* string */
var ai = ['ann', 'dnn', 'cnn', 'rnn'];
for (var i = 0; i < ai.length; i++) {
console.log(ai[i]);
}
/* number */
for (var i = 0; i < 10; i++) {
console.log(i);
}
ES6, forEach loop
let numbers = [1, 2, 3, 4, 5];
for (let num of numbers) {
console.log(num);
}
ES6, for ~ of loop
let numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(num) {
console.log(num);
});
3. Arrow Functions
화살표 함수는 기존 Function에 비해 코드가 간결해지고 this 키워드를 자동으로 바인딩합니다.
/* ES5 */
var sum = function(x, y) {
return x + y
};
/* ES6 */
const sum = (x, y) => x + y;
/* 위 ForEach 코드를 화살표 함수로 변경 */
let numbers = [1, 2, 3, 4, 5];
numbers.forEach(num => {
console.log(num);
});
4. Destructuring assignment, 구조 분해 할당
배열 또는 객체의 값을 여러 변수로 분해하여 할당하는 것을 쉽게 할 수 있습니다. 또한 함수의 매개변수로도 사용할 수 있습니다.
Array
const array = [ 1, 2, 3 ];
const [ a, b, c ] = array;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
Object
const object = { name: 'Yoon', age: 33 };
const { name, age } = object;
console.log(name); // Yoon
console.log(age); // 33
Fucntion Parameter
const logData = ({ brand, model }) => {
console.log(brand, model); // Tesla, 3
};
logData({ brand: 'Tesla', model: 3 });
Alias
const object = { address: 'street-1', zipcode: '123-45' };
const { address: x, zipcode: y } = object;
console.log(x, y);
5. Spread 연산자
이 연산자는 배열 또는 객체의 값을 쉽게 펼칠 수 있게 합니다.
Array
const array1 = [ 1, 2, 3 ];
console.log(...array1); // 1 2 3
const array2 = [ 4, 5 ,6 ];
const combineArray = [ ...array1, ...array2 ];
console.log(combineArray); // [ 1, 2, 3, 4, 5, 6 ]
Object
const { name } = { name: 'Kim', age: 34 };
console.log(name); // Kim
const object1 = { name: 'Yoon', age: 33 };
const object2 = { job: 'student' };
const combinedObject = { ...object1, ...object2 };
console.log(combinedObject); // { name: 'Yoon', age: 33, job: 'student' }
6. Template literals, 템플릿 리터럴
문자열을 만드는 더 편리하고 강력한 방법입니다. 백틱(`)으로 감싸며 표현식(expression)을 포함할 수 있고 줄 바꿈도 그대로 인식합니다.
// 기존의 문자열 연결 방법
let name = "Kim";
let message = "Hello " + name + "!";
console.log(message); // Hello Kim!
// 템플릿 리터럴 방법
let name = "Kim";
let message = `Hello ${name}!`;
console.log(message); // Hello Kim!
// 줄바꿈
let message = `This is a
multiline string.`;
console.log(message);
/*
This is a
multiline string.
*/
7. 비교 연산자
ES5에서 사용하던 '=='를 사용해서 값을 비교했었지만 ES6부터는 '==='를 이용해서 타입까지 비교가 가능해졌다.
const numA = 3;
const numB = '3';
/* ES5 */
console.log( numA == numB ); // True
/* ES6 */
console.log( numA == numB ); // True
console.log( numA === numB ); // False
8. Import / Export
ES5에서의 모듈 작성 방법은 CommonJS의 표준을 따랐습니다. 그러나 ES6부터는 ECMAScript의 모듈 시스템을 사용하게 되면서 브라우저와 Node.js 모두에서 사용 가능해졌습니다.
ES5, require와 exports
// ES5: exports
var myModule = {
hello: function() {
console.log('Hello, world!');
},
goodbye: function() {
console.log('Goodbye, world!');
}
};
module.exports = myModule;
// ES5: require
var myModule = require('./myModule');
myModule.hello();
myModule.goodbye();
ES6, import와 export
// ES6: exports, calc.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
// ES6: import, app.js
import { add, subtract } from './calc';
console.log(add(1, 2)); // 3
console.log(subtract(1, 2)); // -1
9. Class
ES5에서는 클래스를 함수로 흉내 내는 방식으로 작성하였습니다. 이것을 constructor 함수라고 부르며, 생성자 함수를 이용해 객체를 만들 수 있습니다. 반면, ES6에서는 클래스를 선언하는 새로운 방식이 추가되었습니다. 이것은 class 키워드를 사용하여 작성합니다.
추가로 ES6 클래스에서 super는 부모 클래스의 생성자를 호출하는 특별한 키워드입니다. super를 사용하여 부모 클래스의 생성자를 호출하고, 그 결과로 인스턴스 변수를 초기화하거나 부모 클래스에서 정의된 메서드를 호출할 수 있습니다. super를 사용하여 부모 클래스의 메서드를 호출할 때는 this를 사용하여 자식 클래스에서 정의된 인스턴스 변수나 메서드를 참조할 수 있습니다.
ES5
function MyClass(value) {
this.value = value;
}
MyClass.prototype.myMethod = function() {
// do something
};
ES6, Class
class MyClass {
constructor(value) {
this.value = value;
}
myMethod() {
// do something
}
}
ES6, Class
/* super를 사용하여 부모 클래스의 생성자를 호출하고 인스턴스 변수를 초기화하는 코드 */
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal {
constructor(name, age, breed) {
super(name, age);
this.breed = breed;
}
}
const myDog = new Dog("Fido", 3, "Labrador");
console.log(myDog.name); // "Fido"
console.log(myDog.age); // 3
console.log(myDog.breed); // "Labrador"
위 예제에서 Dog 클래스는 Animal 클래스를 상속하고 있으며, Dog 클래스의 생성자에서 super를 사용하여 Animal 클래스의 생성자를 호출하고 있습니다. 이로써 Dog 인스턴스가 생성될 때 Animal 클래스의 생성자가 호출되어 name과 age 인스턴스 변수가 초기화됩니다. 그다음에 Dog 클래스의 생성자에서 breed 인스턴스 변수를 추가적으로 초기화합니다.
💡 ES6의 클래스는 상속, 정적 메서드, getter 및 setter 등의 기능을 지원합니다. 또한, 클래스를 작성할 때 일반 함수처럼 호이스팅이 발생하지 않습니다.
10. Promise
ES6에서 추가된 Promise는 비동기 처리를 위한 기능 중 하나로, 콜백 지옥(callback hell)을 해결하고 비동기 작업을 더 쉽게 다룰 수 있도록 합니다. Promise 객체는 세 가지 상태를 가질 수 있습니다.
- 대기(pending) 상태: 비동기 작업이 아직 완료되지 않은 상태입니다.
- 이행(fulfilled) 상태: 비동기 작업이 성공적으로 완료된 상태입니다. 이행 상태에서는 비동기 작업의 결과 값을 반환합니다.
- 거부(rejected) 상태: 비동기 작업이 실패한 상태입니다. 거부 상태에서는 오류 정보를 반환합니다.
Promise 객체는 then()과 catch() 메서드를 사용하여 성공 및 실패 시 처리할 콜백 함수를 등록합니다.
fetch
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
위 코드에서는 fetch() 함수를 사용하여 서버에서 데이터를 가져옵니다. fetch() 함수는 Promise를 반환하며, 이행 상태에서 Response 객체를 반환합니다. 이행 상태에서는 then() 메서드를 사용하여 Response 객체를 JSON 형태로 변환합니다. 변환된 JSON 데이터는 다시 then() 메서드에서 처리됩니다.
만약 fetch() 함수에서 오류가 발생하면 거부 상태가 되며, catch() 메서드에서 오류를 처리합니다. 이를 통해 비동기 작업의 결과를 다룰 수 있습니다.
XMLHttpRequest
function getData() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts');
xhr.onload = function() {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText));
} else {
reject('Error: ' + xhr.status);
}
};
xhr.send();
});
}
getData()
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
위 코드에서는 XMLHttpRequest를 사용하여 서버에서 데이터를 가져옵니다. Promise 생성자 함수에 비동기 작업을 수행하는 코드를 작성하고, 작업이 완료되면 resolve() 메서드를 호출하여 이행 상태로 전환합니다. 작업이 실패하면 reject() 메서드를 호출하여 거부 상태로 전환합니다.
getData() 함수를 호출하면 Promise 객체가 반환되며, then() 메서드를 사용하여 이행 상태에서 처리할 콜백 함수를 등록합니다. catch() 메서드는 거부 상태에서 처리할 콜백 함수를 등록합니다. 이를 통해 비동기 작업의 결과를 다룰 수 있습니다.
💡 async / await는 ES2017( ES8 )에서 추가되었습니다.
Reference
ChatGPT, adjh54 님 블로그
'PROGRAMMING > Javascript & Typescript' 카테고리의 다른 글
[Javascript] 자바스크립트 물음표(?) 2개 / 느낌표(!) 2개 / 물결(~) 2개 연산자(feat.예시코드) (33) | 2023.03.07 |
---|---|
[Typescript] 타입스크립트, 정의 | 특징 | 비교 | 장단점 | 설치방법 | 문법 (feat.mac / window) (26) | 2023.03.03 |
[Javascript] 자바스크립트 톺아보기:동작 원리 (45) | 2023.02.27 |
[Javascript] filter / map / reduce 기능, 구조, 예제코드 (feat.ES6) (29) | 2023.02.25 |
Babel, 바벨 | 정의 / 필요성 / 설치 / 설정 / 오류 (9) | 2023.01.27 |