2017-02-16 2 views
0

Обновленный Заголовок вопроса & Описание - 17 февраля 2017 годаКак установить значения Object.assign() по умолчанию для другого частично полного объекта только для ложных свойств hasOwnProperty?

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

В настоящее время я работаю над классом ботов, который извлекает API-интерфейс JSON путем обновления веб-вызовов. Object.assign(targetObj, sourceObj) помог много, но задавался вопросом, есть ли другой метод.

function (result) { 
    // default properties if they don't exist inside result object 
    const defaults = { 
     from: { 
      id: NaN, 
      username: "" 
     } 
    }; 

    // Example "from" may not exist at all in the result object. 
    // Maybe "from" does exist in result and provides only an "id", 
    // but I don't want to overwrite the "id" and still provide 
    // the "username" with a default value if there isn't one. 
} 

Я думал о нескольких, если кондиционер hasOwnProperty но мне интересно, есть ли лучший способ, чем таблица, если условия, такие как Object.assign()?

Я не хочу требовать другого сценария или использовать для этого npm.

+0

Лучший способ, которым я знаю, сделать глубокий клон [lodash's _.cloneDeep] (https://lodash.com/docs/4.17.4#cloneDeep) –

ответ

0

Я шел через мои фрагменты кода и пытается построить функциональность я хотел. После многих часов мне удалось добиться успеха.

Возврат нового целевого объекта без ущерба для оригинала.

function defaultsDeep(target, defaults) { 
    var clone = JSON.parse(JSON.stringify(target)); 
    function run(clone, defaults) { 
     const DEFAULTS_PROPERTY_NAMES = Object.getOwnPropertyNames(defaults); 
     DEFAULTS_PROPERTY_NAMES.forEach(function (property) { 
      if (Object.prototype.toString.call(defaults[property]) === "[object Object]") { 
       if (!clone.hasOwnProperty(property)) { 
        clone[property] = {}; 
       } 
       run(clone[property], defaults[property]); 
      } else if (!clone.hasOwnProperty(property)) { 
       clone[property] = defaults[property]; 
      } 
     }); 
    } 
    run(clone, defaults); 
    return clone; 
} 

Пример

var result = { 
    "message_id": 1, 
    "from": { 
     "id": 12345 
    } 
}; 

const defaults = { 
    "from": { 
     "id": null, 
     "username": "" 
    } 
}; 

var newObj = defaultsDeep(result, defaults); 
console.log("newObj " + JSON.stringify(newObj)); 
/* result 
{ 
    "message_id": 1, 
    "from": { 
     "id": 12345, 
     "username": "" 
    } 
} 
*/ 

Я не знаю, если есть лучший способ кодирования это. Но если есть, не стесняйтесь редактировать. Кроме того, если вам интересно, почему я не использовал метод цикла for in. Это потому, что jslint отпугивает его сейчас в es6, и я не думаю, что могу отключить предупреждение.

0

Как Джулиан Соро сказал в комментариях, я думаю, что лучший способ сделать это - через lodash. Они даже имеют функцию defaultsDeep

https://lodash.com/docs/4.17.4#defaultsDeep

+0

Я думаю, что это именно то, что мне нужно. Есть ли версия, отличная от npm, которая выполняет ту же задачу? Я не хочу включать другие библиотеки в свой класс, кроме встроенных узлов. – Nova

+0

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

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