2017-10-04 76 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