Scope란?
- 변수가 접근가능한 범위이다.
- 내부와 외부를 판별하는 기준은 함수이다.
- var 키워드는 함수 단위함수가 하나의 범위.
- let 키워드는 ‘{}’ 중괄호가 하나의 범위.
- 내부에서 외부는 접근 가능하지만, 외부에서 내부는 접근 불가능 하다.
1
2
3
4
5
6
7
8
9
10
11
| var a = 'out'; // 함수 밖에서 변수를 선언하면 전역변수
function foo () {
var b = 'in'; //함수 내에서 변수를 선언하면 지역변수
console.log(b); // 'in'
console.log(a); // 'out'
}
foo();
console.log(b); // error 외부에서 내부 접근이 불가능 하다.
|
- 함수가 범위의 기준이 된다.
- 내부에서 외부는 접근 가능하지만, 외부에서 내부는 접근 불가능 하다.
1
2
3
4
5
6
7
8
9
10
| var a = 'global'; // 전역변수
function foo () {
var a = 'local'; // 지역변수
alert('함수안 ' , a); // 'local'
}
foo();
alert('함수밖 ' + a); // 'global'
|
- 함수 안에서 같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 지역변수를 우선순위를 가진다
1
2
3
4
5
6
7
8
9
10
| var a = 'global'; // 전역변수
function foo () {
a = 'local'; // 전역변수 a의 'global' 을 'local'로 재할당
alert('함수안 ' + a); // 'local'
}
foo();
alert('함수밖 ' , a); // 'local'
|
- 선언 키워드 없이 함수 안에서 전역변수와 같은 변수에 값을 할당하면 전역 변수의 값을 재할당 하는 것이다.
for loop 와 var
1
2
3
4
5
6
7
8
9
10
11
|
function foo () {
var a = 5;
for (var i=0; i < a; i++) {
i = i + 1;
}
console.log(i); // 6 -> i는 foo함수의 scope
}
foo();
|
위와 같은 경우 i++
을 하고 i = i + 1
하면서 콘솔에 6이 찍힌다.
let, const Socpe
let
과 const
는 블록 단위로 스코프가 정해진다.
1
2
3
4
5
6
7
8
9
| function foo () {
let a = 5;
for (let i=0; i < a; i++) {
i = i + 1;
}
console.log(i); // erro
}
foo();
|
let
과 const
키워드는 {}
중괄호 scope 범위를 가진다. i는 for 문 {}
중괄호 scope를 가지기 때문에 console.log(i)를 실행했을 경우 중괄호 내부 변수에 접근할 수 없다.
Hoisting
hoisting
1
2
3
4
5
| console.log(a); // undefind
var a = 1;
console.log(a); // 1
|
첫 번째 console.log(a);
이 undefind
가 뜨는 이유는 hoisting 때문이다. 실제로 실행될 때에는 아래와 같이 변수를 선언하는 부분이 끌어올려지는 것과 같기 때문에 var a;
에 값이 할당되어 있지 않으므로 undefinde
가 된다.
1
2
3
4
5
6
7
| var a;
console.log(a);
a=1;
console.log(a);
|
본인이 속한 Scope 내에서 Hoisting
1
2
3
4
5
6
7
8
9
| var a = 'hello';
function foo () {
alert(a); // undefind
var a = 'world';
}
foo();
|
alert(me);
는 undefind
가 된다. 아래와같이 Scope 내에서 Hoisting 되기 때문이다.
1
2
3
4
5
6
7
8
9
10
11
| var a = 'hello';
function foo () {
var a;
alert(a);
a = 'world';
}
foo();
|
함수 표현식 Hoisiting
변수를 만들고 함수를 할당하는 방식을 함수 표현식이라고 한다.
1
2
3
4
5
6
7
| fn(); // ERROR
var fn = funcion () {
console.log('hello world');
};
fn();
|
함수 표현식 또한 변수에 함수를 할당하면 아래와 같이 변수 var fn;
이 hoisting 되고 var fn;
는 undefind
이기 때문에 var fn;
를 호출하면 undefind
가 호출되면서 ERROR
가 뜨게된다.
1
2
3
4
5
6
7
8
9
| var fn;
fn(); // ERROR
var fn = funcion () {
console.log('hello world');
};
fn();
|
함수 선언식 Hoisiting
아래와 같이 함수 선언식으로 함수를 정의할 경우 함수가 모두 호출된다.
1
2
3
4
5
6
7
| fn();
function fn () {
console.log('hello world');
}
fn();
|
아래와 같이 함수 자체가 hoistiong 된다.
1
2
3
4
5
6
7
| function fn () {
console.log('hello world');
}
fn();
fn();
|
Primitive vs Reference
Primitive 원시형
1
2
3
4
5
6
7
8
9
| var a = 1;
var b = 1;
var c = 'hello';
var d = 'hello';
console.log(a === b); // true
console.log(c === d); // true
|
Reference 참조형
1
2
3
4
5
6
7
8
9
| var arr1 = [ 1, 2, 3 ];
var arr2 = [ 1, 2, 3 ];
var obj1 = {a: 1, b: 2};
var obj2 = {a: 1, b: 2};
console.log(arr1 === arr2); // false
console.log(obj1 === obj2); // false
|
arr1과 arr2 모두 선언한 후 배열을 만들어 생성하였다. 위와 같은 경우 arr1과 arr2가 같아 보일 수 있지만 실제로 arr1과 arr2는 다른 배열이다. 서로의 위치에서 만들어진 값으로 위치 값이 다르기 때문에 false
이다.
1
2
3
4
5
6
7
8
| var arr1 = [ 1, 2, 3 ];
var arr2 = arr1;
var obj1 = {a: 1, b: 2};
var obj2 = obj1;
console.log(arr1 === arr2); // true
console.log(obj1 === obj2); // true
|
arr1
을 arr1
에 할당한 것으로 위치 값이 같이 때문에 true
이다.