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
setTimeoutfunction(){
    console.log("I waited 1 second!");
}, 1000 );
 
 
setTimeoutfunction 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가 발생한다.



5. 소스


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

+ Recent posts