찾다

 >  Q&A  >  본문

javascript - 클로저를 이해하고 있나요? 설명을 구하십시오.

으아악

이 이해가 맞는지 선배님들께 묻고 싶습니다.
보충: 클로저가 처음 실행되면 상위 레이어에서 변수를 검색해야 하고, 찾은 후에는 상위 레이어의 변수 값이 하위 함수의 변수 값이 되는 것으로 이해할 수 있나요? . 앞으로는 첫 번째 실행 시 상속되어 자신의 것이 되기 때문에 상위 레이어에서 검색할 필요가 없습니다.
조금 지저분한 느낌이에요. . .
(얼굴을 가리다

---------다시 추가했습니다---------
볼수록 , 더 혼란스러워집니다.
그럼 완전 엉망이었죠.
출력 결과로 판단하면 첫 번째 콘솔 출력과 마지막 콘솔 출력, f1의 n은 변경할 수 없습니다.
하지만 하위 함수는 서로 변수를 읽을 수 없나요? nAdd의 표현식이 f2의 n에 영향을 미치는 이유는 무엇입니까?

高洛峰高洛峰2780일 전490

모든 응답(4)나는 대답할 것이다

  • 某草草

    某草草2017-05-18 10:51:50

    으아악

    이때 결과의 b와 n은 동일하지 않습니다.
    nAdd의 b와 n은 동일합니다.
    n은 변경할 수 없습니다.

    회신하다
    0
  • PHP中文网

    PHP中文网2017-05-18 10:51:50

    에 같은 질문이 있어서 내 답변을 복사하고 일부를 추가했습니다.

    1. var result=f1(): f1 함수는 f2 함수를 반환합니다. var result=f1():f1函数返回了f2函数
      把返回的f2函数赋值给result全局变量,(f2的作用域链保存到result全局变量中)

    2. result():调用result(),这就形成闭包:有权访问另外一个函数作用域中的变量
      因为在f2中的作用域引用了f1中的n这个局部变量,当f1执行完毕后,垃圾回收机制发现n变量还在被result中引用所以垃圾回收机制不会把n回收释放。
      以至于n一直保存在result作用域链中。result的作用域链正常能访问f1中的局部变量n,形成闭包。

    3. nAdd():nAdd没有写var所以nAdd是全局变量,在调用nAdd()和result()是一样的都会形成闭包,匿名函数function(){n+=1}的作用域链中有n这个局部变量,所以当nAdd=funtion(){n+=1}时,这个匿名函数的作用域链保存到了全局变量nAdd形成闭包,调用nAdd()作用域链中找到f1局部变量n=999,n+1=1000。

    4. result() 반환된 f2 함수를 결과 전역 변수

      (f2의 스코프 체인은 결과 전역 변수에 저장됩니다)
    5. result(): 클로저를 형성하는 result() 호출:
    6. 다른 함수 범위의 변수에 액세스할 수 있는 권한이 있습니다

      # 🎜🎜 # f2의 범위는 f1의 지역 변수 n을 참조하기 때문에 f1이 실행될 때 가비지 수집 메커니즘은 n 변수가 결과에서 여전히 참조되고 있음을 발견하므로 가비지 수집 메커니즘은 n을 해제하지 않습니다.

      따라서 n은 항상 결과 범위 체인에 저장됩니다. 결과의 범위 체인은 일반적으로 f1의 지역 변수 n에 액세스하여 클로저를 형성할 수 있습니다.
    7. nAdd(): nAdd는 var를 작성하지 않으므로 nAdd는 전역 변수입니다. nAdd() 및 result()를 호출하면 클로저가 형성되고 익명 함수 function( ){n+=1}은 범위 체인에 로컬 변수 n을 가지므로 nAdd=funtion(){n+=1}일 때 이 익명 함수의 범위 체인은 전역 변수 nAdd에 저장되어 클로저 및 nAdd()는 범위 체인에서 f1 지역 변수 n=999, n+1=1000을 찾았습니다.

    result(): result()는 1000
    을 출력합니다.

    nAdd(); 세 번째 단계를 반복합니다. n+1 = 1001

    result(); 네 번째 단계를 반복하고 n#🎜🎜##🎜🎜#을 출력합니다. #🎜🎜##🎜🎜#f1(); f1이 호출될 때 클로저가 형성되지 않습니다. n은 항상 999입니다. n은 f1을 실행할 때마다 가비지 수집 메커니즘에 의해 삭제되므로 여기서 var n=이 다시 호출됩니다. ; 후속 출력도 999#🎜🎜##🎜🎜# #🎜🎜# #🎜🎜##🎜🎜#nAdd 표현식이 f2의 n에 영향을 미치는 이유는 무엇인가요? #🎜🎜##🎜🎜# 클로저 때문에 n은 한번도 소멸되지 않았습니다. nAdd()도 클로저를 형성하고 n의 값을 변경했기 때문에 나중에 result()가 다시 호출되어 n이 소멸되지 않았습니다. 재활용됩니다. +1이므로 영향을 받습니다. #🎜🎜# 마지막으로 f1()이 호출될 때 클로저가 없으며 n은 이전에 소멸되었습니다. 따라서 항상 a=999;#🎜🎜#을 출력합니다. #🎜🎜##🎜🎜# 그냥 제 이해입니다. 틀린 부분이 있으면 신고해주세요 #🎜🎜##🎜🎜#

    회신하다
    0
  • 黄舟

    黄舟2017-05-18 10:51:50

    이 글을 읽어보시길 권합니다
    http://www.ruanyifeng.com/blo...
    더 명확하게 설명되어 있습니다

    회신하다
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-18 10:51:50

    말하기 너무 복잡해요

    이 클로저는 이 효과를 얻기 위해 js의 정적 범위 기능을 사용합니다

    으아악

    result()에 대한 첫 번째 호출:

    alert(n)#을 찾고 있습니다.

    nAdd(); 추가되는 것도 n1

    의 값입니다.

    뒤쪽도 마찬가지

    그리고 마지막으로 f1();

    실행시 var n = 999; 에도 n1이 할당됩니다.

    console.log(n)의 n도 n1이므로 출력되는 값은 999입니다

    귀하의 예는 약간 간단합니다(정적 범위에 대한 설명에 중점을 둡니다).

    static 범위

    회신하다
    0
  • 취소회신하다