# 유효범위

## 유효범위(Scope)

> #### 변수의 수명

```javascript
var vscope = 'global';
function fscope(){
    alert(vscope);
}
fscope(); //global
```

## 1. 전역변수(Global Scope)

**함수 밖에서 선언된 변수**\
\- 함수 안에서도 그 변수에 접근할 수 있음

```javascript
var vscope = 'global';
function fscope(){
    var vscope = 'local';
    alert('함수안 '+vscope); //함수안 local
}
fscope();
alert('함수밖 '+vscope); //함수밖 global
```

## 2. 지역변수(Local Scope)

**함수 안에서 선언된 변수**\
\- 함수 밖에서 함수 안의 변수에 접근할 수 없음

{% hint style="success" %}
같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 \
**지역변수가 우선시** 됨
{% endhint %}

```javascript
var vscope = 'global';
function fscope(){
    vscope = 'local'; //var를 사용하지 않음 = 전역변수가 됨을 뜻함
    alert('함수안 '+vscope); //함수안 local
}
fscope();
alert('함수밖 '+vscope);//함수밖 local
```

## 3. 유효범위의 효용

{% tabs %}
{% tab title="지역변수의 사용" %}

```javascript
//var가 있는 경우
function a (){
    var i = 0;
}
for(var i = 0; i < 5; i++){
    a();
    document.write(i); //01234
}
```

{% endtab %}

{% tab title="전역변수의 사용" %}

```javascript
//var가 없는 경우
function a (){
    i = 0;
}
for(i = 0; i < 5; i++){
    a();
    document.write(i); //i가 전역변수가 됨에 따라 계속 0이라 무한반복됨
}
```

{% endtab %}
{% endtabs %}

### 3-1. 전역변수를 불가피하게 써야하는 경우

하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리하는 방법을 사용

```javascript
MYAPP = {}
MYAPP.calculator = {
    'left' : null,
    'right' : null
}
MYAPP.coordinate = {
    'left' : null,
    'right' : null
}
 
MYAPP.calculator.left = 10;
MYAPP.calculator.right = 20;
function sum(){
    return MYAPP.calculator.left + MYAPP.calculator.right;
}
document.write(sum()); //30
```

### 3-2. 전역변수를 사용하고 싶지 않을 때 익명함수를 호출

```javascript
(function(){
    var MYAPP = {}
    MYAPP.calculator = {
        'left' : null,
        'right' : null
    }
    MYAPP.coordinate = {
        'left' : null,
        'right' : null
    }
    MYAPP.calculator.left = 10;
    MYAPP.calculator.right = 20;
    function sum(){
        return MYAPP.calculator.left + MYAPP.calculator.right;
    }
    document.write(sum()); //30
}())
```

## 4. 유효범위의 대상 (함수)

> 자바스크립트는 **함수**에 대한 유효범위만을 제공\
> 많은 언어들이 블록(대체로 {,})에 대한 유효범위를 제공하는 것과 다른 점

```javascript
for(var i = 0; i < 1; i++){
    var name = 'coding everybody' //name =  지역변수
}
alert(name); //for문 밖에서 호출되고 있음
//coding everybody


//자바에서는 아래의 코드는 허용되지 않
for(int i = 0; i < 10; i++){
    String name = "egoing";
}
System.out.println(name);
```

## 5. 정적 유효범위(static scoping)

> 자바스크립트는 함수가 선언된 시점에서의 유효범위를 갖게 됨\
> 이러한 유효범위 방식을 \
> 정적 **유효범위(static scoping), 렉시컬(lexical scoping)**&#xC774;라 함
>
> 즉, 함수를 호출해서 변수값을 가져오는 시점이 아닌 함수가 정의되는 시점\
> 이후 **클로저(Closure)**&#xC640; 연결됨

```javascript
var i = 5;
 
function a(){
    var i = 10;
    b();
}
 
function b(){
    document.write(i);
}
 
a(); //5
```
