항해99 -[Chapter 3-1] 주특기 입문 (W3) - WIL
JavaScript의 ES란?
JavaScript와 ECMA Script 둘 다 뒤에 Script라는 키워드가 붙어있지만, 자바스크립트는 언어이고, ECMA 스크립트는 규격, 표준 즉, 스펙을 말한다.
초기 JavaScript는 넷스케이프라는 웹브라우저에서 사용하기 위해 만들어진 언어이다.
브라우저마다 언어를 개발하는 방식이 달라서 표준화시키는 작업이 필요했다. 그렇게 나온 것이 ECMAScript이다.
ES5/ES6 문법 차이
변수 선언의 방식
function scopeVariableWindow() {
var var1 = 1;
if(true){
var var2 = 2;
}
console.log(var1); // 출력결과 : 1
console.log(var2); // 출력결과 : 2
}
ES5의 변수 선언시 var는 Function Scope를 사용한다.
var는 block scope가 아닌 function scope이기 때문에 if 조건문의 block과는 상관없이 외부에서도 접근이 가능하다.
기존의 var keyword의 scope는 전역범위로 스크립트 파일 어디서나 참조하여 사용이 가능하다.
var keyword의 장점은 함수 호이스팅이 되기 때문에 var로 생성 안하고 그냥 변수로 사용해도 에러없이 생성되어 사용이 가능하였다.
하지만 이러한 경우 스크립트 파일이 많아지거나 길어질 경우 개발자가 의도하지 않게 동일한 변수명에 다른 값을 넣어서 시스템에 문제를 발생시킬 수 있는 여지가 있다.
함수(function) 선언 방식의 변경
ES5 함수의 선언 방식
function plus (a,b) { return a+b; }
var plus = function(a,b) { return a+b; }
ES6 화살표 함수의 선언 방식
let plus = (a,b) => {return a+b}
한눈에 봐도 함수 선언 방식이 간결해진 것을 확인할 수 있다.
또한 this의 사용에도 큰 변화가 있었다.
ES5같은 경우 객체 내에 있는 메소드를 실행시 메소드의 this는 메소드가 선언된 해당 객체를 가리킨다.
하지만 객체 안에서 선언된 함수의 this는 해당 객체가 아닌 window를 바라보고 있기 때문에 함수 안에서 this.name, this.age를 하여도 아무 값이 나오지 않는다.
이러한 경우 해결 방안으로 this를 바인딩 시켜주거나 this를 해당 변수에 담아서 사용하면 된다.
var thisTest = {
name : "김핵센",
age : 25,
info : function() {
console.log(this)
console.log(this.name , this.age)
function innerInfo(){
console.log(this)
return this.name + ":" + this.age
}
return innerInfo()
}
}
// 실행결과
// {name: "김핵센", age: 25, info: ƒ}
// 김핵센 25
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
// ":undefined"
ES6에서의 this는 자신을 둘러싸고 있는 this를 바라보기 때문에 따로 바인딩이나 변수에 담을 필요없이 사용 가능하다.
또한 ES5의 info:function () {} 처럼 사용하지 않고 바로 info key에게 함수를 선언하여 사용할 수 있도록 되어 좀 더 간결하게 짤 수 있다.
let thisTest = {
name : "김핵센",
age : 25,
info() {
console.log(this)
console.log(this.name , this.age)
innerInfo = () =>{
console.log(this)
return this.name + ":" + this.age
}
return innerInfo()
}
}
템플릿 리터럴 (Template literals)
ES6에서 템플릿 리터럴이라고 불리는 새로운 문자열 표기법이 생겼다. 이전에는 문자열을 표현하기 위해선 ' 또는 " 를 사용했는데,
템플릿 리터럴은 백틱을 사용한다. 템플릿 리터럴은 ' 와 "를 혼용해서 사용할 수 있다. 그리고 이전에는 줄 바꿈을 표현하기 위해선 \n을 넣어줘야 인식을 했지만 템플릿 리터럴은 있는 그대로 인식한다.
var name = "김핵센";
var age = 25;
var country = "대한민국";
var msg = "안녕하세요 저는 " + name + "입니다 나이는 " + age + "살이며 \"" + country + "\"에 살고있습니다.";
console.log(msg);
''(따옴표),""(쌍따옴표)로 구분해야 해서 + 연산자로 항상 이어줘야 했고 길어지면 불편함을 느낄 수 있고 복잡하다.
또한 따옴표나 쌍따옴표를 자유롭게 사용하지 못하고 맞춰서 사용해야 했다.
위의 소스코드에서는 자기소개를 하기 위한 msg를 작성하고 쌍따옴표를 표현하기 위해 역슬래시까지 사용하였다.
또한 비동기 통신 이후 동적으로 HTML 태그를 그려주기 위해 밑에 있는 소스처럼 작성을 하게 된다.
지금은 간단한 템플릿에 대하여 작성했지만 좀 더 복잡해진다면 원하지 않은 실수를 야기할 수 있다.
var dynamicElement = '';
dynamicElement += "<p>" + name + "</p>";
dynamicElement += "<p>" + age + "</p>";
dynamicElement += "<p>" + country + "</p>";
ES6로 넘어오면서 ``(백틱)와 ${}를 통해 한 줄로 표현이 가능하며 따옴표와 쌍따옴표를 자유롭게 사용할 수 있다.
위에 나온 소스코드들을 ES6 템플릿 엔진에 맞게 바꿔본다면 아래처럼 바꿀 수 있다.
let name = "김핵센";
let age = 25;
let country = "대한민국";
let msg = `안녕하세요 저는 ${name}입니다 나이는 ${age}살이며 "${country}"에 살고있습니다.`;
</source>
<source lang="javascript>
let dynamicElement = `
<p>${name}</p>
<p>${age}</p>
<p>${country}</p>
`;
class
ES5에선 class 라는 키워드는 없었지만 프로토타입을 통해 실현 가능했다.
var Add = function(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
};
Add.prototype.calc = function() {
return this.arg1 + "+" + this.arg2 + "=" + (this.arg1 + this.arg2);
};
var num = new Add(5, 8);
console.log(num.calc()); // 5 + 8 = 13
ES6에서는 class 키워드를 사용해서 선언할 수 있다.
class Add {
constructor(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
calc() {
return this.arg1 + "+" + this.arg2 + "=" + (this.arg1 + this.arg2);
}
}
var num = new Add(5, 8);
console.log(num.calc()); // 5 + 8 = 13
import / export
import와 export는 자바스크립트의 코드를 모듈화 할 수 있는 기능이다.
ES5 이전에는 각 기능별로 JS 파일을 나누고 개발 및 관리하는 것이 불가능했다.
ES5에선 require를 통해 모듈화를 할 수 있었다.
ES6부터는 import/export로 모듈을 관리할 수 있다.
모듈은 실현 가능한 특정 프로그램의 그룹이다.
그리고 이것은 다른 파일의 변수, 함수를 참조한다.
클래스와 같은 모듈이 로딩될 때, import와 export를 이용해 사용될 수 있다.
Import
import hundred from './ex';
// export default 파일의 경우 함수나 객체를 가저올때 이름을 임의로 지정해서 사용가능.
import { exam1, exam2, animal } from './ex2';
// 여러개의 함수나 객체를 가저올때 {} 사이에 이름을 지정해줌.
import * as R from './test1'
// 모든 함수나 객체를 가저올때 *를 사용하고 as 뒤에 임이의 이름을 지정할 수있음.
Export
// export default를 사용하고 파일내에 하나의 함수만 있을때 이름 지정 익명함수 사용가능.
export default function (x) {
return x * 100;
}
// 익명함수를 사용하며 그결과단순한 값을 반환할때 화살표 함수로 변경 가능.
export default x => x * 100;