JavaScript Factory Functions with ES6 - Lee-hyuna/33-js-concepts-kr GitHub Wiki

Note : 이것은 μžλ°” 슀크립트 ES6+ 의 ν•¨μˆ˜ ν”„λ‘œκ·Έλž˜λ° 및 ν•©μ„± μ†Œν”„νŠΈμ›¨μ–΄ κΈ°μˆ μ„ μ²˜μŒλΆ€ν„° λ°°μš°λŠ” "Composing Software"μ‹œλ¦¬μ¦ˆ(ν˜„μž¬ μ±…)의 
       μΌλΆ€μž…λ‹ˆλ‹€. 계속 μ§€μΌœλ΄λΌ. 이보닀 더 λ§Žμ€ 것이 μžˆμŠ΅λ‹ˆλ‹€.!

νŒ©ν† λ¦¬ ν•¨μˆ˜λŠ” 객체(μ•„λ§ˆλ„ μƒˆλ‘œμš΄)λ₯Ό λ°˜ν™˜ν•˜λŠ” ν΄λž˜μŠ€λ‚˜ μƒμ„±μžκ°€ μ•„λ‹Œ ν•¨μˆ˜μž…λ‹ˆλ‹€.
JavaScriptμ—μ„œλŠ” λͺ¨λ“  ν•¨μˆ˜κ°€ 객체λ₯Ό λ°˜ν™˜ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. new ν‚€μ›Œλ“œκ°€ μ—†μœΌλ©΄ νŒ©ν† λ¦¬ ν•¨μˆ˜μž…λ‹ˆλ‹€.

νŒ©ν† λ¦¬ ν•¨μˆ˜λŠ” JavaScriptμ—μ„œ 항상 맀λ ₯μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€.
클래슀의 λ³΅μž‘μ„±κ³Ό μƒˆ ν‚€μ›Œλ“œλ‘œ λ›°μ–΄λ“€μ–΄ 가지 μ•Šκ³ λ„ 객체 μΈμŠ€ν„΄μŠ€λ₯Ό μ‰½κ²Œ 생성 ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

JavaScriptλŠ” 맀우 νŽΈλ¦¬ν•œ 객체 λ¦¬ν„°λŸ΄ ꡬ문을 μ œκ³΅ν•©λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 λ³΄μž…λ‹ˆλ‹€.

const user = {
  userName: 'echo',
  avatar: 'echo.png'
};

JavaScript의 객체 λ¦¬ν„°λŸ΄ ν‘œκΈ°λ²•μ— κΈ°λ°˜ν•œ JSONκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ :의 μ™Όμͺ½μ€ 속성 이름이고 였λ₯Έμͺ½μ€ κ°’μž…λ‹ˆλ‹€.
점 ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬ props에 μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

console.log(user.userName); // "echo"

λŒ€κ΄„ν˜Έ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬ 계산 된 νŠΉμ„± 이름에 μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const key = 'avatar';
console.log( user[key] ); // "echo.png"

μ›ν•˜λŠ” 속성 이름과 λ™μΌν•œ μ΄λ¦„μ˜ λ²”μœ„ λ³€μˆ˜κ°€μžˆλŠ” 경우 객체 λ¦¬ν„°λŸ΄ λ§Œλ“€κΈ°μ—μ„œ 콜둠과 값을 μƒλž΅ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const userName = 'echo';
const avatar = 'echo.png';
const user = {
  userName,
  avatar
};
console.log(user);
// { "avatar": "echo.png",   "userName": "echo" }

객체 λ¦¬ν„°λŸ΄μ€ κ°„κ²°ν•œ λ©”μ†Œλ“œ ꡬ문을 μ§€μ›ν•©λ‹ˆλ‹€. .setUserName () λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const userName = 'echo';
const avatar = 'echo.png';
const user = {
  userName,
  avatar,
  setUserName (userName) {
    this.userName = userName;
    return this;
  }
};
console.log(user.setUserName('Foo').userName); // "Foo"

κ°„κ²°ν•œ λ©”μ†Œλ“œμ—μ„œ, 이것은 λ©”μ†Œλ“œκ°€ ν˜ΈμΆœλ˜λŠ” 였브젝트λ₯Ό μ°Έμ‘°ν•©λ‹ˆλ‹€. 객체의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ €λ©΄ 객체 λ„νŠΈ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬
λ©”μ„œλ“œμ— μ•‘μ„ΈμŠ€ν•˜κ³  κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•˜μ—¬ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ game.play ()λŠ” .play ()λ₯Ό κ²Œμž„ 객체에 μ μš©ν•©λ‹ˆλ‹€.
λ„νŠΈ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•˜μ—¬ λ©”μ†Œλ“œλ₯Ό μ μš©ν•˜λ €λ©΄ ν•΄λ‹Ή λ©”μ†Œλ“œκ°€ ν•΄λ‹Ή 였브젝트의 νŠΉμ„±μ΄μ–΄μ•Όν•©λ‹ˆλ‹€.
ν•¨μˆ˜ ν”„λ‘œν†  νƒ€μž… λ©”μ„œλ“œ 인 .call (), .apply () λ˜λŠ” .bind ()λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€λ₯Έ μž„μ˜μ˜ κ°œμ²΄μ— λ©”μ„œλ“œλ₯Ό 적용 ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

이 경우 user.setUserName ( 'Foo')λŠ” .setUserName ()을 μ‚¬μš©μžμ—κ²Œ μ μš©ν•˜λ―€λ‘œ
this === user. .setUserName () λ©”μ„œλ“œμ—μ„œμ΄ 바인딩을 톡해 μ‚¬μš©μž 개체의 .userName 속성을 λ³€κ²½ν•˜κ³  λ©”μ„œλ“œ 체인에 λŒ€ν•΄
λ™μΌν•œ 객체 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

ν•˜λ‚˜μ— λŒ€ν•œ λ¦¬ν„°λŸ΄, λ§Žμ€ Factories

λ§Žμ€ 객체λ₯Ό μƒμ„±ν•΄μ•Όν•˜λŠ” 경우 객체 λ¦¬ν„°λŸ΄κ³Ό νŒ©ν† λ¦¬ ν•¨μˆ˜μ˜ κΈ°λŠ₯을 κ²°ν•©ν•΄μ•Όν•©λ‹ˆλ‹€.

νŒ©ν† λ¦¬ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ›ν•˜λŠ” 만큼 λ§Žμ€ μ‚¬μš©μž 객체λ₯Ό 생성 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ μ±„νŒ… 앱을 λ§Œλ“œλŠ” 경우 ν˜„μž¬ μ‚¬μš©μžλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ‚¬μš©μž 객체와 ν˜„μž¬ λ‘œκ·ΈμΈν•˜κ³  μ±„νŒ…ν•˜λŠ” λ‹€λ₯Έ λͺ¨λ“  μ‚¬μš©μžλ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ§Žμ€ λ‹€λ₯Έ μ‚¬μš©μž 객체λ₯Ό κ°€μ§ˆ 수 μžˆμœΌλ―€λ‘œ 이름을 ν‘œμ‹œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€ 아바타도.

μ‚¬μš©μž 객체λ₯Ό createUser () νŒ©ν† λ¦¬λ‘œ λ³€ν™˜ν•©μ‹œλ‹€.

const createUser = ({ userName, avatar }) => ({
  userName,
  avatar,
  setUserName (userName) {
    this.userName = userName;
    return this;
  }
});
console.log(createUser({ userName: 'echo', avatar: 'echo.png' }));
/*
{
  "avatar": "echo.png",
  "userName": "echo",
  "setUserName": [Function setUserName]
}
*/

λ°˜ν™˜κ°μ²΄

ν™”μ‚΄ν‘œ ν•¨μˆ˜ (=>)λŠ” μ•”μ‹œ 적 λ°˜ν™˜ νŠΉμ„±μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. ν•¨μˆ˜ 본문이 단일 ν‘œν˜„μ‹μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ 있으면 return ν‚€μ›Œλ“œλ₯Ό μƒλž΅ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. () => 'foo'λŠ” 맀개 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  " foo ".

객체 λ¦¬ν„°λŸ΄μ„ λ°˜ν™˜ ν•  λ•Œμ£Όμ˜ν•˜μ‹­μ‹œμ˜€. 기본적으둜 JavaScriptλŠ” μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•  λ•Œ ν•¨μˆ˜ 본문을 λ§Œλ“€λ €κ³ ν•œλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.
(예 : {broken : true}). 객체 λ¦¬ν„°λŸ΄μ— λŒ€ν•΄ μ•”μ‹œ 적 λ°˜ν™˜μ„ μ‚¬μš©ν•˜λ €λ©΄ κ΄„ν˜Έ μ•ˆμ— 객체 λ¦¬ν„°λŸ΄μ„ λž˜ν•‘ν•˜μ—¬ λͺ…ν™•ν•˜κ²Œ ν•΄μ•Όν•©λ‹ˆλ‹€.

const noop = () => { foo: 'bar' };
console.log(noop()); // undefined
const createFoo = () => ({ foo: 'bar' });
console.log(createFoo()); // { foo: "bar" }

첫 번째 μ˜ˆμ—μ„œ foo :λŠ” λ ˆμ΄λΈ”λ‘œ ν•΄μ„λ˜κ³  barλŠ” ν• λ‹Ήλ˜κ±°λ‚˜ λ°˜ν™˜λ˜μ§€ μ•ŠλŠ” ν‘œν˜„μ‹μœΌλ‘œ ν•΄μ„λ©λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” undefinedλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

createFoo () μ˜ˆμ œμ—μ„œ κ΄„ν˜ΈλŠ” μ€‘κ΄„ν˜Έλ₯Ό ν•¨μˆ˜ λ³Έλ¬Έ 블둝이 μ•„λ‹Œ 평가할 ν‘œν˜„μ‹μœΌλ‘œ ν•΄μ„ν•˜λ„λ‘ν•©λ‹ˆλ‹€.

해체

ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜μ— νŠΉλ³„ν•œμ£Όμ˜λ₯Ό κΈ°μšΈμ΄μ‹­μ‹œμ˜€.

const createUser = ({ userName, avatar }) => ({

이 μ€„μ—μ„œ μ€‘κ΄„ν˜Έ ({,})λŠ” 객체 파괴λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” ν•˜λ‚˜μ˜ 인수 (객체)λ₯Ό μ‚¬μš©ν•˜μ§€λ§Œ 단일 인수 인 userNameκ³Ό μ•„λ°”νƒ€μ—μ„œ
두 개의 ν˜•μ‹ 맀개 λ³€μˆ˜λ₯Ό μ†Œλ©Έμ‹œν‚΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 맀개 λ³€μˆ˜λŠ” ν•¨μˆ˜ λ³Έλ¬Έ λ²”μœ„μ—μ„œ λ³€μˆ˜λ‘œ μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€. 배열을 μ†Œλ©Έμ‹œν‚¬ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€ :

const swap = ([first, second]) => [second, first];
console.log( swap([1, 2]) ); // [2, 1]

λ‚˜λ¨Έμ§€ ꡬ문을 μ‚¬μš©ν•˜μ—¬ (... varName) λ°°μ—΄ (λ˜λŠ” 인수 λͺ©λ‘)μ—μ„œ λ‚˜λ¨Έμ§€ 값을 μˆ˜μ§‘ ν•œ λ‹€μŒ ν•΄λ‹Ή λ°°μ—΄ μš”μ†Œλ₯Ό
λ‹€μ‹œ κ°œλ³„ μš”μ†Œμ— λΆ„μ‚°μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

const rotate = ([first, ...rest]) => [...rest, first];
console.log( rotate([1, 2, 3]) ); // [2, 3, 1]

계산 된 속성 ν‚€

이전에 μš°λ¦¬λŠ” μ•‘μ„ΈμŠ€ ν•  객체 속성을 λ™μ μœΌλ‘œ κ²°μ •ν•˜κΈ° μœ„ν•΄ λŒ€κ΄„ν˜Έ μ‚°μˆ  속성 μ ‘κ·Ό ν‘œκΈ°λ²•μ„ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€ :

const key = 'avatar';
console.log( user[key] ); // "echo.png"

λ‹€μŒμ— ν• λ‹Ή ν•  ν‚€ 값을 계산할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

const arrToObj = ([key, value]) => ({ [key]: value });
console.log( arrToObj([ 'foo', 'bar' ]) ); // { "foo": "bar" }

이 μ˜ˆμ œμ—μ„œ arrToObjλŠ” ν‚€ / κ°’ 쌍 (일λͺ… νŠœν”Œ)둜 κ΅¬μ„±λœ 배열을 κ°€μ Έ μ™€μ„œ 객체둜 λ³€ν™˜ν•©λ‹ˆλ‹€.
ν‚€μ˜ 이름을 μ•Œμ§€ λͺ»ν•˜κΈ° λ•Œλ¬Έμ— 객체의 ν‚€ / κ°’ μŒμ„ μ„€μ •ν•˜λ €λ©΄ 속성 이름을 κ³„μ‚°ν•΄μ•Όν•©λ‹ˆλ‹€.
이λ₯Ό μœ„ν•΄ 계산 된 속성 μ ‘κ·Όμžμ—μ„œ λŒ€κ΄„ν˜Έ ν‘œκΈ°λ²•μ„ 빌렀 객체 λ¦¬ν„°λŸ΄μ„ μž‘μ„±ν•˜λŠ” μ»¨ν…μŠ€νŠΈμ—μ„œ λ‹€μ‹œ μ‚¬μš©ν•©λ‹ˆλ‹€.

{ [key]: value }

μ±„μš°λŠ” μž‘μ—…μ΄ λλ‚˜λ©΄, μš°λ¦¬λŠ” κ²°κ΅­ λ‹€μŒκ³Ό 같은 μ΅œμ’… λŒ€μƒμ„ μ–»κ²Œ λœλ‹€.

{ "foo": "bar" }

κΈ°λ³Έ 맀개 λ³€μˆ˜

JavaScript의 ν•¨μˆ˜λŠ” κΈ°λ³Έ 맀개 λ³€μˆ˜ 값을 μ§€μ›ν•˜λ©° λ‹€μŒκ³Ό 같은 λͺ‡ 가지 이점이 μžˆμŠ΅λ‹ˆλ‹€.

  1. μ‚¬μš©μžλŠ” μ μ ˆν•œ κΈ°λ³Έκ°’μœΌλ‘œ 맀개 λ³€μˆ˜λ₯Ό μƒλž΅ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  2. 기본값은 μ˜ˆμƒλ˜λŠ” μž…λ ₯의 예λ₯Ό μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ— 이 ν•¨μˆ˜λŠ” 더 자체적으둜 λ¬Έμ„œν™”λ©λ‹ˆλ‹€.
  3. IDE와 정적 뢄석 λ„κ΅¬λŠ” 기본값을 μ‚¬μš©ν•˜μ—¬ 맀개 λ³€μˆ˜μ— ν•„μš”ν•œ μœ ν˜•μ„ μΆ”λ‘  ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    예λ₯Ό λ“€μ–΄, κΈ°λ³Έκ°’ 1은 맀개 λ³€μˆ˜κ°€ Number μœ ν˜•μ˜ 멀버λ₯Ό μ‚¬μš©ν•  수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

κΈ°λ³Έ 맀개 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ createUser νŒ©ν† λ¦¬μ— λŒ€ν•œ μ˜ˆμƒ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ¬Έμ„œν™”ν•˜κ³  μ‚¬μš©μž 정보가 μ œκ³΅λ˜μ§€ μ•Šμ€ 경우
'읡λͺ…'μ„ΈλΆ€ 정보λ₯Ό μžλ™μœΌλ‘œ μ±„μ›λ‹ˆλ‹€.

const createUser = ({
  userName = 'Anonymous',
  avatar = 'anon.png'
} = {}) => ({
  userName,
  avatar
});
console.log(
  // { userName: "echo", avatar: 'anon.png' }
  createUser({ userName: 'echo' }),
  // { userName: "Anonymous", avatar: 'anon.png' }
  createUser()
);

ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜μ˜ λ§ˆμ§€λ§‰ 뢀뢄은 μ•„λ§ˆλ„ μ•½κ°„ 우슡게 보일 κ²ƒμž…λ‹ˆλ‹€.

} = {}) => ({

μ„œλͺ…이 λ‹«νžˆκΈ° μ§μ „μ˜ λ§ˆμ§€λ§‰ = {} λΉ„νŠΈλŠ”μ΄ 맀개 λ³€μˆ˜μ— 아무것도 μ „λ‹¬λ˜μ§€ μ•ŠμœΌλ©΄ 빈 객체λ₯Ό κΈ°λ³Έκ°’μœΌλ‘œ μ‚¬μš©ν•œλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
빈 κ°μ²΄μ—μ„œ 값을 μ œκ±°ν•˜λ €κ³ ν•˜λ©΄ 속성에 λŒ€ν•œ 기본값이 μžλ™μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€. κΈ°λ³Έ 값은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
undefinedλ₯Ό 미리 μ •μ˜ 된 κ°’μœΌλ‘œ λ°”κΎΈμ‹­μ‹œμ˜€.

= {} 기본값이 μ—†μœΌλ©΄ undefinedμ—μ„œ 속성에 μ•‘μ„ΈμŠ€ ν•  수 μ—†κΈ° λ•Œλ¬Έμ— μΈμˆ˜κ°€μ—†λŠ” createUser()κ°€ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.

Type Inference

JavaScriptλŠ” 이 글을 μ“°λŠ” λ™μ•ˆ λ„€μ΄ν‹°λΈŒ νƒ€μž… 주석을 가지고 μžˆμ§€ μ•Šμ§€λ§Œ JSDoc (더 λ‚˜μ€ μ˜΅μ…˜μ˜ μΆœν˜„μœΌλ‘œ 인해 κ°μ†Œ),
페이슀 뢁의 ν”Œλ‘œμš° 및 마이크둜 μ†Œν”„νŠΈμ˜ νƒ€μž… 슀크립트λ₯Ό ν¬ν•¨ν•˜μ—¬ λͺ‡ 가지 경쟁 포맷이 κ·Έ 격차λ₯Ό ν•΄μ†Œν•˜κΈ° μœ„ν•΄ μˆ˜λ…„κ°„ κΈ‰μ„±μž₯ ν•΄ μ™”μŠ΅λ‹ˆλ‹€.
λ‚˜λŠ” rtype을 λ¬Έμ„œν™”μ— μ‚¬μš©ν•œλ‹€ - κΈ°λŠ₯적 ν”„λ‘œκ·Έλž˜λ°μ„μœ„ν•œ TypeScript보닀 훨씬 더 읽기 μ‰¬μš΄ ν‘œκΈ°λ²•.

이 글을 μ“°λŠ” μ‹œμ μ—λŠ” μœ ν˜• 주석에 λŒ€ν•΄ ν™•μ‹€ν•œ μŠΉμžκ°€ μ—†μŠ΅λ‹ˆλ‹€.
JavaScript μ‚¬μ–‘μ—λŠ” 별닀λ₯Έ λŒ€μ•ˆμ΄ μ—†μœΌλ©° λͺ¨λ“  κΈ°λŠ₯에 λͺ…ν™•ν•œ λ‹¨μ μ΄μžˆλŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€.

μœ ν˜• μœ μΆ”λŠ” μ‚¬μš© 된 λ¬Έλ§₯을 기반으둜 μœ μΆ” μœ ν˜•μ„ μΆ”λ‘ ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€μž…λ‹ˆλ‹€. μžλ°” μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” 주석을 μž…λ ₯ν•˜λŠ” 쒋은 λŒ€μ•ˆμž…λ‹ˆλ‹€.

ν‘œμ€€ JavaScript ν•¨μˆ˜μ—μ„œ 좔둠을 μœ„ν•œ λ‹¨μ„œλ₯Ό μΆ©λΆ„νžˆ μ œκ³΅ν•œλ‹€λ©΄ λΉ„μš©μ΄λ‚˜ μœ„ν—˜μ΄ μ—†λŠ” μœ ν˜• μ£Όμ„μ˜ 이점 λŒ€λΆ€λΆ„μ„ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

TypeScript λ˜λŠ” Flow와 같은 도ꡬλ₯Ό μ‚¬μš©ν•˜κΈ°λ‘œ κ²°μ •ν•œ κ²½μš°μ—λ„ μœ ν˜• μœ μΆ”λ‘œ κ°€λŠ₯ν•œ ν•œ 많이 μˆ˜ν–‰ν•˜κ³  μœ ν˜• μœ μΆ”κ°€ λΆ€μ‘±ν•œ μƒν™©μ—μ„œ
μœ ν˜• 주석을 μ €μž₯ν•΄μ•Όν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ 곡유 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ§€μ •ν•˜λŠ” μžλ°” μŠ€ν¬λ¦½νŠΈμ—λŠ” κΈ°λ³Έ 방법이 μ—†μŠ΅λ‹ˆλ‹€.
μ΄λŠ” TypeScript λ˜λŠ” rtypeμ—μ„œ 쉽고 μœ μš©ν•©λ‹ˆλ‹€.

Tern.jsλŠ” λ§Žμ€ μ½”λ“œ νŽΈμ§‘κΈ°μ™€ IDE 용 ν”ŒλŸ¬κ·ΈμΈμ΄μžˆλŠ” JavaScript 용 μœ μΆ”ν˜• μœ μΆ” λ„κ΅¬μž…λ‹ˆλ‹€.

Microsoft의 Visual Studio μ½”λ“œλŠ” TypeScript의 μœ ν˜• μœ μΆ” κΈ°λŠ₯을 일반 JavaScript μ½”λ“œλ‘œ κ°€μ Έ 였기 λ•Œλ¬Έμ— Tern이 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

JavaScriptμ—μ„œ ν•¨μˆ˜μ˜ κΈ°λ³Έ 맀개 λ³€μˆ˜λ₯Ό μ§€μ •ν•˜λ©΄ Tern.js, TypeScript 및 Flow와 같은 μœ ν˜• μœ μΆ”κ°€ κ°€λŠ₯ν•œ λ„κ΅¬λŠ” μ˜¬λ°”λ₯΄κ²Œ μž‘μ—…μ€‘μΈ APIλ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ IDE 힌트λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

λ””ν΄νŠΈκ°€ μ—†λ‹€λ©΄, IDEλŠ” μ˜ˆμƒλ˜λŠ” 맀개 λ³€μˆ˜ μœ ν˜•μ„ νŒŒμ•…ν•˜κΈ°μœ„ν•œ μΆ©λΆ„ν•œ 힌트λ₯Ό 가지고 μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

기본값을 μ‚¬μš©ν•˜λ©΄ IDE (예 : μ‚¬λžŒ)κ°€ μ˜ˆμ œμ—μ„œ μœ μΆ” ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

맀개 λ³€μˆ˜λ₯Ό κ³ μ • μœ ν˜•μœΌλ‘œ μ œν•œν•˜λŠ” 것이 μ˜λ―Έκ°€μžˆλŠ” 것은 μ•„λ‹™λ‹ˆλ‹€(일반 ν•¨μˆ˜μ™€ κ³ μ°¨ ν•¨μˆ˜λ₯Ό μ–΄λ ΅κ²Œ λ§Œλ“­λ‹ˆλ‹€). ν•˜μ§€λ§Œ μ΄ν•΄κ°€λ˜λ©΄ κΈ°λ³Έ 맀개 λ³€μˆ˜κ°€ κ°€μž₯ 쒋은 λ°©λ²•μž…λ‹ˆλ‹€. TypeScript λ˜λŠ” Flowλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

Mixin 합성을 μœ„ν•œ νŒ©ν† λ¦¬ ν•¨μˆ˜λ“€

νŒ©ν† λ¦¬λŠ” 멋진 호좜 APIλ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό 크랭크 μ•„μ›ƒν•˜λŠ”λ° μ ν•©ν•©λ‹ˆλ‹€.
일반적으둜 ν•„μš”ν•œ 것은 μ „λΆ€μ΄μ§€λ§Œ, ν•œ λ²ˆμ— μ—¬λŸ¬ μœ ν˜•μ˜ 객체에 λΉ„μŠ·ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€.
μ΄λŸ¬ν•œ κΈ°λŠ₯을 κΈ°λŠ₯ 믹슀둜 μΆ”μƒν™”ν•˜μ—¬ 보닀 μ‰½κ²Œ β€‹β€‹μž¬μ‚¬μš© ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

그것이 κΈ°λŠ₯ λ―ΉμŠ€κ°€ λΉ›λ‚˜λŠ” κ³³μž…λ‹ˆλ‹€. λͺ¨λ“  객체 μΈμŠ€ν„΄μŠ€μ— .constructor 속성을 μΆ”κ°€ν•˜λ €λ©΄ withConstructor 믹슀 인을 λΉŒλ“œν•˜μ‹­μ‹œμ˜€.

with-constructor.js:

const withConstructor = constructor => o => ({
  // create the delegate [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)
  __proto__: {
    // add the constructor prop to the new [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)
    constructor
  },
  // mix all o's props into the new object
  ...o
});

이제 κ°€μ Έ μ™€μ„œ λ‹€λ₯Έ λ―ΉμŠ€μ™€ ν•¨κ»˜ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import withConstructor from `./with-constructor';
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
// or `import pipe from 'lodash/fp/flow';`
// Set up some functional mixins
const withFlying = o => {
  let isFlying = false;
  return {
    ...o,
    fly () {
      isFlying = true;
      return this;
    },
    land () {
      isFlying = false;
      return this;
    },
    isFlying: () => isFlying
  }
};
const withBattery = ({ capacity }) => o => {
  let percentCharged = 100;
  return {
    ...o,
    draw (percent) {
      const remaining = percentCharged - percent;
      percentCharged = remaining > 0 ? remaining : 0;
      return this;
    },
    getCharge: () => percentCharged,
    getCapacity: () => capacity
  };
};
const createDrone = ({ capacity = '3000mAh' }) => pipe(
  withFlying,
  withBattery({ capacity }),
  withConstructor(createDrone)
)({});
const myDrone = createDrone({ capacity: '5500mAh' });
console.log(`
  can fly:  ${ myDrone.fly().isFlying() === true }
  can land: ${ myDrone.land().isFlying() === false }
  battery capacity: ${ myDrone.getCapacity() }
  battery status: ${ myDrone.draw(50).getCharge() }%
  battery drained: ${ myDrone.draw(75).getCharge() }% remaining
`);
console.log(`
  constructor linked: ${ myDrone.constructor === createDrone }
`);

λ³΄μ‹œλ‹€μ‹œν”Ό μž¬μ‚¬μš© κ°€λŠ₯ν•œ withConstructor() λ―ΉμŠ€μΈμ€ λ‹€λ₯Έ 믹슀인과 ν•¨κ»˜ νŒŒμ΄ν”„ 라인으둜 κ°„λ‹¨νžˆ λ“œλ‘­ λ©λ‹ˆλ‹€.
withBattery()λŠ” λ‘œλ΄‡, μ „κΈ° μŠ€μΌ€μ΄νŠΈ λ³΄λ“œ λ˜λŠ” νœ΄λŒ€μš© μž₯치 좩전기와 같은 λ‹€λ₯Έ μ’…λ₯˜μ˜ 객체와 ν•¨κ»˜ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
withFlying()은 비행쀑인 μžλ™μ°¨, λ‘œμΌ“ λ˜λŠ” 풍선을 λͺ¨λΈλ§ν•˜λŠ” 데 μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.

μ»΄ν¬μ§€μ…˜μ€ μ½”λ“œμ˜ νŠΉμ • κΈ°μˆ λ³΄λ‹€ 사고 방식에 κ°€κΉμŠ΅λ‹ˆλ‹€. 당신은 μ—¬λŸ¬ 가지 λ°©λ²•μœΌλ‘œ 그것을 μ„±μ·¨ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
ν•¨μˆ˜ μž‘μ„±μ€ μ²˜μŒλΆ€ν„° λ‹€μ‹œ λΉŒλ“œν•˜λŠ” 것이 κ°€μž₯ μ‰¬μš΄ 방법이며, νŒ©ν† λ¦¬ ν•¨μˆ˜λŠ” κ΅¬ν˜„ μ„ΈλΆ€ 사항에 μΉœμˆ™ν•œ APIλ₯Ό κ°„λ‹¨ν•˜κ²Œ λž˜ν•‘ν•˜λŠ” κ°„λ‹¨ν•œ λ°©λ²•μž…λ‹ˆλ‹€.

κ²°λ‘ 

ES6은 객체 생성 및 νŒ©ν† λ¦¬ κΈ°λŠ₯을 μ²˜λ¦¬ν•˜κΈ°μœ„ν•œ νŽΈλ¦¬ν•œ ꡬ문을 μ œκ³΅ν•©λ‹ˆλ‹€.
λŒ€λΆ€λΆ„ 당신이 ν•„μš”λ‘œν•˜λŠ” 것은 μ „λΆ€μ§€λ§Œ, JavaScript이기 λ•Œλ¬Έμ— μžλ°”μ™€ 같은 λŠλ‚Œμ„ μ£ΌλŠ” 또 λ‹€λ₯Έ μ ‘κ·Ό 방식이 μžˆμŠ΅λ‹ˆλ‹€ : class ν‚€μ›Œλ“œ.

JavaScriptμ—μ„œ ν΄λž˜μŠ€λŠ” 곡μž₯보닀 더 μž₯ν™©ν•˜κ³  μ œν•œμ μ΄λ©° λ¦¬νŒ©ν† λ§μ— μžˆμ–΄μ„œλŠ” μ•½κ°„μ˜ μ§€λ’°λ°­μ΄μ§€λ§Œ
React와 Angular와 같은 μ£Όμš” ν”„λ‘ νŠΈμ—”λ“œ ν”„λ ˆμž„ μ›Œν¬μ— μ˜ν•΄ μˆ˜μš©λ˜μ–΄ μ™”μœΌλ©° λͺ‡ 가지 λ“œλ¬Έ μš©λ„κ°€ μžˆμŠ΅λ‹ˆλ‹€. λ³΅μž‘μ„±μ„ κ°€μΉ˜μžˆκ²Œ λ§Œλ“œλŠ” 경우.

"λ•Œλ‘œλŠ” μš°μ•„ν•œ κ΅¬ν˜„μ€ 단지 ν•¨μˆ˜ 일 뿐이지, λ©”μ†Œλ“œκ°€ μ•„λ‹ˆλΌ ν΄λž˜μŠ€κ°€ μ•„λ‹ˆλΌ ν”„λ ˆμž„ μ›Œν¬κ°€ μ•„λ‹ˆλΌ ν•¨μˆ˜ μΌλΏμž…λ‹ˆλ‹€."~ John Carmack

κ°€μž₯ κ°„λ‹¨ν•œ κ΅¬ν˜„μœΌλ‘œ μ‹œμž‘ν•˜κ³  ν•„μš”ν•œ κ²½μš°μ—λ§Œ 보닀 λ³΅μž‘ν•œ κ΅¬ν˜„μœΌλ‘œ μ΄λ™ν•˜μ‹­μ‹œμ˜€.