Your SlideShare is downloading. ×
0
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Javascript hoisting
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Javascript hoisting

1,396

Published on

2013.04.02 스터디 팀 복습을 위한 문서.

2013.04.02 스터디 팀 복습을 위한 문서.

Published in: Technology
4 Comments
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
1,396
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
14
Comments
4
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. JavaScript Hoisting 안오균
  • 2. 먼저,지역 변수의 유효 범위는 블럭이 아닌 함수! function foo() { var bar = ‘bar’; console.log(bar); //--> ‘bar’ if (true) { var bar = ‘baz’; console.log(bar); //--> ‘baz’ } console.log(bar); //--> ‘baz’ }
  • 3. 즉시 실행 함수로 유효 범위를 제한할 수 있음. function foo() { var bar = ‘bar’; console.log(bar); //--> ‘bar’ if (true) { (function () { var bar = ‘baz’; console.log(bar); //--> ‘baz’ }()); } console.log(bar); //--> ‘bar’ }
  • 4. 호이스팅(Hoisting) 변수 선언과 함수 선언은 인터프리터에 의해 함수의 맨 앞으로 끌어올려진다(옮겨진다). * hoist = 끌어올리다
  • 5. 용어가 좀 헷갈릴 수 있다.변수 선언(Variable Declaration) var foo = ‘bar’;함수 선언(Function Declaration) function foo() {}함수 표현식(Function Expression) var foo = function () {}; (function foo() {});
  • 6. 변수 선언인 경우 function foo() { console.log(bar); //--> undefined var bar = baz; console.log(bar); //--> baz }아래와 동일 function foo() { var bar; // 변수 선언은 함수의 맨 앞으로 끌어올려진다.(hoisted) console.log(bar); bar = baz; // 할당은 실행 시점에 수행 console.log(bar); }
  • 7. for 문의 경우도 동일 function foo(arr) { for (var i = 0, len = arr.length; i < len; i++) { console.log(arr[i]); } }아래와 동일 function foo(arr) { var i, len; for (i = 0, len = arr.length; i < len; i++) { console.log(arr[i]); } }
  • 8. 함수 정의인 경우 function foo() { bar(); //--> bar function bar() { console.log(bar); } }아래와 동일 function foo() { function bar() { console.log(bar); } bar(); }
  • 9. 함수 표현식인 경우 (변수 선언과 동일) function foo() { bar(); //--> ReferenceError var bar = function () {}; bar(); // 호출되지 않음 }아래와 동일 function foo() { var bar; bar(); bar = function () {}; bar(); }
  • 10. 변수 선언은 호이스팅으로 맨 앞으로,변수 할당은 실행시점에 수행됨.호이스팅으로 헷갈릴 수 있으니,함수의 맨 앞 부분에 한 개의 var만 쓸 것을 권장. function foo() { var a = 1, b = 2, c = 3; }
  • 11. 그치만, 눈을 크게 떠야할 때가 있음. function foo() { var a = 1, b = 3, c = 4; d = 2; }오류 없이 실행되며, 변수 d는 전역으로 선언됨.린트 툴을 사용할 것을 권장.
  • 12. 디버깅이 어려운 경우도 있음. function foo() { var a = 1, b = getComplexValue(a), // 브레이크 포인트를 잡기 어려움 c = b + 3; }상황에 따라 var로 나누는 것도 나쁘지 않은 선택. function foo() { var a = 1; var b = getComplexValue(a); var c = b + 3; }
  • 13. 또한, 분기문 내에 함수 정의를 넣지 말 것. function foo(condition) { if (condition) { function bar() { console.log(first bar); } } else { function bar() { console.log(second bar); } } bar(); } foo(true); //--> second bar foo(false); //--> second bar
  • 14. 함수 정의 호이스팅에 따라 아래와 같기 때문. function foo(condition) { function bar() { console.log(first bar); } function bar() { console.log(second bar); } if (condition) { } else { } bar(); }* ES5 strict 모드에서는 SyntaxError 발생
  • 15. 상황에 따라 동적으로 할당하고 싶다면. function foo(condition) { var bar; if (condition) { bar = function () { console.log(first bar); }; } else { bar = function () { console.log(second bar); }; } bar(); } foo(true); //--> first bar foo(false); //--> second bar
  • 16. 개인적으로는, var는 맨 위에,함수는 읽어내려가기 편하게 작성하는 것을 선호함.function foo() { var a, b, c; doAll(); function doAll() { doA(); doB(); } function doA() {} function doB() {}}
  • 17. 하지만 리턴문 뒤의 함수 정의는,문맥 상 그다지 좋은 것 같지 않음. function foo() { return bar(); function bar() { return ‘baz’; } } * 함수 정의 호이스팅으로 문제 없이 실행됨.
  • 18. 끝.
  • 19. 부록. 좀 더 자세히 알아보면. function test(a, b) { console.log(a, b, c, d); var c = 10; function d() {} } test(10);위와 같은 함수가 전역 범위에서 실행될 때.
  • 20. 다음과 같은 식으로 실행됨.1. foo()가 호출되면,2. foo()의 실행 컨텍스트가 생성되고,3. 실행 컨텍스트는 함수를 실행하기 전 활성화 객체를 생성한다.4. 활성화 객체에는 파라미터 정보, 변수 선언, 함수 정의가 포함된다.5. 함수가 실행되고 변수를 만났을 때엔, 유효범위 체인에 따라 활성화 객체에서 먼저 찾고, 상위 탐색을 진행한다.
  • 21. 이 때, 활성화 객체에는 다음 값들이 할당된다. - 파라미터로 전달된 값 파라미터의 이름과 값을 할당 없는 경우 undefined로 할당 - 모든 함수 선언 함수의 이름과 정의를 할당 이미 정의되어 있는 경우 덮어씀 - 모든 변수 선언 변수의 이름과 undefined를 할당 이미 정의되어 있는 경우 할당하지 않음
  • 22. 즉, 아래 코드가 실행되기 전, function test(a, b) { console.log(a, b, c, d); var c = 10; function d() {} } test(10);활성화 객체(Activation Object)는 다음과 같이 생성된다. AO = { a: 10, b: undefined, c: undefined, d: <reference to function ‘d’> };
  • 23. 실행 시점에서 변수를 만났을 때엔,활성화 객체의 값을 찾거나 설정한다. function test(a, b) { console.log(a, b, c, d); // 각각 AO[‘a’], AO[‘b’], AO[‘c’], AO[‘d’]의 값 // 10, undefined, undefined, function var c = 10; // AO[‘c’] = 10; 과 동일하다. function d() {} } test(10);
  • 24. 함수 표현식은 활성화 객체에 할당되지 않는다. function test() { var foo = function bar() {}; // foo는 AO에 존재하지만, bar는 존재하지 않는다. // bar의 접근을 시도하면 ReferenceError가 발생한다. (function baz() {}); // 마찬가지로 baz도 AO에 할당되지 않는다. }
  • 25. 호이스팅은 활성화 객체의 할당 방식에 따른 현상. function foo() { console.log(bar); //--> function ‘bar’ // AO[‘bar’] = <reference to function ‘bar’> var bar = 10; function bar() {}; var bar = 20; }
  • 26. 정말 끝.

×