웹 프론트엔드 JS 튜토리얼 자바스크립트 클로저(Closure) 사용예제_자바스크립트 스킬에 대한 간략한 분석

자바스크립트 클로저(Closure) 사용예제_자바스크립트 스킬에 대한 간략한 분석

May 16, 2016 pm 03:29 PM
javascript 폐쇄

본 글의 예시에서는 자바스크립트 클로저(Closure) 사용법을 설명하고 있습니다. 참고하실 수 있도록 모든 사람과 공유하세요. 자세한 내용은 다음과 같습니다.

폐쇄는 '폐쇄'로 번역되는데, 이건 너무 학문적으로 포장된 것 같은 느낌이 듭니다. 책과 온라인 자료를 참고하여 간략히 살펴보겠습니다. (부적절하게 이해한 부분은 주의해 주시기 바랍니다.)

1. 폐쇄란 무엇인가

공식 답변: 소위 "클로저"는 많은 변수와 이러한 변수에 바인딩된 환경이 있는 표현식(일반적으로 함수)을 의미하므로 이러한 변수도 표현식의 일부입니다.

위의 정의를 읽고 나면 전문가가 아닌 경우 저처럼 화를 내며 이렇게 물을 것이라고 굳게 믿습니다. 이것이 tmd 인간의 언어인가요?
클로저를 이해하려면 코드가 가장 설득력이 있습니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

function funcTest()

{

 var tmpNum=100; //私有变量

 //在函数funcTest内定义另外的函数作为funcTest的方法函数

 function innerFuncTest(

 {

    alert(tmpNum); //引用外层函数funcTest的临时变量tmpNum

 }

 return innerFuncTest; //返回内部函数

}

//调用函数

var myFuncTest=funcTest();

myFuncTest();//弹出100

로그인 후 복사

위 코드에서는 댓글이 명확하게 작성되었습니다. 이제 우리는 "클로저"를 다음과 같이 이해할 수 있습니다. 함수 본문의 다른 함수를 대상 개체의 메서드 함수로 정의하고(예제에서는 함수 funcTest 내에서 funcTest의 메서드 함수로 다른 함수 innerFuncTest를 정의합니다), 메서드 함수 이 개체의 반대입니다. 외부 함수 본문에서 임시 변수를 참조하십시오(클로저는 변수 값을 간접적으로 유지하는 메커니즘입니다. 예제에서 내부 함수 innerFuncTest는 외부 함수 funcTest의 임시 변수 tmpNum을 참조합니다. 여기서는 임시 변수가 선언된 모든 지역 변수, 매개변수 및 기타 선언된 내부 함수에 포함될 수 있다는 점에 유의해야 합니다. 이러한 내부 함수 중 하나가 이를 포함하는 외부 함수 외부에서 호출되면 클로저가 형성됩니다(예제에서 함수를 호출할 때 myFuncTest는 실제로 innerFuncTest 함수를 호출합니다. 이는 funcTest의 내부 함수인 innerFuncTest가 외부에서 호출된다는 의미입니다) funcTest, 클로저가 생성됩니다).

2. 클로저 사용의 두 가지 예

여기 두 가지 예가 있습니다. 하나는 클로저가 문제를 일으키기 때문이고, 다른 하나는 클로저를 사용하여 함수 범위를 통해 매개변수를 교묘하게 바인딩하기 때문입니다.

이 두 가지 예와 관련된 HTML 마크업 조각은 다음과 같습니다.

1

2

3

4

<a href="#" id="closureTest0">利用闭包的例子(1秒后会看到提示)</a><br />

<a href="#" id="closureTest1">由于闭包导致问题的例子1</a><br />

<a href="#" id="closureTest2">由于闭包导致问题的例子2</a><br />

<a href="#" id="closureTest3">由于闭包导致问题的例子3</a><br />

로그인 후 복사

(1) 폐쇄로 인한 문제

위의 HTML 태그 조각에는 4개의 요소가 있습니다. 이제 사용자가 클릭할 때 페이지에 순서가 보고되도록 마지막 3개에 이벤트 핸들러를 할당해야 합니다. 두 번째 링크에 연결하면 "첫 번째 링크를 클릭했습니다"라고 보고됩니다. 이를 위해 마지막 세 링크에 대한 이벤트 핸들러를 추가하는 다음 함수를 작성하면 됩니다.

1

2

3

4

5

6

7

8

function badClosureExample(){

  for (var i = 1; i <4; i++) {

    var element = document.getElementById('closureTest' + i);

    element .onclick = function(){

      alert('您单击的是第' + i + '个链接');

    }

  }

}

로그인 후 복사

그런 다음 페이지가 로드된 후 이 함수를 호출하세요. 그렇지 않으면 오류가 보고될 수 있습니다.

1

2

3

window.onload = function(){

  badClosureExample();

}

로그인 후 복사

실행 결과를 보면 마지막 세 개의 링크를 클릭하면 경고 상자에 어떤 정보가 표시되나요? ——모두 "네 번째 링크를 클릭했습니다"입니다. 당신을 놀라게 합니까? 왜?

분석: badClosureExample() 함수에서 element.onclick에 할당된 이벤트 핸들러, 즉 onclick 익명 함수는 badClosureExample() 함수가 완료된 후에(사용자가 링크를 클릭할 때) 호출되기 때문입니다. 호출할 때 변수 i를 평가해야 합니다. 파서는 먼저 이벤트 핸들러 내부를 검색하지만 i는 정의되지 않습니다. 그런 다음 badClosureExample() 함수에서 검색합니다. 이때 정의되지만 i의 값은 4입니다(for 루프는 i가 4보다 큰 경우에만 실행을 중지합니다). 따라서 해당 값을 얻습니다. 즉, 외부 함수(badClosureExample)의 범위에서 변수를 사용하는 경우 클로저(익명 함수)가 수행하는 작업과 정확히 같습니다. 게다가 이는 익명 함수 자체가 매개변수를 전달할 수 없기 때문에 발생합니다(따라서 자체 범위를 유지할 수 없음).

그렇다면 이 예에서 문제를 어떻게 해결해야 할까요? 실제로 방법은 많습니다(직접 작성해 보는 것이 나을 수도 있습니다). 코드가 비교적 간단하고 직접적이라고 생각합니다.

1

2

3

4

5

6

7

8

9

10

11

function popNum(oNum){

  return function(){

          alert('您单击的是第'+oNum+'个链接');

  }

}

function badClosureExample(){

  for (var i = 1; i <4; i++) {

    var element = document.getElementById('closureTest' + i);

    element .onclick =new popNum(i);

    }

}

로그인 후 복사

(2) 클로저를 영리하게 사용하여 매개변수 바인딩

여전히 위의 HTML 조각을 사용하여 사용자가 첫 번째 링크를 클릭할 때 경고 상자 팝업을 지연시키려고 합니다. 어떻게 해야 할까요? 대답은 다음과 같이 지정된 밀리초 후에 함수를 호출하는 setTimeout() 함수를 사용하는 것입니다.

코드 복사 코드는 다음과 같습니다.
setTimeout(someFunc,1000);
하지만 문제는 someFunc 함수에 매개변수를 전달할 수 없다는 것입니다. 이 문제는 클로저를 사용하여 쉽게 해결할 수 있습니다.

1

2

3

4

5

function goodClosureExample(oMsg){

  return function(){

    alert(oMsg);

  };

}

로그인 후 복사
goodClosureExample 함수는 익명 함수(클로저)를 반환하는 데 사용됩니다. 그리고 반환된 익명 함수에 다음과 같은 매개변수를 전달하여 매개변수를 바인딩하도록 할 수 있습니다.


코드 복사 코드는 다음과 같습니다.
var good = goodClosureExample('이 매개변수는 클로저를 통해 바인딩됩니다.') ;

而此时,就可以将绑定了参数的good函数传递给setTimeout()实现延时警告了:
复制代码 代码如下:
setTimeout(good,1000) //此时good中已经绑定了参数

最后,测试通过的完整代码:

1

2

3

4

5

6

7

8

9

window.onload = function(){

  var element = document.getElementById('closureTest0');

  if (element) {

    var good = goodClosureExample('这个参数是由闭包绑定的');

    element.onclick = function(){

      setTimeout(good, 1000); //延迟1秒弹出提示

    }

  }

}

로그인 후 복사

3、javascript的垃圾回收原理

(1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;

(2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

在js中使用闭包,往往会给javascript的垃圾回收器制造难题。尤其是遇到对象间复杂的循环引用时,垃圾回收的判断逻辑非常复杂,搞不好就有内存泄漏的危险,所以,慎用闭包。ms貌似已经不建议使用闭包了。

希望本文所述对大家JavaScript程序设计有所帮助。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

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

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

C++ 람다 표현식에서 클로저의 의미는 무엇입니까? C++ 람다 표현식에서 클로저의 의미는 무엇입니까? Apr 17, 2024 pm 06:15 PM

C++에서 클로저는 외부 변수에 액세스할 수 있는 람다 식입니다. 클로저를 생성하려면 람다 표현식에서 외부 변수를 캡처하세요. 클로저는 재사용성, 정보 숨기기, 지연 평가와 같은 이점을 제공합니다. 이는 클로저가 외부 변수가 파괴되더라도 여전히 접근할 수 있는 이벤트 핸들러와 같은 실제 상황에서 유용합니다.

C++ 람다 표현식에서 클로저를 구현하는 방법은 무엇입니까? C++ 람다 표현식에서 클로저를 구현하는 방법은 무엇입니까? Jun 01, 2024 pm 05:50 PM

C++ Lambda 표현식은 함수 범위 변수를 저장하고 함수에 액세스할 수 있도록 하는 클로저를 지원합니다. 구문은 [캡처 목록](매개변수)->return-type{function-body}입니다. 캡처 목록은 캡처할 변수를 정의합니다. [=]를 사용하여 모든 지역 변수를 값으로 캡처하고, [&]를 사용하여 모든 지역 변수를 참조로 캡처하거나, [변수1, 변수2,...]를 사용하여 특정 변수를 캡처할 수 있습니다. 람다 표현식은 캡처된 변수에만 액세스할 수 있지만 원래 값을 수정할 수는 없습니다.

C++ 함수에서 클로저의 장점과 단점은 무엇입니까? C++ 함수에서 클로저의 장점과 단점은 무엇입니까? Apr 25, 2024 pm 01:33 PM

클로저는 외부 함수의 범위에 있는 변수에 액세스할 수 있는 중첩 함수입니다. 클로저의 장점에는 데이터 캡슐화, 상태 보존 및 유연성이 포함됩니다. 단점으로는 메모리 소비, 성능 영향, 디버깅 복잡성 등이 있습니다. 또한 클로저는 익명 함수를 생성하고 이를 콜백이나 인수로 다른 함수에 전달할 수 있습니다.

클로저로 인한 메모리 누수 문제 해결 클로저로 인한 메모리 누수 문제 해결 Feb 18, 2024 pm 03:20 PM

제목: 클로저로 인한 메모리 누수 및 솔루션 소개: 클로저는 내부 함수가 외부 함수의 변수에 액세스할 수 있도록 하는 JavaScript에서 매우 일반적인 개념입니다. 그러나 클로저를 잘못 사용하면 메모리 누수가 발생할 수 있습니다. 이 문서에서는 클로저로 인해 발생하는 메모리 누수 문제를 살펴보고 솔루션과 구체적인 코드 예제를 제공합니다. 1. 클로저로 인한 메모리 누수 클로저의 특징은 내부 함수가 외부 함수의 변수에 접근할 수 있다는 것입니다. 즉, 클로저에서 참조되는 변수는 가비지 수집되지 않습니다. 부적절하게 사용하는 경우,

함수 포인터와 클로저가 Golang 성능에 미치는 영향 함수 포인터와 클로저가 Golang 성능에 미치는 영향 Apr 15, 2024 am 10:36 AM

함수 포인터와 클로저가 Go 성능에 미치는 영향은 다음과 같습니다. 함수 포인터: 직접 호출보다 약간 느리지만 가독성과 재사용성이 향상됩니다. 클로저: 일반적으로 느리지만 데이터와 동작을 캡슐화합니다. 실제 사례: 함수 포인터는 정렬 알고리즘을 최적화할 수 있고 클로저는 이벤트 핸들러를 생성할 수 있지만 성능 저하를 가져옵니다.

Java에서는 클로저가 어떻게 구현됩니까? Java에서는 클로저가 어떻게 구현됩니까? May 03, 2024 pm 12:48 PM

Java의 클로저를 사용하면 외부 함수가 종료된 경우에도 내부 함수가 외부 범위 변수에 액세스할 수 있습니다. 익명의 내부 클래스를 통해 구현된 내부 클래스는 외부 클래스에 대한 참조를 보유하고 외부 변수를 활성 상태로 유지합니다. 클로저는 코드 유연성을 높이지만 익명 내부 클래스에 의한 외부 변수 참조는 해당 변수를 활성 상태로 유지하므로 메모리 누수의 위험을 인지해야 합니다.

PHP 함수의 연쇄 호출 및 폐쇄 PHP 함수의 연쇄 호출 및 폐쇄 Apr 13, 2024 am 11:18 AM

예, 체인 호출 및 클로저를 통해 코드 단순성과 가독성을 최적화할 수 있습니다. 체인 호출은 함수 호출을 유창한 인터페이스에 연결합니다. 클로저는 재사용 가능한 코드 블록을 생성하고 함수 외부의 변수에 액세스합니다.

테스트에서 golang 함수 클로저의 역할 테스트에서 golang 함수 클로저의 역할 Apr 24, 2024 am 08:54 AM

Go 언어 함수 클로저는 단위 테스트에서 중요한 역할을 합니다. 값 캡처: 클로저는 외부 범위의 변수에 액세스할 수 있으므로 테스트 매개변수를 캡처하고 중첩된 함수에서 재사용할 수 있습니다. 테스트 코드 단순화: 클로저는 값을 캡처함으로써 각 루프에 대해 매개변수를 반복적으로 설정할 필요가 없으므로 테스트 코드를 단순화합니다. 가독성 향상: 클로저를 사용하여 테스트 로직을 구성하고 테스트 코드를 더 명확하고 읽기 쉽게 만듭니다.

See all articles