避免多个javascript文件加载

时间:2016-02-05 07:49:37

标签: javascript jquery html web namespaces

我将此代码段添加到我的asp.net web api应用程序中使用的每个javascript文件中,以避免多次加载:

Fullcalendar.js

blog = {};
blog.comments = blog.comments || {};
blog.comments.debugMode = false;

blog.isFirstLoad = function (namesp, jsFile) {
    var isFirst = namesp.jsFile.firstLoad === undefined;
    namesp.jsFile.firstLoad = false;
    return isFirst;
};

$(document).ready(function () {
    if (!blog.isFirstLoad(blog.comments, "fullcalendar.js")) {
        return;
    }
});

有时我得到一个奇怪的例外

  

未捕获的TypeError:无法读取未定义的属性“firstLoad”

我需要知道:

  1. 为什么会这样?
  2. 我该如何解决?

2 个答案:

答案 0 :(得分:1)

那里有几个问题。

首先,您不应该首先加载文件多次,所以不必经历这个尝试弄清楚您是否已加载文件的业务

但如果你想这样做:

第一个实际问题是你总是这样做:

blog = {};

...这意味着如果已经有blog全局,那么您将消除其值并将其替换为空对象。如果要使用现有的全局值或创建新值,请执行以下操作:

var blog = blog || {};

这看起来很奇怪,但由于重复的var声明很好(并且不会更改变量),这将使用现有的值,或者如果没有一个(或其值为false)它将创建一个新的并用{}初始化它。

然后,行

namesp.jsFile.firstLoad = false;

...在jsFile上查找名为namesp的媒体资源,并假设它不是nullundefined。它不会使用jsFile参数的值来查找属性。

为此,请使用括号表示法:

namesp[jsFile].firstLoad = false;

尽管如此,你还是假设它不是nullundefined,但很可能。你可能只是想要:

namesp[jsFile] = false;

或者可能:

namesp[jsFile] = namesp[jsFile] ||{};
namesp[jsFile].firstLoad = false;

也就是说,使用blog.comments来跟踪JavaScript文件是否已加载似乎很奇怪。如果文件可能已经加载,只需这样就可以了:

var fullCalendarLoaded;
if (fullCalendarLoaded) {
    // It's already loaded
} else {
    // It isn't, but it is now
    fullCalendarLoaded = true;
    // ...do your init...
}

或者,如果您有其中的几个,并希望使用单个全局:

var loadedScripts = loadedScripts || {};
if (loadedScripts.fullCalendar) {
    // Already loaded
} else {
    // Not loaded yet
    loadedScripts.fullCalendar = true;
    // ...do init...
}

或者如果使用文件名很重要:

var loadedScripts = loadedScripts || {};
function firstLoad(filename) {
    if (loadedScripts[filename[) {
        return false;
    }
    // Not loaded yet, remember we've loaded it now
    loadedScripts[filename] = true;
    return true;
}

然后:

if (firstLoad("fullcalendar.js")) {
    // First load, do init...
}

答案 1 :(得分:1)

这很简单:

在初次运行时,您可以定义

blog = {};
blog.comments = blog.comments || {};
blog.comments.debugMode = false;

理论上,这意味着在某些负载上,blog是:

var blog = {
  comments: {
    debugMode: false
  }
}

然后,您将blog.comments作为isFirstLoad参数传递到函数namesp。在该函数中,您进行评估:

namesp.jsFile.firstLoad === undefined;

好吧,您从未定义jsFile的{​​{1}}属性。这意味着它是未定义的。尝试访问未定义变量的属性blog.comments将为您提供错误

  

未捕获的TypeError:无法读取属性' firstLoad'未定义的