2017-10-04 75 views
1

在試圖尊重不訪問對象外循環(JavaScript的)

"polluting the global namespace"

和其他原因,我看到全局變量是「一般」一個壞主意的原則,我在我的代碼轉換,從全球變量:

stBgAsset15_src = $image.attr('src'); 

什麼,作爲一個初學者我認爲最相關的,也就是說用「src」屬性/方法來創建Object Image()

var stBgAsset15 = new Image(); 
stBgAsset15.src = $image.attr('src'); 

但我無法在'for'循環之外訪問它。我需要能夠在循環的外部函數內部以及在主外部函數底部引用的名爲ClickOnButton()的函數內部訪問它。

我收到以下錯誤消息:

Uncaught ReferenceError: stBgAsset15 is not defined 

而且,這是可選的,因爲它不是必需的今天(但可能會在未來的),我不知道是否有可能也存取權限它從一個完全不同的函數調用上的jsfiddle anotherFunctionTotallyUnrelated()

完整演示https://jsfiddle.net/nm4t1nob/

我已經把console.log提示在每個地方我需要能夠訪問變量。

這裏的循環不起作用,只是爲了允許範圍的討論和實現這一點的最佳方式。

代碼:

preloadFirstPriorityStAssets(); 

var $image = $('#intro').find('#Asset-15'); 

function preloadFirstPriorityStAssets() { 

    // Variables 
    var i, 
     s;  
    var rawDataArray = [ 
      'https://example.com/image9', 
      'https://example.com/image10', 
      'https://example.com/image11'], 
    len = rawDataArray.length; 

    var $image = $('#intro').find('#Asset-15'); 

    for (i=0; i<len; ++i) { 
     (function(index) { 
     var s = rawDataArray[index]; 

     //send to img shell the first raw data-src 
     //which *automatically* generates src for img via Cloudinary responsive 
     $image.attr('data-src', s); 

     //fire off a request to Cl. server to get the correct SRC 
     //(asynchronous by default) 
     $.cloudinary.responsive($image); 

     var stBgAsset{a dynamic variable-injected by my backend on each loop occurence"} == new Image(); 
     stBgAsset{a dynamic variable-injected by my backend on each loop occurence"}.src = $image.attr('src'); 
     //if we take as assumption one of the dynamic variable 
     //injected by my backend on each loop occurence" is 15 
     stBgAsset15.src = $image.attr('src'); 
     })(i);  
    }; 

//if we take as assumption one of the dynamic variable-injected by  
//my backend on each loop occurence" is 15 
    console.log('stBgAsset15 value: '+stBgAsset15); 
    console.log('stBgAsset15.src value: '+stBgAsset15.src); 

    afterClickOnStThrobber(); 
    }; 

function afterClickOnStThrobber() { 
    console.log('stBgAsset15 value: '+stBgAsset15); 
    console.log('stBgAsset15.src value: '+stBgAsset15.src); 
} 

我不是很好的領域,如JavaScript初學者,不知道如何使這項工作。

我真的不能使用數組,因爲,即使在這個例子中,我只有stBgAsse15,其實我會在實際的代碼再生不良可變

stBgAsset+<id form database that will change on each loop> 

所以我真的需要他們有一個顯當它們從循環輸出時我可以調用的名稱。在一個數組中,這些值將全部在數組中,但是要知道哪一個是哪一個會太複雜。我需要他們有一個名字,一個變量或者他們可以被調用。

編輯 我需要補充的重要信息如下這個答案 「只要定義stBgAsset15你的for循環。這個變量仍然不會是全球性的,因爲它會在您preloadFirstPriorityStAssets函數內的作用域之外。然後,你需要通過stBgAsset15作爲afterClickOnStThrobber的參數。「

事情是我不能,因爲我添加somùe細節:src被設置在循環內部,因爲它改變了DataArray的每個值。這是一個功能,我注入一個dat-src,然後Cloudinary分析每個data-src並生成一個不同的src。所以我不能在循環之外移動它。它需要由循環處理。

+1

[從其他函數訪問變量而不使用全局變量](https://stackoverflow.com/questions/407048/accessing-variables-from-other-functions-without-using-global-variables) – Mark

+2

This沒有意義。鑑於'var stBgAsset15'已在循環中聲明,如果'len'爲'0',則可能有多個圖像,甚至沒有。如果你想從循環之外訪問它,你想要哪一個? – Bergi

+0

*事情是我不能,因爲我添加somùe細節:src被設置在循環內部,因爲它改變DataArray *的每個值,所以你想循環它,但也可以使用它,就好像它沒有被循環。 @Bergi是正確的,你的問題沒有意義。我的建議。深吸一口氣,好好想想你真正想要什麼,因爲我覺得你在這裏讓自己感到非常困惑。 – Liam

回答

1

您可以將資產在陣列和傳遞數組其他功能:

preloadFirstPriorityStAssets(); 
 

 
function preloadFirstPriorityStAssets() { 
 

 
    // Variables 
 
    var i, 
 
     s;  
 
    var rawDataArray = [ 
 
      'https://example.com/image9' ], 
 
    len = rawDataArray.length; 
 
    
 
    var $image = $('#Intro').find('#Asset-15'); 
 
    
 
    var bgAssets = []; // create array for images 
 
    
 
    for (i=0; i<len; ++i) { 
 
     (function(index) { 
 
     var s = rawDataArray[index]; 
 
       
 
     var stBgAsset15 = new Image(); 
 
     stBgAsset15.src = $image.attr('src'); 
 
     bgAssets.push(stBgAsset15); // put image in array 
 
    
 
     })(i);  
 
    }; 
 
    console.log('assets: '+bgAssets); 
 

 
    afterClickOnStThrobber(bgAssets); // pass array to another function 
 
    }; 
 
    
 
function afterClickOnStThrobber(data) { 
 
    console.log('assets: '+data); // another operation with array 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="intro"> 
 
    <img  
 
     class="example" 
 
     id="Asset-15" 
 
     src="https://media-cdn.tripadvisor.com/media/photo-s/08/cd/99/1a/hard-rock-hotel-ibiza.jpg"> 
 

 
</div>

+0

謝謝。順便說一句,我只是添加一些信息,並編輯我的代碼。我寧願不使用數組,因爲事後我需要能夠EXPLCITLY調用每個值。例如,我需要調用stBgAsset15,然後調用stBgAsset14或stBgAsset18(這取決於爲stBgAsset15創建的值)。所以在一個數組中,我將無法像這樣訪問它們。我真的需要他們有一個名字,我可以打電話時,他們是從循環輸出。 – Mathieu

+0

我明白了。您可以使用鍵和值創建對象,然後迭代此對象。就像這樣: 讓資產= { stBgAsset15:圖片, stBgAsset16:圖片, ... } –

+0

我可以,但它會迫使我之後解析此JSON或事和我的後端(Ruby)的解析,這是慢。我只希望他們有一個特定的「名字」,我可以打電話給他。 StBgAsset15,stBgAsset16 ...問題是我不知道如何在循環之外訪問它們... – Mathieu

0

只需在您的for循環之外定義stBgAsset15即可。這個變量仍然不是全局的,因爲它將在你的preloadFirstPriorityStAssets函數的範圍內。然後您需要將stBgAsset15作爲參數傳遞給afterClickOnStThrobber

+0

我剛剛編輯了我的問題。我沒有放一段代碼,試圖簡化問題,但實際上我確實避免了一個重要的信息:我不能把它放在循環之外(據我的理解) – Mathieu

1

您需要在循環開始前創建stBgAsset作爲一個空對象:

var stBgAsset = {}; 

然後,在循環內,您需要使用如下代碼啓動其元素:

stBgAsset["stBgAsset15"] = {}; //Your value 

這樣你將得到你需要的名字,你就可以在服務器端找到它們。因此,您也可以在此之後聯繫任何此類會員,因此在此週期之外。

你抱怨在此之前,JSON.stringify -ing,送東西到服務器,並把它們解析太慢我懇請你試試吧,我敢打賭,你會被結果感到驚訝。如果不是,確實很慢,那麼我想知道哪一行很慢,它的速度有多慢,分析和發送的數據量是多少。

+0

好的,謝謝,不錯的建議:) – Mathieu

+0

@Mathieu歡迎您。如果這個答案解決了你的問題,那麼你可以考慮接受它作爲正確的答案。 –

+1

非常感謝。我仍然在測試阿爾喬姆科洛德科的回答。我必須真正嘗試使用真實代碼,並且我會投票選出最相關的答案。我不會忘記。 – Mathieu