IAT 대비 어려움부분을 정리한다.
시작부터 어려워서 멘탈이...으스러졌다...😱

Practice IAT Difficult 🥑

1. Recursion - 1

id 를 이용하여, 해당 객체를 찾아내는 문제. 라고 적혀있다.
주어진 data에서 id에 해당하는 숫자를 받아서 해당 객체를 리턴하는 함수를 생성한다.
children때문에 계속 JSONStringify가 떠올라서 더 헷갈렸다.
간단하게 논리를 정리해보고 구현하였다.

  1. data를 돌면서 id가 n인 obj를 찾는다.
  2. (해당 id가 없으면?) object를 갖고 있는 객체를 찾는다.
  3. 찾아서 그 객체를 recursion에 집어넣는다.
  4. 해당 id를 발견하면 해당 obj를 리턴한다.

기본 함수에 data를 받는 인자가 없어서 불편하게... 따로 구현하였다.
처음엔 for...of로 돌았지만, 그러면 recursion할 때 iterable이 성립하지 않는다.
키워드 🗝: recursion, typeof, object

let data = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4, children: [
      { id: 6 },
      { id: 7, children: [
          { id: 8 },
          { id: 9 }
      ]}
  ]},
  { id: 5 }
]

function recur(data, id) {
  for(const prop in data) {
    if (data.id === id) {
      return data;
    } else {
      if (typeof data[prop] === 'object') {
        const obj = recur(data[prop], id);
        if(obj) return obj;
      }
    }
  }
}

function findObjectById(n) {
  return recur(data, n)
}

console.log(findObjectById(6)) // { id: 6 }
console.log(findObjectById(7)) // { id: 7, children: [{id:8}, {id:9}] }

2. recursion - 2

recursion으로 구현해야 합니다...라고 적혀있지만 이미 구현되어 있었다.
그래서 좀 더 있어보이게 변경해보았다.
meal배열에서 뒤부터 하나씩 먹어치우는...!문제다.
키워드 🗝: recursion, 삼항연산자

// # recursion2
// 아래 함수를 recursion으로 고치시오

var eat = function(meal) {
  return !meal.length ? console.log('done with the meal!') : (
    console.log('meal before bite:', meal),
    console.log('now eating', meal.pop()),
    eat(meal)
  )
}

eat(['soup', 'potatoes', 'fish']);
// => meal before bite: ["soup", "potatoes", "fish"]
// => now eating fish
// => meal before bite: ["soup", "potatoes"]
// => now eating potatoes
// => meal before bite: ["soup"]
// => now eating soup
// => done with the meal!

3. closure - 1

기본적인 클로저 패턴이다.
상황에 맞는 실행컨텍스트를 잘 생각하면 된다.
키워드 🗝: closure, context

function outerFn() {
  let outerVar = 'outer';
  console.log(outerVar);

  function innerFn() {
    let innerVar = 'inner';
    console.log(innerVar);
  }
  return innerFn;
}

let globalVar = 'global';

outerFn()()               // outer inner
let innerFn = outerFn();  // outer
innerFn();                // inner

4. closure - 2

주석에 적힌 대로 거창하게, 클로저 모듈 패턴이다.
privateCounter를 함수안에 숨겨놓고 인스턴스 메소드를 통해 값을 변경한다.
이해는 간단하지만 구현은 조금 어려울 수 있다. 직접 따라해보는게 좋다.
인스턴스를 생성하면 두 개의 다른 countMaker를 사용하는 것이다.
키워드 🗝: closure, module pattern, private

// closure module pattern
function countMaker() {
  let privateCounter = 0;
  return {
    increment() {
      privateCounter++;
    },
    decrement() {
      privateCounter--;
    },
    showCount() {
      return privateCounter;
    }
  }
}
let counter1 = countMaker();
let counter2 = countMaker();
counter1.increment();
counter1.increment();
console.log("private : " + counter1.showCount()); // private : 2
counter2.increment();
console.log("private : " + counter2.showCount()); // private : 1

5. scope

강의에서 자주 언급되었던 스코프 문제이다.
문제는 간단하지만, 꼬아서 나온다면 꽤 헷갈릴 수 있는 문제같다.
키워드 🗝: scope, var, IIFE

// 1. i가 전역변수로 선언되어 3이 된 상태로 콘솔에 출력된다.
var fns = [];
for (var i=0; i<3; i++) {
  fns[i] = function() {
    console.log('#1. My value:' + i);
  }
}
for (var j=0; j<3; j++) {
  fns[j]();
}
// #1. My value:3
// #1. My value:3
// #1. My value:3
// 2. fns에 값이 들어갈 때마다 i가 정해지므로 0, 1, 2 로 출력된다.
var foo = function(j) {
  console.log('#2. My value:' + j);
}
var fns = [];
for (var i=0; i<3; i++) {
  fns[i] = foo(i);
}
// #2. My value:0
// #2. My value:1
// #2. My value:2
// 3. IIFE : 2랑 별 차이없다. 반복문 안에서 대입할 때 실행도 같이 한 것이다.
var fns = [];
for (var i=0; i<3; i++) {
  fns[i] = (function(j) {
    console.log('#3. My value:' + j);
  })(i);
}
// #3. My value:0
// #3. My value:1
// #3. My value:2

6. this

이것 때문에 강의를 새로 보았지만, 좀 헷갈린다.😳
각각의 this의 의미를 이해해야 한다.
image.png

  1. global, function scope 내의 this는 모두 global을 가리킨다.
  2. method호출에서는 this는 해당 부모 객체를 가리킨다.
  3. call, apply는 첫 번째 인자가 this를 가리킨다.
  4. 생성자의 this는 인스턴스 생성 시 해당 인스턴스 객체를 가리킨다.

잊지말고 commit commit!!😤😤😤