Scope (스코프)
개념
변수가 유효성을 가지는 범위.
스코프는 기본적으로 프로세스 메모리 맵의 구조에 의존적.
선언된 위치에 따라 스코프가 결정된다.
같은 이름으로 변수가 선언된 경우 스코프가 겹칠 수 있다.
스코프가 겹칠 때 어떤 변수가 우선권을 가지는지 판단하는 기능이 필요하며 이러한 기능을 식별자 결정(identifier resolution)이라고 한다.
종류
구분 | 전역 스코프 | 지역 스코프 |
변수의 의미 | 전역변수 | 지역 변수 |
선언위치 | 코드의 가장 바깥 부분 | 함수의 내부 |
유효영역 | 전역 영역과 그 하위 영역 | 함수 자신과 그 하위 영역 |
특징 | Var와 같은 선언자를 생략시 전역 스코프 | - ES5(var)는 함수 레벨 스코프 지원 - ES6(let, const)는 블록 레벨 스코프 지원 |
** 블록 레벨 스코프스코프 : C++, JAVA 언어 등에서 지원하는 스코프. if, for, try/catch 등이 스코프 영역으로 판단된다.
식별자 결정
식별자 결정은 가장 가까운 스코프를 우선으로 한다.
<body>
<script>
const sc = 'global'
function func()
{
console.log(sc);
}
func()
//global
function func2()
{
const sc = 'local'
console.log(sc);
}
func2()
//local
</script>
</body>
▷ 함수 레벨 스코프
1. ES5 방식
- var 사용
- var 생략
- ES5의 var는 함수 레벨 스코프를 가진다. 즉 함수 내에서 유효하다.
2. ES6 방식
- const : 값을 바꿀 수 없다.
- let : 값을 바꿀 수 있다.
- ES6의 const나 let은 블록 레벨 스코프를 가진다. 즉 블록 내에서만 유효하다.
<body>
<script>
function func()
{
for (var i = 0; i < 5; i++)
{
i;
}
console.log(i);
}
func()
//5
function func2()
{
for (let i = 0; i < 5; i++)
{
i;
}
console.log(i);
}
func2()
//Uncaught ReferenceError: i is not defined
</script>
</body>
▷ 식별자 결정 시
Javascript는 변수 선언 없이 변수를 사용할 수 있다. → var로 해석
var는 Hoisting에 적용되어 식별된다.
<body>
<script>
function func()
{
sc1 = 'local' //var로 해석함
console.log(sc1);
}
func()
//loacl
let sc2 = 'global'
function func2()
{
sc2 = 'loacl' //var로 해석하여 전역변수에 입력함
console.log(sc2);
}
func2()
console.log(sc2)
//local
//local
</script>
</body>
var를 사용할 시 문제점
- 함수 레벨 스코프
- Hoisting
- 전역 영역 침범
= 코드를 읽기 어렵다.
▷ 식별자 결정의 난해함
아래 코드는 무한 루프가 발생한다.
- f1()에서의 i는 for문에서 선언한 i를 초기화한다.
- f1()에 i가 없기 때문에 스코프 체이닝으로 인하여 for문에 i를 참조한다.
<body>
<script>
function f1()
{
i = 0;
}
for (var i = 0; i < 10; i++)
{
f1();
}
//무한루프 발생
</script>
</body>
* 스코프 체인
함수의 중첩 구조로 인해 스코프도 중첩 구조가 생긴다.
식별자 결정을 위해 가까운 스코프로부터 전역 스코프까지 계층적으로 연결된 구조를 스코프 체인이라고 한다.
<body>
<script>
let a = 30;
const f1 = function()
{
let a = 10;
const f2 = function()
{
let a = 10;
console.log(a);
}
f2()
}
f1()
//10
</script>
</body>
<body>
<script>
let a = 30;
const f1 = function()
{
let a = 10;
const f2 = function()
{
console.log(a);
}
f2()
}
f1()
//10
</script>
</body>
<body>
<script>
let a = 30;
const f1 = function()
{
const f2 = function()
{
console.log(a);
}
f2()
}
f1()
//30
</script>
</body>
Closure (클로저)
개념
내부 함수에서 외부 함수로 스코프 체이닝을 통해 외부 함수의 변수로 접근 가능한 함수의 조합.
내부 함수에서 전역 영역 범주.
자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(Functional Programming language: 얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.
“A closure is the combination of a function and the lexical environment within which that function was declared.”
"클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다."
by. MDN
원인
스코프 체이닝
결과
클로저
내부 함수는 외부함수 변수에 접근 가능 (스코프 체이닝)
외부 함수는 내부 함수의 변수에 접근이 불가능.
활용
<body>
<script>
const makeInstance = function(title)
{
return {
getTitle() //function 축약됨
{
return title;
},
setTitle : function(_title)
{
title = _title;
}
}
}
const book1 = makeInstance('title1');
console.log(book1.getTitle());
book1.setTitle('titl2')
console.log(book1.getTitle());
//title1
//titl2
</script>
</body>
var의 중복 선언
전역 변수(Global Variable)의 사용
전역 변수의 문제점
해결방안
전역 객체를 이용 = 사용할 전역 변수의 객체를 만들어서 사용.
즉시 호출 함수를 이용.
<body>
<script>
(function()
{
const myGolbal = {
value1 : 1,
array1 : [11, 22, 33, 44, 55]
};
const func = function()
{
return myGolbal.array1[0] + myGolbal.value1;
}
console.log(func());
})()
//12
</script>
</body>
'JavaScript' 카테고리의 다른 글
[JavaScript] 소숫점 자리수 정하기 toFixed() (0) | 2022.04.18 |
---|---|
[JavaScript] 문자열 정렬하기 (+예제, sort()이해) (0) | 2022.04.16 |
[JavaScript] sort(), 오름차순 정렬, 내림차순 정렬 (0) | 2022.04.14 |
[JavaScript] 특정 범위 랜덤수 생성하여 버블소팅하기. Math (0) | 2022.04.14 |
[JavaScript] 두 배열 합치기 (0) | 2022.04.14 |