通过对象属性实现条件逻辑

时间:2019-01-29 07:43:51

标签: javascript reactjs

const abc = ({ data }) => {
  console.log('abc'+data);
}

const bcd = ({ data }) => {
  console.log('bcd'+data);
}

鉴于上述两个功能,取决于data,调用相关功能。

方法A:

if (data === 'funA') {
  this.abc({ data });
} else if (data === 'funB') {
  this.bcd({ data });
}

方法B:

const obj = {
  funA: () => this.abc({ data: 'age' }),
  funB: () => this.bcd({ data: 'name' })
}

obj[data] && obj[data]();

//Or provide a default handling function as below
//(obj[data] && obj[data]()) || someDefaultHandlingMethod()

最近遇到了一些中型文章,建议使用方法B而不是方法A,以避免使用冗长的if语句。我想知道当我们有() => abc({ data: 'age' })时,MethodB是否实际上创建了冗余对象?还是有更好的方法来实现它?

注意:

以上只是伪代码,用于分享更多关于如何通过使用obj属性并替换if-else来调用函数的想法

2 个答案:

答案 0 :(得分:3)

为什么不仅仅为属性设置函数?这需要访问器来获取正确的功能,并且还需要使用数据进行调用。逻辑保留在原始功能中。

const obj = {
    funA: this.abc,
    funB: this.bcd
}

obj[data](data);

答案 1 :(得分:1)

您可以从面向对象的方法中获取一页,也许可以使用polymorphism

//define two types
function Foo() {}
function Bar() {}

//define a common interface for interacting with them
Foo.prototype.callMe = data => console.log( "Hi, I'm Foo, and your data is: " + data);
Bar.prototype.callMe = data => console.log( data + "\nthis was your data and this has been Bar.");

//instantiate one of each
let collection = [
  new Foo(),
  new Bar()
]

for (let obj of collection) {
  //call the common interface - the implementation depends on the object that uses it
  obj.callMe("lorem ipsum");
}

这是决定发生什么情况的多态方法。但是,它是单个分发的基础-即,选择要调用的方法取决于单个对象。其他语言具有multiple dispatch,您可以在其中根据多个条件来更改所调用的方法。 OO对此有一些解决方案,例如Visitor Pattern的形式double dispatch

function SingleObjectType() {
  this.foo = data => console.log("calling foo() method. Data is: " + data);
  
  this.bar = data => console.log(data + " was passed to bar() method");
  
  //entry point for a visitor
  this.accept = visitor => visitor(this); 
};

//set the common data
let data = "lorem ipsum";

//create visitors
function fooVisitor(obj) {
  obj.foo(data);
}

function barVisitor(obj) {
  obj.bar(data);
}

const singleObject = new SingleObjectType();

singleObject.accept(fooVisitor);
singleObject.accept(barVisitor);

这是Visitor模式的轻量级实现,其中您传递了一个函数作为回调,而不是整个对象。对于JavaScript来说,它更惯用,而且设置起来也更少。一种更实用的方法是使具有更高阶的函数生成访问者回调,这意味着您可以更轻松地更改传入的数据(目前,这取决于访问者函数定义中可用的数据):

function SingleObjectType() {
  this.foo = data => console.log("calling foo() method. Data is: " + data);
  
  this.bar = data => console.log(data + " was passed to bar() method");
  
  //entry point for a visitor
  this.accept = visitor => visitor(this); 
};

//set the common data
let commonData = "lorem ipsum";

//more OO terminology: visitor creators
//more FP terminology: curried functions
function fooVisitor(data) {
  return function(obj) {
    obj.foo(data);
  }
}

function barVisitor(data) {
  return function(obj) {
    obj.bar(data);
  }
}

const singleObject = new SingleObjectType();

singleObject.accept(fooVisitor(commonData));
singleObject.accept(barVisitor(commonData));

出于完整性考虑,一种更面向对象的方法是将访问者转变为实际的课堂:

function SingleObjectType() {
  this.foo = data => console.log("calling foo() method. Data is: " + data);
  
  this.bar = data => console.log(data + " was passed to bar() method");
  
  //entry point for a visitor
  this.accept = visitor => visitor.visit(this); 
};

//set the common data
let data = "lorem ipsum";

//visitor classes
function FooVisitor(data) {
  this.visit = obj => obj.foo(data);
}

function BarVisitor(obj) {
  this.visit = obj => obj.bar(data);
}

const singleObject = new SingleObjectType();

singleObject.accept(new FooVisitor(data));
singleObject.accept(new BarVisitor(data));