[초보자들] S70 스터디 다섯번째 후기

자바스크립트 함수와 객체에 대해 알아가보는 S70 다섯번째 강의가 진행되었습니다.
지난 강의를 통해 To-Do 프로그램에서 권한의 모순점을 발견했고, 특정 행위가 특정 상태와 바인딩되고 단단하게 감쌀 필요가 있다는 것을 알게되었습니다. 그래서 은닉과 캡슐화를 사용해 객체를 만들었죠.
이게 끝이 아닙니다. 계속 새롭고 쉽지않은 객체의 매력을 알아가봅시다^^

Refactoring 1top

우리가 조각해 가는 To-Do 프로그램을 더 예쁘게 만들기 위해 Refactoring은 필수입니다. 저번 강의에서 독립적인 html, con 객체를 todo로 부터 분리 시켰습니다. 분리 과정에서 중 render 메서드에 todo가 가지고 있는 값들(tasks, STATE_P, STATE_C)을 공급해줘야 했습니다. 이를 해결하기 위해 저는 모두 호출 시 인자로 전달해버렸죠. 여기서 넘겨주는 값들 중 STATE_P, STATE_C의 권한에 대해 생각을 해보겠습니다.
STATE_P, STATE_C 값이 todo만의 것이라고 할 수 있을지를..

todo는 상태를 공급하고 있는 STATE_P, STATE_C에 의존하고 있습니다. html, con 객체도 STATE_P, STATE_C에 의존하고 있구요. 즉 STATE_P, STATE_C는 todo, html, con 모두에게 상태를 공급해 주고 있는 것입니다.
그런데 만약 todo가 내부 사정으로 STATE_P, STATE_C를 객체로 대체한다면, html과 con 객체가 망가져 버립니다.
todo 내부 사정으로 고친건데… 독립한 html과 con이 영향을 받아 망가진다면 억울하죠ㅠㅠㅠ

이제 알게되었습니다. STATE_P, STATE_C는 todo만이 소유할 것이 아니라는 것을. 그럼 누가 가져야 하나요?

이런면에서 봤을 때 STATE_P, STATE_C는 세 객체가 공유하는 자원이라고 봐야합니다. 그래서 우리는 STATE 객체를 만듭니다.

var STATE = (function(){
    var p = {toString: function () {return '진행';}};
    var c = {toString: function () {return '완료';}};
    return {
        PROGRESS: function(){return p},
        COMPLETE: function(){return c}
    }
});

만들어진 STATE를 보니 2가지 의문점이 생겼습니다.
첫번째는 p와 c가 문자열이 형태가 아닌 object라는 것입니다. 그동안 STATE_P와 STATAE_C는 문자열이었는데 왜 p와 c는 object로 만들었을까요? 그 이유를 알기 위해 javascript의 데이터타입에 대해 짚어보겠습니다. <click! javascript 데이터타입 참고 글>
자바스크립트의 값(데이터 타입)에는 크게 기본형과 참조형으로 나눌 수 있습니니다. 기본형을 제외한 모든 값은 참조형입니다. 이 둘의 비교하는 방식에 차이가 있습니다. 먼저 기본형 값 비교를 해보겠습니다.

var a = 3;
var b = 3;
console.log(a === b); // true 가 출력됩니다.

a와 b에는 똑같은 값인 숫자 3이 들어있습니다. 기본형의 비교는 값을 비교합니다. 그래서 a, b를 비교한 결과 true를 출력하게 됩니다. 하지만 참조형 값을 비교하는 경우는 결과가 다릅니다.

var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a === b); // false 가 출력됩니다.

a와 b가 똑같은 값을 가진 배열입니다. 하지만 참조형은 값으로 비교하지 않고, 실제 메모리 주소 위치로 식별을 합니다. 그래서 a와 b가 실제 메모리 주소가 다르기 때문에 false를 출력하게 되는 것이죠. 기본형은 값을 비교하여 같은지 아닌지를 평가하고, 참조형은 값으로 평가하지 않고, 실제 메모리 주소를 비교하여 평가합니다.

기존의 STATE_P, STATE_C는 기본형인 문자열입니다. STATE에서 STATE_P와 STATE_C 의 값을 리턴한다면 굳이 STATE_P와 STATE_C 가 아니더라도 ‘진행’, ‘완료’라는 값만 넣어놓으면 일치 시킬수 있게 되는 것이죠. 이 말은 STATE를 사용하도록 할 강제성이 없다는 것입니다. 강제성이 없는데 굳이 STATE를 사용하려고 할까요? 그냥 ‘진행’, ‘완료’라고 적어놓을 수도 있죠.
그래서 object 값을 리턴하도록 한 것입니다.
다시 말해 object 값을 리턴으로 사용하면, 실제 메모리 주소를 사용하여 대체할 수 있는 값이 없기 때문에 STATE를 사용해야 한다는 강제성이 생기는 것입니다.

두번째는 STATE의 PROGRESS, COMPLETE 메서드입니다. 이 메서드들은 결국 p, c를 반환하는데.. 그럼 바로 p, c를 주면안되나요?
이는 미래에 대한 확장을 담보해 놓기 위한 코드입니다. 지금은 단순히 p, c를 반환하기 때문에 불필요해 보일지 모릅니다. 하지만 미래에 p, c를 반환하기 전에 어떤 일을 추가적으로 처리해야한다면? 예를 들어 console.log를 이용하여 p, c 값을 출력해 보는 일을 넣고 싶다면 말이죠. 즉, 미래의 여러가지 행위에 대해 캡슐화 되어있는 함수로 나타내는 것입니다.

이로써 STATE 객체를 만들어 todo, html, con 모두가 STATE 상태를 공급받을 수 있게되었습니다.

이제 STATE_P, STATE_C를 사용하던 코드 또한 STATE.PROGRESS()와 STATE.COMPLETE()로 변경해야겠네요^^
todo의 toggle 함수부터 변경해볼까요?

return{
    setRenderer: function(renderer){ ... },
    add: addTask,
    remove: removeTask,
    toggle: function(id){
        for(var i = 0; i< tasks.length; i++){
            if(tasks[i].id === id){
                if(tasks[i].state === STATE.PROGRESS()) changeState(id, STATE.COMPLETE());
                else changeState(id, STATE.PROGRESS());
                break;
            }
        }
    }
}

이 함수 이외에도 todo의 addTask 함수나 html, con의 render 메서드에서도 변경을 해야합니다. <click! 변경한 코드 보러가기>

명확한 작문top

To-Do 프로그램 코드는 계속 리팩토링되고 있습니다. 사실 실행되는지 안되는지로만 본다면 2, 3강쯤에서 거의 완성되었다고 할 수 있습니다. 하지만 계속해서 바꾸고 있죠. 왜 그럴까요?
우리는 지금 제대로된 개발이 무엇인지를 배우고 있기 때문입니다. 그냥 책만 읽고 외운다고 프로그래밍을 제대로 할 수 없으니까요.
제대로 프로그래밍을 하기 위해서 문법적인 지식은 물론 필요합니다. 하지만 그 뿐만 아니라 무엇을 개발하고 싶은지 명확하게 표현할 수 있어야합니다. 그래서 오해없이 명확하게 표현하는 작문을 연습하는 중입니다.

명확하게 작문한다는 것은 어떤 것 일까요?
‘밥을 먹는다’라고 얘기를 하면 아마도 거의 모든 사람들은 충분히 이해할 수 있을 것입니다. 하지만 실제로는 밥을 먹는 형태는 다양합니다. 한국 사람이 밥을 먹을 때, 미국 사람이 밥을 먹을 때, 개가 밥을 먹을 때도 있고, 자동차가 밥을 먹을 때 등 무엇이 밥을 먹는지에 따라 다르죠. 또한 5시간 째 먹고 있는데 ‘밥을 먹는다’는 괴로움의 의미가 되기도하고, 5일 째 굶은 상태인데 ‘밥을 먹는다’는 기쁨의 의미가 되기도 합니다.
사람은 자연스럽게 뇌가 이를 파악할 수 있기 때문에 ‘밥을 먹는다’라는 문장도 이해할 수 있지만, 컴퓨터는 그렇지 않습니다. 그럼 어떻게 해야 컴퓨터가 오해없이 명확하게 이해할 수 있을까요?
‘먹는다’라는 행위를 명확하게 하기 위해서는 ‘나’가 무엇인지, ‘나’의 상태는 어떠한지 등의 컨텍스트가 확정되어 있어야합니다. 그럼 컨텍스트는 아무나 건들면 안되겠죠?
즉 특정 행위가 특정 컨텍스트 또는 상태와 바인딩되고 아무나 건들 수 없도록 단단히 감쌀 필요가 있습니다. 우리는 이를 객체라고 불렀죠.

컴퓨터에게 명확한 의미를 전달하기 위해 객체화는 아주 중요한 것임을 알게되었습니다.

다형성(Polymorphism)top

우리는 객체를 사용하고 있습니다. 은닉과 캡슐화를 통해 객체를 만들었죠. 그러나 은닉과 캡슐화는 프로그램 전반적으로 사용되는 기술입니다. 객체만의 특성이 아니죠. 객체만의 특성에는 다형성(Polymorphism)이라는 기법이 있습니다.
다형성은 뭘까요? 다양한 형의 성질을 가진다? 여기서 형은 뭘 말하는 걸까요? form? type? 이 보다는 role(역할)에 가깝습니다.
저라는 존재는 하나뿐입니다. 하지만 환경에 따라 사람의 역할, 여자의 역할, 누나의 역할을 가지고 있습니다. 하나의 객체가 다양한 역할을 수행할 수 있다는 의미가 바로 다형성입니다.
다형성은 두 가지 특징을 충족해야합니다.

  • 대체가능성(substitution)
  • 내적동질성(internal identity)

이게 어떤 특징인지, 어떻게 해야 충족하는 것인지를 살펴보도록 하겠습니다.

대체가능성

위에서 언급했다시피 저는 여러가지의 형을 가지고 있습니다. 저는 누나라고 볼 수 있지만 여자라고 볼 수도 있고 사람이라고 볼 수도 있습니다.이 형들 사이에는 포함관계가 있습니다. 여기서 이렇게 저를 큰 그룹의 역할 또는 작은 그룹 역할로 대체하는 것을 캐스팅이라고 합니다.
큰 그룹으로 대체하는 것을 업캐스팅, 작은 그룹으로 대체하는 것을 다운캐스팅이라고 합니다. 예로 든다면, 여자를 사람으로 대체하는 것을 업캐스팅이고, 누나로 대체하는 것이 다운캐스팅이죠.
그런데 여자를 사람으로 대체하는 것은 무조건 가능한 대체인 반면에 여자를 누나로 대체하는 것은 실패할 수 있습니다. 남동생이 없는 여자도 있으니까요~ 즉 업캐스팅은 언제나 안전하고 다운캐스팅은 실패할 수 있으니 위험하다고 볼 수 있죠. 그래서 다운캐스팅은 지양합니다.

저는 종렬적인(포함관계에 있는) 다양한 형을 가지고 있습니다. 하지만 제가 가진 역할은 이외에도 엄청 많아요. 저는 회사에서는 사원이라는 역할을 가지고 있습니다. 저는 누나이자 사원인 병렬적인(포함관계가 없는) 다양한 형도 있단 거죠.

여자인 저를 사람으로 볼 수도 있고 누나로 볼 수도 있고 사원으로도 볼 수 있습니다. 이렇게 소속되어 있는 집합에서 그 것을 포함하고 있는 집합이나 그 것의 부분집합으로 대체할 수 있는 것. 이것을 대체가능성이라고 합니다.

내적동질성

저의 역할을 사람형, 누나형, 사원형으로 대체한다고 생각해 봅시다. 사람형은 ‘숨을 쉰다’라는 행위가 있고, 누나형에는 ‘남동생한테 용돈 줘’라는 행위가 있고, 사원형에서는 ‘출근해’라는 행위가 있습니다.
저를 다양한 형으로 대체한다고 하지만 행위는 누가할까요? 행위를 실행하는 주체는 저입니다.
다양한 형으로 대체를 해도 행위를 하는 주체는 저라는 것이 내적동질성입니다. 이는 다음 시간에 더 자세히 알아보도록 합니다.

Refactoring 2top

위의 Refactoring 1에서 독립적인 html, con 객체를 todo로 부터 분리 시키면서 수정된 코드 중 STATE 값을 인자로 넘겨주는 부분을 살펴보았습니다. 이번에는 todo에서 html, con 객체를 직접적으로 알지 않고 renderer를 공급받기 위해 만들어진 setRenderer 메서드에 대해 살펴보도록 하겠습니다.

return {
    setRenderer: function(renderer){
        if(typeof renderer.init !== 'function' || typeof renderer.render !== 'function') return;// 약 타입 체크
        target = renderer;
        target.init(todo);
    },
    add: addTask,
    remove: removeTask,
    toggle: function(id){ ... }
}

여기서 인자로 받은 renderer에 init, render라는 메서드가 있는지 체크하는 로직이 있습니다. 그런데 이렇게 renderer에 저 두개의 메서드를 검사한다라는 지식은 todo만 가지고 있습니다.
‘todo에 setRenderer라는 메서드에서 renderer를 받아들일 때 renderer가 init, render 메서드를 가지고 있어야 돼’라는 지식을 setRenderer 안에 적어놓은 것이죠. 이는 todo의 개인적인 지식이죠.
todo의 setRenderer 메서드 코드를 들여다보지 않는 이상 renderer로 들어올 html, con 객체는 이 사실을 어떻게 알 수 있죠?
그렇습니다. 이 지식은 todo, html, con 모두가 공유해야하는 것입니다.
아하! 아까 STATE랑 똑같이 공급하면 되는거 아닌가?!!

STATE와는 사정이 다릅니다.
STATE는 자신의 값을 완전히 소유한 상태에서 외부에 공급하는 역할을 합니다. STATE라는 서비스를 제공하는 구체적인 객체인 것이죠. 하지만 ‘renderer는 init과 render라는 메서드를 가져야 해’ 라는 지식은 구체적인 객체로서의 값을 가지고 있는 것이 아닌 todo 와 html, con 간의 약속을 적어놓은 것이라고 할 수 있습니다.
이런 약속이 바로 프로토콜 또는 인터페이스 또는 클래스라고 부릅니다.
우리는 ‘init 과 render 라는 메서드를 가져야 해’라는 약속을 위한, 이 약속을 정의할 특별한 구문이 필요합니다.

약속해줘top

todo, html, con 사이에 약속이 필요하다는 것을 알게되었습니다. 약속을 정의하는 방법은 언어마다 다릅니다. 우리는 javascript를 사용하고 있으니 javascript 형식에 맞게 약속을 정의해야 합니다.

javascript에서는 이런 약속도 함수를 사용해 정의를 합니다. 그럼 함수로 renderer라는 약속을 만들어보겠습니다.
이때 함수명은 대문자로 시작하도록 짓겠습니다. javascript에서 함수로 많은 것을 합니다. 그래서 어떤 의도로 만들어진 함수인지를 쉽게 구분할 수 있도록 관용적으로 인테페이스, 프로토콜, 클래스의 이름은 대문자로 시작하는 명사로 만든다고 합니다.

var Renderer = function(){};

Renderer에 ‘init과 render라는 함수가 있어야한다’는 약속을 정의해야합니다. 그래야 todo는 renderer를 받아 진짜인지 아닌지 확인할 수 있고, html과 con 객체가 renderer형이 될 수 있는 방법을 알죠.
이때 prototype이라는 것을 사용합니다. <click! prototype이란?>
이 때 prototype이 무엇인지 문법적인 요소를 아는 것보단 이 걸 왜 쓰는가에 집중하도록 합시다.

Renderer.prototype.init = function(todo){};
Renderer.prototype.render = function(tasks){};

이를 통해 Renderer 형은 todo라는 인자를 받는 init 메서드와 tasks라는 인자를 받는 render 메서드가 있다고 정의한 것입니다. 이제 todo, html, con 객체는 이 약속을 보고 각자의 행위를 만들어 가면됩니다.

todo 객체는 입력받은 값이 Renderer형인지 확인합니다.

setRenderer 메서드에서 입력받은 renderer가 가진 init, render의 타입이 function인지 타입체크를 했었죠.

if(typeof renderer.init !== 'function' || typeof renderer.render !== 'function') return;

다음으로 프로토콜을 이용하여 입력받은 renderer가 Renderer형인지 확인을 하는 것으로 바꿔야겠죠. Renderer형이라면 당연히 init, render 메서드를 가지고 있을테니까 말이죠.
이를 확인할 수 있는 instanceof 메서드를 사용해보도록 하죠. <click! instanceof 란?>

if(!(renderer instanceof Renderer)) return;

html, con 객체는 Renderer형도 될거에요~

html과 con 객체는 Renderer형으로 만들어야죠! 그런데 html, con이 Renderer형으로써 init, render이라는 행위를 할 수 있다는 것을 어떻게 증명해야할까요?
지금의 html, con은 단순객체인데.. 어디서 형 정의를 하나요? 어떻게 Renderer형의 자식으로 상속받을 수 있을까요?
그러기 위해선 html, con도 각자 자신의 형을 가지고 있어야합니다. 그래서 우리는 Html형, Con형을 정의하고 Renderer형의 자식이 되는 코드를 작성해 봅니다.

var Html = function(){};
Html.prototype = new Renderer();

var Con = function(){};
Con.prototype = new Renderer();

이 코드가 증명해줍니다. ‘본질은 Html, Con이지만 Renderer이기도 해~’라고 말이죠. 왜 이렇게 적는지 문법적인 부분은 일단 묻지도 따지지도 말고 외웁시다!
이제 Html형, Con형으로 부터 html과 con을 만들어보도록 하겠습니다. 참고로 형으로 부터 태어나는 객체는 new 키워드로 만들어 집니다.

var html = new Html();
var con = new Con();

html, con은 instanceof Html, instanceof Renderer 모두를 통과할 수 있게 되었습니다. 이 것이 대체가능성입니다. html, con 객체는 각각 Html형, Con형이지만 Renderer형이기도 한 것이죠. 제가 여자이기도 하고 사람이기도 한 것처럼요. 근데 왜 대체할까요?
그 이유는 todo의 관심사는 Html, Con이 아닌 Renderer니까요. init, render 메서드를 제공하는 Renderer의 기능만이 관심사입니다. 회사에서도 저의 다양한 역할 중 누나의 역할은 신경쓰지 안죠. 사원으로써의 역할만을 보는 것이죠.

overridetop

어떤 형으로 대체되었던 간에 행위는 누가하나요? html, con 객체 각자가 해야된단 말이죠. 이게 내적동질성이죠~ todo에서는 Renderer형으로 보일지 몰라도 진짜 행위는 html, con 객체가 해야하죠. 그럼 이 행위는 어떻게 구현할까요?

일단 Html형, Con형과 Renderer형이 통신할 수 있는 수단이 필요합니다. 부모와 자식간의 통신이죠. 이 것을 override라고 합니다. 부모의 메서드를 자식이 덮어서 재정의하는 행위인거죠. 그러면 부모는 ‘내가 원래 이걸 할 줄 아는데.. 자식이 할 수 있도록 해줄게~’ 하는 것이죠.
여기서 this는 런타임 시점에 클래스인 Renderer로 부터 파생된 인스턴스를 가리킨다고 보면됩니다.

Renderer.prototype.init = function(todo){
    //이(this) 자식이 할 수 있도록 해줄게~
    this._init(todo);
};
Renderer.prototype.render = function(tasks){
    this._render(tasks);
};

Renderer는 실제로 행위하는 객체가 아니죠. 약속일 뿐입니다. 이게 실행될 때는 진짜 행위를 할 객체가 생겼을 때입니다. 즉 this가 있을 때란 거죠. 그런데 this에 _init와 _reder가 있나요? 없죠~ 그래서 만들어줘야합니다.

Renderer.prototype.init = function(todo){ ... };
Renderer.prototype.render = function(tasks){ ... };
Renderer.prototype._init = function(todo){
    //난 진짜가 아니야. 그래서 아무일도 안 해~
};
Renderer.prototype._render = function(tasks){
    //난 진짜가 아니야. 그래서 아무일도 안 해~
};

자식은 _init, _render를 override하면 됩니다. 그런데 여기서 자식들이 밖에서 호출되는 init, render를 바로 override하지 않고 _init, _render를 override합니다. 이는 자식들 각자가 하는 행위는 재정의하지만, 자식으로써 공통된 점은 부모에서 해줄 수 있도록 하기 위함입니다.
init, render에서 todo, tasks를 입력받는 행위는 자식이라면 모두가 해야하는 행위입니다. 그럼 그 코드까지 자식들 각자가 재정의 할 필요가 있을까요? 공통된 행위는 부모에서 하고 자식들이 재정의한 함수를 실행할 수 있도록 변경해 보도록 하겠습니다.

Renderer.prototype.init = function(todo){
    this.todo = todo;
    this._init();
};
Renderer.prototype.render = function(tasks){
    this.tasks = tasks;
    this._render();
};
Renderer.prototype._init = function(){};
Renderer.prototype._render = function(){};

todo, tasks를 입력받아 담아놓는 공통적인 행위를 부모가 하도록 합니다. 그리고 자식이 재정의하는 _init, _render 내에서는 this.todo로 사용하면 되므로 인자를 넘겨주지 않도록 했습니다. 그럼 이제 Html, Con에서는 _init, _render를 override 할 때 받는 인자가 없어집니다.

var Html = function(){};
Html.prototype = new Renderer();
Html.prototype._init = function(){};
Html.prototype._render = function(){};

var Con = function(){};
Con.prototype = new Renderer();
Con.prototype._init = function(){};
Con.prototype._render = function(){};

var html = new Html();
var con = new Con();

이제 html 객체에서 init메서드를 호출하면 어떤일이 일어나는지를 생각해볼까요?

html.init(todo);


html은 자기 자신의 본질인 Html형에서 init 함수를 찾죠. 없네요. 그럼 그 부모인 Renderer형의 init 메서드로 향합니다. 그랬더니 this._init을 호출합니다. 여기서 내적동질성에 의해 this는 html이죠. 그래서 다시 Html형의 _init 메서드를 찾습니다. 있네요! 객체지향의 원리! 다형성의 원리가 이것입니다. 대체가능성과 내적동질성이 동시에 존재합니다.

이제 html의 구체적인 코드을 Html형으로 옮겨주기만 하면됩니다.

객체 스코프top

기존 html 객체가 의존하는 상태들은 Html형 생성자로 옮겨주고 init, render 메서드의 코드도 Html형의 _init, _render로 옮겨주도록 하죠. 아래는 기존 html 객체 코드입니다.

var html = (function(){
    var progressLi, completeLi;
    return {
        init: function(){ 
            progressLi = document.querySelector('#todo .progress li');
            completeLi = document.querySelector('#todo .complete li');

            progressLi.parentNode.removeChild(progressLi);
            completeLi.parentNode.removeChild(completeLi);
 
           // '할 일' 입력창 찾기
           // 추가버튼에 이벤트 주기(todo.addTask)
        },
        render: function(){
            if(typeof completeLi === 'undefined' || typeof progressLi === 'undefined') {
                return;
            }
            ...
        }
    }
})();

아래는 Html 클래스로 코드를 옮겨준 것입니다.

var Html = function(){
    var progressLi, completeLi;
};
Html.prototype = new Renderer();
Html.prototype._init = function(){
    progressLi = document.querySelector('#todo .progress li');
    completeLi = document.querySelector('#todo .complete li');

    progressLi.parentNode.removeChild(progressLi);
    completeLi.parentNode.removeChild(completeLi);
 
    // '할 일' 입력창 찾기
    // 추가버튼에 이벤트 주기(todo.addTask)
};
Html.prototype._render = function(){
    if(typeof completeLi === 'undefined' || typeof progressLi === 'undefined') {
        return;
    }
    ...
};

기존 html 객체는 함수 외부에 의존하는 상태가 있는 것을 즉시실행함수로 스코프를 만들어 그 안에 상태(progressLi, completeLi)를 은닉했습니다.
그런데 코드를 옮겨보니 더 이상 함수 스코프를 사용할 수 없다는 것을 알게되었습니다. 그래서 이제부터는 객체 스코프를 사용하게됩니다. 객체 스코프가 바로 this라는 것입니다. 그래서 필요한 값, 인자들을 전부 this에다가 넣어버릴 수 있습니다. ‘this.XXXX’로 말이죠.

var Html = function(){};
Html.prototype = new Renderer();
Html.prototype._init = function(){
    this.progressLi = document.querySelector('#todo .progress li');
    this.completeLi = document.querySelector('#todo .complete li');

    this.progressLi.parentNode.removeChild(progressLi);
    this.completeLi.parentNode.removeChild(completeLi);
 
    // '할 일' 입력창 찾기
    // 추가버튼에 이벤트 주기(todo.addTask)
};
Html.prototype._render = function(){
    if(typeof this.completeLi === 'undefined' || typeof this.progressLi === 'undefined') {
        return;
    }
    ...
};

이와 같이 con도 코드를 바꿀 수 있습니다. <click! 전체 코드 보러가기>

5강을 마치며..top

개발 입문자들을 대상으로 기초적인 개발 스터디인 S70 강의가 끝나가고 있습니다.
S69에서는 javascript의 기본적인 데이터타입(Boolean, Number, String, Null, Undefined, Symbol, Object)부터 문과 식에 대해 배웠습니다. 이는 한국어를 배울 때 자음과 모음을 배운 셈이죠.
그럼 이번 S70에서는 무엇을 배우고 있을까요? 주제가 함수와 객체였습니다. 이는 언어의 품사를 배우는 것입니다. 내가 표현하고자 하는 걸 표현하기 위해서 동사에 해당하는 함수를 배우고 있구요.

그렇다면 함수를 적는 법만 알면 원하는 걸 표현할 수 있는 것 아닌가요? 자음, 모음, 품사를 배웠다고 우리가 회화를 잘 할 수 있나요? 컴퓨터가 알아 들을 수 있을 정도의 명확한 회화를… 아니었습니다.
즉 많은 책을 읽고 이론만 공부한다고 해서 코드를 잘 작성할 수 있는 것은 아니라는 것을 알게되는 시간이었습니다.

이제는 이론 내용 복습뿐만 아니라 열심히 작문 연습도 합시다!!

——–S70 스터디 5강 영상 공유

s70 자바스크립트 함수와 객체 5강 – 1

s70 자바스크립트 함수와 객체 5강 – 2



dimanche | bsidesoft 신입사원
좋은 개발자가 뭔지도 모르고 좋은 개발자가 되고 싶은 초보 개발자입니다.
회사에서는 열심히 교육받고 발전하는 운 좋은 개발자로 일하고 있습니다.