Как jQuery может возвращать массив и все еще иметь объект jQuery?

Я пытаюсь воспроизвести структуру объекта jQuery (1.7.1), чтобы лучше понять, как это работает. У меня есть следующий код:

(function (window, undefined) {

    var document = window.document,
        navigator = window.navigator,
        location = window.location;

    window.myclass = (function () {
        var __con = function () {
            return new __con.fn.init();
        }

        __con.fn = __con.prototype = {
            'init' : function () {
                return this;
            },
            'test' : function () {
                console.log('test1');
                return this;
            }
        }

        __con.fn.init.prototype = __con.fn;

        __con.test = function () {
            console.log('test2');
            return this;
        }

        return __con;
    })();

})(window);

моя консоль выглядит так:

> myclass().test();
  test1
< __con.fn.__con.init
> myclass.test();
  test2
< function () {

            return new __con.fn.init();

        }

моя путаница заключается в том, как jQuery может возвращать массив и все еще иметь объект jQuery? jQuery, выполняемый с консоли, может выглядеть примерно так:

> $(document.body)
  [<body>​…​</body>​]
> $(document.body).css('width');
  "1263px"

на самом деле, одна вещь, которую я определенно заметил, это отсутствие < для возвращения объект. Так что же здесь происходит? Я искал по всему Google, чтобы объяснить, как работает jQuery, но безрезультатно. Может быть, я просто неправильно понимаю терминологию, я не уверен. Кажется, я не могу найти подробного источника, объясняющего это.

возможно, мой код просто неполный, но основная структура, которую я имею до сих пор, - это то, что я смог извлечь до сих пор. Пожалуйста, исправьте то, что у меня есть до сих пор, если это неправильно, неполно или неэффективно, и, пожалуйста, не стесняйтесь предоставлять хорошие читаем о:

  • лучшие практики Javascript
  • как работает jQuery
  • эффективные классы Javascript
  • Все о структурах объектов Javascript
    • синглтоны
    • прототипы
    • что-нибудь еще, относящееся к тому, что этот тип структуры называется

1 ответов


объекты jQuery похожи на массивы, поэтому выглядят и ведут себя как массивы, но на самом деле это просто пользовательские объекты, сделанные примерно для приравнивания к коллекции узлов DOM (за исключением дополнительной функциональности). Все время как функциональность - длина, ломтик() и т. д.. - фактически добавляется вручную к прототипу jQuery (для которого jQuery.fn - псевдоним), иногда вызывая функцию массива с объектом jQuery в качестве контекста

  slice = Array.prototype.slice,
  ...
  slice: function() {
    return this.pushStack( slice.apply( this, arguments ),
      "slice", slice.call(arguments).join(",") );
  },

и иногда, написав его с нуля. Смотреть the аннотированный код (вероятно, очень полезный ресурс для вас-он охватывает v1.6.2 но я не думаю, что что-то слишком радикально изменилось с тех пор, за исключением, возможно, добавления $.callbacks), чтобы увидеть это this.length устанавливается вручную, например,

if ( selector === "body" && !context && document.body ) {
  this.context = document;
  this[0] = document.body;
  this.selector = selector;
  this.length = 1;
  return this;
}

на jQuery.buildFragment() метод также имеет фундаментальное значение для построения объектов jQuery, содержащих большие коллекции узлов DOM.

Итак, чтобы подвести итог, jQuery не использует массивы, он просто выглядит так, потому что много родной функциональность массива была реплицирована как свойства прототипа jQuery.