Scope(유효범위)와 Closure(클로저)

손연주·2021년 4월 26일
0


한쪽에서만 보이는 취조실 특수 유리는 스코프의 접근 권한과 비슷한 원리다.

스코프

변수의 유효범위

1. 전역 스코프(Global Scope)

변수가 함수 바깥이나 중괄호({}) 바깥에 선언되었다면, 전역 스코프에 정의된다고 한다.

let greeting = 'Hello';

전역 스코프를 선언하면, 코드 모든 곳에서 해당 변수를 참조할 수 있다.

let greeting = 'Hello';
function greetSomeone() {
  let Name = 'yeonju';
  return greeting + ' ' + Name;
}
console.log(greetSomeone()); // 'Hello yeonju'
console.log(greeting); // 'Hello'

1-1. 전역 스코프, 전역 변수의 단점

전역 스코프에 변수를 선언할 수 있어도, 가급적이면 그러지 않는 것이 좋다. 왜냐하면, 두 개 이상의 변수 이름이 중복되어 충돌될 수 있기 때문이다. 만약 변수를 const, let으로 선언하였다면, 같은 이름을 쓸 때마다 에러가 나온다. 코드 양이 많고 다른 사람과 협업한다면, 변수명이 겹쳐서 에러를 만들 수도 있지 않을까?

has already been declared

const name = 'yeonju'
const name = 'jjang' //Error, name has already been declared

원하지 않는 재할당

let name = 'yeonju'
let name = 'son' 

console.log(name); // 'son'

만약 let 사용하였다면 두번째 변수가 첫번째 변수를 덮어쓰게 된다. 그래서 우리는 전역변수가 아닌, 지역변수로 변수를 선언해야 한다.

2. 지역 스코프(Local Scope)

우리 코드의 특정 부분에서만 사용할 수 있는 변수는 지역 스코프에 있다. 그리고 이런 변수들은 지역 변수라고 불린다.

2-1. 지역 스코프를 나누는 기준

중괄호{} 또는 함수에 의해 나뉘어지고, 그 범위를 스코프라고 부른다.

2-2. 지역 스코프의 종류

블록 스코프(block scope): 중괄호를 기준으로 범위가 구분됨


중괄호({}) 내부에서 const,let 변수를 선언하면, 그 변수들은 블록 내부에서만 접근이 가능하다.

{
  const hello = 'Hello world'
  console.log(hello) // 'Hello world'
}
console.log(hello) // Error, hello is not defined
  • 화살표 함수는 블록 스코프로 취급한다.

함수 스코프(function scope)

let username = 'kimcoding';
if (username) {
  let message = `Hello, ${username}!`;
  console.log(message); // "Hello, kimcoding!"
}

console.log(message); // ReferenceError 
//message라는 변수가 지역 스코프에 선언되어 있으므로, 바깥쪽에서는 접근할 수 없다

함수 내부에서 변수를 선언하게 되면, 그 변수는 함수내에서만 접근이 가능하다. 함수 바깥에서는 해당 변수에 접근할 수 없다.

3. let, const, var

규칙

  1. 안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대는 불가능
  2. 스코프는 중첩이 가능하다

    가장 바깥쪽의 스코프는 전역 스코프(Global Scope)라고 부른다.
    전역의 반대말은 지역(local)으로 전역이 아닌 다른 스코프는 전부 지역 스코프(local scope)다.
  3. 지역 변수는 전역 변수보다 더 높은 우선순위를 가진다

클로저

외부함수의 변수에 접근할 수 있는 내부 함수
함수를 리턴해야 하고, 외부함수의 변수에 접근할 수 있어야 한다
함수 내에서 변수를 메모리처럼 사용한다

"함수를 리턴하는 함수"

const adder = function (x) { //외부 함수의 변수 x
  return function (y) { //내부 함수의 변수 y
    return x + y;
  }
}

여기서 adder 함수가 리턴하고 있는 익명 함수가 클로저로 간주된다

1. 클로저 만드는 법

1) 함수 안에서 변수를 선언하거나 매개변수로 받아온다.
2) 리턴을 익명함수로 쓴다.

function example() {
  var num = 0 // 변수를 메모리처럼 사용
  return function() { 
    num++;
    console.log(num);
  }
}

var test = example();
test(); //1
test(); //2

2. 규칙

  1. 클로저는 리턴하는 함수에 의해 스코프가 구분된다
  2. 클로저 함수는 "내부 함수는 외부 함수에 선언된 변수에 접근 가능하다
  3. 데이터를 보존하는 함수
    외부 함수의 실행이 끝나더라도, 외부 함수 내 변수 사용 가능
    = 일반적인 함수는, 함수 실행이 끝나고 나면 함수 내부의 변수를 사용할 수 없다. 이와 다르게, 클로저는 외부 함수의 실행이 끝나더라도, 외부 함수 내 변수가 메모리 상에 저장된다. (어휘적 환경을 메모리에 저장하기 때문에 가능한 일)

더 알아보기

  1. 함수에 매개변수가 없으면 지역 스코프 안에서 let을 쓴 것과 같다
let x = 30; //전역 변수 x
function get() { //매개변수가 없다
  return x; //함수에서 선언이 안 된 변수. 변수를 찾으러 가자 -> 전역변수를 찾는다
};

let result = get(2); //30 
  1. 함수에 매개 변수가 없으면 전역 변수 값을 불러온다
profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.

0개의 댓글