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

问题描述

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

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>)

你有什么想法吗?

解决方法

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

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

// […]

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

您收到的错误意味着 func(...integrationConfig) 不起作用。是的,该函数从未被调用。对象传播和可迭代传播是有区别的。参数和数组使用iterable spread,这意味着必须满足两个条件:首先,你要传播的值必须是non-nullish;其次,值必须是可迭代的,即具有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);
,

Spread 语法不适用于此
使用 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 pushToSlack = function (channel,team,cb = function () {}) {

这个函数接受 7 个参数。

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

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

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

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

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

// order is not guaranteed!!!
...Object.values(integrationConfig) === [botName,channel,text] 
// or
...Object.values(integrationConfig) === [channel,text] 
// or 
...Object.values(integrationConfig) === [team,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,botName} = integrationConfig

pushToSlack(channel,etc);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...