2016-03-25 41 views
-2

我正在做一個測試,var i在父函數和子函數循環中使用。在自己的循環中使用i的函數,以及子函數循環 - var的行爲如let?

這是我的代碼:

<html> 
 
\t <head> 
 
\t \t <script> 
 
\t \t \t var gArr = ['a', 'b', 'c']; 
 

 
\t \t \t function ix(a) { 
 
\t \t \t \t for (var i = 0; i < gArr.length; i++) { 
 
\t \t \t \t \t document.body.innerHTML += '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i from ix: ' + i; 
 
\t \t \t \t \t if (gArr[i] == a) { 
 
\t \t \t \t \t \t return a; 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t } 
 

 
\t \t \t function blah(newAdds) { 
 

 
\t \t \t \t for (var i = 0; i < newAdds.length; i++) { 
 
\t \t \t \t \t document.body.innerHTML += '<br>i from blah: ' + i; 
 
\t \t \t \t \t var cEntry = ix(newAdds[i]); 
 
\t \t \t \t \t document.body.innerHTML += '<br>&nbsp;&nbsp;i from blah post ix: ' + i; 
 
\t \t \t \t \t if (!cEntry) { 
 
\t \t \t \t \t \t gArr.push(newAdds[i]); 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 

 
\t \t \t } 
 

 
\t \t \t window.onload = blah.bind(null, ['d', 'e']); 
 
\t \t </script> 
 
\t </head> 
 
\t <body> 
 
\t </body> 
 
</html>

這段代碼的輸出是這樣的:

i from blah: 0 
    i from ix: 0 
    i from ix: 1 
    i from ix: 2 
    i from blah post ix: 0 
i from blah: 1 
    i from ix: 0 
    i from ix: 1 
    i from ix: 2 
    i from ix: 3 
    i from blah post ix: 1 

因爲函數ix還採用var i我期待的是,i from blah post ix將被覆蓋爲的最後i值這是3在上述情況下。但事實並非如此。

這是預期的行爲?我以爲let應該給我們這種行爲而不是var

+0

[RTFM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Variable_scope) – hindmost

+1

'var'變量限於它們的包含函數,因此兩個'i'在你的職責中是不同的。 – georg

+1

@statemost:[STFU](http://stackoverflow.com/help/be-nice);) – georg

回答

1

你重新聲明的var i

如果您在頂部一次聲明它,然後我覺得它確實你的意思(我認爲)

請參見下面的

<html> 
 
\t <head> 
 
\t \t <script> 
 
\t \t \t var gArr = ['a', 'b', 'c']; 
 
         var i; /* <-- declare it here */ 
 
\t \t \t function ix(a) { 
 
\t \t \t \t for (i = 0; i < gArr.length; i++) { 
 
\t \t \t \t \t document.body.innerHTML += '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i from ix: ' + i; 
 
\t \t \t \t \t if (gArr[i] == a) { 
 
\t \t \t \t \t \t return a; 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t } 
 

 
\t \t \t function blah(newAdds) { 
 

 
\t \t \t \t for (i = 0; i < newAdds.length; i++) { 
 
\t \t \t \t \t document.body.innerHTML += '<br>i from blah: ' + i; 
 
\t \t \t \t \t var cEntry = ix(newAdds[i]); 
 
\t \t \t \t \t document.body.innerHTML += '<br>&nbsp;&nbsp;i from blah post ix: ' + i; 
 
\t \t \t \t \t if (!cEntry) { 
 
\t \t \t \t \t \t gArr.push(newAdds[i]); 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 

 
\t \t \t } 
 

 
\t \t \t window.onload = blah.bind(null, ['d', 'e']); 
 
\t \t </script> 
 
\t </head> 
 
\t <body> 
 
\t </body> 
 
</html>
片斷

+0

哦,哇,非常有趣,是的,它表現的方式,我是否正在考慮如果我們使用'for(i = 0; ....'in'ix()'而不是'for(var i = 0; ....' ,你知道這是爲什麼嗎? – Noitidart

+0

啊,等等,我看到你使它成爲全局的,所以它的工作方式是顯而易見的。 – Noitidart

+0

所以看起來所有帶有函數的變量都會自動關閉。即使我在函數內部定義了一個'var i',它也不會影響全局值,它就像是一種閉包。有趣的是,這很好。它避免了一些重大錯誤。 – Noitidart

1

JavaScript範圍在功能級別

值被複位的原因是因爲它們是在兩個不同的函數聲明的,參見例如以下:

var f = function(){ 
    var i="12"; 
    console.log(i); 
    var fn2 = function(){ 
     var i="13"; 
     console.log(i); 
    }; 
    fn2(); 
    console.log(i); 
}; 

其結果將是

12 
13 
12 

因爲變量被確定範圍在函數級別,內部變量i與父函數中的不一樣。

+0

非常感謝@konkked! – Noitidart