2012-02-18 45 views
2

这个问题更多的是JavaScript原则。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(){功能definintion放在这里}())将所有这三种类型中覆写全局定义的函数()完成或任何其他()完成被内部定义的函数他们各自的关闭?

如果上面的问题没有意义,这里是改写;

  • 是下面的代码应该在任何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); 
        }()); 
    } 
    
+1

不要用你的第二个超时的方法。或者有什么理由? – Bergi 2012-02-18 04:01:03

回答

1

有关一般行为最初的问题:

  • var done =function done做basicaly同样的事情。它们会影响内部作用域中的外部定义,但它们不会在外部作用域上取代它。

  • done =将设置在范围相应done变量,或者如果这样的变量不存在,并且该程序不严格模式下运行将创建一个全局变量。

  • 在全球层面,任何功能外,var done =done =应该工作一样,但他们的工作方式不同在IE中,如果您尝试使用该变量在另一个脚本标签(坚持var = - 其更好反正)。

对于非常邪恶的setTimeout和eval问题:

  • 是的,我想应该是标准化的这种东西足以处处工作相同。无论如何我仍然会测试它。 (或者你可以使用一个不同的解决方案,给定邪恶的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 
    }()); 
    
  • ,你为什么EVAL-ING在一个定时器的东西呢?这一切听起来都很邪恶!

+0

答案最全,谢谢。 这不是坏事,尽管我正在用悍马穿越猴子,告诉猴子在悍马内部做些事情,为了将我所有的代码保存在同一个JS项目中,我必须做一些疯狂的事情,比如通过JSON传递函数。这也是语法高亮的问题。 – 2012-02-18 04:26:48

+0

那么,在这里,我生活在与悍马过猴子是最明显被认为是邪恶的:P – hugomg 2012-02-18 04:38:28

+0

为setvalue与eval你不需要eval你只是将eval内的函数绑定到这是你所在的范围。 – helly0d 2012-03-30 18:49:09

0

var donedone之间的差异,因为后者牵连window.done并且可以因此delete d。

语句done = foobar;将覆盖作用域链中的下一个“完成”变量。如果有一个本地var,它会改变,如果是全局的,它会覆盖那个,如果没有,它会创建一个新的全局。 所有这些都不会影响其他作用域(闭包)中的任何私有变量。

0

关于您的第一个块的一个注释。如果您在第一行中为函数指定名称,则该函数名称将在编译时解析并在范围内的任何位置可用。如果您只是将函数分配给变量,那么该函数(即变量)仅在运行时定义,,甚至后可用,如果您给它的名称。

例如:

// 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();