1. 함수에서 범위 ( Scope From Functions )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!DOCTYPE html> <html> <head> <title></title> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script> </head> <body> <button id="button1">button</button> </body> <script type="text/javascript"> $( document ).ready(function() { $( "#button1" ).click(function() { bar(); // fails console.log(a, b, c); // all 3 fail }); function foo(a) { var b = 2; // some code function bar() { // ... } // more code var c = 3; } }); </script> </html> | cs |
bar(); 는 foo() 안의 들어있는 함수이므로 바로 호출이 불가능하다.
foo()의 인자로 받는 a, foo() 안의 선언한 변수 b,c를 호출하는 것은 불가능하다.
2. 충돌 회피( Collision Avoidance )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!DOCTYPE html> <html> <head> <title></title> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script> </head> <body> <button id="button1">button</button> </body> <script type="text/javascript"> $( document ).ready(function() { $( "#button1" ).click(function() { foo(); }); function foo() { function bar(a) { debugger; i = 3; // changing the `i` in the enclosing scope's for-loop console.log( a + i ); } for (var i=0; i<10; i++) { debugger; bar( i * 2 ); // oops, infinite loop ahead! } } }); </script> </html> | cs |
foo() 함수에 for문 i값은 초기값이 0 이지만
반복하면서 bar() 함수로 진입후 i의 값이 3으로 재정의된다.
이후 bar() 함수를 빠져나오면 재정의된 i값 3이 for문으로 들어와 무한반복을 한다.
3, 11, 11, 11, 11 ...
3. Anonymous vs. Named
1 2 3 4 5 6 7 8 | setTimeout( function(){ console.log("I waited 1 second!"); }, 1000 ); setTimeout( function timeoutHandler1(){ // <-- Look, I have a name! console.log( "I waited 1 second!" ); }, 1000 ); | cs |
익명 함수는 더 읽기 쉽고 이해할 수있는 코드를 제공하는 데 도움이되는 이름을 생략한다.
익명 함수에는 스택 추적에 표시 할 이름이 없어 디버깅을 더 어렵게 만들 수 있다.
이름이 없으면 함수가 자체를 참조해야하거나 재귀를 참조해야하는 경우 사용되지 않는 인자의 참조가 필요하다.
설명이 포함 된 이름은 문제의 코드를 스스로 문서화하는 데 도움이된다.
4. let
1 2 3 4 5 6 7 8 9 | var foo = true; if (foo) { let bar = foo * 2; bar = something( bar ); console.log( bar ); } console.log( bar ); // ReferenceError | cs |
var를 사용하면 어떤 블록에 어떤 변수를 범위에 두었는가에 따라 값이 변하거나 원치않은 결과가 나오는데
let을 사용하여 명시적 블록범위를 작성하면 변수가 연결되는 위치가 명확해진다.
let loop
1 2 3 4 5 | for (let i=0; i<10; i++) { console.log( i ); } console.log( i ); // ReferenceError | cs |
let의 for문은 밖에서 호출시 ReferenceError가 발생한다.
값을 다시 할당해주어야 한다.
const
1 2 3 4 5 6 7 8 9 10 11 12 | var foo = true; if (foo) { var a = 2; const b = 3; // block-scoped to the containing `if` a = 3; // just fine! b = 4; // error! } console.log( a ); // 3 console.log( b ); // ReferenceError! | cs |
ES6에서 const블록 스코프 변수를 만들면 그 값은 고정된다.(상수)
값을 변경하려고하면 ReferenceError가 발생한다.
https://repl.it/@shlee0882/collision-avoidance
'전체 > JS & Jquery' 카테고리의 다른 글
JS IIFE, Modules (0) | 2019.04.10 |
---|---|
JS 표현식(expressions) (0) | 2019.04.09 |
JS ==, === 의 비교 (0) | 2019.04.08 |
JS Implicit Coercion(형변환) (0) | 2019.04.08 |
js value와 reference (0) | 2019.03.12 |