document.head和document.getElementsByTagName(“head”)[0]奇怪的行为

时间:2015-01-07 04:16:26

标签: javascript

我无法弄清楚这段代码有什么问题。在定义了这样的脚本之后:

var script = document.createElement('script');
script.src = 'http://example.com/file.js';
script.type = 'text/javascript';
script.onload = function(){
    //code to execute after script loads
}

然后我有以下一行:

(document.head || document.getElementsByTagName("head")[0]).appendChild(script);

出于某种原因,我发现非常奇怪的不一致行为,似乎在实际加载onload之前调用了file.js函数。我在file.js函数中使用了onload中包含的变量,并且每隔一段时间,函数就会在根据错误控制台定义这些变量之前执行。

如果我将最后一行更改为:

document.head.appendChild(script);

或者

document.getElementsByTagName("head")[0].appendChild(script);

问题似乎消失了。

如果我在附加之前将其分配给变量,问题也会消失:

var head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(script);

为什么会这样?

1 个答案:

答案 0 :(得分:4)

这是由缺少分号引起的:

script.onload = function(){

}; // Add this semicolon and it will be fixed

如果没有分号,解释器会解析您的下一组括号,就像您正在调用该匿名函数然后尝试在该函数的返回值上调用appendChild一样。它的解释如下:

script.onload = (function(){
    //code to execute after script loads
}(document.head || document.getElementsByTagName("head")[0])).appendChild(script);

在 执行匿名函数之后肯定会抛出错误 (除非该函数实际返回一个具有appendChild函数的对象)。