Answer the question
In order to leave comments, you need to log in
jQuery function - God Object anti-pattern?
Once, a friend who was quite authoritative for me said that numerous calls to the $ function seemed to him an anti-pattern of God Object. Then I did not agree with him for intuitive reasons, but I could not substantiate.
If you think about it, then all calls to $ as a function belong to the same subject area - working with the DOM. References to $ as an object are not numerous, moreover - in this case it can be considered as a namespace.
Which one of us is right?
Answer the question
In order to leave comments, you need to log in
You can think of this either as a namespace for functions, or as an operation for accessing a DOM element.
The possibility of conflicts on the basis of the coincidence of identifiers with an extraneous code is minimized.
jQuery function i.e. $(smth) itself is a standalone function that returns a set of DOM elements in a special wrapper. All $.smth functions (like $.each, $.get, etc.) are just in a separate namespace. There is no God Object here. Otherwise, the department mat. functions into the Math object, everyone would also call this antipattern.
This is a monad, and most of the methods are operations on a selected set of nodes. IMHO everything is fine.
It is necessary to separate the function and the namespace. With the namespace, everything is fine, just like with the above Math. But $ as a function - yes, yes, God Object, if by this we mean a violation of the principle of uniqueness of the area of responsibility "on an especially large scale." To see this, just look at its source code.
function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// The body element only exists once, optimize finding it
if ( selector === "body" && !context && document.body ) {
this.context = document;
this[0] = document.body;
this.selector = "body";
this.length = 1;
return this;
}
// Handle HTML strings
if ( typeof selector === "string" ) {
// Are we dealing with HTML string or an ID?
match = quickExpr.exec( selector );
// Verify a match, and that no context was specified for #id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = (context ? context.ownerDocument || context : document);
// If a single string is passed in and it's a single tag
// just do a createElement and skip the rest
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
}
return jQuery.merge( this, selector );
// HANDLE: $("#id")
} else {
elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
return jQuery.makeArray( selector, this );
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question