호다닥

Day7. this, prototype 본문

바닐라코딩

Day7. this, prototype

3jun 2018. 6. 5. 21:45

이미 for문의 내부에서 연산이 끝난 후에 setTimeout이 실행되기 때문에 출력값이 5가 된다. 




for문이 실행되면 var i를 전역스코프로 선언하고 0을 값으로 할당한다. 그리고 for문의 내부코드를 실행한다. 새로운 함수를 만들고 그 함수를 바로 실행한다. 

그러면 지역변수가 개별적으로 선언된다. 이 선언된 지역변수는 closure에 의해 매번 기억되기 때문에 setTimeout에 j는 0이다. 1이다. .... 를 각기 기억한 함수들이 실행된다. 


 즉시실행함수에 있는 j가 closure로 인해 이전의 스코프를 기억하기 때문에 for문이 끝나도 매번 i의 값을 j가 받아들이고 기억하기 때문이다. 


 for문 내부코드를 실행하면 함수를 만들고 변수를 i로 하고 그 함수를 바로 실행한다. 그럼 첫번재 변수값이 0이 매개변수 j로 들어가고 이 값이 지역변수가 된다. 그리고 setTimeout을 실행할때 첫번재 인자를 함수로 주는데, closure는 함수가 생성될때 자기 주변 인자정보들을 기억하기 때문에 j=0, j=1, ... 차례대로 기억하게 된다. 이렇게 setTimeout이 실행된다. setTimeout 내부코드는 아직 실행되지 않은 상태이다.



실습1.



이렇게 해도 사실 상 같다.


 


은행에서 사용자의 은행계좌를 다루는 코드가 위와 같이 있으면 아래와 같은 간단한 코드로 balance정보가 노출될 수 있다.

만약 balance 정보를 감추고 싶다면 



createBankAccount라는 함수를 선언하고 내부에 지역변수로 balance를 선언한다. return값에는 balance정보가 빠져있다. 이 객체가 생성될 때 이 함수들은 closure를 이용해서 balance 정보를 기억한다. 

createBankAccount함수를 실행하면 bankAccount 변수에 balance정보를 기억하고 있는 객체들이 담기게 된다. 하지만, balance 변수는 내부에 있기 때문에 외부스코프에서 접근할 수 없다. 







1. non-strict mode


글로벌에서 함수를 일반함수 호출로 아무런 특이점 없이 호출하면 this는 무조건 global object, 브라우저에서는 window이다.




예시


this 가 뭔지 판별하기 위해서는 this를 포함한 함수가 어떻게 실행되는지 그 순간을 포착해야 한다. 


여기서 foo는 bar함수인데 bar함수는 실행될때 79번째 줄에서 볼 수 있듯이 일반함수 호출방식이기 때문에 83번째 줄 bar의 this는 window가 되어 this.age는 100 이 호출된다.

만약 strict mode라면 undefined가 된다.



2. dot notation 방식 

dot notaion 방식은 함수를 실행할때 객체명.함수명() 으로 호출하는 method방식으로 호출하는 방식을 의미한다.



ken.log() 는 dot notaion방식으로 이렇게 함수를 실행하면 100번째 줄의 함수 foo의 this는 ken이 된다. 따라서 ken.log(); 는 35가 consloe.log 된다.

반면, foo(); 는 일반함수 호출방식이기 때문에 100이 찍힌다.


예시


위에서 실행되는 포인트는 109번째 이다. 때문에 여기서의 함수호출방식만 보면 되는데, 일반함수호출방식이기 때문에 window 객체가 되어 값은 100이다. 


** 106번째 줄 때문에 헷갈릴 수 있지만 이전에 어떻게 했던지와 무관하게 현재 함수가 실행될 당시의 실행방식을 보면 된다. 



ken.foo();        →    35;

wan.foo();        →    31;




3. Function.prototype.call, Function.prototype.bind, Function.prototype.apply - explicit binding

자바스크립트함수에 있는 기본적인 method 3가지 call, bind, apply


이 3가지 method를 사용하면, this 값이 조금 다르게 사용된다. 

prototype 개별적으로 공부하고 올 것




kenLog()        →        일반함수이기 때문에 100이 호출된다.


apply를 실행하면 함수를 실행한다. apply method에는 인자값을 줄 수 있다.

186번째 줄에서 apply method에 ken라는 인자를 주면 177번째의 this가 ken으로 실행이 된다.

첫번째 인자로 들어가는 것이 this가 된다.

foo라는 함수가 실행되는데, 이때 인자값이 this로 설정이 되어 실행된다.

foo.call() 도 apply와 동일하다. (지금 이 예제에서는)


위에서처럼 함수에 this가 없으면 인자값과 상관없이 console.log값이 그대로 출력된다. 

  




Javascript에서는 매개변수의 갯수는 별 다른 큰 의미를 갖지는 않는다.


첫번째 인자가 무조건 this이고, 그 뒤에 있는 인자들은 foo라는 함수의 인자로 다 들어가게 된다.

즉, 211번째줄을 실행하면 this에는 ken이 a,b,c,d,e에는 1,2,3,4,5가 들어간다. 


call method는 인자의 갯수를 무제한으로 줄 수 있다.

하지만 apply method는 2개의 인자만을 받는다. 첫번째 인자는 this로 만들고 싶은 객체, 두번째 인자는 배열이 와야하고, 배열안의 요소들이 인자로 넘어간다. ( 배열이 넘어가는 것이 아니다. )


foo라는 함수를 bind하고 있다. 


call, apply는 함수를 바로 실행하지만 bind는 인자값을 this값으로 만들기만 할뿐 함수를 실행하지는 않는다. 

bind를 한 후에 추가적으로 함수를 실행해줘야만 한다. 


bind도 this값 뿐만아니라 인자값도 줄 수 있다.



bind를 한 후에 해당 함수에 인자값을 주면 bind 된 인자값이 먼저 나오고 함수를 실행할 때 준 인자값이 뒤에 나온다. 



call, apply, bind        -        explicit binding (this를 직접적으로 지정하는 방식)



4. 'new' keyword

new로 함수를 만든 후에 실행한다. javascript에서는 new에 의미가 있다.



함수를 실행할때 new를 붙이면 그 함수는 빈 객체가 된다.


new를 써서 함수를 실행하면 return을 하지 않아도 this 값이 return이 된다. 



단, 객체를 return하면 return이 된다.




하나의 함수에 new method를 실행하면 매번 새로운 객체가 실행된다. 

이러한 객체들을 instance라고 한다. 


ken은 Person의 instance이다. 

wan은 Person의 instance이다.



객체가 함수의 instance인지 확인하는 instanceof

ken은 Person의 instance인지? → Boolean 값으로 출력된다.

11번째 줄과 12번째 줄은 같은 의미이다.


new와 함께 쓰여 객체를 생성하는  함수는 Constructor function (생성자 함수) 라고 한다.



생성자함수는 다른 함수들과 다른 목적으로 쓰이는 경우가 많기 때문에 javascript에서는 함수명의 첫글자를 대문자로 하여 Constructor function 인지 여부를 나타낸다. 






work( ); 는 window 레벨 객체이기 때문에 this.isSmart는 존재하지 않아서 undefined가 출력된다.



















'바닐라코딩' 카테고리의 다른 글

Day 9,10. Server/Client/HTTP, AJAX  (0) 2018.06.14
Day 8. protoype  (0) 2018.06.07
Day 6. Closure  (0) 2018.06.02
Day 5. argument / scope / hoisting / closure  (0) 2018.05.31
Day3, 4. Event  (0) 2018.05.29
Comments