Изменить метод в операторе условно

#javascript

#javascript

Вопрос:

Возможно ли изменить метод в соответствии с вводом без необходимости дублировать функцию? Например, если переменная intent принимает значение payment , метод, применяемый к объекту stripe , является paymentIntents . Если intent есть setup , то метод, применяемый к объекту stripe , является setupIntent

 let intent = req.userIntent

stripe.paymentIntents.update("teste")
  

Чего бы я не хотел делать, так это:

 let intent = req.userIntent

if (intent = "payment") {
     stripe.paymentIntents.update("teste")      
   } else if (intent = "setup") {  
     stripe.setupIntents.update("teste")
 }
  

Уточняю, код намного больше, но одинаков для обеих ситуаций, за исключением метода ( paymentIntents или setupIntent ), и я не хочу повторять код.

Ответ №1:

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

 const o = {
   payment: 'paymentIntents',
   setup: 'setupIntents',
};
  

 let intent = req.userIntent;

const o = {
   payment: 'paymentIntents',
   setup: 'setupIntents',
};

stripe[o[intent]].update("teste");  

Примечание: вы можете расширить вспомогательный объект новыми полями в соответствии с вашими потребностями.

Ответ №2:

Вы можете использовать условный оператор в сочетании с обозначением в скобках:

 const prop = intent === 'payment'
  ? 'paymentIntents'
  : intent === 'setup'
    ? 'setupIntents'
    : null;
stripe[prop]?.update("teste");
  

или вы можете сделать

 stripe[intent   'intents']?.update("teste");
  

Обратите внимание, что = это присваивание, а не сравнение. Вы хотите === сравнить, а не = .

Если intent может быть только 'payment' или 'setup' , это проще:

 stripe[intent === 'payment' ? 'paymentIntents' : 'setupIntents'].update("teste");
  

или

 stripe[intent   'intents'].update("teste");
  

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

1. Удивительно! Когда сложные вещи решаются с элегантностью! Я не знал об этом prop-ресурсе. Сработало отлично…

Ответ №3:

Есть ли идея сэкономить на повторном коде? Вы можете создать stripe-вызов функции из строки…

 function makeAStripeFN(intent) {
  return new Function(`return stripe.${intent}Intents`);
}
  

Используйте его следующим образом…

 makeAStripeFN(req.userIntent)().update("teste")
  

Доказывая это с помощью макетного объекта stripe…

 class MockStripe {
  get paymentIntents() {
    console.log('called paymentIntents')
    return this
  }
  get setupIntents() {
    console.log('called setupIntents')
    return this
  }
  update(string) {
    console.log(`called update with '${string}'`)
  }
}
let stripe = new MockStripe()

function makeAStripeFN(intent) {
  return new Function(`return stripe.${intent}Intents`);
}

// 'payment' and 'setup' are values taken by req.userIntent

makeAStripeFN('payment')().update("teste")
console.log('n')
makeAStripeFN('setup')().update("teste")