Как jQuery может вернуть массив и при этом иметь объект jQuery? - PullRequest
9 голосов
/ 22 февраля 2012

Я пытаюсь воспроизвести объектную структуру 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 лучшие практики
  • Как jQueryworks
  • Эффективные классы Javascript
  • Все о структурах объектов Javascript
    • Синглеты
    • Прототипы
    • Все остальное, что связано с этим типомструктура называется

1 Ответ

9 голосов
/ 22 февраля 2012

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

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

и иногда, написав это с нуля. Посмотрите на аннотированный код (вероятно, очень полезный ресурс для вас - он охватывает 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...