개발팀장이 되면서 겪게된 점들 1

이미지
                                                         <팀원을 모집하기 위해 고군분투하는 모습이다. > 첫 한달  개발팀장을 맡다 2021년 5월 , 기존에 있던 CTO분이 휴직(개인사)을 하게 되면서    개발에 대한 모든 권한을 내게 일임하였다.   개발에 대한 모든 의사결정을 전부 내게 맡긴 것으로 ,   어느 정도 규모가 있는 회사의 의사결정권한을 갖게 된 것은 그만큼 내게 큰 신뢰가 있었음을   알수 있게해주는 대목이었다. 그러나 전혀 예측하지 않았던 상황이기에 준비가 되어있지 않았던만큼 처음에는 삐걱거렸다. 가장 첫번째로 어려움을 겪었던 것은 업무의 배분이었다.   관리자가 되니까 해야할일은 업무를 만들고 또 그것을 팀원들에게 분배하고 잘 되고있는지 취합하고 관리감독을 하는것이었다.   군 시절 장교로 복무하면서 겪어봤던 일이긴 했지만, 군복무 당시에도 그닥 잘 하지는 않았던 것 같다.   그럼에도 어쨌든 전반적인 시스템을 이해하고 있었고, 어떻게 구현해야할지에 대해서는 어느정도 경험이 쌓여있었기때문에 큰 문제가 없을 줄 알았다.   실무자로 일을 할 때에도 항상 업무를 받아서 하지는 않았다. 스스로 돌이켜보건대, 나는 주어진 업무가 없으면 스스로 만들어서 제안하고 기획하여 업무를 진행했다.  조그마한 스타트업이었던 첫 회사에서부터  내가 할일은 내가 만들어서 곧 잘했다. 어떤 큰 방향만 정해져있다면 그건 큰 어려움은 아니었다. 나에게 일은 항상 있었다.   매니저가되면서 달라진게있다면 내가 할일만 만드는 것은 아니라는 점이다 . 남이 할 일도 만들어줘야했다.  다행히 팀원들에 대한 면담을 실시한 결과,(팀원을 맡게되자마자 했던 부분)   마이크로 매니징을 원하지는 않았기때문에 큰 그림을 그리는 정도만 준비하면 됐었다.   문제는 내 실무를 동시에 진행하면서 팀원들의 업무 방향도 설정해야했기때문에 시간이 배로 들게 되었다는 점이다. 물론 두배로 일하지는 않았다. 대신에 내 실무시간을 줄였고

[javascript 이해] this에 대하여 2



시작하며



우리는 이전 포스트 에서 this의 세부적인 움직임을 알아보았다.
이번 포스트에서는  -Scope Chain 을 통해 this의 올바른 참조법을 알아본다. 
Closure가 어떻게 동작하는지 EC 와 LE을 통해 구체적으로 뜯어본다.

 -reference


  • http://hanmomhanda.github.io/2016/01/16/JavaScript-%EC%8B%9D%EB%B3%84%EC%9E%90-%EC%B0%BE%EA%B8%B0-%EB%8C%80%EB%AA%A8%ED%97%98/


흔히 스코프 체인이라고 하는 것은 ES3에서는 스펙에 정식으로 존재했던 용어인데, ES6에서는 스코프 체인이라는 용어는 존재하지 않는다. 정식 용어라고까지 할 수는 없겠지만, ES6에서는 스코프 체인 대신에 Lexical nesting이라는 표현을 쓴다. 체인 보다는 중첩에 더 의미를 두려는 것 같다. 어차피 정식 용어가 없으므로 여기서는 편의상 스코프 체인이라는 용어를 그대로 쓰기로 한다.





우선 예제를 먼저 보자. 
var wow = "wow1";                       // 전역변수
var testObject = {
    thisMember: "test",
    
}

testObject.foo = function (ab) {
    var value1 = a;  
    var value2 = b;
    var user = 'kim';
    var wow = "wow2";                   // foo함수의 지역변수
    bar();
    function bar() {
        var result = this.value1 + this.value2;
        console.log(result);
        console.log(wow);               // ->무슨 값이 나올까????
    }

}

저번 예제와 달라진점이 하나 있다. wow 변수의 등장이다. 
전역변수에 하나 foo 함수의 지역변수로 동일하게 wow를 지정하였다. 
문제. 과연 bar 함수에서 콘솔로 찍으려는 wow는 wow1 이 될까, wow2가 될까?














답은 wow2 이다. 저번 포스트를 보고 wow1인지 wow2인지 헷갈린사람들도 있을 것이다. 

Scope Chain 은 말그대로 Scope의 체인이다. 우리가 일반적으로 말하는 Scope는 무엇을 의미하는 것일까? 이전 포스트에서 봤던 Executon Context이다. 자바스크립트는 기본적으로 함수 블록을 스코프로 잡는다. 우리는 함수가 실행가능한 코드이며 Execution Context임을 알고있다.
이 두가지 사실로 유추해볼 수 있는건 Scope와 EC는 어느정도 일치한다는 것이다. (완전히 동일한 것은 아닐 것 같다... 이점은 좀더 공부해봐야겠다 )


barExecutionContext = {
    LexicalEnvironment: [barLexicalEnvironment],
    VariableEnvironment: [barLexicalEnvironment],
    ThisBinding: [window]
}

barLexicalEnvironment = {
    environment_record: {
        DeclarativeEnvironmentRecord: {
            result : NaN // === (undefined + undefined)
        },
        ObjectEnvironmentRecord : {
        }
    },
    outer_environment_referance: fooExecutionContext
}


bar 함수의 EC이다. 


중간에 추가적으로 검색한 포스트를 통해 알게 된것인데, VariableEnvironment 와 ObjectEnvironmentRecored는 with 문이 쓰일때 사용된다고 한다. 하지만 ES6와서는
with 문이 deprecated 되었으므로 신경쓰지 않아도 될것 같다. 



outer _environment_reference는 함수가 중첩되었을 때, 자신을 감싸고 있는 함수블록을 바라본다고 생각하면 된다. foo 함수를 바라보기때문에, bar의 wow 변수는 this가 window 객체로 붙어있음에도 불구하고 foo 함수의 wow 를 먼저 찾게 되는 것이다. 

이러한 점을 이용해서 foo 함수에 var that = this 를 통해 bar함수가 정확하게 this를 참조 할 수 있도록 만들 수 있다. 


var testObject = {
    thisMember: "test",
    
}

testObject.foo = function (ab) {
    var value1 = a;
    var value2 = b;
    var user = 'kim';
    var that = this;
    bar();
    function bar() {
        var result = that.value1 + that.value2;
        console.log(result);
    }

}


이런식으로 작성하면 bar 함수에서 that을 찾기 위해 outer 환경을 찾아보게 될것이며, foo 의 this( testObject ) 값을 가진 that을 바라보게 될것이다. 



 -Closure 


클로저 또한  EC에 의해 쉽게 설명될 수 있다. 함수객체에는 [[Scope]] 라는 속성이 할당되어있다. 

이 [[Scope]] 속성이  EC와 연관있다면 ... 예를 보면 이해해보자. 
클로저는 함수의 스코프가 종료되었음에도 그 환경의 변수값을 이용할 수 있다는 것. 





코드를 보자. ('use strict')가 적용된 상태이다.  우리가 관심있는 것은 emit()이다. emit을 실행시키면 콘솔에 3이 찍히는 이유는 무엇일까. 변수 emit이 받은 것은 emitResult의 함수이다. 즉 result를 모른다. 




그림 1


그림 2

그림 1은 add 함수의 실행환경, 그림 13은 emit 함수의 실행환경이다. 
add 함수가 실행될때에 따로 명시된 객체가 없기때문에 this는 null로 바인딩 되어있다. 
연산을 끝낸후 add 함수 환경 record 에는 result가 저장된다. 

그림 2는 emit 함수의 실행환경이다. 마찬가지로 실행될때 명시된 객체가 없기때문에 this는 null이다. emit의 근간이 되는 emitResult 함수는 애초에 add 함수의 내부함수로써 외부환경참조로 add의 실행환경을 삼고있다. 


스코프체인 관점에서 봤을때, emitResult함수는 자신의 내부에서 result에 대한 값을 찾으려 든다.  그 다음에 찾게되는 것은 외부환경참조로 삼았던 add 스코프 내부이기 때문에 그 값을 사용할 수가 있는 것이다. add 함수는 이미 스코프가 종료되어 사라졌지만(실행환경의 종료) LexicalEnvironment가 남아서 emit 함수로 전해졌기때문에 참조할 수 있는 것이다. 




다음 포스트에서는  함수가 호출되는 여러가지 상황을 살펴보고,

실제로 예제들을 보면서 어떻게 this가 바인딩 되는지 확인해보겠다.







댓글

이 블로그의 인기 게시물

iframe 보안 문제 우회 및 해결법 1

iframe 보안 문제 우회 및 해결법 2

개발팀장이 되면서 겪게된 점들 1