javascript 可链接的嵌套子类

javascript chainable nested subclass

我正在有效地尝试构建一个包含子对象或其他函数的可链接对象。

应该这样使用:

val().rules.phone("someValue");

到目前为止:

var val = function(){
  var validator = function(){
    this.fields = [];
    return this;
  }
  validator.prototype = {
    addField: function(fieldName){
       this.fields.push(fieldName);
       return this;
    },
    rules: {
      phone: function(){
        //RETURNING THIS DOES NOT RETURN THE PARENT SCOPE
        //IT RETURNS SCOPE OF PHONE FUNCTION
        return this;
      }
    }
  }
  return new validator();

}

我还尝试了通过原型链的循环引用:

var val = function(){
    var validator = function(){
        this.fields = [];

        return this;
    }

    var rules = function(){
        validator.call(this);
    }
    rules.prototype = Object.create(validator.prototype);
    rules.prototype.constructor = rules;
    rules.prototype.phone = function(){
    console.log('hone');   
    }

    validator.prototype = {
        addField: function(fieldName){
            this.fields.push(fieldName);    
            return this;
        },
        rules: new rules()

    }

   return new validator();
}

var z = val().rules;
//no 'addFields' function exists on the validator object in the chain.
console.log(z);

问题:

在第一个 val().rules.phone() return 中是其功能范围而不是父范围。它应该 return 验证器范围。

在第二个示例中,val().rules 确实在其原型链上有验证器作为父级,但是 addFields 打印未定义,并且在跟踪链时在控制台中不存在。

我知道我通过添加规则文字使问题复杂化了。我可以用直接放在原型对象上的函数来实现链接。这是为了我自己的澄清。是否有任何其他可能的方法来使用相同的样式用法来实现它?

var val = function(){
    var validator = function(){
        this.fields = [];

        return this;
    }

    var rules = function(){
        if(!this instanceof rules) return new rules();
        validator.call(this);
        return this;
    }
    validator.prototype = {
        addField: function(fieldName){
            this.fields.push(fieldName);    
            return this;
        },
        rules: rules

    }
    rules.prototype = Object.create(validator.prototype);
    rules.prototype.phone = function(){
    console.log('hone');   
    }



   return new validator();
}

z = val().rules 实际上 returns 你是一个对象而不是一个函数。这就是为什么你不能为此使用 prototype

你可以得到一个 API 像你想要的那样:

var validator = function(){
    this.fields = [];
    this.rules = new rules(this);
}
validator.prototype = {
    addField: function(fieldName){
        this.fields.push(fieldName);    
        return this;
    }
};

var rules = function(validator) {
  this.validator = validator;
}
rules.prototype = {
  addField: function(fieldName) {
    this.validator.addField(fieldName);
    return this;
  },
  phone: function() {
    console.log("phone");
  }
};

v = new validator();
v.rules.addField("hello");
v.rules.phone();

rules继承validator在语义上和实践上都是有问题的。您的 validator.prototype 在这里:

validator.prototype = {
    addField: function(fieldName){
        this.fields.push(fieldName);    
        return this;
    },
    rules: new rules()
}

将在所有 validator 对象之间共享相同的 rules 对象,这可能不是您想要的。但是如果你解决这个问题,通过在 validator 构造函数中创建一个 rules 对象,你将有一个无限循环,因为 validator 构造函数会调用 rules 构造函数, rules 构造函数将调用 validator 构造函数(因为 rules validator)。