Изменить значение динамически добавленного объекта js

У меня есть массив с некоторыми предопределенными данными

var data = [
    {amount:20, speed:100},
    {amount:40, speed:50}
];

Затем я добавляю данные в вышеуказанный массив

function addMore() {
    data = appendObjTo(data, {amount: 1500,speed:100});
}

function appendObjTo(thatArray, newObj) {
    const frozenObj = Object.freeze(newObj);
    return Object.freeze(thatArray.concat(frozenObj));
}

Данные добавляются нормально, но по какой-то причине я не могу изменить значение новых данных

function runData() {
    perSec = 0;
    $.each(data, function( key, value ) {
        perSecCalc = Math.round(value.speed/60);
        perSec += perSecCalc;
        // Below line works only for predefined objects, but not objects from "addMore()"
        data[key].amount = value.amount-perSec;
    });

    setTimeout(function() {
        runData();
    },1000);
}

В то время как предопределенный объект в "var data" изменяется, динамически добавленные данные из "addMore" не изменяются.

Почему новые данные не меняются?

Обновление: см. Эту скрипку

1 ответ

Решение

Вы используете Object.freeze в своем appendObjTo функция. Определение Object.freeze - Object.freeze().

Так как frozenObj создан с использованием Object.freeze(), значения не могут быть изменены. Кроме того, вы не получаете никаких ошибок на консоли. JS не показывает ошибку без строгого режима. Я изменил скрипту, чтобы включить строгий режим, и вы можете видеть, что он выдает и ошибка, когда вы делаете data[key].amount = value.amount-perSec;, Я также прикрепил скрипку, чтобы поиграть с методом Object.freeze(), и вы можете экспериментировать самостоятельно.

Модифицированная скрипка

JS

(function () {

"use strict";

var data = [
    {amount:20, speed:100}
];


function runData() {
    var perSec = 0;
    $.each(data, function( key, value ) {
        var perSecCalc = Math.round(value.speed/60);
        perSec += perSecCalc;
        // Below line works only for predefined objects, but not objects from "addMore()"
        data[key].amount = value.amount-perSec;
        $('#test').prepend(data[key].amount+'<br>');
    });

    setTimeout(function() {
        runData();
    },1000);
}

function appendObjTo(thatArray, newObj) {
  const frozenObj = Object.freeze(newObj);
  return Object.freeze(thatArray.concat(frozenObj));
}

function addMore() {
    data = appendObjTo(data, {amount: 1500,speed:100});
}

setTimeout(function() { addMore(); },1500);

runData();


})();

Object.freeze скрипка

var arr = [10, 20, 30];
console.log(arr);

arr = Object.freeze(arr.concat([40, 50]));
console.log(arr);

arr[3] = 80;
console.log(arr); // doesn't change

// arr.push(60); // error, cannot add property 5, object is not extensible

arr = Object.freeze(arr.concat([{ x: 100 }]));
console.log(arr);

arr[5].x = 200;
console.log(arr); // changes, as Object.freeze only locks the first level values.
Другие вопросы по тегам