JavaScript. Каков наилучший способ создания цепочки функций?
РЕДАКТИРОВАТЬ
Вот попытка упростить мой вопрос.
return this.someFunc(); == return { XXX:this.someFunc() };
Что мне нужно сделать для XXX, чтобы сделать это утверждение истинным?
Я пытаюсь создать функцию, которая может быть скована. Позвольте мне написать некоторый гипотетический код. (Любые ошибки синтаксиса просто игнорируются, я набираю это быстро, и это всего лишь код концепции.) Предположим, что все функции либо определены локально, либо глобально.:)
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return this.someFunc();
}
Эта функция позволяет мне цепочка: test().retest();
Но то, что я хочу сделать, это вернуть более одного элемента.
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return { XXX:this.someFunc(), //What do I put for XXX
next:this };
}
Я хочу сделать это для доступа к другой функции, которую предлагает test(): test().next.someFunc2();
Итак, моя проблема заключается в следующем:
Я все еще хочу иметь возможность так цепляться: test().retest();
Но я должен сделать это вот так: test().XXX.retest();
В моем коде, какое имя я могу поставить вместо XXX, чтобы выполнить это? И возможно ли это? Я уже пробовал 0
и default
. Спасибо за помощь.
Ответы
Ответ 1
Вы можете сделать связанные функции следующим образом:
var test = function(){
var self = {};
console.log('test called')
function someFunc() {
console.log('someFunc')
return self;
}
function someOtherFunc() {
console.log('someOtherFunc')
return self;
}
self.someFunc = someFunc;
self.someOtherFunc = someOtherFunc;
return self;
}
test().someFunc().someOtherFunc();
Надеюсь, что это поможет
Ответ 2
function test() {
// when test() is called as a regular function
// it `this` will be `undefined` (in strict mode) or will refer to a global object
// when test() is called with `new` operator
// it `this` will be an instance of `test` object
if(!(this instanceof test)) {
// create a new object
return new test();
}
else {
// this is a `new object` creation
console.log('new Test created');
}
}
// declare functions which will be accessible on test object
test.prototype.someFunc = function() {
console.log('someFunc');
return this;
};
test.prototype.someFunc2 = function() {
console.log('someFunc2');
return this;
};
// declare a `chaining` function - will create a new `test` object
test.prototype.test = function() {
return new test(); // new instance will be created
};
С помощью этого кода вы можете запустить следующий код
test().someFunc().someFunc2().test().someFunc().someFunc().test().test()
Следующая строка будет записана на консоли
new Test created
someFunc
someFunc2
new Test created
someFunc
someFunc
new Test created
new Test created
Ответ 3
у вас проблема с областью - вы не можете ссылаться на _NAME "тест" в функции, потому что вы не знаете, как она называется.
если вы сделаете это статически, вы просто можете сделать:
test = function(){
this.someFunc = function(){ // blaaa
};
//...code
return {
OUTPUT: this.someFunc(), //What do I put for XXX
test: this
};
}
приведет к:
test().test().test().test().OUTPUT (or something like this)
Ответ 4
test = function(){
var someFunc = function(){
//...code
}
return {
someFunc:someFunc,
next:this
}
}
EDIT - Обновлено, чтобы отразить ваше обновление вопроса, для ясности.
Ответ 5
Сделайте это
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
var ret = this.somefunc();
ret.next = this;
return ret;
}
EDIT: здесь лучше, работает, версия
test = function(){
var ret;
var func = function() {
console.log("test func");
}
ret = function(){
func();
return ret;
}
ret.test = ret;
ret.next = ret; // You can define an arbitrary number of members here
ret.XXX = func(); // Like this, and you can still chain it like your question
return ret;
}
Ответ 6
Не уверен, каково ваше намерение, но это будет цепная функция Test
:
function Test(){
Test.retest = Test.retest || function(){console.log('retested'); return Test;}
return Test;
}
Test().retest().retest().retest().retest();
/* => result
retested
retested
retested
retested
*/
// and
log(Test() === Test); //=> true
Ответ 7
Хорошо, поэтому я думаю, что я понимаю ваш вопрос, но я не уверен (и здесь очень поздно ночью, так что дайте мне немного по этому поводу). Я думаю, что вы хотите иметь такое поведение:
test(); //is ["result1"]
test().retest(); //is ["result1", "result2"]
test().retest().retest(); //is ["result1", "result2", "result3"]
Возможно, вы захотите вернуть объекты вместо строк, но это же общая идея. И код оказывается довольно простым:
var test = (function() {
var results = ["result1"],
i = 1;
results.retest = (function() {
results.push("result" + (++i));
return results;
});
return results;
});
test(); //is ["result1"]
test().retest(); //is ["result1", "result2"]
test().retest().retest(); //is ["result1", "result2", "result3"]
Не уверен, что это то, что вы ищете, но, может быть, вы попадете на правильный путь.
Ответ 8
Поскольку ваш пример не работает так, как вы его разместили, я полагаю, вы имели в виду следующее:
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return new this.someFunc();
}
Обратите внимание на новый в возврате.
Теперь, чтобы все еще иметь возможность связывать свои функции, вы должны вернуть это:
return {retest: new this.someFunc().retest, next:this};
Таким образом, вы сможете называть test().retest();
Надеюсь, это поможет.