У меня есть эта функция:

function callWS(input) {
    var output = {
        "type"  : input["type"]  || "",
        "mark"  : input["mark"]  || "",
        "model" : input["model"] || "",
        "year"  : input["year"]  || ""
    };

    return output;
}

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

callWS(); ==> {"type":"","mark":"","model":"","year":""}
callWS({"type":"moto"}); ==> {"type":"moto","mark":"","model":"","year":""}
callWS({"type":"moto","mark":"audi"}); ==> {"type":"moto","mark":"audi","model":"","year":""}

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

Когда я называю это как callWS(), я получаю:

Uncaught TypeError: Cannot read property 'type' of undefined

Честно говоря, я не знаю, почему это работает для случая 2 и 3, но мне нужно заставить его работать и для первого случая. Я знаю, что если я использую:

if (input["type"])

Сделаю трюк, но мне нужно встроенное решение. Возможно ли это как-то?

2
paulalexandru 13 Дек 2016 в 19:33

3 ответа

Лучший ответ

Вы также должны указать для переменной input значение по умолчанию.

function callWS(input) {
   input = input || {};
   ...
}

В противном случае вы получаете доступ к свойствам несуществующего (неопределенного) объекта, которые приводят к ошибке (что у вас есть сейчас).

С другой стороны, доступ к несуществующим свойствам существующего объекта не рассматривается как ошибка в JS.

4
hindmost 13 Дек 2016 в 16:46

В ES6 напишите это как

function callWS({type = "", mark = "", model = "", year = ""} = {}) {
  return {type, mark, model, year};
}

Вот еще один подход, не связанный с ES6. Многие библиотеки содержат утилиту default, которая применяет некоторые свойства к другому объекту, если они отсутствуют.

function deflt(obj, defaults) {
  var keys = Object.keys(defaults);
  for (var i = 0; i < keys.length: i++) {
    var key = keys[i];
    if (!(key in obj)) obj[key] = defaults[key];
  }
  return obj;
}

Вы можете использовать это следующим образом:

function callWS(input) {
  input = input || {};
  deflt(input, {type: "", mark: "", model: "", year: ""});
  return input;
}

Примечание: как написано, это вернет измененную версию ввода. Отрегулируйте по необходимости, если это не то, что вы хотите.

0
13 Дек 2016 в 16:54

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

function extend(a, b){
    for(var key in b){
        if(b.hasOwnProperty(key)){
            a[key] = b[key];
        }
    }

    return a;
}

function callWS(input) {
    var defaultInput = {
        "type": "",
        "mark": "",
        "model":"",
        "year": ""
    }
    
    var output = extend(defaultInput, input);

    return output;
}

console.log(callWS());
console.log(callWS({"type":"moto"}));
console.log(callWS({"type":"moto","mark":"audi"}));
0
Nope 13 Дек 2016 в 16:44