Цепочки вызовов
Подскажите, как создаются такие штуковины? Хочу понять принцип.
F(10).plus(5).minus(3); // => 12 |
Каждый метод должен возвращать объект с другими методами.
var MyObj = { myMethod1: function() { alert('1'); return this; }, myMethod2: function() { alert('2'); return MyObj; } }; MyObj.myMethod1().myMethod2().myMethod1().myMethod2(); |
Спасибо за ответ. Как в этом случае передать данные первому объекту?
|
Цитата:
|
Да, наверное. Взгляните на пример из первого поста. Пока понятно только с методами (.plus(5).minus(3)).
|
Цитата:
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() ); |
Спасибо, понятно. Однако в цепочке появился метод getResult. Существует ли способы вернуть результат автоматически, без появления отдельных методов в цепочке?
|
Цитата:
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 все же удобней. |
Есть еще такой вариант:
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)); |
Спасибо, все ясно. Ушел экспериментировать.
|
Цитата:
|
Цитата:
F(10).plus(5).minus(3) носит чисто ознакомительный характер и врятли кто-то будет применять её в коде JavaScript-приложения. |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Вы не могли бы написать корректный код, который можно и нужно применять.
И желательно не на таком простом примере... Давайте разберём вот такой пример: dom("some_id").append("u").text("some text"); пускай код найдёт объект добавит тэг U и добавит текст. |
Да тут все просто :)
function F(node) { this.node = node; } F.prototype = { append: function(arg) { return new F(this.node.appendChild(typeof arg == "string" ? document.createElement(arg) : arg)); }, text: function(str) { if(typeof str == "undefined") return this.node.innerText || this.node.textContent; this.node.innerHTML = ""; this.node.appendChild(document.createTextNode(str)); return this; } }; function dom(arg) { return new F(typeof arg == "string" ? document.getElementById(arg) : arg); } Не могу не прорекламировать в этой теме :D Цепочки вызовов в JavaScript-фреймворке js-core |
Цитата:
Как всё это сделать в рамках одной функции, как в js-core, не разделяя на function F() и function dom() ? |
В js-core, вместо второй функции, рекурсия добавлена, пример будет выглядеть следующим образом:
function dom(arg) { if(this.dom) return new dom(typeof arg == "string" ? document.getElementById(arg) : arg); this.node = arg; } dom.prototype = { append: function(arg) { return new dom(this.node.appendChild(typeof arg == "string" ? document.createElement(arg) : arg)); }, text: function(str) { if(typeof str == "undefined") return this.node.innerText || this.node.textContent; this.node.innerHTML = ""; this.node.appendChild(document.createTextNode(str)); return this; } }; dom(document.body).append("h1").text("It works!"); Используется тот факт, что одна и таже функция может вызываться явным образом и в конструкторе. При вызове явным образом this указывает на window, так определяем, что нужно рекурсивно вызвать эту же фунции в конструкторе с тем же аргументом. |
Octane,
2-й пример почему-то не работает... |
Цитата:
ReferenceError: arg is not defined { message="arg is not defined", more...} |
понял) а что проверяется этим: if(this.dom) во 2-й строке?
|
Цитата:
Цитата:
http://javascript.ru/forum/misc/7106...html#post40714 |
Octane, а если мне надо чтобы dom() и все методы от неё возвращали объект переданый dom, как так сделать? с методами я вроде понял: return this.node; там) а dom() можно?
|
А смысл? Методы только в прототипе dom могут быть (кросс-браузерно), если DOM-элемент вернуть, никаких кастомных методов мы не получим.
|
ну мне нужно) например чтоб можно было написать и так: dom().style.color'=red'; независимо от методов. Так возможно сделать? (ток при этом чтоб методы тож имели туда доступ, как щас)
|
|
чё-то я ваще запутался с этим js... ( Но есть же вообще в природе какие-то способы сделать так: dom(arg).text('text') - это добавляет текст и возвращает arg и просто dom(arg) возвращает arg?
У вас в js-core если я правильно понял так и есть: "В js-core функции core(…) и $(…) эквивалентны, и возвращают новую копию объекта core, содержащую ссылку на указанный узел. function $(arg) { return typeof arg == "string" ? document.getElementById(arg) : arg; }" Ток чё с методами тогда.. как совместить то эти вещи? |
function dom(arg) { var element = typeof arg == "string" ? document.getElementById(arg) : arg; if (!element) return null; var method, methods = dom.customMethods; for (method in methods) { if (methods.hasOwnProperty(method)) { element[method] = methods[method]; } } return element; } dom.customMethods = { text1: function (str) { if (!arguments.length) return this.innerText || this.textContent; this.innerHTML = ""; this.appendChild(document.createTextNode(str)); return this; } }; dom(document.body).text1("Тарам пам пам").style.backgroundColor = "#fee"; Цитата:
function dom(…) {…} var $ = dom; |
Большое спасибо, то что нужно) последний вопрос, а по скорости это хуже или лучше чем использование prototype?
|
Хуже
|
Octane, я недавно смотрел исходник вашего js-core, не могли бы вы если не трудно конечно, пояснить что означает конструкция
( код... и закрытая далеко в конце ")"вобщем расставленые так скобки? |
Оператор группировки?
|
Часовой пояс GMT +3, время: 23:50. |