簡體   English   中英

JavaScript的關閉范圍

[英]Scope of closure in javascript

function f1(){
    var x = 5;    
    this.f2 = function(){
        var y = 10; 
        function helper(){
            //Do we have x here because of closure as we have y
        }
        setInterval(helper,100);
    }
}

我是JavaScript的初學者。 我正在做new f1()創建一個對象。 據我了解, helper可以通過閉包訪問y ,但是我觀察到x也可以在helper 誰能向我解釋為什么會這樣,直到閉包在JavaScript中起作用到什么程度。

您定義的每個變量將在整個函數范圍內可見。 如果希望x在輔助函數上不可見,我建議使用另一種方法:

var f1 = function () {
  var x = 5; //private variable within f1 scope
}

f1.prototype.f2 = function(){
  var y = 10; // private variable within f2 scope
  function helper(){
    // x is no longer available here
    setInterval(helper,100);
  }
}

由於函數JavaScript中的作用域規則而創建了閉包。 我要說的是,閉包的核心租戶是它們在執行后保持狀態事件,直到下次執行返回嵌套在其內部的某些代碼路徑時為止。

我認為讓您絆倒的是,它可以深入很多層次。 或者換句話說,您不必通過在函數內部嵌套另一個函數來限制其作用域。

x是在f1范圍內定義的變量。 然后,將this.f2定義為一個匿名函數,其作用域仍在f1內。 這意味着匿名函數可以訪問x,就像它可以訪問y一樣。 就像助手可以訪問y一樣。 這就是我向下嵌套的意思。

@masylum完美概述了如何將它們分開:不要在定義f2的同一函數中定義x。

所有這些的一個警告:“ this”可以更改,並且不會遵循所概述的相同模式。 “ this”或上下文對象是您所在的當前函數的一部分。因此f1的“ this”將不同於幫助程序內部的“ this”。 現在,分配給f2的匿名函數將是相同的,因為您已將其分配給f1的“ this”(ala this.f2 =)的上下文。

話雖如此,您可以通過使用閉包來解決該問題。 您將“ this”分配給新變量,然后可以在“ this”的位置使用該變量。 例如:

  function f3() {
    this.isDone = false;
    var that = this;
    function helper() {
      that.isDone = true;
    }
    setTimeout(helper, 100);
  }
  var obj = new f3();
  obj.isDone;  // Will return false.
  ... // Wait 100 ms and ask it again.
  obj.isDone;  // Should be true now.

我希望我與“ this”的切線不要過分。 但是,我知道它可能是很多痛苦的根源,因此如果您遇到麻煩,我想提出來。

請允許我介紹下一個陷阱。 考慮以下。

 for (var i = 0; i < 3; i++) {
    setTimeout(function() {
      alert(i);
    }, 100);
  }

如果運行該代碼,您將看到一條警告,顯示“ 3” 3次。 實際上,它不會進行1到3的計數。這是閉包的常見錯誤。 原因是因為您在setTimeout中調用回調之前一直執行for循環。 因此,當需要匿名函數解析我的身份時,每次都會發現它是3。

您可以在http://www.mennovanslooten.nl/blog/post/62https://developer.mozilla.org/en/JavaScript/Guide/Closures#Creating_closures_in_loops:_A_common_mistake中了解更多

x和y在helper()函數中均可見的原因是,通過使用var關鍵字使它們對於f1()內部的任何函數都是全局的。 如果您都定義了兩個不帶var關鍵字的變量,則它們在helper()函數中將不可見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM