我正在尝试使用类似于jquery的javascript方法创建链接。请告诉我如何使用javascript实现链接。
var controller = {
currentUser: '',
fnFormatUserName: function(user) {
this.currentUser = user;
return this.currentUser.toUpperCase();
},
fnCreateUserId: function() {
return this.currentUser + Math.random();
}
}
var output = controller.fnFormatUserName('Manju').fnCreateUserId();
答案 0 :(得分:1)
正如我已经解释的那样,因为你从fnFormatUserName
返回一个字符串,所以你不能用它来链接。
要启用链接,您需要返回调用方法的对象。因此,您不能使用getter方法进行链接。
在你的例子中,处理它的方法是让getter方法和方法更新可用于链接的对象,如
var controller = {
currentUser: '',
fnFormatUserName: function(user) {
this.currentUser = user.toUpperCase();
return this;
},
fnCreateUserId: function() {
this.userId = this.currentUser + Math.random();
return this;
},
getUserId: function() {
return this.userId;
}
}
var output = controller.fnFormatUserName('Manju').fnCreateUserId().getUserId();
document.body.innerHTML = output;

另一个版本可能是
var controller = {
currentUser: '',
fnFormatUserName: function(user) {
if (arguments.length == 0) {
return this.currentUser;
} else {
this.currentUser = user.toUpperCase();
return this;
}
},
fnCreateUserId: function() {
this.userId = this.currentUser + Math.random();
return this;
},
getUserId: function() {
return this.userId;
}
}
var output = controller.fnFormatUserName('Manju').fnCreateUserId().getUserId();
r1.innerHTML = output;
r2.innerHTML = controller.fnFormatUserName();

<div id="r1"></div>
<div id="r2"></div>
&#13;
答案 1 :(得分:0)
您可以使用 proxies 来修饰方法,以便它们返回对象本身(“this”)而不是实际的方法返回值。下面是一个 chainer 函数的实现,它可以对任何对象执行此操作。代码还声明了一个特殊符号“目标”,可用于访问原始对象(和未更改的方法返回值),丢弃链接代理。
const target = Symbol('Symbol for the target of the chainer proxy');
const targetSymbol = target;
const chainer = (target) =>
new Proxy(target, {
get: (_, prop, receiver) =>
prop === targetSymbol
? target
: typeof target[prop] === 'function'
? new Proxy(target[prop], {
apply: (f, _, args) => {
f.apply(target, args);
return receiver;
},
})
: target[prop],
});
const controller = {
currentUser: '',
fnFormatUserName: function(user) {
return this.currentUser = user.toUpperCase();
},
fnCreateUserId: function() {
return this.currentUser + Math.random();
}
}
const output = chainer(controller).fnFormatUserName('Manju')[target].fnCreateUserId();
console.log(output);
另一种选择是装饰方法将始终返回具有两个属性的中间对象:this 上下文(“this”)和对具有未装饰方法的原始对象的引用(“target”)。见下文。
const chainer = (target) =>
new Proxy(target, {
get: (_, prop, receiver) =>
typeof target[prop] === 'function'
? new Proxy(target[prop], {
apply: (f, _, args) => {
f.apply(target, args);
return {
this: receiver,
target,
}
},
})
: target[prop],
});
const counter = {
value: 0,
increment: function() {
return ++this.value;
}
}
const value = chainer(counter)
.increment().this
.increment().target
.increment();
console.log(value);
答案 2 :(得分:0)
我想这可能会被视为“作弊”,但您可以很容易地通过扩展 String.prototype
获得类似的结果,例如:
String.prototype.upper=function(){return this.toUpperCase()};
String.prototype.makeId=function(){return this+Math.random()};
// test
const str="abc";
console.log(str.upper().makeId(), str);
当然,它会改变当前会话中所有字符串的行为,因为它们现在将具有与其关联的附加方法 .upper()
和 .makeId()
。