Я не могу понять, как работает jQuery Chaining
Я не могу понять, как работает jQuery Chaining.
jQuery("div").attr("id", "_id")
.hide()
.show();
Я сделал что-то вроде цепочки, но я не уверен, что это та же логика, которую использует jQuery.
var fun = (function (parma) {
return function () {
return {
start: function () {
console.log("start");
return this;
},
mid: function () {
console.log("mid");
return this;
},
last: function () {
console.log("last");
return this;
}
}
}
}) ();
// Working
fun().start()
.mid()
.last();
5 ответов
Если возвращаемое значение функции является объектом, у которого есть метод, вы можете немедленно вызвать этот метод. Просто как тот.
Так как ты возвращаешься this
, вы возвращаете тот же объект, к которому был вызван предыдущий метод. Это означает, что вы возвращаете объект всеми одинаковыми методами.
Думайте об этом так:
var f = {
foo: function() {
console.log("foo");
return b;
}
};
var b = {
bar: function() {
console.log("bar");
return f;
}
};
Здесь у нас есть два объекта.
f
Объект имеет метод с именемfoo
который возвращаетb
объект.b
Объект имеет метод с именемbar
который возвращаетf
объект.
Из-за этого после звонка foo
мы можем позвонить bar
, и наоборот.
f.foo().bar().foo().bar(); // etc
Но потому что f
не имеет bar
а также b
не имеет foo
мы никогда не сможем вызвать один и тот же метод дважды.
Но что, если бы у нас был только один объект, у которого были оба метода, и оба метода всегда возвращали один и тот же исходный объект?
var fb = {
foo: function() {
console.log("foo");
return fb;
},
bar: function() {
console.log("bar");
return fb;
}
};
Теперь мы всегда возвращаем объект, который имеет как foo
а также bar
методы, поэтому мы можем вызвать любой метод.
fb.foo().bar().bar().bar().foo().foo().bar();
Так что теперь единственная реальная разница в том, что мы возвращаемся fb
вместо this
, но это не имеет значения, так как они один и тот же объект. Код выше может сделать return this;
и он будет вести себя так же.
Было бы важно, если бы вы хотели создать несколько экземпляров объекта, но это вопрос техники ориентации объекта, а не цепочки методов.
return
на каждой функции есть объект jQuery. Каждый объект jQuery будет иметь ссылку на все функции, такие как show/hide
и так вы можете просто написать
jQuery("#myDiv") //returns a jQuery object
.attr("id", "_id") //sets the ID and returns the jQuery object
.hide() //Hides the element with ID myDiv and returns jQuery object
.show(); //show the element with ID myDiv and returns jQuery object
Думайте об этом так:
var myLib = {
foo: function() {
alert("FOO!");
return this;
},
bar: function() {
alert("BAR!");
return this;
}
}
myLib.foo().bar();
jQuery делает это не совсем так, но это один из способов получить функциональность цепочки. Этот конкретный не хранит информацию о текущем объекте.
У объекта jQuery есть методы, которые возвращают модифицированный объект jquery, что позволяет вам вызывать больше методов для него.
Если я правильно помню, jQuery использует классический подход к созданию цепочки в своих прототипах с одним исключением, он также имеет enhanced
Конструктор в это init
прототип. Вот простой шаблон:
function myQuery(elem){
return new myQuery.prototype.init(elem);
};
myQuery.prototype.init = function(elem) { // the constructor "enhanced"
this.elem = elem;
};
// now copy the myQuery prototypes into init.prototype
myQuery.prototype.init.prototype = myQuery.prototype;
// here comes the chainable prototypes:
myQuery.prototype.start = function() {
this.elem.className = 'start';
return this; // returning the instance allows further chaining
};
myQuery.prototype.finish = function() {
this.elem.className = 'finish';
return this;
};
// now use it
myQuery(document.body).start().finish();
Цепочка прототипов более эффективна, потому что вы можете повторно использовать методы прототипа для каждого экземпляра. jQuery часто инициализируется много раз в документе, и если вы каждый раз создаете новый объект со всеми цепочечными методами, это добавляет ненужные издержки и возможные утечки.
Почти каждая функция jQuery также будет возвращать объект jQuery. В результате вы можете запускать функции jQuery для каждого возвращаемого объекта.
Написав связанный код, вы не только сэкономите время, но и улучшите производительность. Не заставляя компьютер искать и использовать определенный узел, работа с возвращенным объектом намного эффективнее, чем запуск другого экземпляра.