全局范围映射的 Javascript 方法

发布于 2024-12-22 13:56:18 字数 393 浏览 1 评论 0原文

我们使用一些 JavaScript 来覆盖 IE 的 setTimeout 方法。这是因为在某些版本的 IE 中,参数无法正确传递(请参阅

我必须首先加载修改后的 setTimeout 脚本,因为如果我在解析(而不是运行)调用 setTimeout 的代码之后加载它,则不会调用修改后的版本。

当 javascript 引擎解析对全局范围内的方法进行方法调用的文件时,会发生什么情况?方法的映射是在解析时还是在执行代码时创建的?

编辑

我对这个问题有一些答案,它们给出了其他解决方案问题,但手头的问题不是我关心的,因为我已经有解决方案了。我想通过这个问题获得的是更好地理解 javascript 是如何解析和运行的。

We use a bit of javascript that overwrites the setTimeout method for IE. This is because in some versions of IE the parameters do not get passed correctly (see here).

I have to load the modified setTimeout script first, because if I load it after the code that calls setTimeout is parsed (not run) then the modifed version does not get called.

What happens when the javascript engine parses files that have method calls to methods at the global scope? Do the mappings to the methods get created at parse time or when the code is executed?

EDIT

I have had a few answers to this question, which give other solutions to this problem, but the problem at hand is not my concern as I already have a solution for it. What I want to gain by this question is a better understanding of how javascript is parsed and run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝眼睛不忧郁 2024-12-29 13:56:18

方法是在执行代码时创建的。

如果代码的语义正确,解释器就能够执行代码。
解析时没有任何内容被执行。
解析后的文件将被逐个执行,然后再解析下一个。

看看这个:
我们有两个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' ); }

Methods are created at when the code is executed.

If the semantics of the code is correct interpreter is able to execute code.
While parsing nothing wasn't be executed.
File after parsing is executed singly one by one , before parsing the next.

Check this out:
We have two js files.

<script src ='1.js'></script>  
<script src ='2.js'></script>

In second file we put declaration of setTimeout;

 //file2
 window.setTimeout = function(){};

In first file we'll checking for setTimeout being overridden

//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

If methods which I added were would be created during parsing. This would have access to it anywhere in the script in which it was created, even before its declaration.
so:

//somefile.js
  setTimeout(); // we do not have access to function declared below, so while parsing  this wasn't created.
  window.setTimeout = function() { alert( 'whatever' ); }
内心荒芜 2024-12-29 13:56:18

编辑 #2

小提琴 #1 - http://jsfiddle.net/zEaL8/4/ - 允许您设置/重置本机功能。查看重新定义和调用顺序是如何工作的。

Fiddle #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>

EDIT #2

Fiddle #1 - http://jsfiddle.net/zEaL8/4/ - Allows you to set/reset a native function. To see how the redefinition and calling order works.

Fiddle #2 - http://jsfiddle.net/aKnjA/1/ -Demonstrates that the order of definition does not matter. Notice that the redefinition happens after the browser parses the call to the function.

EDIT

To answer your question: Javascript does not enforce any order of definition of functions. i.e. we can call a function defined afterwards in code. When the browser parses a line of code that calls a function that is defined afterwards, it does not have any clue as to where to find that function. This being the case, it is clear that binding happens only at run-time and not during initial parse. This in effect would mean that your redefinition of setTimeout is what will execute. The only thing to ensure is that the redefinition of setTimeout itself gets executed before any call to that is executed.

To ensure that the redefinition of your new setTimeout is processed first, you can place it in a script block as the first element inside the head node outside load, domReady etc.

i.e. Something like:

<html>
<head>
<script>
window.setTimeout = function() {
    alert('new sT');
}
</script>
</head>
<body onload="setTimeout();"></body>
</html>
So要识趣 2024-12-29 13:56:18

您可以将原始 setTimeout 存储在代码开头的全局变量中,然后使用新函数重载 setTimeot。

 window.oldST = setTimeout;
 window.setTimeout = function(funct,x) {
    return oldST(funct,x);
 }

因此,如果这些是 js 代码的第一行,您将使用您的代码重载 setTimeout 函数,并在 oldST 中设置旧的函数。

you can store original setTimeout in a global variable at the beginning of the code and then overload the setTimeot with a new function.

 window.oldST = setTimeout;
 window.setTimeout = function(funct,x) {
    return oldST(funct,x);
 }

so if these are the first lines of the js code you will have overloaded the setTimeout function with yours and set the old one in oldST.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文