JavaScript에서 ES 란?
ECMASCRIPT의 약어를 뜻하며, 자바스크립트의 표준, 규격을 나타내는 용어이다.
모든 브라우저에서 동작할 수 있는 표준화된 자바스크립트가 필요해지면서
비영리 표준화 기구인 ECMA 인터네셔널에 자바스크립트의 표준화를 요청하였다.
ES5 는 2009년도에 HTML5와 함께 출연한 표준 사양이며,
ES6는 2015년에 버전업을하여 출시한 버전이다.
ES6 이후로도 매년 업데이트가 되고 있고, 이후를 '모던 자바스크립트'라고 부른다.
아래에는 ES6에 포함된
let, const 키워드 / 화살표 함수 / 클래스 / 모듈 다루고 있다.
let, const 키워드
ES5
ES5의 변수 선언 방법은 var가 유일하다.
var : 선언과 초기화가 동시에 실행
단점:
함수 레벨 스코프 지원 → 지역변수를 전역변수로 사용남발
var키워드 생략 허용 → 암묵적 전역변수 양산
변수 중복 선언 허용 → 변수값의 의도치 않은 변경
변수 호이스팅 → 선언하기 이전에 참조
ES6
var 키워드의 단점을 보완하기위해
let과 const 키워드가 도입되었다.
const : 상수(변하지 않는 값, 재할당 x)
let : 재할당이 가능한 값
블록 레벨 스코프 → 지역변수{ } 에서 사용된 변수는 코드 블로내에서만 유효
변수 중복 선언 금지 → 중복 선언시, 문법에러가 발생
호이스팅 → 변수 선언 이전에는 참조할 수 없다.
변수 선언에는 기본적으로 const를 사용하고,
let은 재할당이 필요한 경웨 한정하여 사용하는 것이 좋다.
전역 변수 (Global scope)
전역에서 선언된 변수이며, 어디에서든지 참조할 수 있다.
지역 변수 (Local scope of Function-level scope)
지역(함수) 내에서 선언된 변수이며, 그 지역과 그지역의 하부지역에서만 참조할 수 있다.
함수 레벨 스코프 (Function-level scope)
함수 내에서 선언된 변수는 함수 내에서만 유효, 함수 외부에서는 참조할 수 없다.
즉, 함수 내부에서 선언변수는 지역변수 / 함수 외부에서 선언한 변수는 전역 변수
블록 레벨 스코프 (Block-level scope)
모든 코드 블록(함수 if문, for문, while문, try/catch 문 등)내에서 선언된 변수는 코드 불록 내에서만 유효,
코드 블록 외부에서는
화살표 함수(Arrow function)의 선언
화살표 함수는 function키워드 대신 (=>)를 사용하여 함수를 선언한다.
// 매개변수 지정 방법
() => { ... } // 매개변수가 없을 경우
x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.
ES5보다 ES6의 화살표 함수는 좀더 간결하게 표현된다.
// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100
// ES6
const pow = x => x * x;
console.log(pow(10)); // 100
기존의 함수와 this 바인딩이 다르며,
Lexical this를 지원하므로 콜백함수로 사용하기 편리하다.
(이 부분은 추가적으로 공부가 필요할 것같다.)
클래스(Class)
ES5
생성자 함수와 프로토타입, 클로저를 사용하여
객체 지향 프로그래밍을 구현하였다.
// ES5
var Person = (function () {
// Constructor
function Person(name) {
this._name = name;
}
// public method
Person.prototype.sayHi = function () {
console.log('Hi! ' + this._name);
};
// return constructor
return Person;
}());
var me = new Person('Lee');
me.sayHi(); // Hi! Lee.
console.log(me instanceof Person); // true
ES6
기존 방식보다 단순명료한 새로운 문법으로 Class함수가 추가 되었다.
// 클래스 선언문
class Person {
// constructor(생성자)
constructor(name) {
this._name = name;
}
sayHi() {
console.log(`Hi! ${this._name}`);
}
}
// 인스턴스 생성
const me = new Person('Lee');
me.sayHi(); // Hi! Lee
console.log(me instanceof Person); // true
(디테일한 내용은 추가 공부가 필요할것같다.)
모듈 (Module)
모듈은 애플리케이션을 구성하는 개별적 요소로서 재사용이 가능한 코드 조각을 말한다.
모듈은 세부 사항을 캡슐화하고 공개가 필요한 API만을 외부에 노출한다.
모듈은 파일단위로 분리되어 있으며 필요에 따라 모듈을 로드하여 재사용한다.
script 태그에 type="module" 을 추가하면 모듈로서 동작한다.
ES6 모듈의 파일 확장자는 모듈임을 명확하기 위해 mjs를 사용하도록 권장한다.
<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>
모듈은 모듈 스코프를 가진다.
모듈 내에서 var 키원드로 선언한 변수는 더이상 전역 변수가 아니며
window 객체 프로퍼디도 아니다.
// foo.mjs
var x = 'foo';
console.log(x); // foo
// 변수 x는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
console.log(window.x); // undefined
// bar.mjs
// 변수 x는 foo.mjs에서 선언한 변수 x와 스코프가 다른 변수이다.
var x = 'bar';
console.log(x); // bar
// 변수 x는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
console.log(window.x); // undefined
<!DOCTYPE html>
<html>
<body>
<script type="module" src="foo.mjs"></script>
<script type="module" src="bar.mjs"></script>
</body>
</html>
Export: 외부에 공개하여 다른 모듈들이 참조할 수 있게한다.
// lib.mjs
const pi = Math.PI;
function square(x) {
return x * x;
}
class Person {
constructor(name) {
this.name = name;
}
}
// 변수, 함수 클래스를 하나의 객체로 구성하여 공개
export { pi, square, Person };
Import: 모듈에서 공개한 (export)한 대상을 로드하려면 import 키워드를 사용한다.
아래의 import 3가지 방식을 참고할 수 있다.
// app.mjs
// 같은 폴더 내의 lib.mjs 모듈을 로드.
// lib.mjs 모듈이 export한 식별자로 import한다.
// ES6 모듈의 파일 확장자를 생략할 수 없다.
import { pi, square, Person } from './lib.mjs'; // import 첫번째 방식
import * as lib from './lib.mjs'; // import 두번째 방식
import { pi as PI, square as sq, Person as P } from './lib.mjs'; // import 세번째 방식
console.log(pi); // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }
<참고용>
lib.mjs / app.mjs / html 에서 import와 export 동작 사용방법
// lib.mjs
export default x => x * x;
// app.mjs
// 브라우저 환경에서는 모듈의 파일 확장자를 생략할 수 없다.
// 모듈의 파일 확장자는 .mjs를 권장한다.
import square from './lib.mjs';
console.log(square(10)); // 100
<!DOCTYPE html>
<html>
<body>
<script type="module" src="./lib.js"></script>
<script type="module" src="./app.js"></script>
</body>
</html>