k12th
@k12th
console.log(`You're pulling my leg, right?`);

Функция jQuery — антипаттерн God Object?

Однажды некий достаточно авторитетный для меня товарищ сказал, что многочисленные вызовы функции $ кажутся ему антипаттерном God Object. Тогда я с ним не согласился по интуитивным причинам, но обосновать не смог.



Если подумать, то все обращения к $ как функции относятся к одной предметной области — работе с DOM. Обращения к $, как к объекту, немногочисленны, к тому же — в этом случае его можно рассматривать как неймспейс.



Кто из нас прав?
  • Вопрос задан
  • 2973 просмотра
Пригласить эксперта
Ответы на вопрос 5
@kirsan_vlz
Можно воспринимать это либо как пространство имён для функций, либо как операцию для обращения к DOM-элементу.
Минимизируется возможность конфликтов на почве совпадения идентификаторов с посторонним кодом.
Ответ написан
GearHead
@GearHead
Fullstack разработчик и предприниматель
Функция jQuery, т.е. сама по себе $(smth) — standalone-функция, возвращающая набор DOM элементов в особой обёртке. Все функции $.smth (к примеру $.each, $.get и т.д.) просто в отдельном пространстве имён. Здесь нет никакого God Object. Иначе отделение мат. функций в объект Math все бы тоже называли этим антипаттерном.
Ответ написан
Это монада, а большинство методов — операции над выбранным набором узлов. Имхо всё нормально.
Ответ написан
vanxant
@vanxant
Надо разделять функцию и неймспейс. С неймспейсом все нормально, так же как с приведенным выше Math. А вот $ как функция — таки-да, God Object, если под этим понимать нарушение принципа единственности области ответственности «в особо крупном размере». Чтобы в этом убедиться, достаточно посмотреть её исходный код.
	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 );
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы