如何在不污染String.prototype的情况下继承和链接String



我想做的是这样的事情:

var where = new Where();
where('a'); // returns a string 'WHERE a' that I can chain against
where('a').andWhere('b'); // reuturns 'WHERE a AND b' that is also chainable
where('a').andWhere('b').orWhere('c'); // 'WHERE a AND b OR c', and so on ...

where方法应该返回一个字符串,具有所有类似字符串的方法,但具有两个自定义的andWhereorWhere方法。

当我尝试从Sting.prototype继承时,我的where方法返回了一个对象,而不是字符串。当然,如果我直接从这些方法返回一个字符串,那么它们没有andWhereorWhere方法,所以链接中断了。

下面的代码实现了我想要的,但它通过污染String.prototype来实现。有没有一种方法可以获得相同的行为,但封装在自定义对象中?

Object.defineProperty(String.prototype, "andWhere", {
value: function _andWhere(clause) {
return [this, 'AND', clause].join(' ');
},
configurable: true,
enumerable: false,
writeable: true
});
Object.defineProperty(String.prototype, "orWhere", {
value: function _orWhere(clause) {
return [this, 'OR', clause].join(' ');
},
configurable: true,
enumerable: false,
writeable: true
});

function where(clause){
return ['WHERE', clause].join(' ');
}
where('a').andWhere('b').orWhere('c');
// => 'WHERE a AND b OR c'

编辑

我仍然想直接访问对象之外的所有字符串方法。换句话说,返回的对象的行为就像一个字符串,但有更多的方法。例如:

var whereStr = where('a').andWhere('b').orWhere('c');
whereStr.length; // => 18
whereStr.concat(' and so on'); // => 'WHERE a AND b OR c and so on'

如果有什么不同的话,这主要适用于Node,但理想情况下适用于任何最近的(ES5)javascript实现。同样,如果我不好并且使用String.prototype,这非常有效,我希望有一种方法可以进行替换。

UPDATED在创建长度属性作为"getter"的示例中添加。

function Where(conditional) {
var thisObj = this;
//Setup the length property's "getter"
this.__defineGetter__( "length", function() {
return thisObj.clause.length;
});
this.start( conditional );
}
Where.prototype = {
AND_STR: " AND ",
OR_STR: " OR ",
add: function(conditional, prefix) {
this.clause += prefix + conditional;
},
and: function(conditional) {
this.add( conditional, this.AND_STR ); 
return this;
},
or: function(conditional) { 
this.add( conditional, this.OR_STR ); 
return this;
},
start: function(conditional) {
this.clause = "WHERE " + conditional;
},
toString: function() {
return this.clause;
}
}
//Use it like this (this shows the length of the where statement):
alert( new Where( "a" ).and( "b" ).or( "c" ).length );

相关内容

最新更新