我们使用一些javascript来覆盖IE的setTimeout方法。这是因为在IE的某些版本中,参数无法正确传递(请参阅here)。
我必须首先加载修改后的setTimeout脚本,因为如果我在解析调用setTimeout的代码(未运行)之后加载它,则不会调用修改后的版本。
当javascript引擎解析对全局范围内的方法进行方法调用的文件时会发生什么?是否在解析时或执行代码时创建了方法的映射?
修改
我对这个问题有几个答案,这个问题给出了其他解决方案,但手头的问题不是我关心的问题,因为我已经有了解决方案。我想通过这个问题获得的是更好地理解如何解析和运行javascript。
答案 0 :(得分:1)
在执行代码时创建方法。
如果代码的语义正确,则解释器能够执行代码。 解析什么都没有被执行。 解析后的文件在解析下一个之前逐个单独执行。
检查一下: 我们有两个js文件。
<script src ='1.js'></script>
<script src ='2.js'></script>
在第二个文件中我们放置了setTimeout的声明;
//file2
window.setTimeout = function(){};
在第一个文件中,我们将检查是否覆盖了setTimeout
//file1
var f = function() { alert( setTimeout ); };
f();// alerts native setTimeout
setTimeout( f, 1000 ); // We use native settimeout, propably after one second file2 being loaded and executed and function `f` will be alerts the overriden setTimeout
如果在解析过程中创建了我添加的方法。即使在声明之前,它也可以在创建它的脚本中的任何位置访问它。 这样:
//somefile.js
setTimeout(); // we do not have access to function declared below, so while parsing this wasn't created.
window.setTimeout = function() { alert( 'whatever' ); }
答案 1 :(得分:0)
编辑#2
小提琴#1 - http://jsfiddle.net/zEaL8/4/ - 允许您设置/重置本机功能。要了解重新定义和调用顺序的工作原理。
小提琴#2 - http://jsfiddle.net/aKnjA/1/ - 证明定义的顺序无关紧要。请注意,重新定义发生在浏览器解析对函数的调用之后。
修改强>
回答你的问题:Javascript不强制执行任何函数定义的顺序。即我们可以在代码中调用之后定义的函数。当浏览器解析调用之后定义的函数的一行代码时,它没有任何关于在何处找到该函数的线索。在这种情况下,很明显绑定仅在运行时发生,而不是在初始解析期间发生。这实际上意味着您重新定义setTimeout将执行的内容。唯一要确保的是setTimeout本身的重新定义在执行任何调用之前执行。
为了确保首先处理新setTimeout的重新定义,您可以将它放在脚本块中作为load节点之外的头节点内的第一个元素,domReady等。
即。类似的东西:
<html>
<head>
<script>
window.setTimeout = function() {
alert('new sT');
}
</script>
</head>
<body onload="setTimeout();"></body>
</html>
答案 2 :(得分:0)
您可以将原始setTimeout存储在代码开头的全局变量中,然后使用新函数重载setTimeot。
window.oldST = setTimeout;
window.setTimeout = function(funct,x) {
return oldST(funct,x);
}
所以如果这些是js代码的第一行,你将用你的set重置setTimeout函数,并在oldST中设置旧的。