Как экземпляр jQuery отображается как массив при вызове в console.log?

При вводе в консоль JavaScript объект jQuery отображается как массив. Однако это по-прежнему экземпляр объекта jQuery.

var j = jQuery();
=> []
console.log(j);
=> []
console.log('test with string concat: ' + j);
=> test with string concat: [object Object]
j instanceof Array
=> false
j instanceof jQuery
=> true

Как можно дублировать это со своим собственным объектом?

--------- РЕДАКТИРОВАТЬ ---------

Спасибо ZER0 за то, что разобрались. Вот пример кода для создания объекта, который работает так же, как jQuery в консоли:

var Foo = function() {
  this.splice = Array.prototype.splice;
  Array.prototype.push.apply(this, arguments);

  return this;
}

var f = new Foo();
=> []
console.log(f);
=> []
console.log('test with string concat: ' + f);
=> test with string concat: [object Object]
f instanceof Array
=> false
f instanceof Foo
=> true

Очень круто.


person NudeCanalTroll    schedule 11.03.2012    source источник
comment
Я хочу, чтобы моя функция возвращала себя, а не массив (примечание: jQuery() instanceof Array возвращает false). Однако я бы хотел, чтобы он отображался как массив в консоли.   -  person NudeCanalTroll    schedule 11.03.2012
comment
вы не можете объединить строку и объект   -  person charlietfl    schedule 11.03.2012
comment
Я не пытаюсь. Я просто демонстрирую поведение jQuery. Моя цель — повторить это поведение. Кроме того, вы можете объединять строки и объекты, если вы установили метод toString() для объекта.   -  person NudeCanalTroll    schedule 11.03.2012
comment
Не могли бы вы поместить свой собственный ответ в свой собственный ответ, пожалуйста? Тело вопроса, ну, только для вопроса;)   -  person k0pernikus    schedule 21.04.2013


Ответы (5)


Я думаю, что у них есть что-то вроде этого:

// Adding items to an object like an Array:
var myObject = {splice : Array.prototype.splice};

Array.prototype.push.call(myObject, 1, 10, "foo");

// Getting items from an object like an Array:

alert(Array.prototype.slice.call(myObject, 0));

console.log(myObject);

alert(myObject);
person ZER0    schedule 11.03.2012
comment
Это круто, но единственная проблема здесь в том, что Array.prototype.slice.call(myObject, 0) не возвращает экземпляр типа myObject, он возвращает экземпляр типа Array. jQuery удается сохранить возвращаемое значение как объект jQuery (даже несмотря на то, что он отображается в консоли как Array), что полезно, потому что тогда вы можете вызывать для него методы jQuery. - person NudeCanalTroll; 11.03.2012
comment
Итак, если вы хотите этого, вам нужно предоставить свойство splice для вашего объекта, потому что это свойство, которое console.log вызывает для отображения объекта, подобного массиву. Обратите внимание, что это поведение неодинаково для разных инструментов и браузеров, а также оно работает только для consolealert и другие вещи не затрагиваются (точно так же, как это делает jquery). - person ZER0; 11.03.2012
comment
Ну, цель состоит не просто в том, чтобы создать массивоподобный объект, а в том, чтобы консоль отображала объект как массив. Даже если вы создаете объект, который можно склеивать, при входе в консоль (console.log(instanceOfMyNewObject)) он отображается как общий объект JavaScript со своим списком свойств и значений. - person NudeCanalTroll; 12.03.2012
comment
Да, я понял, и добавление splice делает именно это. Однако, как я уже сказал, это зависит от браузера: например, этот код в Chrome работает так, как вы хотите, но не в веб-консоли Firefox. Однако это точно такое же поведение, как у нас с jQuery — он использует этот подход. - person ZER0; 12.03.2012
comment
Конечно, вы должны добавить элементы так, как я описал в коде выше — с push, которые добавляют свойство length — иначе это не сработает, если вы не добавите вручную length. - person ZER0; 12.03.2012
comment
Экземпляр достигается с помощью нового оператора. И, как я уже говорил, это просто объект с правильными свойствами, чтобы выглядеть как массив. Это не колдовство. - person AutoSponge; 12.03.2012
comment
Одним из предостережений в более поздних версиях браузера Chrome является то, что любые и все методы объекта будут отображаться в консоли как элементы отображения, подобного массиву. - person natlee75; 23.03.2013

Консоль делает его похожим на массив, потому что у него есть свойства, подобные массиву. Он имеет длину и n ключей, использующих целые числа.

person AutoSponge    schedule 11.03.2012
comment
Таким образом, любой объект с целочисленными ключами и свойством length отображается в консоли как массив? Можете ли вы продублировать это с помощью пользовательского объекта? - person NudeCanalTroll; 11.03.2012

Когда вы вызываете jQuery(), вы не передаете никаких аргументов функции, поэтому она возвращает пустой объект. Когда вы передаете селектор в качестве аргумента, он создает объект элементов, соответствующих селектору.

person charlietfl    schedule 11.03.2012
comment
Да, но это не совсем массив, не так ли? Это объект jQuery: jQuery('span') instanceof Array возвращает false, а jQuery('span') instanceof jQuery возвращает true. - person NudeCanalTroll; 11.03.2012
comment
JQuery никогда не возвращает массив - person AutoSponge; 11.03.2012

Он возвращает пустой массив, потому что он ничего не сделал - затронут массив элементов.

Правильным способом проверки будет

console.log(jQuery);

если бы ты сделал

console.log(jQuery('div'));

вы увидите, что он возвращает массив элементов.

person lukas.pukenis    schedule 11.03.2012
comment
Да, но как я мог сделать это с моим собственным объектом? - person NudeCanalTroll; 11.03.2012
comment
NudeCanalTroll, пожалуйста, объясните себя немного лучше. Вы хотите вернуть массив из вашей функции затронутых элементов или что? - person lukas.pukenis; 11.03.2012
comment
Нет, перечитайте мой первоначальный вопрос еще раз. Я хочу создать объект, который ведет себя точно так же, как jQuery. jQuery не возвращает массив, он возвращает экземпляр самого себя: jQuery(anything you want to put here) instanceof Array равно false. - person NudeCanalTroll; 11.03.2012
comment
@ lukas.pukenis, он / она хочет, чтобы вывод его объекта был [], когда он вводится в консоль сам по себе, даже если объект не является массивом. - person matt b; 11.03.2012
comment
JQuery не возвращает массив. - person AutoSponge; 11.03.2012
comment
Мне самой теперь интересно узнать причину :) - person lukas.pukenis; 11.03.2012

Я думаю, что вы пытаетесь увидеть свойства вашего объекта. Если это так, вы непреднамеренно преобразуете объект в строку, когда добавляете его к другой строке. Используйте оператор , вместо +, чтобы отобразить свойства объекта вместо «строковой» версии объекта:

console.log('test with string concat: ', j);
person rjz    schedule 11.03.2012
comment
Я не пытаюсь увидеть свойства объекта. Фактически, это поведение по умолчанию, которого я пытаюсь избежать. Вместо этого я хочу, чтобы мой объект отображался как массив, даже если это не массив. - person NudeCanalTroll; 11.03.2012