为什么我的JavaScript函数有时“未定义”?

时间:2008-09-30 16:38:57

标签: javascript

我调用我的JavaScript函数。当 定义时,为什么有时会收到错误'myFunction is not defined'?

例如。即使在这个例子中,我偶尔会得到'copyArray未定义':

function copyArray( pa ) {
    var la = [];
    for (var i=0; i < pa.length; i++)
        la.push( pa[i] );
    return la;
}

Function.prototype.bind = function( po ) {
    var __method = this;
    var __args = [];

    // Sometimes errors -- in practice I inline the function as a workaround.
    __args = copyArray( arguments );

    return function() {
        /* bind logic omitted for brevity */
    }
}

正如您所看到的,copyArray已定义就在那里,因此这不能与脚本文件加载的顺序有关。

我一直在难以解决的情况下得到这个,其中调用函数位于另一个应该在被调用函数之后加载的文件中。但这是我能提出的最简单的案例,似乎也是同样的问题。

它不会100%发生,所以我怀疑某种加载时序相关的问题。但我不知道是什么。

@Hojou:这是问题的一部分。我现在收到此错误的函数本身就是我的addLoadEvent,它基本上是公共库函数的标准版本。

@James:我理解这一点,并且函数中没有语法错误。在这种情况下,也会报告语法错误。在这种情况下,我只得到“未定义”错误。

@David:这种情况下的脚本驻留在使用普通&lt; script src =“file.js”&gt;&lt; / script&gt;引用的外部文件中。页面头部的方法。

@Douglas:有趣的想法,但如果是这种情况,我们怎么能永远自信地调用用户定义的函数?无论如何,我试过这个并没有用。

@sk:此技术已经过浏览器测试,基本上是从Prototype库中复制的。

13 个答案:

答案 0 :(得分:21)

我没有在最新的Firefox for Linux中定义此功能,尽管Chromium处理得很好。

在我的案例中发生的事情是,在定义具有问题的函数的块之前,我有一个前SCRIPT块,以下列方式说明:

<SCRIPT src="mycode.js"/>

(即没有结束标记。)

我必须通过以下方式重新声明此块。

<SCRIPT src="mycode.js"></SCRIPT>

然后接下来的工作很好......很奇怪吧?

答案 1 :(得分:8)

如果您只是在页面上包含脚本,则不可能发生这种情况。

当JavaScript代码开始执行时,“copyArray”函数应始终可用,无论它是在它之前还是之后声明 - 除非您使用依赖库动态加载JavaScript文件。如果是这种情况,会有各种各样的时间问题。

答案 2 :(得分:4)

我的猜测是,在调用方法时文档没有完全加载。在文档准备就绪后执行代码。

答案 3 :(得分:4)

使用JSLint验证您的代码。它通常会发现大量的小错误,所以警告“JSLint可能会伤害你的感情”是相当明显的。 =)

答案 4 :(得分:2)

函数中的语法错误 - 或上面的代码中的语法错误 - 可能导致它未定义。

答案 5 :(得分:2)

如果您正在更改内置“函数”对象的原型,则可能会因修改基本内置对象而遇到浏览器错误或竞争条件。

在多个浏览器中测试以查找。

答案 6 :(得分:2)

这不能解决您的原始问题,但您始终可以将对copyArray()的调用替换为:

__args = Array.prototype.slice.call(arguments);

Google提供了更多信息。

我在以下浏览器中对上述内容进行了测试:IE6,7&amp; 8B2,Firefox 2.0.0.17&amp; 3.0.3,Opera 9.52,适用于Windows 3.1.2的Safari和谷歌浏览器(无论本帖发布时的最新版本如何),它适用于所有浏览器。

答案 7 :(得分:2)

这可能已经得到纠正,但是......显然firefox有一个缓存问题,这是javascript函数无法被识别的原因..我真的不知道具体细节,但如果你清除你的缓存将修复问题(直到你的缓存再次满了......不是一个好的解决方案)..我一直在四处寻找firefox是否有一个真正的解决方案,但到目前为止没有...哦,不是所有的版本,我认为它可能只在某些3.6.x版本中,不确定...

答案 8 :(得分:1)

通过删除“异步”加载来解决:

  <script type="text/javascript" src="{% static 'js/my_js_file.js' %}" async></script>

更改为:

  <script type="text/javascript" src="{% static 'js/my_js_file.js' %}"></script>

答案 9 :(得分:0)

使用匿名函数保护本地符号表。类似的东西:

(function() {
    function copyArray(pa) {
        // Details
    }

    Function.prototype.bind = function ( po ) {
        __args = copyArray( arguments );
    }
})();

这将创建一个闭包,其中包含您在本地符号表中的函数,并且在调用函数时,您不必依赖它在全局命名空间中可用。

答案 10 :(得分:0)

我担心,当你向Function类添加一个新方法时(通过prtotyping),你实际上是将它添加到所有声明的函数中,与你的copyArray()一样好。结果你的copyArray()函数被递归地自引用。即应该存在copyArray()。bind()方法,它正在调用自身。

在这种情况下,某些浏览器可能会阻止您创建此类引用循环并触发“函数未定义”错误。

在这种情况下,内联代码将是更好的解决方案。

答案 11 :(得分:0)

使用框架集时可能会发生这种情况。在一个框架中,定义了我的变量和方法。在另一个,他们不是。当使用调试器并查看我的变量时,它特别令人困惑,然后在帧内的断点处未定义。

答案 12 :(得分:0)

我认为你的javascript代码应放在标签之间,需要文件加载