Как jQuery имеет конструктор $object и методы, связанные с $?
Каким образом jQuery может выполнять $("#foo").addClass("bar")
и $.ajax()
?
Я создаю структуру микро javascript и хочу создать новый экземпляр объекта, например $("#hello")
. С этим объектом существуют связанные методы, такие как addClass
, css
и т.д., Как и с jQuery. Поэтому я мог бы сделать что-то вроде
$("#foo").addClass("remove").css("color", "red");
Мне удалось создать это. Однако, когда я хочу вызвать метод из этого объекта, например $.ajax
, функция конструктора перезаписывается, и я могу вызвать $.ajax, но не $( "# foo" ).
В принципе, как jQuery может выполнять оба?
Ответы
Ответ 1
ОК, функция $
- это не только функция, но и объект, как и все функции. Таким образом, он может иметь методы. Что все это ajax
, это метод функции $
. Поэтому мы можем начать с этого:
$ = function(obj) {
// some code
};
$.ajax = function (arg1, arg2) {
// some ajax-y code
};
Пока все хорошо. Теперь, что мы добавили в функцию $
? Ну, он должен вернуть объект, и этот объект должен иметь некоторые хорошие методы, определенные на нем. Поэтому нам понадобится функция конструктора (чтобы дать нам новые объекты) и прототип (чтобы обеспечить отличные методы для этих объектов).
$ = function(obj) {
var myConstructor = function (obj) {
this.wrappedObj = obj;
};
myConstructor.prototype = {
niftyMethod: function () {
// do something with this.wrappedObj
return this; // so we can chain method calls
},
anotherNiftyMethod: function (options) {
// do something with this.wrappedObj and options
return this;
}
};
return new myConstructor(obj);
};
Итак, у нас это есть. Мы можем это сделать:
var mySnazzObject = $("whatever");
mySnazzObject.niftyMethod().anotherNiftyMethod(true);
И мы можем это сделать:
$.ajax("overthere.html", data);
Очевидно, jQuery делает чертов много больше, чем это, и он делает это по-настоящему впечатляюще, но что общая идея.
UPDATE: AS @Raynos был достаточно любезен, чтобы наблюдать, не представив конструктивный ответ, мой оригинальный код создаст прототип ad infinitum. Поэтому мы используем анонимную функцию автоматического выполнения, чтобы объявить конструктор и прототип отдельно:
(function () {
var myConstructor = function (obj) {
this.wrappedObj = obj;
};
myConstructor.prototype = {
niftyMethod: function () {
// do something with this.wrappedObj
return this; // so we can chain method calls
},
anotherNiftyMethod: function (options) {
// do something with this.wrappedObj and options
return this;
}
};
var $ = function(obj) {
return new myConstructor(obj);
};
$.ajax = function (arg1, arg2) {
// some ajax-y code
};
window.$ = $;
}());
Ответ 2
$ = function(arg) { console.log("$ function called with " + arg); }
$.ajax = function(arg) {console.log("$.ajax called with " + arg);}
$('foo');
$.ajax('bar');
http://jsfiddle.net/ac7nx/
Я не думаю, что здесь есть какая-то магия. $
- это просто имя глобальной функции. Просто имейте в виду, что в javascript функции являются объектами первого класса, которые могут иметь свои собственные свойства, включая подфункции, что и есть $.ajax
.
Поскольку вы упомянули конструкторную функцию, я должен отметить, что здесь нет OO-объектов, а просто регулярных функций (нет new
), поэтому функции-конструкторы не играют в этом. Если вы используете ключевое слово new
, то, вероятно, вы сбиваетесь с толку. Если вы хотите, чтобы $('#foo')
возвращал новый объект, то внутри кода функции $
вы должны создать новый объект с помощью new
и вернуть его, что и делает jQuery, но сама функция $
не является конструктор и не должен вызываться с помощью new
. Или в случае чего-то вроде $('#someID')
внутри этой функции jQuery получает объект-объект из DOM и затем возвращает этот объект, но все же $
- это просто регулярная функция, возвращаемое значение которой является объектом, а не функцией-конструктором.
Ответ 3
Две разные вещи:
$.ajax
является прототипированной функцией jQuery, называемой ajax.
Хотя $
('foo') является вызовом функции jQuery и в зависимости от типа foo он реагирует по-разному. В http://api.jquery.com/jQuery вы можете увидеть, что jQuery (почти то же самое, что и $) может реагировать на три разных типа: селектора, html или обратные вызовы.
Ответ 4
Вы можете имитировать поведение магического jQuery следующим образом:
//define
var _$ = {};
var $ = function(selector) {
_$.html = function(args) {
alert("Doing the method 'html' with arguments " + args
+ " for selector " + selector);
return _$; //needed for pipeline
};
return _$;
};
$.ajax = function(args){alert("Doing the method 'ajax' "); }
//and try
$("selector1").html("args1").html("args2");
$.ajax("args2");