2012-01-08 2 views
1

У меня есть следующий (пример) массив объектов:Javascript «неопределенными» при использовании переменной функции на множестве объектов

var theArray = [ 
    {theId:'1', num: 34}, 
    {theId:'2', num: 23}, 
    {theId:'5', num: 26} 
]; 

и эта функция, которая прекрасно работает в цикле через них:

function printValues() { 
    var i = 0; 
    for(i; i<theArray.length; i++) { 
     var obj = theArray[i]; 
     document.getElementById('result1').innerHTML += obj.theId + ' = ' + obj.num + '<br>'; 
    } 
} 

Однако, если я хочу абстрагироваться эту функцию для использования в подобных массивов с помощью функции переменных для доступа к объектам в них, как это:

function printValuesVar(arr,elemId,arrId,arrNum) { 
    var i = 0; 
    for(i; i<arr.length; i++) { 
     var obj = arr[i]; 
     document.getElementById(elemId).innerHTML += obj.arrId + ' = ' + obj.arrNum + '<br>'; 
    } 
} 

«не определена» результат при вызове, как показано ниже (как я вроде ожидать, так как «Arrid» не имя объекта):

printValuesVar(theArray,'result2','theId','num'); 

Как можно использовать значение, передаваемое переменную функцию к получить доступ к значениям объектов в массиве по имени?


переписаны следующие советы против antipatterns:

function printValuesVar(arr,elemId,arrId,arrNum) { 
    var i = 0; 
    var content = ''; 
    for(i; i<arr.length; i+=1) { 
     var obj = arr[i]; 
     content += obj[arrId] + ' = ' + obj[arrNum] + '<br>'; 
    } 
    document.getElementById(elemId).innerHTML = content; 
} 
+2

Ваш код содержит несколько антишаблоны: (1) Вы запрос через 'getElementById' внутри цикла - нет необходимости. Просто получите ссылку заранее; (2) вы присваиваете 'innerHTML' внутри цикла - снова нет необходимости в этом. Вы хотите сохранить DOM-манипуляцию как минимум. Постройте строку HTML с циклом, а затем присвойте 'innerHTML' * после * цикла. –

+0

+1 для руководства - так как это был учебный процесс, я переписал функцию (добавленную выше), чтобы включить ваши предложения, * перед тем, как смотреть на ваши примеры ниже. Теперь я попробую совет от PointedEars. –

ответ

2

Поскольку вы loking для ключа "Arrid", а не ключ хранится в переменной Arrid

document.getElementById(elemId).innerHTML += obj[arrId] + ' = ' + obj[arrNum] + '<br>'; 
+0

Хороший простой ответ, заставил все сразу работать. –

3

Попробуйте это:

function printValuesVar(arr, elemId, arrId, arrNum) { 
    var content = ''; 

    arr.forEach(function (arrElem) { 
     content += arrElem[ arrId ] + ' = ' + arrElem[ arrNum ] + '<br>'; 
    }); 

    document.getElementById(elemId).innerHTML = content; 
} 

Или немного больше преимуществ CED:

function printValuesVar(arr, elemId, arrId, arrNum) { 
    document.getElementById(elemId).innerHTML = arr.map(function (arrElem) { 
     return arrElem[ arrId ] + ' = ' + arrElem[ arrNum ]; 
    }).join('<br>'); 
} 

ES5-shim for shitty browsers

+2

Вместо последовательной конкатенации строк ('+ =') в цикле, рассмотрите 'push'ing в' Array', который вы присоедините позже. Простой цикл 'for', скорее всего, более эффективен и, очевидно, более совместим, чем любой из' forEach' или 'map'. – PointedEars

+1

@PointedEars В моем втором примере используется 'join()' вместо '+ =' конкатенации строк. Методы итераций массива не реализованы в IE8, но вы можете легко закрепить этот браузер. Что касается эффективности, то верно, что 'for' немного быстрее, чем методы массива, но [это не значит, что это предпочтительнее] (http://www.youtube.com/watch?v=UTEqr0IlFKY#t=19m46s). –

+1

'var content = []; for (var i = 0, len = arr.length; i PointedEars

Смежные вопросы