API:使构造函数在 JavaScript 中无需括号即可链接
API: Making constructor functions chainable without parenthesis in JavaScript
所以我正在构建一些可以进行简单类型检查的可链接函数。目前,我必须这样调用我的函数:
Proceed().if('someString').is.a('string');
但我 真正想要的 是让我的 API 看起来像这样:
proceed.if('someString').is.a('string');
请注意,在第二个代码示例中,第一个函数调用中缺少左括号和右括号。
正如您从下面的代码中看到的,我已经想出了如何让 is
和 a
工作,但我似乎无法找到一种方法来删除来自 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
我从这里得到的错误是这样的:
Uncaught ReferenceError: proceed is not defined
如果我将 Proceed.prototype
换成 Object.prototype
,那么我可以让它工作,但这意味着我扩展了一个本机对象,这可能会有问题。
所以有谁知道我可以在不危险地扩展本机对象的情况下完成此操作的方法吗?我在这里做错了什么?
Here is a jsFiddle with the above code samples.
感谢任何帮助。
更新 #1 此代码被设计为节点模块,因此将无法访问浏览器的 window
对象。
变化:
Object.defineProperty(Proceed.prototype, 'proceed', {
到
Object.defineProperty(window, 'proceed', {
已更新 fiddle:https://jsfiddle.net/Lw29zyf1/4/
因此您将在 window 范围内有一个 "proceed" 变量。
您需要从实例值变量开始:
var proceed = new Proceed();
为了使其可链接,您应该 return 从您的方法中创建新实例,而不是改变 "static" proceed
对象:
function Proceed(target) {
this.target = arguments.length ? target : "";
}
Proceed.prototype.if = function (target) {
return new Proceed(target);
}
或者一般来说,您需要使 proceed.if
成为一个包含 return 个 Proceed
个实例的工厂,无论 proceed
已经是一个对象还是只是一个普通对象。
请看下面的代码是否有帮助
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');
所以我正在构建一些可以进行简单类型检查的可链接函数。目前,我必须这样调用我的函数:
Proceed().if('someString').is.a('string');
但我 真正想要的 是让我的 API 看起来像这样:
proceed.if('someString').is.a('string');
请注意,在第二个代码示例中,第一个函数调用中缺少左括号和右括号。
正如您从下面的代码中看到的,我已经想出了如何让 is
和 a
工作,但我似乎无法找到一种方法来删除来自 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
我从这里得到的错误是这样的:
Uncaught ReferenceError: proceed is not defined
如果我将 Proceed.prototype
换成 Object.prototype
,那么我可以让它工作,但这意味着我扩展了一个本机对象,这可能会有问题。
所以有谁知道我可以在不危险地扩展本机对象的情况下完成此操作的方法吗?我在这里做错了什么?
Here is a jsFiddle with the above code samples.
感谢任何帮助。
更新 #1 此代码被设计为节点模块,因此将无法访问浏览器的 window
对象。
变化:
Object.defineProperty(Proceed.prototype, 'proceed', {
到
Object.defineProperty(window, 'proceed', {
已更新 fiddle:https://jsfiddle.net/Lw29zyf1/4/
因此您将在 window 范围内有一个 "proceed" 变量。
您需要从实例值变量开始:
var proceed = new Proceed();
为了使其可链接,您应该 return 从您的方法中创建新实例,而不是改变 "static" proceed
对象:
function Proceed(target) {
this.target = arguments.length ? target : "";
}
Proceed.prototype.if = function (target) {
return new Proceed(target);
}
或者一般来说,您需要使 proceed.if
成为一个包含 return 个 Proceed
个实例的工厂,无论 proceed
已经是一个对象还是只是一个普通对象。
请看下面的代码是否有帮助
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');