웹 프론트엔드 JS 튜토리얼 JavaScript 클로저 개념에 대한 이해 심화

JavaScript 클로저 개념에 대한 이해 심화

Nov 28, 2016 pm 03:16 PM
javascript

인터넷에서 JavaScript 클로저에 대한 많은 정보를 확인해 보았는데, 대부분 매우 학술적이고 전문적인 내용이었습니다. 초보자의 경우 클로저에 대한 이해는커녕 텍스트 설명조차 이해하기 어렵습니다. 이 글을 쓰는 목적은 가장 널리 사용되는 단어를 사용하여 JavaScript 클로저의 진정한 모습을 드러내는 것입니다.

1. 폐쇄란 무엇인가요?

"공식적인" 설명은 다음과 같습니다. 클로저는 많은 변수와 이러한 변수에 바인딩된 환경을 포함하는 표현식(일반적으로 함수)이므로 이러한 변수도 표현식의 일부입니다. 나는 그의 설명이 너무 학문적이기 때문에 이 문장을 직접적으로 이해할 수 있는 사람은 거의 없다고 생각합니다. 사실, 일반인의 관점에서 이 문장은 다음을 의미합니다. JavaScript의 모든 함수는 클로저입니다. 그러나 일반적으로 말하면 중첩된 함수에 의해 생성된 클로저가 더 강력합니다. 이를 우리는 대부분 "클로저"라고 부릅니다. 다음 코드를 살펴보세요.

function a() {
    var i = 0;
    function b() {
        alert(++i);
    }
    return b;
}
var c = a();
c();
로그인 후 복사

이 코드에는 두 가지 특징이 있습니다.

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

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

이런 식으로 var c=a()를 실행하면 변수 c는 실제로 b 함수를 가리킵니다. c()를 실행하면 변수 i가 b에 사용됩니다. i.(처음은 1입니다.) 이 코드는 실제로 클로저를 생성합니다. 이유는 무엇입니까? 함수 a 외부의 변수 c는 함수 a 내의 함수 b를 참조하기 때문에, 즉 함수 a의 내부 함수 b가 함수 a 외부의 변수에 의해 참조될 때 소위 "클로저"가 생성됩니다.

더 철저하게 합시다. 소위 "클로저"는 생성자 본문에 있는 다른 함수를 대상 개체의 메서드 함수로 정의하고, 이 개체의 메서드 함수는 차례로 외부 함수 본문에 있는 임시 변수를 참조하는 것입니다. 이를 통해 대상 개체가 수명 동안 항상 메서드를 유지할 수 있는 한 원래 생성자 본문에서 사용된 임시 변수 값을 간접적으로 유지할 수 있습니다. 초기 생성자 호출이 종료되고 임시변수의 이름은 사라졌지만, 변수의 값은 항상 대상 객체의 메소드 내에서 참조할 수 있으며, 이 메소드를 통해서만 값에 접근할 수 있다. 동일한 생성자를 다시 호출하더라도 새 개체와 메서드만 생성되며 새 임시 변수는 마지막 호출과 독립적인 새 값에만 해당합니다.

클로저에 대해 더 깊이 이해하기 위해 클로저의 기능과 효과를 계속해서 살펴보겠습니다.

2. 폐쇄의 기능과 효과는 무엇인가요?

요컨대 클로저의 기능은 a가 실행되고 반환된 후 a의 내부 함수 b의 실행으로 인해 a가 점유한 리소스를 회수하는 Javascript의 가비지 수집 메커니즘 GC를 방지하는 것입니다. a의 변수에 의존합니다. 이것은 클로저의 역할에 대한 매우 간단한 설명입니다. 전문적이거나 엄격하지는 않지만 확실히 이해할 수 있습니다. 클로저를 이해하려면 단계별 프로세스가 필요합니다.

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

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

3. 클로저의 미시적 세계

클로저와 함수 a와 중첩 함수 b의 관계를 더 깊이 이해하려면 몇 가지 다른 개념을 소개해야 합니다. 함수 환경(실행 컨텍스트), 활성 개체(호출 개체), 범위(scope), 범위 체인(scope chain). 이러한 개념을 설명하기 위해 정의부터 실행까지 함수 a의 프로세스를 예로 들어 보겠습니다.

함수 a를 정의할 때 js 인터프리터는 함수 a의 범위 체인을 a가 정의된 "환경"으로 설정합니다. a가 전역 함수인 경우 범위 체인에는 window 개체만 있습니다. 그것.

함수 a를 실행할 때 a는 해당 실행 컨텍스트로 들어갑니다.

실행 환경을 생성하는 과정에서 먼저 a, 즉 a의 범위에 범위 속성이 추가되며 해당 값은 1단계의 범위 체인입니다. 즉, a.scope=a의 범위 체인입니다.

그런 다음 실행 환경은 호출 개체를 생성합니다. 활성 객체도 속성은 있지만 프로토타입이 없고 JavaScript 코드에서 직접 액세스할 수 없는 객체입니다. 활성 개체를 만든 후 범위 체인의 맨 위에 활성 개체를 추가합니다. 이때 a의 범위 체인에는 a의 활성 개체와 창 개체라는 두 개체가 포함됩니다.

다음 단계는 함수 a를 호출할 때 전달된 매개변수를 보유하는 활성 객체에 인수 속성을 추가하는 것입니다.

最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。

到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。

当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象

当在函数b中访问一个变量的时候,搜索顺序是:

先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。

如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。

如果整个作用域链上都无法找到,则返回undefined。

小结,本段中提到了两个重要的词语:函数的定义与执行。文中提到函数的作用域是在定义函数时候就已经确定,而不是在执行的时候确定(参看步骤1和3)。用一段代码来说明这个问题:

function f(x) {
    var g = function () { return x; }
    return g;
}
var h = f(1);
alert(h());
로그인 후 복사

这段代码中变量h指向了f中的那个匿名函数(由g返回)。

假设函数h的作用域是在执行alert(h())确定的,那么此时h的作用域链是:h的活动对象->alert的活动对象->window对象。

假设函数h的作用域是在定义时确定的,就是说h指向的那个匿名函数在定义的时候就已经确定了作用域。那么在执行的时候,h的作用域链为:h的活动对象->f的活动对象->window对象。

如果第一种假设成立,那输出值就是undefined;如果第二种假设成立,输出值则为1。运行结果证明了第2个假设是正确的,说明函数的作用域确实是在定义这个函数的时候就已经确定了。

4. 闭包的应用场景

保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。

在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。

function Constructor(...) {
    var that = this;
    var membername = value;
    function membername(...) {...}
}
로그인 후 복사

以上3点是闭包最基本的应用场景,很多经典案例都源于此。

5. JavaScript的垃圾回收机制

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

6. 结语

理解JavaScript的闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。


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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 Dec 17, 2023 pm 02:54 PM

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 Dec 17, 2023 pm 05:30 PM

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 Dec 17, 2023 pm 12:09 PM

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 Dec 17, 2023 am 09:39 AM

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript와 WebSocket: 효율적인 실시간 일기예보 시스템 구축 JavaScript와 WebSocket: 효율적인 실시간 일기예보 시스템 구축 Dec 17, 2023 pm 05:13 PM

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 Jan 05, 2024 pm 06:08 PM

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

자바스크립트에서 insertBefore를 사용하는 방법 자바스크립트에서 insertBefore를 사용하는 방법 Nov 24, 2023 am 11:56 AM

사용법: JavaScript에서 insertBefore() 메서드는 DOM 트리에 새 노드를 삽입하는 데 사용됩니다. 이 방법에는 삽입할 새 노드와 참조 노드(즉, 새 노드가 삽입될 노드)라는 두 가지 매개 변수가 필요합니다.

JavaScript 및 WebSocket: 효율적인 실시간 이미지 처리 시스템 구축 JavaScript 및 WebSocket: 효율적인 실시간 이미지 처리 시스템 구축 Dec 17, 2023 am 08:41 AM

JavaScript는 웹 개발에 널리 사용되는 프로그래밍 언어인 반면 WebSocket은 실시간 통신에 사용되는 네트워크 프로토콜입니다. 두 가지의 강력한 기능을 결합하면 효율적인 실시간 영상 처리 시스템을 만들 수 있습니다. 이 기사에서는 JavaScript와 WebSocket을 사용하여 이 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 첫째, 실시간 영상처리 시스템의 요구사항과 목표를 명확히 할 필요가 있다. 실시간 이미지 데이터를 수집할 수 있는 카메라 장치가 있다고 가정해 보겠습니다.

See all articles