[英]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()函數?
如果上述問題沒有道理,請改寫;
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 done
和done
之間有區別,因為后者涉及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.