2

変数置換を使用して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];
4

6 に答える 6

2

'.one()。two()'という名前の関数はありません

これを試して、

test['one']()['two']();

編集: これは学習目的でのみ使用しており、本番サイトでは使用していないと思います。

于 2012-09-03T05:42:44.450 に答える
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()、split&string関数を使用して、配列を動的に生成できます。

于 2012-09-03T05:41:15.013 に答える
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');
于 2012-09-03T05:50:10.850 に答える
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

これは「evalisevil 」という警告を発します(jslint、私は思います)-しかし、関数が悪になる可能性があるとは思いません。

さらに悪いことに、文字列があった場合はどうなります'one(); two(4 * 5);'か?
以下を使用して、それを機能させることもできますwith

this.excecute = function(commands){
    with(this){
        eval(commands);
    }
}; 

これには追加の警告があります:「'with'を使用しないでください」 -彼らは今日私たちに対して本当に何かを持っていますね?

実例: http: //jsbin.com/ipazaz/2/edit

于 2012-09-03T06:03:18.327 に答える
0

迅速なサポートをありがとうございました。私は結局、ベン・ロウの提案に落ち着きました。

var funcs = ['one','two'];
   for(var i = 0; i < funcs.length; i++) {
   test[funcs[i]]();
}

それは私の要件にうまく適合しました。助けてくれてありがとう。みなさん素晴らしいです。

于 2012-09-03T09:20:20.603 に答える
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とその連鎖メソッドは返さないようです。

于 2018-06-27T01:57:50.763 に答える