簡體   English   中英

Javascript閉包-全局范圍內覆蓋函數的行為

[英]Javascript closures - behavior of overridden functions from the global scope

這個問題更多的是關於javascript的原理。

function done(){ console.log('done defined with `function done(){ ...`'); }
var done = function(){ console.log('done defined with `var done = ...`'); }
done = function(){ console.log('without `var`, just `done = ...`'); }

如果在<script>標記內定義它們,它們是否都會做相同的事情,對嗎?

但是,如果我將它們放在閉包中(function(){ 函數定義在此處 }()) ,這三種類型中的任何一種都會覆蓋全局定義的函數done()或在其各自閉包中定義的任何其他done()函數?

如果上述問題沒有道理,請改寫;

  • 以下代碼在任何JS運行時中都應該做相同的事情嗎?
  • eval代碼可以在上下文或全局范圍內的任何地方執行該特定代碼嗎?
  • 如何才能setTimeout呼叫進行配置,以便其“引號”之間的代碼執行中具有特定范圍內setTimeout被稱為(請參閱第二超時里面for下面)? 我的意思是除了定義window.blabla函數並告訴它們在運行后刪除自己之外,還有其他方法嗎?

     function done(d){ console.log('cha cha cha: '+d); } setTimeout( function(){ done(2); }, 3500 ); for(i=0; i<10; i++){ (function(){ done = function(x){ console.log('done #'+i+' sais: '+x); } setTimeout(function(){ done(i*2); },2500); setTimeout(function(){ done(i*2); }.toString()+'(); ',2500); }()); } 

對於有關一般行為的最初問題:

  • var done =function done執行相同的操作。 它們將在內部作用域中隱藏外部定義,但不會在外部作用域中替換它。

  • done =將在范圍內設置相應的done變量,或者如果不存在這樣的變量並且程序不在嚴格模式下運行,則將創建一個全局變量。

  • 在全局級別上,在任何函數之外, var done =done =應該工作相同,但是如果您嘗試在另一個腳本標簽中使用變量,則它們在IE中的工作方式有所不同(始終堅持使用var = -更好)。

至於非常邪惡的setTimeout和eval問題:

  • 是的,我想這種東西應該足夠標准化,以便在任何地方都可以使用。 無論如何,我仍然會對其進行測試。 (或者,考慮到惡性評估,您可以使用其他解決方案)

  • eval在當前范圍內運行代碼(使用深黑魔術來運行)。 如果要在全局范圍內運行代碼,則可以改用new Function

  • 為了讓settimeout在當前范圍內運行字符串,您可以自己添加eval

     var done = function(d){ console.log('outer done', d); }; (function(){ var done = function(x){ console.log('inner done', x); }; setTimeout(function(){ done(1); }, 200); //inner done setTimeout('done(2)', 400); //outer done setTimeout(function(){ eval('done(3)'); }, 600); //inner done }()); 
  • 再一次,為什么要評估setTimeouts中的內容? 這聽起來完全是邪惡的!

var donedone之間有區別,因為后者涉及window.done ,因此可以delete d。

語句done = foobar; 將覆蓋作用域鏈中的下一個“完成”變量。 如果有一個本地var ,它將更改為,如果有一個全局var ,它將覆蓋該var ;如果沒有,它將創建一個新的全局var 所有這些都不會影響其他作用域(閉包)中的任何私有變量。

在第一塊上的一個音符。 當您像在第一行中一樣給函數命名時,該函數名稱將在編譯時進行解析,並且可以在范圍內的任何位置使用。 如果僅將函數分配給變量,則該函數(即變量)僅在定義之后在運行時可用, 即使您給它起了名字。

例如:

// this is valid
foo();
function foo(){ console.log("foo"); }

// this throws an error...
bar();
var bar = function (){ console.log("bar"); };

// ...and so does this...
baz();
var bat = function baz(){ console.log("bazbat"); };

// ...and this!
baz();

暫無
暫無

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

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