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

时间:2020-03-06 14:56:00  来源:igfitidea点击:

我调用我的JavaScript函数。为什么有时在定义时会出现错误" myFunction未定义"?

例如。即使在此示例中,我有时也会得到"未定义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:在这种情况下,脚本位于一个外部文件中,该文件使用页面头部的常规<script src =" file.js"> </ script>方法进行引用。

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

@sk:此技术已在各种浏览器上进行了测试,并且基本上是从Prototype库中复制的。

解决方案

我的猜测是,在调用该方法时,某种程度上文档还没有完全加载。在文档准备就绪事件之后让代码执行。

函数或者其上方代码中的语法错误可能导致其未定义。

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

无论JavaScript代码是在JavaScript代码之前还是之后进行声明," copyArray"函数始终应该可用,除非我们使用依赖库动态加载JavaScript文件。如果是这样的话,时间安排会出现各种各样的问题。

使用匿名函数来保护本地符号表。就像是:

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

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

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

如果要更改内置"功能"对象的原型,则可能通过修改基本内置对象而遇到浏览器错误或者竞争状态。

在多个浏览器中对其进行测试以找出答案。

恐怕,当我们将新方法添加到Function类(通过原型设计)时,实际上是将其添加到所有声明的函数中,以及添加到copyArray()中。结果,copyArray()函数被递归地自我引用。 IE。应该存在copyArray()。bind()方法,该方法正在调用自身。

在这种情况下,某些浏览器可能会阻止我们创建此类参考循环并引发"函数未定义"错误。

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

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

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

可从Google获得更多信息。

我已经在以下浏览器中测试了以上内容:IE6、7和8B2,Firefox 2.0.0.17和3.0.3,Opera 9.52,适用于Windows 3.1.2的Safari和Google Chrome(无论本文发布时的最新版本) ),并且可以在所有浏览器中使用。

使用JSLint验证代码。通常会发现大量的小错误,因此警告" JSLint可能会伤害感觉"很明显。 =)

尽管Chromium可以很好地处理此功能,但我无法将其识别为最新版Firefox for Linux中的定义。

在我的情况下发生的事情是,在定义有问题的功能的代码块之前,我有一个以前的" SCRIPT"代码块,它用以下方式表示:

<SCRIPT src="mycode.js"/>

(也就是说,没有结束标记。)

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

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

然后接下来发生的事情很好...奇怪吗?