API:在JavaScript中使构造函数可以链接而不带括号

时间:2016-02-19 13:47:18

标签: javascript api object native chaining

所以我正在构建一些可进行简单类型检查的可链接函数。目前,我必须调用我的函数:

Proceed().if('someString').is.a('string');

但我真正想要的是我的API看起来像这样:

proceed.if('someString').is.a('string');

请注意,在第二个代码示例中,第一个函数调用中缺少左括号和右括号。

从下面的代码中可以看出,我已经找到了如何让isa工作,但我似乎无法找到一种方法来删除来自Proceed()函数的括号。

以下是适用的代码示例

function Proceed() {
  if (!(this instanceof Proceed)) {
      return new Proceed();
    }
    this.target = "";
}

Proceed.prototype.if = function (target) {
    this.target = target;
    return this;
}

Proceed.prototype.a = function (type) {
    console.log(this.target + ' === ' +type, typeof this.target === type);
};

Object.defineProperty(Proceed.prototype, 'is', {
        get: function () {
            return this;
        }
    });


Proceed().if('someString').is.a('string'); // true
Proceed().if('someString').is.a('function'); // false


// Everything Above this line Works!

现在,我尝试从Proceed()删除括号,如下所示:

Object.defineProperty(Proceed.prototype, 'proceed', {
  set: function(){},
  get: function(){
    return Proceed(this);
  },
  configurable: true
});

proceed.if('someString').is.a('string');    // ReferenceError
proceed.if('someString').is.a('function');  // ReferenceError 

我从这里得到的错误是:

  

未捕获的ReferenceError:尚未定义

如果我将Proceed.prototype换成Object.prototype,那么我可以让它工作,但这意味着我已经扩展了一个原生对象,这可能会有问题。

所以有人知道我可以在没有危险地扩展原生对象的情况下解决这个问题吗?我在这里做错了什么?

Here is a jsFiddle with the above code samples

感谢任何帮助。

更新#1 此代码被设计为节点模块,因此无法访问浏览器的window对象。

3 个答案:

答案 0 :(得分:2)

您需要从实例值变量开始:

var proceed = new Proceed();

为了使它可以链接,你应该从你的方法返回新的实例,而不是改变"静态" proceed对象:

function Proceed(target) {
    this.target = arguments.length ? target : "";
}

Proceed.prototype.if = function (target) {
    return new Proceed(target);
}

或者通常,您需要使proceed.if工厂返回Proceed个实例,无论proceed是否只是一个普通对象。

(jsfiddle demo)

答案 1 :(得分:0)

变化:

Object.defineProperty(Proceed.prototype, 'proceed', {

Object.defineProperty(window, 'proceed', {

更新小提琴:https://jsfiddle.net/Lw29zyf1/4/

因此,您将在窗口范围内有一个“proceed”变量。

答案 2 :(得分:0)

请查看以下代码是否有任何帮助

var proto = Object.create(null);
proto.a = function(type) {
 console.log(this.target + ' === ' + type, typeof this.target === type);

};

Object.defineProperty(proto, 'is', {
    get: function() {
       return this;
    }
});

proto.if = function(target) {
 this.target = target;
 return this;

};


var proceed = Object.create(proto);

proceed.if('someString').is.a('string');