2013-02-14 91 views
3

我是JavaScript新手,我发现我不知道一个合适的方法来重复获取同一个变量的实例。我打开一个XML文件是:单例模式javascript

function testXML(){ 
if (window.XMLHttpRequest) 
    {// code for IE7+, Firefox, Chrome, Opera, Safari 
    xmlhttp=new XMLHttpRequest(); 
    } 
else 
    {// code for IE6, IE5 
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
xmlhttp.open("GET","../res/data.xml",false); 
xmlhttp.send(); 
xmlDoc=xmlhttp.responseXML; 
return xmlDoc; 
} 

我加入了回报,所以我可以挑选XML文件,并进行一些搜索加载一些列表数据。问题是,每次我想用xml文件读取一些数据时,我都会调用这个方法,它不仅返回了xml,还有IF/Else和openfile等等,我猜这不是那是适当的。

那么我怎样才能使一个方法,只是返回我的XML文件,所以我只能打开它一次?另外,打开一次xml文件并将其加载到一个变量中是安全的,比如在index.html中,然后导航到其他htmls而不会丢失该变量值(xml文件)?

谢谢!

+2

它不是单例模式。你在问缓存。 – freakish 2013-02-14 11:54:41

+0

hmm thx,im noob :( – 2013-02-14 12:02:31

回答

5
var xml; 

function testXML(){ 
    if(!xml){ 
     if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
     } else {// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     xmlhttp.open("GET","../res/data.xml",false); 
     xmlhttp.send(); 
     xml = xmlhttp.responseXML; 
    } 
    // return xml; // You can optionally also return the xml, but it'd be assigned to the variable already, any way. 
} 

调用该函数一次,你可以只使用xml变量。

或者,像下面建议的那样,只需使用testXML()代替代码中的变量,然后取消注释返回。
这可确保您不会遇到未定义的xml。

+0

或者你可以使用'textXML._xml = xml;'来避免意外的全局变量(然后使用'return textXML._xml;')。 – freakish 2013-02-14 11:56:23

+0

@Cerbrus if'return xml;'是可选的,'xml'需要在你每次想要使用它时测试undefined,如果它未定义,那么在使用它之前调用'testXML()',所以我总是调用'testXML()'并使用返回的对象 – 2013-02-14 11:59:25

+0

@ t.niese:对答案已添加评论 – Cerbrus 2013-02-14 12:02:22

2

我会使用函数闭包在JavaScript实现这个建议你:

function createSingleton(fn) { 
    var singleton = fn.apply(this); 
    return function() { 
    return singleton; 
    }; 
} 

这是一个创建从返回一些其他功能的单泛型函数。 它的结果将存储在函数闭包中,并且您可以执行任何次数的结果函数来访问单例。 如果担心传递给函数围绕你可以把它存储在全局对象:

var xml = createSingleton(getXML); 

console.log(xml()); //use the xml object 
console.log(xml() === xml()); 

什么是真正发生在这里的是,createSingleton在执行时执行一次潜在的工厂方法,将其存储的结果,并给你回函数只返回该结果。你甚至可以做延迟加载与此:

function createSingletonLayz(fn) { 
    var singleton = null, 
     context = this; 
    return function() { 
    if (!singleton) { 
     singleton = fn.apply(context) 
    } 
    return singleton; 
    }; 
} 

PS:不要担心跟平时lock东西多线程使单码线程安全的。 JavaScript只在一个循环中执行代码(这就是为什么我们在所有地方都有回调的原因)

+0

哇,很好的答案的人,非常感谢!! – 2013-02-14 12:11:35

+0

人们并没有意识到JavaScript是一个功能语言的核心,因此它可以做的很漂亮 如果您对这种事感兴趣,我建议您阅读Douglas Crockfords的“JavaScript The Good Parts”一书或在他的网站上观看他的一些非常有趣的会谈。 – Tigraine 2013-02-14 12:15:35