以特定顺序在链中执行一系列方法

时间:2017-09-07 03:41:24

标签: javascript constructor

假设我们有一个构造函数及其原型:

function Person(name){
  this.name = name;
}

Person.prototype = {
  setSex: function(sex){
    this.sex = sex;
    return this;
  },
  setEyes: function(color){
    this.eyes = color;
    return this;
  },
  setHair: function(color){
    this.hair = color;
    return this;
  }  
}

为了创建人并构建他们的功能,我们使用方法链,如下所示:

var person1 = new Person('John');    
person1.setEyes('Blue').setHair('Brown').setSex('male')

除了我使用令人沮丧的框架要求我创建sex 第一个,然后是eyes然后hair(具体而言)以该顺序)。我认为期望按顺序排序方法是愚蠢和不合理的,但我别无选择。所以,我试图构建一个更宽容的函数,并采用(可能无序的)方法列表并在后台按顺序构建它们。

问题是,我甚至不知道从哪里开始。

我正在考虑在链中的每个方法执行后将结果推送到对象中,然后触发一系列遵循预定义顺序的函数(可能看起来像这样):

person1 = {
  hair: 'brown',
  sex: 'male',
  eyes: 'blue',
}    

var orderOfMethods = ['sex','eyes','hair'];

orderOfMethods.forEach(function(){
  if(currentValue in person1){
    //do that function
  } 
})

但这似乎是一个非常复杂的解决方案。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

嗯,为什么不只是有一个函数以正确的顺序调用函数并将params作为对象?

function createPerson(params) {
  return (new Person())
    .setSex(params.sex)
    .setEyes(params.eyes)
    .setHair(params.hair);
}

然后你可以createPerson({ hair: 'blue', eyes: 'brown', sex: 'male' })

如果确实需要一系列方法,只需使用这些方法创建一个虚拟对象,将params存储起来,然后再使用某种run函数来应用所有方法调用。假设:

function makeChainBuilder(...funcs) {
    const builder = { __params__: {} };
    funcs.forEach(func => {
        builder[func] = function(...args) {
            this.__params__[func] = args;
        };
    });

    builder.run = target => {
        funcs.forEach(func => {
            const args = this.__params__[func];
            if(args) {
                target = target[func](...params);
            }
        });

        return target;
    }
}

这可以像makeChainBuilder('setSex', 'setEyes', 'setHair')一样使用,并返回一个builder对象,如果你调用其中一个方法,只需将params存储起来。稍后当你可以run并传递一个目标时,它将使用存储的参数调用相同的函数,但是在目标对象上以指定的顺序调用:

builder.setEyes('brown');
builder.setHair('blue');
builder.setSex('male');
builder.run(new Person()); // this will apply (new Person()).setSex('male').setEyes('brown').setHair('blue');