Лучший способ сбросить все значения в объекте Javascript

мой объект JavaScript выглядит примерно так:

$scope.display = {
  current: {
       key1: 'value1',
       key2: ['a', 'b'],
       key3: 'value2'
    }
}

при некоторых событиях в моем коде я хотел бы сбросить эти значения до undefined как показано ниже:

$scope.display = {
  current: {
       key1: undefined,
       key2: [],
       key3: undefined
    }
}

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

8 ответов


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

function getDisplayObject() {
    return {
        current: {
            key1: undefined, // or you can omit undefined keys
            key2: [],
            key3: undefined
        }
    };
}

$scope.display = getDisplayObject();

поэтому позже, когда вам нужно сбросить данные, вы выполните $scope.display = getDisplayObject(); еще раз.


вот мое решение с lodash mapValues функция:

var $clearObject = function(value) {
  if (_.isString(value)) {
    return undefined
  };
  if (_.isArray(value)) {
    return [];
  };
};

var $scopeDisplay = {
  current: {
    key1: 'value1',
    key2: ['a', 'b'],
    key3: 'value2'
  }
};

$scopeDisplay.current = _.mapValues($scopeDisplay.current, $clearObject);

console.log($scopeDisplay);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>

вы бы петля свойства вашего объекта, как это

for (var key in current){
    if (current.hasOwnProperty(key)){
        if (typeof current[key] === 'string'){
            current[key] = undefined;
        } else if (current[key] instanceof Array) {
            current[key] = [];
        } // else ???  Not sure how you want to handle other types
    }
}

проверка массива с учетом некоторых потенциальных проблем, описанных в комментариях здесь


в моем угловом контроллере я делаю следующее:

    $scope.user = {
        firstname: "",
        lastname: "",
        displayname: "",
        email: "",
        password: "",
        passwordConfirm: ""
    };

    // default state of the form
    $scope.default = angular.copy($scope.user);

    /**
     * Resets the form to its default state
     * @return {void}
     */
    $scope.reset = function () {
        $scope.user = angular.copy($scope.default);
    }

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


Я сделал это в контроллере AngularJS как:

function item_object() {
    var list_item = {
        ID: '',
        Title: '',
        LastName: '',
        Contact: '',
        City: ''
    };

  return list_item;
}

//Define the object for the item
$scope.Item = item_object();

// Reset product details
$scope.clear = function () {
    $scope.Item = item_object();
}

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


Как насчет этого?

// If you just want to reset a simple object
let reset = (obj) => {
  Object.keys(obj).map(key => {
    if (obj[key] instanceof Array) obj[key] = []
    else obj[key] = undefined
  })
}


// If you want to reset a complex object
let recursiveReset = (obj) => {
  Object.keys(obj).map(key => {
    // Test if it's an Object
    if (obj[key] === Object(obj[key])) {
      recursiveReset(obj[key])
      return
    }
    if (obj[key] instanceof Array) obj[key] = []
    else obj[key] = undefined
  })
}

// So you can simply use
reset($scope.display.current)
// or
recursiveReset($scope.display)


нет встроенного способа. Вам нужно будет выполнить цикл и установить значения по умолчанию на основе типа.

var x = {
    current: {
        key1: 'value1',
        key2: ['a', 'b'],
        key3: 'value2'
    }
};

_(x.current).forEach(
    function(value, key, obj) {
        var result = undefined;
        if (_.isArray(value)) {
            result = [];
        }
        obj[key] = result;
    }
);

console.log(x);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>

основная идея, если у вас есть вложенные объекты

var x = {
        current: {
            key1: 'value1',
            key2: ['a', 'b'],
            key3: 'value2',
            xxxx:  {
                keyx1: 'valuex1',
                keyx2: ['xa', 'xb'],
                keyx3: 'valuex2'
            }         
        }
    };

function resetObj (obj) {
    _(obj).forEach(
        function(value, key, objRef) {
            var result = undefined;
            if (_.isObject(value)) {
                resetObj(objRef[key]);
            } else {                    
              if (_.isArray(value)) {
                  result = [];
              }
              objRef[key] = result;
            }
        }
    );

}  

resetObj(x)
console.log(x);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>

если вы используете Jquery, как кажется, вы делаете, вы можете сделать это:

Preapre пустой шаблон вашего объекта:

var emptyTemplate = {
  current: {
       key1: undefined,
       key2: [],
       key3: undefined
    }
}

и затем выполнить:

 $scope.display = $.extend(true, {}, emptyTemplate);

если вы хотите автоматизировать его, определить некоторые обязательные данные:

var defaults = {
 String:  undefined,
 Array: [],
 bool: false
}

затем цикл в вашем объекте, как и другие предложения:

function resetObj (obj) {
    _(obj).forEach(
        function(value, key, objRef) {
            if (_.isObject(value)) {
                resetObj(objRef[key]);
            } else {                    
              var myvarType = typeOf value;
              objRef[key] = defaults[myvarType];
            }
        }
    );
}  

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