如何在声明无法更改的函数中将对象作为单个参数传播?

How to spread an object as individual arguments in a function whose declaration I cannot change?

我有一个具有某些属性的对象,例如;

integrationConfig = {
  iconEmoji: ':myIconEmoji:', 
  team: 'myTeam', 
  text: 'myText', 
  channel: 'myChannel', 
  botName: 'myBot'
}

我将此对象传递给下面所示的函数(attachments 不重要)。

return await this.pushToSlack(...integrationConfig, attachments);

重要的是,这个函数是 NPM 包的一部分,所以 我不想更改函数声明

函数声明如下:

exports.pushToSlack = function (channel, text, botName, iconEmoji, team, attachments, cb = function () {}) {
  // […]
}

我在 pushToSlack 函数中放置了一些断点,但调试器没有跳转到该行。我想这个函数没有以某种方式被调用。我也收到此错误:

Debug: internal, implementation, error 
    TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
    at Function.all (<anonymous>)

你有什么想法吗?

扩展语法不适用于此
使用 Destructuring assignment

integrationConfig = 
  { iconEmoji : ':myIconEmoji:'
  , team      : 'myTeam'
  , text      : 'myText'
  , channel   : 'myChannel'
  , botName   : 'myBot'
  } 

来电:

return await this.pushToSlack( integrationConfig, attachments);

函数:

 exports.pushToSlack = function ({channel, text, botName, iconEmoji, team}, attachments, ...
 //..Destructuring assignment....^.......................................^
 // Arguments can be in any order you want
 // and no obligation to have all of them

如果您无法更改函数的参数列表,则必须定义参数的预期顺序,然后将您的对象映射到此顺序:

const argumentOrder = [
    "channel",
    "text",
    "botName",
    "iconEmoji",
    "team"
  ];

// […]

return await this.pushToSlack(...argumentOrder.map((property) => integrationConfig[property]), attachments);

您收到的错误意味着 func(...integrationConfig) 无法正常工作。是的,永远不会调用该函数。对象传播和可迭代传播之间存在区别。参数和数组使用iterable spread,这意味着必须满足两个条件:首先,你要传播的值必须是non-nullish; and secondly, the value must be iterable, i.e. something that has Symbol.iterator。对象传播只检查第一个条件。

理论上,您可以将这样的符号 属性 添加到您的对象中,这样您就可以使用您的原始语法:

const integrationConfig = {
    iconEmoji: ":myIconEmoji:",
    team: "myTeam",
    text: "myText",
    channel: "myChannel",
    botName: "myBot",
    *[Symbol.iterator](){
      yield this.channel;
      yield this.text;
      yield this.botName;
      yield this.iconEmoji;
      yield this.team;
    }
  };

// […]

return await this.pushToSlack(...integrationConfig, attachments);

所以你有功能

const pushToSlack = function (channel, text, botName, iconEmoji, team, attachments, cb = function () {}) {

这个函数接受 7 个参数。

你有一个好主意,传播一个对象integrationConfig,希望它成为7个论点。

然而,传播对象只会克隆完全相同的对象 属性。

const obj = {...integrationConfig} 等于 ONE 对象.

您可以改为传递数组并展开它。

pushToSlack(...Object.values(integrationConfig)) 但是一个对象并不能保证键的顺序。所以它可能是

// order is not guaranteed!!!
...Object.values(integrationConfig) === [botName, channel, iconEmoji, team, text] 
// or
...Object.values(integrationConfig) === [channel, botName, iconEmoji, team, text] 
// or 
...Object.values(integrationConfig) === [team, botName, iconEmoji, channel, text] 

However your function need a fix order of arguments. 
 1. channel as first argument, 
 2. text as second argument
 3. etc.

我相信你可以做到这一点

const integrationConfig = {
        iconEmoji: ':myIconEmoji:', 
        team: 'myTeam', 
        text: 'myText', 
        channel: 'myChannel', 
        botName: 'myBot'
    }

const {iconEmoji, team, text, channel, botName} = integrationConfig

pushToSlack(channel, text, botName, iconEmoji, team, etc);