2017-02-01 87 views
1

這裏是代碼:JavaScript的關閉和範圍

function fn() { 
 
    var x = 1; 
 

 
    function fn2() { 
 
    x++; 
 
    console.log(x); 
 
    } 
 
    return fn2; 
 
} 
 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //2 
 
foo(); //3

我得到了我想不通,爲什麼結果是不是2 3 4。我的意思是一個問題,根據關閉原則,foo和bar應該保持函數的範圍,所以我認爲foo和bar具有相同的x。希望你能幫我解決問題。

回答

1

foobar不共享相同的x。當調用fn時,x被創建。因此,每個致電fn的電話都將創建一個全新的x,可通過將返回的品牌定義功能fn2訪問。

要檢查foobar不共享相同的x,這裏有一個例子:

function fn() { 
 
    var x = 1; 
 

 
    function fn2() { 
 
    x++; 
 
    return x; 
 
    } 
 
    return fn2; 
 
} 
 
var foo = fn(); 
 
var bar = fn(); 
 
console.log("foo: " + foo()); 
 
console.log("bar: " + bar()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("bar: " + bar());

0

由於變種X創建一個私有變量,它重新每次FN創建() 被安排了。如果你想讓它結轉,只需更改變種x到this.x:

fn = (function() { 
 
    this.x = 1; 
 

 
    function fn2() { 
 
    this.x++; 
 
    console.log(this.x); 
 
    } 
 
    return fn2; 
 
}); 
 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //3 
 
foo(); //4

+0

我很困惑。這裏應該提到的是什麼?它將在嚴格模式下爲undefined,否則爲窗口對象。這與聲明全局'x'變量相同。另外,我想你的意思是「每次fn()'都被**調用**,而不是」賦值「 –

+0

'this.x'會使'x'全局,就好像'x'被定義在' fn'(全球),所以我們不再談論關閉了, –

+0

是的,我正在修補,意識到你是絕對正確的。 – Snowmonkey

1

您需要調用一次第一功能和過x建立閉合,然後返回一個函數用功能在裏面。

var fn = function() {   
 
    var x = 1; 
 
    return function() { 
 
     return function() { 
 
      x++; 
 
      console.log(x); 
 
     }; 
 
    }; 
 
}(); 
 

 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //3 
 
foo(); //4

0

這兩個是相同的呼叫,因此2當你調用它們:

var foo = fn(); 
var bar = fn(); 

兩個設置var x=1私人。因此,當您再次呼叫它們時foo(); //3內部函數fn2是用增量語句調用的函數