创建包含动态变量的多个对象,并在循环内为其属性赋值

时间:2017-10-05 23:16:50

标签: javascript jquery global-variables

我有一个问题,如何创建多个名称中包含变量的对象,并为属性赋值,所有这些都在循环的上下文中。

javascript代码位于问题的底部。

基本上,在我当前的代码中,以下代码正在运行:

window['stBgAsset'+stId] = new Image();

有效地,它创造了 stBgAsset15 = new Image()和stBgAsset23 = new Image() 当我键入:stBgAsset15时,这与Chrome开发工具中的工作方式相同 它返回img。

但是一旦我尝试给这些对象赋予属性(同时保持在'for'循环内),它就不起作用,因为我试图在chrome dev工具的控制台上访问它并且它表示未定义。

例如,当我使用'stBgAsset'+ stId.imageloaded = 1; ,我的意思是“在循环for循环时设置以下内容”

stBgAsset15.imageloaded = 1
stBgAsset23.imageloaded = 1
and so on...

同样当我把afterClickOnButton('stBgAsset'+ stId);在循环结束时,我的意思是“在循环for循环时设置以下内容”

afterClickOnButton('stBgAsset15');
afterClickOnButton('stBgAsset23');

今天我遇到了当前代码的两大问题:

  1. 这不起作用(最大的问题) 我确定,因为当我键入Dev tools'stBgAsset15.imageloaded'时,它会输出“undefined”

  2. 次要不太重要的问题:我知道我正在污染全局命名空间,并且想要一个更干净/更安全的javascript方式来执行此操作,如果它可能并且与我正在做的相关,而不是使用此窗口[] 。

  3. storyObject

    // main object is a array made of json elements
    // of course this is an example and comes from  the database. We have no way to know before if id is 15 and 23.it changes for each page loaded
    StoryObject =
    [ {"id":15,
       "name": "name1",
       "filename":"img5.jpg"},
      {"id":23,
       "name": "name2",
       "filename":"img7.jpg"},
      //...and so on
    
    ]
    

    JS代码

    //iterating through each json of the above array
    for (var i = 0; i < storyObject.length; i++) {
        var currentObject = storyObject[i];
    
        var stId          = currentObject.id;
        var stFilename    = currentObject.filename; 
    
        var jqueryCurrentShellImg = $('#content').find('#asset-'+stId);   
    
        //ISSUE IS HERE
        // I want to create names with variable number inside
        // creating this way 
        // stBgAsset15 = new Image() and stBgAsset23 = new Image() 
        window['stBgAsset'+stId] = new Image();
    
        jqueryCurrentShellImg.on('load', function(e) {
          console.log("image XXX downloaded");      
          'stBgAsset'+stId.imageloaded = 1;
          console.log('value: '+'stBgAsset'+stId);
        }); 
    
        afterClickOnButton('stBgAsset'+stId);         
    
      }
    
    function afterClickOnButton(data) {
      //some actions here where i need to have stBgAsset15 and stBgAsset23 passed
    }
    

2 个答案:

答案 0 :(得分:0)

您可以直接在StoryObject内存储其他信息。

var StoryObject = [{
    "id": 15,
    "name": "name1",
    "filename": "img5.jpg"
  },
  {
    "id": 23,
    "name": "name2",
    "filename": "img7.jpg"
  }
];

StoryObject.forEach((so, i) => {
  $('#content').find('#asset-' + so.id).on('load', function () {
    so.imageloaded = true;
    console.log(so.filename + " loaded successfully");
  });
  afterClickOnButton(so);
});

function afterClickOnButton(data) {
  //some actions here where i need to have stBgAsset15 and stBgAsset23 passed
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
  <img id="asset-15" src="http://via.placeholder.com/350x150">
  <img id="asset-23" src="http://via.placeholder.com/450x150">  
</div>

答案 1 :(得分:0)

'stBgAsset'+ stId.imageloaded = 1;不行。

你需要做     window ['stBgAsset'+ stId] .imageloaded = 1;

否则,将imageloaded属性添加到stId变量。

至于你的第二个问题,有多种方法可以限制全局命名空间污染,或者完全阻止它。

一种方法是通过创建根对象来命名它。所以而不是:

window[object15]=1;

或等效的

window.object15=1;

你做

window.myNamespace = {};
window.myNamespace[object15]=1;

或者你可以在功能范围内做所有事情:

(function () {
    var object15=1;
    var b = document.getElementsByTagName('body');
    b.onClick=function(){
        alert(object15);
    };
})();

本地函数变量与全局命名空间完全隔离。在此示例中,该值显示为保留,因为单击正文时会显示该值。