我正在尝试使用变量替换来实现javascript链接。无法使其发挥作用。帮助赞赏。
var Class = function() {
this.one = function() {
alert('one');
return this;
}
this.two = function() {
alert('two');
return this;
}
if (this instanceof Class) {
return this.Class;
} else {
return new Class();
}
}
var test = new Class();
// this works
test.one().two();
var func = '.one().two()';
// want to make this work
test[func];
答案 0 :(得分:2)
没有名为'.one()。two()'
的函数试试这个,
test['one']()['two']();
修改强> 我相信您仅将其用于学习目的,而不是用于生产现场。
答案 1 :(得分:1)
强烈不推荐。您可能希望尝试使用数组:
var funcs = ['one','two'];
for(var i = 0; i < funcs.length; i++) {
test[funcs[i]]();
}
然后你可以将它包装成一个小函数:
function callChain(obj, funcs)
{
for(var i = 0; i < funcs.length; i++) {
obj[funcs[i]]();
}
return obj;
}
编辑:如果您的链条存储为字符串:.one().two()
,则可以使用拆分&amp;字符串函数动态生成数组。
答案 2 :(得分:0)
您可以向构造函数添加方法:
this.chain = function chain(){
if (arguments.length && /\./.test(arguments[0])) {
return chain.apply(this,arguments[0].split('.'));
}
var methods = [].slice.call(arguments),
method = methods.shift();
if(this[method] instanceof Function){
this[method].call(this);
}
if (methods.length){
chain.apply(this,methods);
}
return this;
}
// now you could do something like:
test.chain('one.two.one.two.two');
或延伸Object.prototype
Object.prototype.chain = function chain(){
if (arguments.length && /\./.test(arguments[0])) {
return chain.apply(this,arguments[0].split('.'));
}
var methods = [].slice.call(arguments),
method = methods.shift();
if(this[method] && this[method] instanceof Function){
this[method].call(this);
}
if (methods.length){
chain.apply(this,methods);
}
return this;
};
// usage
({one:function(){console.log('I am one');},
two:function(){console.log('I am two');}})
.chain('one.two.one.one.two.two.two.one.two');
答案 3 :(得分:0)
嗯,你所要求的远非最佳做法 - 所以我会给你一个不受欢迎的答案 - 使用eval
。
如果你的输入是一般代码作为字符串,你实际上没有任何其他选项(特别是当你的函数有参数 - .one(1 + 0.5).two(new Date())
)时。
例如,在Class
添加:
this.excecute = function(commands){
eval('this' + commands);
};
然后:
test.excecute('.one().two(4 * 5)');
工作示例:http://jsbin.com/ipazaz/1/edit
这会发出警告“eval is evil”(jslint,我认为) - 但我不相信功能可能是邪恶的。
更糟糕的是,如果你有字符串'one(); two(4 * 5);'
怎么办?
您也可以使用with
:
this.excecute = function(commands){
with(this){
eval(commands);
}
};
这有一个额外的警告:“不要使用'与'” - 他们今天真的有些东西反对我们,不是吗?
答案 4 :(得分:0)
谢谢大家的及时帮助。我最终解决了Ben Rowe的建议。
var funcs = ['one','two'];
for(var i = 0; i < funcs.length; i++) {
test[funcs[i]]();
}
很好地符合我的要求。感谢所有人的帮助。你们都很棒。
答案 5 :(得分:0)
我认为一种更简单的方法是使用javascript的数组 reduce 函数。 我需要这些来编写一些动态的jquery东西。一旦有了一系列可链接方法,就可以轻松地执行以下操作。
var methods = ['next', 'child', 'parent'];
var element = methods.reduce(function(method){
return $(selector)[method]();
});
console.log(element) //works! as all method names in methods array are applied and returned each iteration.
对于我来说,被接受的答案对我不起作用,似乎只返回传递的obj,而不返回obj及其链接的方法。