[英]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.