JavaScript .свойство длины, дающее неверное значение

#javascript

#javascript

Вопрос:

У меня есть эта программа, в которой я добавляю значения внутри недавно объявленного массива с именем arr. Но когда я пытаюсь console.log(arr.length) , оно выдает мне значение 1 вместо 10 (ожидаемое значение). Кто-нибудь может объяснить, почему это происходит?

 httpRes.done(function (res) {
        if (httpRes.status == 201) {
            $('#salary_detail').empty();
            $('#salaryModal').removeClass('disabled').attr('data-toggle', 'modal');
        }
        else {
            var arr = [render_detail(res)]
            console.log(arr.length); // returns 1
            if (arr.length < 16) {
                $('#salaryModal').addClass('disabled').removeAttr('data-toggle');
            }
            else {
                $('#salaryModal').removeClass('disabled').attr('data-toggle', 'modal');
            };
            $('#salary_detail').html(render(arr));

        }
    });
  

И это функция render:

 function render_detail(res) {
    if (res.length < 9) {
        res[0] = `<span class='text-warning'>${formatter.format(res[0])}</span>`;
        res[1] = `<span class='text-danger'>-${formatter.format(res[1])}</span>`;
        res[2] = `<span class='text-danger'>-${formatter.format(res[2])}</span>`;
        res[3] = `<span class='text-danger'>-${formatter.format(res[3])}</span>`
        res[4] = `<span class='text-success'> ${formatter.format(res[4])}</span>`;
        res[5] = `<span class='text-danger'>-${formatter.format(res[5])}</span>`;
        res[6] = `<span class='text-muted'>${formatter.format(res[6])}</span>`;
        res[7] = `<span class='text-muted'>${res[7]}</span>`;
    }
    else {
        res[0] = `<span class='text-warning'>${formatter.format(res[0])}</span>`;
        res[1] = `<span class='text-danger'>-${formatter.format(res[1])}</span>`;
        res[2] = `<span class='text-danger'>-${formatter.format(res[2])}</span>`;
        res[3] = `<span class='text-danger'>-${formatter.format(res[3])}</span>`
        res[4] = `<span class='text-success'> ${formatter.format(res[4])}</span>`;
        res[5] = `<span class='text-danger'>-${formatter.format(res[5])}</span>`;
        res[6] = `<span class='text-muted'>${formatter.format(res[6])}</span>`;
        res[7] = `<span class='text-muted'>${res[7]}</span>`;
        res[8] = `<span class='text-warning'>${formatter.format(res[8])}</span>`;
        res[9] = `<span class='text-danger'>-${formatter.format(res[9])}</span>`;
        res[10] = `<span class='text-danger'>-${formatter.format(res[10])}</span>`;
        res[11] = `<span class='text-danger'>-${formatter.format(res[11])}</span>`
        res[12] = `<span class='text-success'> ${formatter.format(res[12])}</span>`;
        res[13] = `<span class='text-danger'>-${formatter.format(res[13])}</span>`;
        res[14] = `<span class='text-muted'>${formatter.format(res[14])}</span>`;
        res[15] = `<span class='text-muted'>${res[15]}</span>`;
    }
    return res;
}
  

Комментарии:

1. Вместо того, чтобы передавать res в функцию и выполнять res[0] = , создайте локальный массив, задайте ему значения и верните его. Изменение объекта — не очень хорошая идея. Также вы получаете длину как 1 из-за этого: var arr = [render_detail(res)] . res имеет несколько значений, но вы инкапсулируете внутри другого массива. Итак, arr[0] = res. Удалите квадратные скобки в этом выражении, и оно должно работать нормально

2. Функция может возвращать значение null и попадать в массив, и, следовательно, длина равна 1.

3. @Rajesh Я понимаю, что вы пытаетесь сделать. Спасибо, теперь это работает.

Ответ №1:

Вы оборачиваете свой массив внутри другого массива:

 var arr = [render_detail(res)]
  

Не делайте этого, просто назначьте его напрямую:

 var arr = render_detail(res);
  

Комментарии:

1. В качестве альтернативы вы можете даже предложить чисто функциональный подход, в котором render_details вместо мутации возвращается локально созданный arrey

2. @Rajesh это не тот вопрос, который задавал OP, но я составляю отдельный (вики сообщества) ответ, который делает это.

3. Отлично! Кроме того, я знаю, что OP не задает этот вопрос. Следовательно, предложил его в качестве альтернативы

Ответ №2:

Сохраняя это отдельно от ответа на вопрос, который вы на самом деле задали, ваша render_detail функция может быть написана таким образом:

 function render_detail(res) {
    const classes = ['warning', 'danger', 'danger', 'danger',
                     'success', 'danger', 'muted', 'muted'];
    const signs = ['', '-', '-', '-', ' ', '-', '', ''];

    return res.map((value, n) => {
        const mod = n % 8;
        if (mod !== 7) {
            value = formatter.format(value);
        }
        const cls = classes[mod];
        const sign = signs[mod];
        return `<span class="text-${cls}">${sign}${value}</span>`;
    });
}
  

Это возвращает новый массив, где каждый элемент преобразуется с помощью внутренней функции. Эта функция, в свою очередь, полагается на повторяющиеся шаблоны в данных, чтобы добавить необходимую оболочку вокруг каждого элемента.

Комментарии:

1. классный трюк, но мне нужен знак плюс и минус спереди, и, похоже, вы просто добавляете минус к каждому элементу. Хотя спасибо за упрощение!

2. @MunkhturB. Я только что заметил это и сейчас исправляю.

3. @Rajesh оставьте это в покое, пожалуйста.

4. ОК. Добавлено объяснение, чтобы читателям было легче понять. Но ваш вызов

5. Я создал эту вики-страницу сообщества, потому что я не хочу, чтобы она имела репутацию, а не для того, чтобы сделать ее бесплатной для всех. Ваши изменения столкнулись с правкой, которую я делал сам.