Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Цепочки вызовов (https://javascript.ru/forum/misc/4403-cepochki-vyzovov.html)

Vladimir[gs] 19.07.2009 14:57

Цепочки вызовов
 
Подскажите, как создаются такие штуковины? Хочу понять принцип.
F(10).plus(5).minus(3); // => 12

Riim 19.07.2009 15:02

Каждый метод должен возвращать объект с другими методами.

var MyObj = {
	myMethod1: function() {
		alert('1');
		return this;
	},
	myMethod2: function() {
		alert('2');
		return MyObj;
	}
};

MyObj.myMethod1().myMethod2().myMethod1().myMethod2();

Vladimir[gs] 19.07.2009 15:22

Спасибо за ответ. Как в этом случае передать данные первому объекту?

Riim 19.07.2009 16:02

Цитата:

Сообщение от Vladimir[gs
]Как в этом случае передать данные первому объекту?

Может не объекту, а функции?

Vladimir[gs] 19.07.2009 16:33

Да, наверное. Взгляните на пример из первого поста. Пока понятно только с методами (.plus(5).minus(3)).

Riim 19.07.2009 16:50

Цитата:

Сообщение от Vladimir
Взгляните на пример из первого поста.

Простейший вариант будет примерно таким:
var F = function(x) {
	return {
		plus: function(y) {
			x += y;
			return this;
		},
		minus: function(y) {
			x -= y;
			return this;
		},
		getResult: function() {
			return x;
		}
	};
};

alert(
F(10).plus(5).minus(3).getResult()
);


Он плох тем, что при каждом вызове F создается новый объект, тем самым забивается память браузера.

Вариант получше:
var F = function(x) {
	return new F._f(x);
};

F._f = function(x) {
	this.x = x;
};
F._f.prototype.plus = function(y) {
	this.x += y;
	return this;
};
F._f.prototype.minus = function(y) {
	this.x -= y;
	return this;
};
F._f.prototype.getResult = function(y) {
	return this.x;
};


alert(
F(10).plus(5).minus(3).getResult()
);

Vladimir[gs] 19.07.2009 17:35

Спасибо, понятно. Однако в цепочке появился метод getResult. Существует ли способы вернуть результат автоматически, без появления отдельных методов в цепочке?

Riim 19.07.2009 17:47

Цитата:

Сообщение от Vladimir[gs
]Существует ли способы вернуть результат автоматически, без появления отдельных методов в цепочке?

Можно добавлять методы в prototype числа (только F здесь уже не нужен):
Number.prototype.plus = function(num) {
	return this + num;
};
Number.prototype.minus = function(num) {
	return this - num;
};

alert(
(10).plus(5).minus(3)
);


Для удобного наполнения объектов свойствами/методами обычно используют функцию Object.extend . Простейший вариант:
Object.extend = function(self, obj) {
	for (var key in obj) self[key] = obj[key];
	return self;
};


И наполняем:
Object.extend(Number.prototype, {
	plus: function(num) {
		return this + num;
	},
	minus: function(num) {
		return this - num;
	}
});


upd: не очень удачно получилось, здесь методов мало, при большом количестве методов с Object.extend все же удобней.

Octane 19.07.2009 18:08

Есть еще такой вариант:

function F(x) {
	x = new Number(x);
	x.plus = function(y) {
		return F(x + y);
	};
	x.minus = function(y) {
		return F(x - y)
	};
	return x;
}

alert(F(10).plus(5).minus(3));

Vladimir[gs] 19.07.2009 18:31

Спасибо, все ясно. Ушел экспериментировать.


Часовой пояс GMT +3, время: 05:12.