这个问题更多的是关于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
-ing 代码在上下文或全局范围内执行该特定代码? 如何配置
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 =
- 无论如何它更好(。
至于非常邪恶的设置超时和评估问题:
-
是的,我想这种东西应该足够标准化,以便在任何地方都一样工作。无论如何,我仍然会测试它。(或者你可以使用不同的解决方案,考虑到 eval 是多么邪恶(
-
eval在当前范围内运行代码(使用Deep Black Magic来执行此操作(。如果要在全局作用域上运行代码,可以改用
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 }());
-
再说一遍,你为什么要在设置超时中评估事情?这一切听起来都非常邪恶!
var done
和 done
之间有区别,因为后者牵涉window.done
,因此可以delete
。
语句done = foobar;
将覆盖作用域链中的下一个"done"变量。如果有一个本地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();