"클릭 이벤트의 정의에서 변수가 예상과 다른 값으로 동작하는 문제"에서 천천히 배우는 역할 체인과 엔클로저

7486 단어 jQueryJavaScript
Javascript에서 단추 동작을 부여할 때 값이 생각처럼 처리되지 않는 곳에 반합니다.평소에 다른 언어를 사용하는 관계는 잘 모르지만 찾아보니 자바스크립트의 작용역 체인, 폐쇄 규격과 관련이 있는 것 같습니다.처음엔 뜬금없었지만 왠지 잡힌 것 같아서 정리했어요.

무슨 문제


id는button0,button1,...........,버튼 4를 눌렀을 때 버튼 번호를 표시하려고 경고할 때의 상황입니다.아래와 같이 각 버튼에 등록된 이벤트는 값을 유지합니다.
(jQuery 사용을 단순화하기 위해)

테스트용 html


index.html
<html>
    <head>
        <title>ボタンテスト</title>
    </head>
    <body>
        <button id="button0">ボタン0</button>
        <button id="button1">ボタン1</button>
        <button id="button2">ボタン2</button>
        <button id="button3">ボタン3</button>
        <button id="button4">ボタン4</button>

        <script type="text/javascript" src="jquery.min.js"></script>
        <script type="text/javascript" src="script.js"></script>
    </body>
</html>

모르지만 열심히 쓴 JS.


script.js
for(i=0; i<5; i++){
    $("#button"+i).click(function() {
        alert(i);
    });
}

실행해 보다


이것을 실행해 봅시다.
먼저 버튼을 누르면 0...

왜요!거기 0이죠!
다시 정신을 차리고 버튼을 눌러 1...

Oh...
나는 이것이 우연이 아니라는 것을 깨닫고 원인을 탐색하기로 결정했다.

분석편


범위 체인


간단히 말하면, 이것은 역할 영역을 통합하고 끼워 넣는 이미지이다.여기서 기억해야 할 키워드는 전역 대상과 콜 대상이다.

글로벌 객체


스크립트를 실행할 때 내부적으로 생성된 대상입니다.이것은 전역 변수와 전역 함수를 관리하기 편리한 대상이며, 우리는 인코딩된 대상을 볼 수 없다.전역 대상은 변수나 함수를 속성으로 관리합니다.즉, 전역 변수를 정의하는 것은 전역 대상의 속성을 정의하는 것과 같다.

Call 객체란 무엇입니까?


활성 객체라고도 합니다.Call 객체는 함수가 호출될 때마다 내부적으로 생성되는 객체입니다.전역 대상과 마찬가지로 국부 변수를 관리하는 편리한 대상이기도 하다.

그러니까 이게 어떻게 된 거야?


역할 도메인 체인은 생성 순서에 따라 전역 객체와 Call 객체를 결합하는 목록입니다.중복 이름의 변수나 함수를 호출할 때 내부 (뒤에 정의된) 에서 호출합니다.
그림에서 보면 이런 느낌이다.변수와 함수가 모든 대상의 속성이라고 생각하시기 바랍니다.

앞의 예시에서 클릭 이벤트에 등록된 무명 함수 콜 대상에 변수 i 가 존재하지 않기 때문에 for문장 초기화에 정의된 전역 대상 속성, 즉 전역 변수 i 를 참조합니다.단추 중 하나를 눌렀을 때, 모든 단추에 이벤트를 할당했을 것입니다.즉, i 순환을 통과할 때의 값으로 5.응, 어려워.다른 언어의 규격자에게 함수 단위로 대상을 관리하는 것은 조화롭지 못하겠지.

해결편


역할 도메인 체인의 사양에 따라


방금 전의 규격을 학습함으로써 우리는 모든 단추가 같은 변수i를 참조한 것을 발견하였다.똑똑한 사람은 이곳에서 해결책을 생각해 낼 것이다.네, 반복적으로 호출되는 이벤트 로그인 방법을 함수로 묶으면 됩니다.이것은 묶는 함수에 이름이 하나 있다.그게 벽장이야.

폐쇄


엔클로저는 국부 변수를 보존하기 때문에 엔클로저는 함수에 끼워 넣은 함수입니다.일반 함수에 사용되는 국부 변수는 함수 처리가 끝날 때 폐기됩니다.그러나 내부 함수(폐쇄 함수)가 국부 변수를 인용했기 때문에 포기할 수 없다.즉, 값을 유지해야 한다는 것이다.

폐쇄 함수 제작 방법


폐쇄에 대해 지루한 설명을 하였는데, 어쨌든 어떻게 하였는가!그런 거지?제작 방법은 다음과 같다.
  • 함수에서 함수 만들기
  • 외부 함수로 변수 정의
  • 안쪽에서 함수 2.에 정의된 변수
  • 개선된 스크립트


    상기 내용에 근거하여 우리는 방금 전의 코드를 다시 한 번 쓰자.
    이렇게 하면 동작을 잘 할 수 있을 것이다.
    script.js(예상과 같은 녀석)
    for(i=0; i<5; i++){
        (function() {
            var num = i;
            $("#button"+num).click(function() {
                alert(num);
            });
        })();
    }
    
    

    실행해 보다


    당장 실행해 보세요.
    먼저 버튼을 누르면 0...흥분

    너무 좋아!!아니 5!!0 나왔어!!
    하지만 우연의 가능성을 고려해 버튼 1을 눌러보자.

    이거 잘 되고 있어!

    총결산


    이번에는 다음과 같은 주제를 제시했다.
  • 역할 영역 체인
  • 폐쇄
  • 나 혼자 공부하고 있는데 잘 썼는지 모르겠다.조사해 보니 개인적으로 이런 일이라고 생각하는 것을 총결하였다.더 열심히 공부하고 싶은 사람은 참고서를 읽어보세요!

    참고 자료

  • 산전상관(2010) 《자바스크립트 정식 입문~현대풍의 기초부터 아약스·jQuery》 기술평론사.
  • javascript-for 문장에서 클릭을 정의할 때의 행동 - 스택 넘침
  • 좋은 웹페이지 즐겨찾기