analogcoding

5.28 / Scope , Closure , memorize , stringify 본문

Be well coding/In Immersive

5.28 / Scope , Closure , memorize , stringify

be well 2019. 5. 28. 22:22

체크포인트

 

스코프와 클로져 

 

어제 체크포인트 문제들을 리뷰하는 시간. 헷깔렸던 문제들 정리.

var x = 10;                // 전역변수 x

function outer () {
var x = 20;                // outer 함수 내부에서 x는 20
function inner () {
return x;                  // 20을 리턴
}
return inner();
}

var result = outer();

console.log(result) //  20 
var x = 10;

function outer () {
var x = 20;               
function inner () {
x = x + 10;             // outer 안에 선언된 x 의 값은 30이 된다.
return x;
}
inner();
}

outer();

var result = x;        // 하지만 여기선 전역변수 x를 바라본다.

console.log(result) // 10
var x = 10;
function outer () {
  x = 20;                // 전역 x 가 20으로 바뀜
  function inner () {
    x = x + 20;          // 20 + 20
  }
  inner();
}

outer();

var result = x;

console.log(result) // 40

 

설명해주시는 와중에 currying 에 대해 한 번 찾아보라고 언급하셨다. 메모메모..

 

그리고 문제 중 나왔던 javascript 에서 closure 의 정의.

 

내가 적은 간단한 답은 "외부 함수의 context 에 접근할 수 있는 내부 함수" 

 

추가 답변으로는 외부함수가 실행 종료된 뒤에도 반환된 내부함수가 계속 이 외부함수의 스코프를 참조할 수 있다. 라는 것을 배웠다

+ (실행컨텍스트 찾아보기)

 

 

스프린트 때 진행된 underbar 와 recursion 에서 복습 겸 jest 를 사용하고 터미널을 통해서 테스트를 확인하는 중에 

underbar 에 memorize , 그리고 다시 접한 recursion 에 JSON.stringify() 또한 나를 당황시켰다..

 

유독 힘들었던 두 가지 코드를 복습해본다.

 

memorize

_.memoize = function(func) { // 함수를 인자로 받아서 그 함수의 인자와 리턴값을 저장.
                             //  ㄴ 호출을 줄이고 이미 있는 값이면 계산 없이 저장된 값을 불러올 수 있다.
  
  var results = {};          // 객체의 키로 인자를 , 값으로 리턴값을 저장할 빈 객체 생성. 
  
  return function() {        // 내부함수 생성
  
  var args = Array.prototype.slice.call(arguments);  // 내부함수 인자로 들어올 arguments배열 카피.
  
  var key = JSON.stringify(args)  // 가장 헤맨 부분.. args 를 굳이 왜 JSON형식으로 변환하는가에
                                  // 대한 이유는 밑에 서술.
  
    
  if (!(key in results)) {        // 빈 객체에 인자로 만든 key 가 없을 경우 
  
  results[key] = func.apply(this, args);  // 카피가 배열이기에 apply로 memoize(func)에 args를 
                                          // 받아서 실행.  
  }
  
  return results[key];              // 그 후 값을 리턴.
  
  };
};

 


테스트를 실행시켰을 때 테스트케이스에서 다른 키인데 중복 저장되는 경우가 있었다.

 

그 때는 key 에 JSON.stringify() 를 사용하지 않았었는데 그 이유를 몰라서 엄청 시간을 낭비했다.

 

 

먼저 실수했던 , strigify() 를 왜 사용하는지 몰랐을 때의 코드를 콘솔에 찍어보았다.

 

실수가 있다. add 함수는 인자로 2개만 받는데 난 멍청하게 3개를 받아서 써 버렸다. 그렇지만 두가지 차이를 보는데 지장없으므로 진행.

1 , 2 , 3 을 인자로 받을 때와 [ 1 , 2 , 3 ] 때 키 값으로 들어오면서 같은 값이 저장된다.

이래서 각각 객체에 값이 따로 저장되지 않았던 것이다.

 

이번엔 stringify() 를 사용했을 때의 콘솔이다.

 

stringify 를 통해 JSON 형식으로 스트링 형식으로 변경해서 고유의 값을 가졌다.
값은 물론 이상한 값이 나와버렸지만.. 별 것 아니고 이 문제가 가지고 있던 메인이 이게 아니여도 좋다.

 

오늘의 응어리가 풀렸다..

 

 

JSON.stringify()

 

recursion 과제로 한 번 접했던 문제지만 오랜만에 다시 풀어보니 너무 막막했다.

JSON.stringify({});                  // '{}'
JSON.stringify(true);                // 'true'
JSON.stringify('foo');               // '"foo"'
JSON.stringify([1, 'false', false]); // '[1,"false",false]'
JSON.stringify({ x: 5 });            // '{"x":5}'

주어진 값과 대응하는 JSON 문자열을 리턴.

 

이를 재귀적으로 코드를 짜는 문제였는데 아무 생각 없이 하나 씩 써내려가다보니 빼 먹는 것도 많고 놓치고 있는 부분도 많고 

코드는 지저분해지고 난장판이었다.

 

그래서 페어분과 함께 의사코딩을 진행하고 그에 맞게 코드를 작성하기로 하고 먼저 필요한 것들을 순차적으로 확인하면서

 

적기 시작했다.

 

한 줄 한 줄 필요한 조건을 모두 적어보고 그 조건 안에 다른 조건을 천천히 세우기 시작했다.

 

그에 맞게 한 줄 씩 코드를 작성하고 마지막 조건까지 작성하여 완성했다. 배열 안의 값이나 객체일 경우 키 / 값을 재귀적으로
다시 stringify 함수를 거친 값을 사용해서 재귀적으로 해결해보았다.

 

의사코드의 장점을 느꼈고 이런 식의 문제가 주어진다면 다음 번에도 의사코딩을 사용할 것 같다.

 

 

checkpoint

 

keyword 'this'

 

자신없던 this 의 관한 짧은 문제들을 접했다. 예상보다 훨씬 많이 틀렸다... 정말 맞출만 한 문제조차 나를 의심해서 틀리기도 했다.

 

헷깔리고 틀렸던 문제들 복습.

 

먼저 가장 중요한 개념.

 

this 의 5가지 호출방식

 

1. Global                         ㅡ             window

2. function                     ㅡ             window

3. Method                      ㅡ             상위 부모객체

4. call & apply                ㅡ             첫 번째 인자로 명시된 객체

5. construction Mode    ㅡ             (new연산자) 새로 생성된 객체
    

var obj = {
  foo: function(){
    console.log(this);
  }
}
var fn = obj.foo;
fn();

이 문제를 보고 this 는 obj 를 바라보고 있다고 생각했다.

그렇지만 var fnobj.foo 의 값인 function(){ console.log(this);} 를 대입만 한 것이라서
fn() 실행 시 obj 에 묶인 것이 아닌 function 호출인 것이다.

 

var obj = {
  foo: function(){
    console.log(this);
  }
}
var obj2 = {
  foo: obj.foo
}

obj.foo.call(obj2);

꼬아놓은 코드 같았지만 call 뒤에 첫번 째로 명시된 객체가 this 가 바라보는 것이다. (저는 멍청이입니다.)

 

 

 

늘 그렇듯 오늘도 부족한 실력을 뽐내며 쩔쩔매며 수업했다. 내일도 제 시간에 집에 못 갈 것 같다.

Comments