yngmanie 블로그

ES5와 ES6의 차이점

해당 포스트는 Difference between ES 5 and ES 6를 번역한 컨텐츠입니다. 잘못된 부분이 있다면 댓글 부탁드립니다.

템플릿 리터럴

  • `Rune`을 템플릿 리터럴을 사용함으로써, 특수문자로 감쌀 필요가 없어졌습니다. 또한 템플릿 리터럴 ${variable}안에는 변수는 있는 그대로 표현될 수 있습니다.

ES5

var name = "용민";
var age = 31;
console.log('저의 이름은 " ' + name + ' "이고, 나이는 ' + age + "살 입니다.");
//  저의 이름은 "용민"이고, 나이는 31살 입니다.

ES6

let name = "용민";
let age = 31;
console.log(`저의 이름은 ${name}이고, 나이는 ${age}살 입니다.`);
//  저의 이름은 "용민"이고, 나이는 31살 입니다.

화살표 함수

  • ES5에서 함수 선언

    • ES5에서 함수를 선언하는 방법은 3가지가 있습니다.
  • 함수 선언식

function str(arg1, arg2) {
  console.log("용민");
}
  • 생성자 함수(많이 사용하지 않음)
var str = new Function("arg1", "arg2", "console.log('용민')");
  • 함수 리터럴(익명함수를 만들때 사용)
var str = function(arg1, arg2) {
  console.log("용민");
};

화살표함수 선언

  • ES6에서 화살표 함수를 활용해 함수 리터럴 방식을 간단하게 하는것이 가능하다. this는 아래에 함수 리터럴의 this와 다른 것을 유념해야합니다.
var str = (arg1, arg2) => {
  console.log("용민");
};
  • 화살표 함수는 하나의 argument가 있다면 아래와 같습니다.
var str = arg1 => console.log(arg1);
  • argument에서 ()를 생략할 수 있습니다.( argument가 없다면 생략할 수 없습니다.) 또한 한줄로 표현이 가능하다면 위에 예제와 같이 {}를 생략할 수 있습니다.

  • 만약 화살표 함수가 객체를 반환한다면 아래 예제와 같습니다.

var str = func => ({ id: "31" });

()로 눈에 보이는 모든 부분을 감싸야 합니다.

this의 다른 동작

  • (1) 메소드 콜
var obj = {
  value: 10;
  show: function () {
    console.log (this.value); // 10
  }
}
obj.show();
  • 메소드의 this는 함수를 호출한 객체 자체입니다. 위에 예시에 this.value는 obj.value와 동일 합니다.

  • (2) 함수 콜

function func() {
  var value = 2;
  console.log(this.value);
}
func();
  • 위와 같이 일반적인 함수를 호출할 때(함수가 객체 안에서 선언되었을지라도), this는 전역을 가리킵니다. 이러한 이유로 this.value는 함수안에는 this를 참조하지 않습니다. 그리고 전역에 value는 undefined입니다. 만약 전역에 var value = 1;이 정의되어 있으면 함수 호출값은 1이 나옵니다.

  • (3) 생성자 함수 호출

function Obj(value) {
  this.value = value;
}
var obj = new Obj(0);
console.log(obj.value); // 0
  • 생성자함수의 인스턴스의 경우, this는 인스턴스를 가리킵니다.

  • (4) apply, call, bind

var obj = {
  value: 1,
  show: function() {
    console.log(this.value);
  }
};
var newObj = {
  value: 5
};
obj.show(); //1
obj.show.call(newObj); // 5;
obj.show.apply(newObj); // 5;
  • call, apply 메소드를 활용함으로 첫번 째 argument에 this를 바인딩할 수 있습니다. 그것은 newObj={value: 5}이기 때문에 this.value에 값을 5로 바꾸는 것입니다.

  • argument는 두번 째 argument를 전달 받을 수 있습니다. call은 순서대로 받고 apply라는 배열로 전달합니다. 또한 bind 메소드를 사용할 때, 아래와 같이 사용합니다. (this는 바인딩하는 함수를 생성합니다.)

var newFunc = obj.show.bind(newObj);
newFunc();
  • (5) 화살표 함수[ES6 ~] 화살표함수에서 함수가 선언된 스코프에 자동으로 바인딩 됩니다.
var obj = {
  value: 10,

  // 메소드 호출
  show: function () {
    console.log(this.value); // 10

    // 함수 호출
    function show_01 () {
      console.log(this.value); // undefined
    }
    show_01();

    // 화살표 함수
    function show_02 = () => {
      console.log(this.value); // 10
    }
    show_02();
  }
}
obj.show();

변수 선어

var, let, const

  • ES6에서 var와 새롭게 let, const 문법을 추가적으로 사용할 수 있습니다.

  • let …… unable
  • const는 변수를 다신선언…. 할 수 없고 값을 재할당할 수 없습니다.

  • var는 변수를 선언할 때 사용합니다. 아래와 같이 사용해도 문제가 없습니다.
var x = 10;
x = 15;
console.log(x); //15
var x = 12;
console.log(x); //12
  • let은 한번 선언된 변수는 동일한 이름으로 선언할 수 없습니다. (값을 재할당 할 수 있습니다.)
let x = 10;
x = 15;
console.log(x); //15
let x = 12; // Identifier 'x' has already been declared

또한, const는 constant와 같은 룰을 가지고 있습니다. 그리고 한번 초기화된 변수에 재할당하는 것을 허락하지 않습니다.

const x = 10;
console.log(x); // 10;
x = 15; // TypeError: Assignment to constant variable.

만약에 const를 객체나 배열타입으로 선언했다면, 참조 자체를 변경할 수 없지만 컨텐츠를 변경할 수 있습니다.

var ary1 = () => {
  const aryFalse = [1, 2, 3];
  aryFalse = [4, 5, 6]; //Error
  console.log(aryFalse);
};
ary1(); // Error

var ary2 = () => {
  const aryTure = [1, 2, 3];
  aryTure[1] = 10;
  console.log(aryTrue);
};
any2(); // [1, 10, 3]

변수의 스코프 범위

  • 만약에 {, if}블록 안에 let, const를 선언하면 스코프밖에서 안에있는 변수를 참조할 수 없습니다.
if (true) {
  var i = 0;
}
console.log(i); // 0
if (true) {
  let j = 10;
}
console.log(j); // ReferenceError
if (true) {
  const k = 100;
}
console.log(k); // ReferenceError
  • 변수 let, const 밖에 스포프에서 선언된 변수를 참조할 수 있습니다.
const i = 5;
if (ture) {
  console.log(i); // 5
}

모듈

  • ES5 이전에는 각 기능별로 JS파일은 나누고 개발 및 관리하는 것이 불가능했습니다.

p.s var obj = obj || {}는 네이스페이스 패턴을 사용할 수 있는 것처럼 보입니다.

require

js / - - -script.js
      |
      ---  slider.js
  • 파일구성의 경우,
  • index.html
<script>
  src = "slider.js";
</script>
<script>
  src = "script.js";
</script>

위에 예시는 기존에 사용하던 방식입니다.

  • script.js
var slider = require(./slider.js)
// 혹은 require(./slider)

위와 같이 함으로써, slider.js는 임포트할수 있습니다. 이러한 방법으로 파일 자체를 사용할 수 있습니다.

p.s require은 ES5부터 CommonJS 규격으로 존재해 왔습니다. 그러나 브러우저는 여전히 지원하고 있지않습니다.(다른 전환 프로세스를 이용해야 합니다.)

import / export

  • 모듈은 실현가능한 특정프로그램의 그룹입니다. 그리고 이것은 다른 파일의 변수, 함수를 참조합니다. 클래스와 같은 모듈이 로딩될 때, import와 export를 이용해 사용될 수 있습니다.

하나의 모듈만 공유할때

  • 로드 모듈

    import ‘import to loadname’ from ‘파일 경로’

  • 아웃풋 모듈

    export default ‘module’

  • script.js

import Carousel from "./carousel";
const carousel = new Carousel();
  • carousel.js
export default class Carousel {
  constructor() {
    this.calc();
  }
  calc() {
    console.log(10);
  }
}

여러 모듈을 사용할 때

  • 아웃풋 관점에서, export는 사용하고 싶은 곳에 붙이고, import는 다음과 같이 사용하면 됩니다.

    import {a1, a2, …} from ‘파일 경로’

  • script.js
import { multi, SuperMulti } from "./Multiplay";
console.log(multi(5)); // 50
console.log(SuperMulti(6)); // 600
export const i = 10;

export function multi(x) {
  return i * x;
}

export function superMulti(x) {
  return i * x * 10;
}
  • 만약 모든 모듈은 전달받기위해서는 import사이드는 아래와 같이 작성하면 됩니다.

    import * as ‘object name’ form ‘파일 경로’

위의 예제를 아래와 같이 작성하면 됩니다.

import * as lib from "./multiply";
console.log(lib.multi(5)); // 50

클래스

클래스 선언

ES5에서 클래스 선언은 프로토타입을 통해서 실현됐습니다. ES6에서는 class 키워드를 사용해서 선언할 수 있습니다.

  • ES5
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 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

클래스 상속

  • 클래스 상속과 오버라이딩은 super을 사용해서 수행할 수 있습니다.

  • ES5 (Add는 이미 선언되었다고 가정)

var AddSquare = function(arg1, arg2) {
  Add.call(this, arg1, arg2);
};

Object.assign(AddSquare.prototype, Add.prototype);

AddSquare.prototype = {
  calc: function() {
    // 메소드는 생략될 수 없습니다.
    Add.prototype.calc.call(this);
  },
  calcSquare: function() {
    this.pow = Math.pow(this.arg1 + this.arg2, 2);
    return "(" + this.arg1 + "+" + this.arg2 + ")^2=" + this.pow;
  }
};

var numSquare = new AddSquare(5, 8);
console.log(numSquare.calc()); // 5 + 8 = 13
console.log(numSquare.calcSquare()); // (5 + 8) ^ 2 =169
  • ES6 (Add 클래스는 이미 선언되었다고 가정)
class AddSquare extends Add {
  constructor(arg1, arg2) {
    super(arg1, arg2);
  }
  calc() {
    super.calc();
  }
  calcSquare() {
    this.pow = Math.pow(this.arg1 + this.arg2, 2);
    return "(" + this.arg1 + "+" + this.arg2 + ") ^ 2 =" + this.pow;
  }
}

var numSquare = new AddSquare(5, 8);
console.log(numSquare.calc()); // 5 + 8 = 13
console.log(numSquare.calcSquare()); // (5 + 8) ^ 2 = 169