Javascript闭包-全局范围内被重写函数的行为
这个问题更多的是关于javascript原则的Javascript闭包-全局范围内被重写函数的行为,javascript,scope,closures,Javascript,Scope,Closures,这个问题更多的是关于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 = ...`'); } 如果在
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 = ...`'); }
如果在
标记中正确定义,它们会做相同的事情吗
但是如果我将它们放在一个闭包(function(){
函数定义在这里}())
这三种类型中的任何一种会覆盖全局定义的函数done()或在各自闭包中定义的任何其他done()函数吗
如果上面的问题没有意义,这里是重新措辞
- 下面的代码在任何JS运行时都应该做同样的事情吗李>
-ing code anywhere在上下文或全局范围内执行特定代码eval
- 如何配置
调用,以使其“引号”之间的代码在调用该特定setTimeout
的范围内执行(请参见下面的setTimeout
中的第二个超时)?我的意思是,除了定义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); }()); }
和函数完成(d){console.log('chacha:'+d);} setTimeout(函数(){done(2);},3500);
对于(i=0;i关于一般行为的初始问题:
和var-done=
do基本上是一样的。它们将在内部范围中隐藏外部定义,但不会在外部范围中替换它function-done
将在作用域中设置相应的done=
变量,或者如果该变量不存在且程序未在严格模式下运行,则将创建一个全局变量done
- 在全局级别上,在任何函数之外,
和var-done=
应该工作相同,但是如果您尝试在另一个脚本标记中使用变量,它们在IE中的工作方式就不同了(坚持使用done=
,无论如何都会更好)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 }());
- 再说一次,你为什么要在设定的超时时间里评估事情?这听起来非常邪恶
之间存在差异,因为后者涉及done
,因此可以window.done
d 语句delete
将覆盖作用域链中的下一个“done”变量。如果存在一个局部变量done=foobar;
,它将更改,如果存在全局变量,它将覆盖该变量,如果没有,它将创建一个新的全局变量。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();
不要使用第二个超时方法。或者有什么原因吗?最完整的答案,谢谢。这不是坏事,尽管我用悍马穿越一只猴子,告诉猴子从悍马内部做一些事情,为了让我所有的代码都在同一个JS项目中,我不得不做一些疯狂的事情,比如通过JSON传递函数。这也是一个错误语法突出显示的问题。好吧,我住的地方,一只猴子和一辆悍马的交叉被认为是最邪恶的:p对于带有eval的setTimeout,你不需要eval,你只需要将eval中的函数绑定到这个范围就可以了。@helly0d:我知道,这就是我在第一个例子中所做的。setTimeout中的eval是c与向settimeout传递字符串的大小写兼容。