K
K
Konstantin Kitmanov2011-04-24 21:26:27
JavaScript
Konstantin Kitmanov, 2011-04-24 21:26:27

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

5 answer(s)
K
kirsan_vlz, 2011-04-24
@kirsan_vlz

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.

A
Andrey Shaydurov, 2011-04-25
@GearHead

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.

A
alex_blank, 2011-04-26
@alex_blank

Brain patterning.

S
Sergey Shirokov, 2011-04-25
@kurokikaze

This is a monad, and most of the methods are operations on a selected set of nodes. IMHO everything is fine.

V
vanxant, 2011-04-26
@vanxant

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 question

Ask a Question

731 491 924 answers to any question