JavaScript で使用する Factory クラスを使用して、AJAX を介してクラス ファイルを動的にロードし、オブジェクトを返します。システムで非常に奇妙なバグに遭遇しましたが、それはすべてのブラウザでエラーをスローしますが、説明する能力を超えた状況下にあります.
これは、私の Factory クラスの簡略化されたバージョンです (最小限に抑えるために、多くの型チェックとエラー処理を削除しました)。
function Factory(){
// This holds which files have already been loaded
var loaded=new Object();
// Returns a new object
this.getObject=function(className,methodName,methodData){
if(loadFile('class.'+className+'.js')){
// Making sure that the object name is defined
if(window[className]!=null){
// Has to be an object
if(typeof(window[className])=='function'){
// Creating a temporary object
return new window[className];
}
}
}
}
// Loads a file over AJAX
var loadFile=function(address){
// Loads as long as the file has not already been loaded
if(loaded[address]==null){
// Required for AJAX connections (without ASYNC)
var XMLHttp=new XMLHttpRequest();
XMLHttp.open('GET',address,false);
XMLHttp.send(null);
// Result based on response status
if(XMLHttp.status===200 || XMLHttp.status===304){
// Getting the contents of the script
var data=XMLHttp.responseText;
// Loading the script contents to the browser
(window.execScript || function(data){
window['eval'].call(window,data);
})(data);
// makes sure that file is loaded only once
loaded[address]=true;
}
}
}
これはユーザーが行うことです:
var Factory=new Factory();
var alpha=Factory.getObject('example');
alpha.set(32);
alpha.get();
var beta=Factory.getObject('example');
beta.set(64);
alpha.get();
beta.get();
これは失敗します。関数を 2 回目に実行すると (行で)、「オブジェクトは関数ではありません」と表示されますreturn new window[className];
。ここで何かが欠けているかどうかは理解していますが、キッカーは次のとおりです。
通話にプレフィックスを付けるclassName
と、機能します。window[]
たとえば、'example'
クラスのファイル名を次のように変更し、'test_example'
次の行があるとします。
... if(window['test_'+className]!=null){ ...
... if(typeof(window['test_'+className])=='function'){ ...
... return new window['test_'+className]; ...
その後、機能し、アルファ オブジェクトとベータ オブジェクトの両方が期待どおりに機能します。純粋に変数を介してそれらを参照すると、失敗します。className.toString() のようなことを試してみましたが成功しませんでしたが、これでも失敗しました:
className+''
これは本当に奇妙です。どこを見ればいいのか、何を試したらいいのかわからないのですが、なぜこれが起こるのか知っている人はいますか?
編集: ロードされている「example.js」スクリプトの例を次に示します。
function example(){
var myVar=16;
this.set=function(value){
myVar=value;
}
this.get=function(){
alert(myVar);
}
}
(そして、これを test_example() に名前変更し、上記のように構築された文字列で関数をロードすると、再び機能します)