>  기사  >  웹 프론트엔드  >  자바스크립트의 클로저란 무엇인가요?

자바스크립트의 클로저란 무엇인가요?

青灯夜游
青灯夜游원래의
2021-10-18 11:59:222161검색

JavaScript에서 두 함수가 서로 중첩되면 내부 함수가 클로저입니다. 클로저는 다른 함수의 범위에 있는 변수에 액세스할 수 있는 함수입니다. 클로저를 만드는 가장 일반적인 방법은 함수 내에 다른 함수를 만들고 다른 함수를 통해 이 함수의 지역 변수에 액세스하는 것입니다.

자바스크립트의 클로저란 무엇인가요?

이 튜토리얼의 운영 환경: Windows 7 시스템, JavaScript 버전 1.8.5, Dell G3 컴퓨터.

1. 클로저란?

클로저는 다른 함수의 내부 변수를 읽을 수 있는 함수입니다. JavaScript에서는 함수 내부의 하위 함수만 지역 변수를 읽을 수 있으므로 클로저는 "함수 내부에 정의된 함수"로 이해될 수 있습니다. 본질적으로 클로저는 함수 내부와 함수 외부를 연결하는 다리입니다. (클로저의 가장 일반적인 적용은 콜백 함수를 구현하는 것입니다).

2. JS 클로저의 장점, 단점 및 특징

장점:

1. 함수 내 변수의 안전성 보호

2. 메모리에 변수 유지(사용하면 변경됨) 3. 로직 연속성. 클로저를 다른 함수 호출의 매개변수로 사용하면 현재 로직에서 벗어나 별도의 로직을 작성하는 것을 방지할 수 있습니다.

4. 호출 컨텍스트를 용이하게 하는 지역 변수.

5. 캡슐화를 강화하면 변수 보호를 달성할 수 있습니다.

단점: 1. 상주 메모리로 인해 메모리 사용량이 늘어나고, 부적절한 사용으로 인해 메모리 누수가 쉽게 발생할 수 있습니다.

2. 매우 심각한 문제도 있는데 바로 메모리 낭비 문제입니다. 이러한 메모리 낭비는 메모리에 상주하기 때문일 뿐만 아니라 더 중요한 것은 클로저를 잘못 사용하면 잘못된 메모리가 생성된다는 것입니다.


기능: 1. 함수 중첩 함수

2. 내부 함수는 외부 함수의 변수에 액세스할 수 있습니다.

3. 매개변수와 변수는 재활용되지 않습니다.

3. 가변 범위

클로저를 이해하려면 위의 클로저 개념만 이해하는 것만으로는 충분하지 않습니다. 먼저, 자바스크립트의 특수 변수 범위를 이해해야 합니다.

1. 변수에는 전역 변수와 지역 변수의 두 가지 범위만 있습니다.

2. JavaScript 언어의 특별한 점은 전역 변수는 함수 내부에서 직접 읽을 수 있지만 함수 내부의 지역 변수는 함수 외부에서 읽을 수 없다는 것입니다.

3. 참고: 함수 내에서 변수를 선언할 때는 반드시 var 명령을 사용하세요. 사용하지 않으면 실제로 전역 변수를 선언하는 것입니다!

4. 코드로 클로저 해석하기

자바스크립트에서 클로저를 생성하는 과정은 다음 프로그램과 같습니다.

function a () {
   var i = 0;
   function b () {
      alert (i++);
   }
  return b;
}
var c = a();
c();  //函数调用

코드 기능이 코드에는 두 가지 기능이 있습니다.

1. 함수 b는 함수 a 내에 중첩되어 있습니다.

2. 함수 a는 함수 b를 반환합니다.

이렇게 하면 var c = a()를 실행한 후 변수 c는 실제로 함수 b를 가리킵니다. c()를 다시 실행하면 i의 값을 표시하는 창이 팝업됩니다(처음에는 1입니다). 함수 a 외부의 변수 c가 함수 a 내부의 함수 b를 참조하기 때문에 이 코드는 실제로 클로저를 생성합니다. 즉, 함수 a 내부의 함수 b가 함수 a 외부의 변수에 의해 참조되면 클로저가 생성됩니다.

Function간단히 말해서, 클로저의 기능은 a가 실행되고 반환된 후 Javascript의 가비지 수집 메커니즘이 a가 점유한 리소스를 회수하는 것을 방지하는 것입니다. 왜냐하면 a의 내부 함수 b가 의 실행은 a의 변수에 따라 달라집니다.

위의 예에서 클로저의 존재로 인해 a의 i는 함수 a가 반환된 후에 항상 존재하게 됩니다. 이런 식으로 c()가 실행될 때마다 i는 1을 더한 후 경고되는 i 값이 됩니다. .

그럼 a가 함수 b가 아닌 다른 것을 반환한다면 상황은 완전히 달라집니다. 왜냐하면 a가 실행된 후 b는 a의 외부 세계로 반환되지 않고 a에 의해서만 참조되기 때문입니다. 이때 a는 b에 의해서만 참조됩니다. 따라서 함수 a와 b는 서로를 참조하지만 방해받지 않습니다. 외부 세계에서 참조됨), 함수 a 및 b가 재활용됩니다.

응용 시나리오1. 함수 내의 변수를 보호합니다. 함수 a에서 i는 함수 b를 통해서만 접근할 수 있고 다른 수단으로는 접근할 수 없으므로 i의 보안이 보호됩니다.

2. 메모리에 변수를 유지합니다. 클로저로 인해 함수 a의 i는 항상 메모리에 존재하므로 c()가 실행될 때마다 i가 1씩 증가합니다.

五、如何从外部读取函数内部的局部变量?

  出于种种原因,我们有时候需要获取到函数内部的局部变量。但是,上面(三、变量作用域)已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。那就是在函数内部,再定义一个函数。

function demo1 () {
    var n = 6699;
    function demo2 () {
      alert(n); // 6699
    }
  }

在上面的代码中,函数 demo2 就被包括在函数demo1内部,这时demo1内部的所有局部变量,对demo2都是可见的。但是反过来就不行,demo2内部的局部变量,对demo1就是不可见的。 

这就是Javascript语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。 

既然demo2可以读取demo1中的局部变量,那么只要把demo2作为返回值,我们不就可以在demo1外部读取它的内部变量了吗!

六、闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在demo1调用后被自动清除。 

那为什么会这样呢?原因就在于demo1是demo2的父函数,而demo2被赋给了一个全局变量,这导致demo2始终在内存中,而demo2的存在依赖于demo1,因此demo1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

七、使用闭包的注意点

1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 

2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

八、总结:

1、闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。 

2、不适合场景:返回闭包的函数是个非常大的函数。 

    闭包的典型框架应该就是jquery了。 

    闭包是javascript语言的一大特点,主要应用闭包场合主要是为了:设计私有的方法和变量。 

    这在做框架的时候体现更明显,有些方法和属性只是运算逻辑过程中的使用的,不想让外部修改这些属性,因此就可以设计一个闭包来只提供方法获取。 

3、 不必纠结到底怎样才算闭包,其实你写的每一个函数都算作闭包,即使是全局函数,你访问函数外部的全局变量时,就是闭包
的体现。

更多编程相关知识,请访问:编程入门!!

위 내용은 자바스크립트의 클로저란 무엇인가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.