πŸ“–ES6 ν•¨μˆ˜μ˜ μΆ”κ°€ κΈ°λŠ₯

κΈ°λ‘μΌκΈ°πŸ“«Β·2021λ…„ 3μ›” 6일
1

Javascript κ°œλ…μ •λ¦¬

λͺ©λ‘ 보기
15/15

이번 ν¬μŠ€νŒ…μ—μ„œλŠ” ES6 μŠ€νŽ™μ—μ„œ μΆ”κ°€λœ ν•¨μˆ˜μ—μ„œμ˜ μΆ”κ°€ κΈ°λŠ₯에 λŒ€ν•΄μ„œ 닀뀄본닀.

ES6λž€?πŸ€”

ES6λž€ λ¬΄μ—‡μΌκΉŒ? ES6λŠ” ECMAλΌλŠ” ꡭ제 κΈ°κ΅¬μ—μ„œ λ§Œλ“  ν‘œμ€€λ¬Έμ„œμΈ ECMAScript(=ES)의 6번째 κ°œμ •νŒ λ¬Έμ„œμ— μžˆλŠ” ν‘œμ€€ μŠ€νŽ™μ„ λ§ν•œλ‹€.

λ§Žμ€ 버전 쀑 ES6κ°€ 자주 μ–ΈκΈ‰λ˜λŠ” μ΄μœ λŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜, Promise, Spread μ—°μ‚°μž, ν…œν”Œλ¦Ώ λ¦¬ν„°λŸ΄λ“± μ΅œμ‹  μžλ°”μŠ€ν¬λ¦½νŠΈ 개발 ν™˜κ²½μ—μ„œ μ΄μš©λ˜λŠ” 문법듀이 λŒ€κ±° μƒˆλ‘œ λ“±μž₯ν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

ECMAScript

ECMAScript에 λŒ€ν•΄μ„œ 쑰금 더 μ•Œμ•„λ³΄μž. ECMAScriptλž€ λ‹€μ–‘ν•œ μ›Ή λΈŒλΌμš°μ €λ“€μ—μ„œ JavaScriptκ°€ κ³΅ν†΅λ˜κ²Œ 잘 μž‘λ™λ˜κΈ° μœ„ν•΄μ„œ μ •μ˜ν•œ ν‘œμ€€ κ·œκ²©μ„ λ§ν•œλ‹€.

ECMA ꡭ제 κΈ°κ΅¬μ—μ„œ 'ECMAScript standard'λΌλŠ” 슀크립트 ν‘œμ€€μ„ λ§Œλ“ λ‹€.

πŸ’‘ ECMASCript μŠ€νŽ™ μ •μ˜μ„œλŠ” μ΄κ³³μ—μ„œ 확인해 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.


ES6 ν•¨μˆ˜μ˜ μΆ”κ°€ κΈ°λŠ₯

자, 그러면 ES6μ—μ„œ μ •μ˜λœ ν•¨μˆ˜μ˜ μΆ”κ°€ κΈ°λŠ₯에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μž.

λ‹€μŒκ³Ό 같은 κΈ°λŠ₯λ“€μ˜ λ“±μž₯ 배경을 μ‚΄νŽ΄λ³Έλ‹€.

  • λ©”μ„œλ“œ ν•¨μˆ˜
  • ν™”μ‚΄ν‘œ ν•¨μˆ˜
  • rest νŒŒλΌλ―Έν„°

ES6 λ“±μž₯ μ „ λͺ¨λ“  ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜, μƒμ„±μž ν•¨μˆ˜λ‘œμ¨ 호좜이 κ°€λŠ₯ν–ˆλ‹€.
λ‹€μŒ μ½”λ“œλ₯Ό 보자.

var foo = function () {
  return 1;
}

// 일반 ν•¨μˆ˜λ‘œ 호좜
foo();

// μƒμ„±μž ν•¨μˆ˜λ‘œ 호좜
new foo();

// λ©”μ„œλ“œλ‘œ 호좜
var obj = {foo: foo}
obj.foo()

즉, ES6 μ „μ˜ λͺ¨λ“  ν•¨μˆ˜λŠ” [[Constructor]] μ΄λ©΄μ„œ [[Callable]]μ΄μ—ˆλ‹€. (λ‚΄λΆ€ 슬둯과 λ‚΄λΆ€ λ©”μ„œλ“œμ— λŒ€ν•΄ μ΅μˆ™ν•˜μ§€ μ•ŠμœΌμ‹  뢄듀은 ν”„λ‘œνΌν‹° μ–΄νŠΈλ¦¬λ·°νŠΈ ν¬μŠ€νŒ…μ„ μ°Έμ‘°ν•˜μ„Έμš”!)

μ–Έλœ» 보면 νŽΈλ¦¬ν•΄ 보일 수 μžˆμœΌλ‚˜ μ΄λŸ¬ν•œ 방식은 μžμΉ«ν•˜λ©΄ 버그λ₯Ό μœ λ°œν•  수 μžˆλ‹€. 예λ₯Ό λ“€λ©΄, μƒμ„±μž ν•¨μˆ˜λ‘œμ¨ 이용되면 μ•ˆ λ˜λŠ” ν•¨μˆ˜λ“€μ΄ new ν‚€μ›Œλ“œλ₯Ό 톡해 μƒμ„±μž ν•¨μˆ˜λ‘œ 호좜 ν•˜λŠ” 것을 막을 방법이 μ—†λ‹€.

λ˜ν•œ, μƒμ„±μž ν•¨μˆ˜λ‘œμ¨ μ‚¬μš©ν•˜μ§€ μ•Šμ„ ν•¨μˆ˜λ“€λ„ prototype 객체λ₯Ό λ§Œλ“€κΈ° λ•Œλ¬Έμ— μ„±λŠ₯μ μœΌλ‘œλ„ 쒋지 μ•Šλ‹€.

μ΄λŸ¬ν•œ 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ES6μ—μ„œλŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš© λͺ©μ μ— 따라 3κ°€μ§€λ‘œ λͺ…ν™•νžˆ κ΅¬λΆ„ν•œλ‹€.

  1. 일반 ν•¨μˆ˜
  2. λ©”μ„œλ“œ
  3. ν™”μ‚΄ν‘œ ν•¨μˆ˜

μ—¬κΈ°μ„œ 일반 ν•¨μˆ˜λ§Œμ΄ μƒμ„±μž ν•¨μˆ˜λ‘œμ¨ 호좜 될 수 μžˆλ‹€.

λ©”μ„œλ“œ

ES6 μ‚¬μ–‘μ—μ„œ λ©”μ„œλ“œλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λ§Œμ„ μ˜λ―Έν•œλ‹€.

const obj = {
  x: 1,
  foo(){ return this.x;}, // λ©”μ„œλ“œ
  bar: function(){ return this.x} // λ©”μ„œλ“œ μ•„λ‹˜
}
// bar만 μƒμ„±μž ν•¨μˆ˜λ‘œ new ν‚€μ›Œλ“œμ™€ ν•¨κ»˜ 호좜 κ°€λŠ₯

// new obj.bar() ??

obj.foo.hasOwnProperty('prototype') // false
obj.bar.hasOwnProperty('prototype') // true

μœ„ μ½”λ“œμ—μ„œ 보면 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μƒμ„±λœ foo만 λ©”μ„œλ“œμ΄κ³ , bar은 λ©”μ„œλ“œκ°€ μ•„λ‹ˆλ‹€. λ”°λΌμ„œ ECMAScriptμ—μ„œλŠ” λ©”μ„œλ“œ 생성 μ‹œ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•  것을 ꢌμž₯ν•œλ‹€.

λ©”μ„œλ“œμΈ foo의 경우 prototype 객체λ₯Ό 갖지 μ•Šκ³ , λ©”μ„œλ“œκ°€ μ•„λ‹Œ bar의 경우 prototype 객체λ₯Ό κ°–λŠ”κ²ƒμ„ 확인할 수 μžˆλ‹€.

ν™”μ‚΄ν‘œ ν•¨μˆ˜

ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” ES6 μ‚¬μ–‘μ—μ„œ 처음 λ“±μž₯ν•œ ν•¨μˆ˜λ‘œ, this 바인딩을 갖지 μ•ŠλŠ” 것이 κ°€μž₯ 큰 νŠΉμ§•μ΄λ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisκ°€ μ „μ—­ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

this κ΄€λ ¨ ν¬μŠ€νŒ…μ—μ„œλ„ ν™œμš©ν–ˆλ˜ μ½”λ“œμΈλ°, 이해λ₯Ό μœ„ν•΄ ν•œλ²ˆ 더 가지고 μ™”λ‹€.
μ•„λž˜ μ½”λ“œλ₯Ό 보자.

class Prefixer {
  constructor(prefix) {
    this.prefix = prefix;
  }

  add(arr) {
    return arr.map(function (item) {
      return this.prefix + item; 
      // TypeError: Cannot read property 'prefix' of undefined
    });
  }
}

const prefixer = new Prefixer('-webkit-');
console.log(prefixer.add(['transition', 'user-select']));

Prefixer Class λ‚΄λΆ€μ˜ add λ©”μ„œλ“œκ°€ μ˜λ„ν•œ λ™μž‘μ€ μ „λ‹¬ν•œ λ°°μ—΄μ˜ μ›μ†Œλ₯Ό 돌며 prefix인 '-webkit-'을 뢙인 λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” 것이닀.

ν•˜μ§€λ§Œ add λ©”μ„œλ“œ arr.mapμ•ˆμ˜ 콜백 ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜λ‘œ ν˜ΈμΆœλ˜μ—ˆκ³ , 일반 ν•¨μˆ˜μ—μ„œ thisλŠ” μ „μ—­ 객체인 windowλ₯Ό 가리킀기 λ•Œλ¬Έμ— prefix값을 μ°Έμ‘°ν•  수 μ—†λ‹€.

이런 경우 κΈ°μ‘΄μ—λŠ” bindλ₯Ό 톡해 thisλ₯Ό bindingν•˜κ±°λ‚˜ class의 thisλ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— μ €μž₯ν•˜κ³  κ·Έ λ³€μˆ˜μ— μ ‘κ·Όν•˜λŠ” λ°©μ‹μœΌλ‘œ ν•΄κ²°ν•˜μ—¬μ•Ό ν–ˆλ‹€.

ES6 μ΄μƒμ˜ κ°œλ°œν™˜κ²½μ—μ„œλŠ” μ•„λž˜μ™€ 같이 ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ ν•΄κ²° κ°€λŠ₯ν•˜λ‹€.

class Prefixer {
  constructor(prefix) {
    this.prefix = prefix;
  }

  add(arr) {
    return arr.map(item => this.prefix + item);
  }
}

const prefixer = new Prefixer('-webkit-');
console.log(prefixer.add(['transition', 'user-select']));
// ['-webkit-transition', '-webkit-user-select']

ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” this 바인딩이 μ—†κΈ° λ•Œλ¬Έμ— μƒμœ„ μŠ€μ½”ν”„μΈ Prefixer classλ₯Ό μ°Έμ‘°ν•˜κ²Œ λœλ‹€.

Rest νŒŒλΌλ―Έν„°

rest νŒŒλΌλ―Έν„°λŠ” ν•¨μˆ˜μ— μ „λ‹¬λœ μΈμˆ˜λ“€μ˜ λͺ©λ‘μ„ λ°°μ—΄λ‘œ μ „λ‹¬λ°›λŠ”λ‹€.

function foo(...rest){
	console.log(rest); // [1,2,3,4,5]
}

foo(1,2,3,4,5)

ES6 이전에 자주 μ‚¬μš©λœ argument와 거의 같은 κΈ°λŠ₯을 ν•˜μ§€λ§Œ, arguments κ°μ²΄λŠ” 배열이 μ•„λ‹Œ μœ μ‚¬ λ°°μ—΄ κ°μ²΄μ΄λ―€λ‘œ λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ €λ©΄ λ°°μ—΄λ‘œ λ³€ν™˜ν•΄μ•Ό ν•œλ‹€λŠ” 단점이 μžˆμ—ˆλ‹€.

function sum() {
  var array = Array.prototype.slice.call(arguments);
  
  return array.reduce(function(pre,cur){
    return pre + cur;
  }, 0);
}

console.log(sum(1,2,3,4,5)) // 15

Rest νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ λ³€ν™˜ 과정이 없이 μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.

function sum(...args){
  return args.reduce((pre,cur) => pre+cur,0))
}

console.log(sum(1,2,3,4,5)) // 15

0개의 λŒ“κΈ€