如何在JavaScript中实现非CQS API以设置和获取选项

时间:2016-03-14 12:48:10

标签: javascript api

我正在开发一个提供一些配置选项的库。简化,想象一下:

let library() {
  let options = {
    optA: 'optA',
    optB: 'optB'
  };

  return {
    //Public API
    stuff1: ...,
    stuff2: ...
  };
};

这个库以这种方式使用:

let libInstance = library();
libInstance.stuff1(...);
//Do stuff
libInstance.stuff2(...);
//Do more stuff

但我的想法是你也可以改变库的配置选项。这将是这样的:

libInstance.optA('new value for optA');
let optBValue = libInstance.optB();
console.log(optBValue);
//prints "optB"

因此,如果您将方法的名称作为方法调用,则它将作为setter或getter使用,具体取决于调用是否带有参数。我的问题是有很多选项,我认为必须有可能实现这一点,而无需在公共API中为每个选项定义一个方法,特别是因为所有这些方法都会有非常相似的行为。

然后,我想要的是当你在我的库中调用一个未定义的函数时,它检查是否有一个带有该函数名称的选项,如果它存在,则调用相关的setter或getter。只有在函数不与任何选项匹配的情况下,才会抛出异常。

这可能吗?怎么样?谢谢。

1 个答案:

答案 0 :(得分:0)

我一直在调查,我认为不可能做到我想要的(当你在我的库中调用未定义的函数时,它检查是否有一个带有函数名称的选项,并且如果存在,请调用相关的setter或getter)。

相反,我创建了这个辅助方法来生成默认访问器:

var generateAccessors = function generateAccessors(obj, api, exceptions) {
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (exceptions.indexOf(key) < 0 && !api[key]) {
        api[key] = function accessor(newValue) {
          if (arguments.length === 0) {
            return obj[key];
          } else {
            obj[key] = newValue;
            return api;
          }
        };
      }
    }
  }
};

obj是输入对象,api是我们要创建访问器的对象,exceptions是一个数组,我们可以列出帮助器将忽略的键。此外,如果在key对象中定义api,它也将被忽略,因此如果您想要一个特殊的访问者,请先在api对象中定义它,然后再调用此生成器。

关于accessor功能本身的几条评论:

  • 请注意,确定访问者是否被称为getter或a 我们检查arguments长度。这允许设置变量 值undefined,如果它是明确提供的。
  • 另请注意,如果将访问者作为setter调用,它将返回 api对象。这提供了method chaining功能。

当我将此作为解决方案的时刻,但如果有人知道更好的解决方案,我将很高兴看到它。