【问题标题】:Infinite functions calls like 'string'.replace().replace()无限函数调用,如 'string'.replace().replace()
【发布时间】:2018-10-17 08:23:00
【问题描述】:

我不确定如何解释,所以我将从输出开始。 我需要返回这个:

{
   replies:
   [
      { type: 'text', content: 'one' }
      { type: 'text', content: 'two' }
      { type: 'text', content: 'three' }
   ],
   conversation: {
      memory
   }
}

我想通过内联语句返回它。 所以我想这样称呼:

reply.addText('one').addText('two').addText('three').addConversation(memory)

请注意,addText 可以无限次调用,而 addConversation 只能调用一次。对话也是可选的,在这种情况下,如果没有对话,则对话对象不应出现在输出中。

【问题讨论】:

标签: javascript


【解决方案1】:

要创建自定义结构化对象,请使用构造函数,例如 Reply

要在方法调用的返回值上调用实例方法,请从方法中返回实例对象。

防止多次添加对话对象的选择包括抛出错误(如下所示)或可能记录警告,并且在第一次调用 addConversation 后根本不添加其他对象。

编写代码来实现需求。

例如使用原生 javascript:

function Reply() {
    this.replies = [];
}
Reply.prototype.addText = function( content) {
    this.replies.push( {type: "text", content: content});
    return this;
}
Reply.prototype.addConversation = function( value) {
    if( this.conversation) {
        //throw new Error("Only one conversation allowed");
    }
    this.conversation = {conversation: value};
    return this;
};
Reply.prototype.conversation = null;

// demo
var reply = new Reply();
reply.addText( "one").addText("two").addConversation("memory?");
console.log( JSON.stringify( reply, undefined," "));

(console.log 使用 JSON stringify 避免列出继承的方法)

【讨论】:

  • 如今,即使是普通的 Javascript 也支持实际的类语法,但这只是一个小提示。
【解决方案2】:

一种可能的实现方式是创建一个构建器,如下所示:

function create() {
  const replies = []; // store all replies in this array
  let conversation; // store the memory here
  let hasAddConversationBeenCalled = false; // a state to check if addConversation was ever called

  this.addText = function(content) {
    // add a new reply to the array
    replies.push({
      type: 'text',
      content
    });

    return this;  // return the builder
  };

  this.addConversation = function(memory) {
    if (!hasAddConversationBeenCalled) {  // check if this was called before
      // if not set the memory
      conversation = {
        memory
      };
      hasAddConversationBeenCalled = true;  // set that the memory has been set
    }
    return this;  // return the builder
  }

  this.build = function() {
    const reply = {
      replies
    };

    if (conversation) { // only if converstation was set
      reply.conversation = conversation;  // add it to the final reply object
    }

    return reply; // finally return the built respnse
  }

  return this; // return the new builder
}

然后您可以按如下方式使用它:

const builder = create();

const reply = builder.addText('one').addText('two').addText('three').addConversation({}).build();

Here is a link to a codepen 玩。

【讨论】:

    【解决方案3】:

    如果您特别想通过多个函数调用添加 assemble 这个,那么 builder 模式是您最好的选择,正如 vader 在他们的评论中所说的那样。

    但是,如果目标是简单地创建简明地构建这些对象的简写,则可以使用将文本列表作为数组的函数来完成。

    const buildObject = (textArray, memory) => {
      return Object.assign(
        {},
        {
          replies: textArray.map(x => {
            return {
               type: 'text',
               value: x
              }
            })
        },
        memory ? {conversation: memory} : null
      )
    }
    var memory = { };
    
    //with memory
    console.log(buildObject(['one', 'two', 'three'], memory ))
    
    //without memory
    console.log(buildObject(['one', 'two', 'three']));
    

    小提琴示例:http://jsfiddle.net/ucxkd4g3/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-23
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 2014-12-28
      • 2020-07-14
      • 1970-01-01
      • 2022-07-18
      相关资源
      最近更新 更多