繁体   English   中英

Javascript闭包-全局范围内覆盖函数的行为

[英]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()函数?

如果上述问题没有道理,请改写;

  • 以下代码在任何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); }()); } 

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

  • 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 donedone之间有区别,因为后者涉及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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM