IAT 대비 어려움부분을 정리한다.
시작부터 어려워서 멘탈이...으스러졌다...😱
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}] }
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!
기본적인 클로저 패턴이다.
상황에 맞는 실행컨텍스트를 잘 생각하면 된다.
키워드 🗝: 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
주석에 적힌 대로 거창하게, 클로저 모듈 패턴이다.
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
강의에서 자주 언급되었던 스코프 문제이다.
문제는 간단하지만, 꼬아서 나온다면 꽤 헷갈릴 수 있는 문제같다.
키워드 🗝: 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
이것 때문에 강의를 새로 보았지만, 좀 헷갈린다.😳
각각의 this의 의미를 이해해야 한다.
1. global
, function scope
내의 this
는 모두 global
을 가리킨다.
2. method
호출에서는 this
는 해당 부모 객체를 가리킨다.
3. call, apply
는 첫 번째 인자가 this
를 가리킨다.
4. 생성자의 this
는 인스턴스 생성 시 해당 인스턴스 객체를 가리킨다.