내용으로 건너뛰기
JavaScript에서 클로저란 무엇입니까?

JavaScript에서 클로저란 무엇입니까?

JavaScript 클로저는 생성된 환경을 기억하는 함수입니다. 하나의 메소드와 개인 변수가 있는 객체로 생각할 수 있습니다.

7min read

JavaScript 클로저는 클로저가 생성되었을 때 모든 변수(환경)와 함께 함수와 함수의 로컬 범위를 포함하는 특별한 종류의 객체입니다.

JavaScript 클로저는 생성된 환경을 기억하는 함수입니다

클로저를 이해하려면 먼저 JavaScript에서 SCOPING을 이해해야 합니다.  세 가지 수준의 범위 지정으로 변수 또는 함수를 만들 수 있습니다.

  1. Global scope
  2. 함수 또는 로컬 범위
  3. 어휘 범위

Scopes in JavaScript

변수를 생성하자마자 전역 범위에 있습니다. 따라서 어떤 함수 내부에도 없는 변수를 만들었다면 전역 범위에 있습니다.

var foo = "foo";
console.log(foo);

무언가가 글로벌 범위에 있다면 우리는 어디서든 접근할 수 있으며, 이는 우리의 친구이자 동시에 적입니다. 모든 것을 전역 범위에 넣는 것은 다른 문제들 사이에서 네임스페이스 충돌을 일으킬 수 있으므로 결코 좋은 생각이 아닙니다. 무언가가 전역 범위에 있으면 어디에서나 액세스할 수 있으며 함수에 동일한 이름의 변수가 있으면 충돌이 발생할 수 있습니다.

전역 범위 내에 있지 않은 모든 변수 또는 함수는 기능 또는 로컬 범위 내에 있습니다. 아래 목록을 고려하십시오.

function foo() {
  var doo = "doo";
  console.log(doo);
}

foo();

foo 함수의 함수 범위 내에 있는 변수 doo를 만들었습니다. 변수 doo 의 수명은 foo 함수에 로컬이며 해당 함수 외부에서는 액세스 할 수 없습니다. 이를 JavaScript에서는 로컬 범위 지정이라고 합니다.  아래 다이어그램과 같이 표시된 코드 목록을 고려해 보겠습니다.

다이어그램과 같이 표시된 코드 목록을 고려해 보겠습니다

여기서 우리는 전역 범위의 변수와 동일한 이름으로 foo 함수에 변수를 만들었으므로 이제 두 개의 변수가 있습니다. 우리는 이러한 변수가 각각의 수명을 가진 두 개의 다른 변수라는 것을 명심해야 합니다. 함수 외부에서는 값이 a 인 변수 doo 에 액세스 할 수 있지만 foo 함수 내부에는 vale doo 가있는 변수 doo 가 존재합니다. 참고로 위의 코드는 다음과 같습니다.

var doo = "a";
function foo() {
  var doo = "doo";
  console.log(doo); //print doo
}

foo();
console.log(doo); //print a

Let us tweak the above code snippet a bit as shown in listing below:

var doo = "a";
function foo() {
  doo = "doo";
  console.log(doo); //print doo
}

foo();
console.log(doo); //print doo

이제 변수 doo에 대한 두 개의 범위가 없습니다. foo 함수 내에서 전역 범위에서 생성된 변수 doo 가 수정되고 있습니다.  foo 내에서 변수 doo 를 다시 만드는 것이 아니라 전역 범위에서 기존 변수 doo 를 수정합니다.

foo 내에서 변수 doo를 다시 만드는 것이 아니라 전역 범위에서 기존 변수 doo를 수정합니다

로컬 또는 기능 범위에서 변수를 생성하는 동안 var 키워드를 사용하여 변수를 생성해야 합니다.  그렇지 않으면 변수가 전역 범위에서 생성되거나 변수가 전역 범위에 이미 있는 경우 수정됩니다.

JavaScript에서는 함수 내부에 함수를 가질 수 있습니다. 모든 수준의 중첩 함수가 있을 수 있으며, 이는 서로 내부에 중첩된 함수를 원하는 수만큼 가질 수 있음을 의미합니다.  아래 목록을 고려하십시오.

function foo() {
  var f = "foo";

  function doo() {
    console.log(f);
  }

  doo();
}

foo(); //print foo

본질적으로 위의 스 니펫에는 foo 함수 내부에 생성 된 doo 함수가 있으며 자체 변수가 없습니다. function foo 는 로컬 변수를 생성하며 function doo 내에서 액세스 할 수 있습니다. function doo 는 function foo 의 내부 함수이며 function foo 의 변수에 액세스 할 수 있습니다. 또한 function doo 는 foo 함수의 body 내에서 호출 할 수 있습니다. function doo는 parent 함수에 선언된 변수에 액세스할 수 있으며 이는 JavaScript의 어휘 범위 지정 때문입니다.

여기에는 두 가지 수준의 범위 지정이 있습니다.

  1. Parent function foo scope
  2. Child function doo scope
여기에는 두 가지 수준의 범위 지정이 있습니다

function doo 내에서 생성된 변수는 JavaScript의 Lexical Scoping으로 인해 foo 함수 의 범위 내에서 생성된 모든 항목에 액세스할 수 있습니다. 그러나 function foo 는 function doo 의 변수에 액세스 할 수 없습니다.

foo 함수는 doo 함수의 변수에 액세스할 수 없습니다.

Closures in JavaScript

예를 들어 JavaScript의 클로저에 대한 이해를 시작하겠습니다. 아래와 같이 목록을 고려하십시오. foo 함수의 body 내에서 doo 함수를 호출하는 대신, foo 함수에서 doo 함수를 반환합니다.

function foo() {
  var f = "foo";
  function doo() {
    console.log(f);
  }
  return doo;
}
var afunct = foo();
afunct();

 

위 목록에서:

  1. function foo 가 다른 function doo 를 반환합니다.
  2. function doo에는 자체 변수가 없습니다.
  3. 어휘 범위 지정으로 인해 function doo 는 부모 function foo 의 변수에 액세스 할 수 있습니다
  4. function foo 가 호출되어 afunct 변수에 할당됩니다.
  5. 그런 다음 afunct 가 함수로 호출되고 문자열 "foo" 가 인쇄됩니다
 function foo

놀랍게도 위 코드 조각의 출력은 문자열 "foo"입니다. 이제 우리는 혼란스러워 할 수 있습니다 : 변수 f 는 foo 함수 외부에서 어떻게 액세스됩니까? 일반적으로 함수 내의 로컬 변수는 해당 함수가 실행되는 동안만 존재합니다. 따라서 이상적으로는 foo 를 실행 한 후 변수 f 에 더 이상 액세스 할 수 없어야합니다. 그러나 JavaScript에서는 afunct가 JavaScript 클로저가 되었기 때문에 액세스 할 수 있습니다. closure afunct에는 function doo 와 afunct closure 생성 시점의 function doo 의 모든 로컬 범위 변수에 대한 정보가 있습니다.

클로저의 경우, inner 함수는 외부 function scope의 참조를 유지합니다. 그래서, 클로저에서 :

  • Inner 함수는 외부 함수 범위의 참조를 유지합니다. 이 경우 function doo는 function foo scope의 참조를 유지합니다.
  • function doo는 외부 function foo 가 실행을 완료하더라도 언제든지 function food scope reference 의 변수에 액세스 할 수 있습니다.
  • JavaScript는 내부 함수가 존재하고 이를 참조할 때까지 외부 함수(이 경우 foo)의 범위 참조와 해당 변수를 메모리에 유지합니다. 이 경우 foo 함수의 범위와 변수는 doo 함수가 존재할 때까지 JavaScript에 의해 메모리에 유지됩니다.

클로저를 더 잘 이해하기 위해 한 가지 예를 더 논의해 보겠습니다.

function add(num1) {
  function addintern(num2) {
    return num1 + num2;
  }

  return addintern;
}

var sum9 = add(7)(2);
console.log(sum9);
var sum99 = add(77)(22);
console.log(sum99);

여기에는 sum9 및 sum99라는 두 개의 클로저가 있습니다.

클로저 sum9 가 생성되었을 때 함수 addintern 의 로컬 범위에서 num1 의 값은 7이었고 JavaScript는 sum9 클로저를 생성하는 동안 해당 값을 기억합니다.

클로저 sum99 의 경우에도 동일하며, addintern 함수의 로컬 범위에서 num1 의 값은 7이고 JavaScript는 클로저 sum99 를 생성하는 동안 해당 값을 기억합니다.  예상대로 출력은 9와 99입니다.

클로저는 개인 변수와 하나의 메소드가 있는 객체로 생각할 수 있습니다. 클로저를 사용하면 해당 데이터에서 작동하는 함수로 데이터를 연결할 수 있습니다.  따라서 클로저는 다음과 같은 특성으로 정의할 수 있습니다.

  • It is an object
  • 여기에는 함수가 포함되어 있습니다.
  • 클로저가 생성되었을 때 function의 로컬 범위의 변수를 포함하여 함수와 관련된 데이터를 기억합니다
  • 클로저를 만들려면 함수가 다른 함수 참조를 반환해야 합니다

마지막으로 클로저를 정의할 수 있습니다.

"JavaScript Closure는 함수와 함수가 생성된 환경을 포함하는 특별한 종류의 객체입니다. 여기서 environment 는 클로저 생성 시점의 함수와 모든 변수의 로컬 범위를 나타냅니다.

결론

이 게시물에서는 JavaScript의 클로저에 대해 배웠습니다. 유용하게 사용되셨으면 합니다. 읽어 주셔서 감사합니다!

[2019년 3월 22일 업데이트]

데모 요청