【问题标题】:Array Like Objects in JavascriptJavascript中的数组类对象
【发布时间】:2011-09-29 18:07:50
【问题描述】:

我想知道 jQuery 是如何构造它的类数组对象的。我要解决的关键问题是它如何设法让控制台将其解释为数组并按原样显示。我知道它与长度属性有关,但玩了一会儿后我不太明白。

我知道这与像下面示例中的普通数组这样的对象相比没有技术优势。但我认为这是用户在测试和调试时的重要语义元素。

像 Object 一样的普通数组。

function foo(){
    // Array like objects have a length property and it's properties use integer
    // based sequential key names, e.g. 0,1,2,3,4,5,6 just like an array.
    this.length = 1;
    this[0] = 'hello'
}
// Just to make sure add the length property to the prototype to match the Array 
// prototype
foo.prototype.length = 0;

// Give the Array like object an Array method to test that it works     
foo.prototype.push = Array.prototype.push

// Create an Array like object 
var bar = new foo;

//test it 
bar.push('world');

console.log(bar);
// outputs 
{ 0: 'hello',
  1: 'world',
  length: 2,
  __proto__: foo
}

jQuery 的输出位置

var jQArray = $('div')

console.log(jQArray);

// outputs
[<div></div>,<div></div>,<div></div>,<div></div>]

如果你运行

console.dir(jQArray)

// Outputs

{ 0: HTMLDivElement,
  1: HTMLDivElement,
  2: HTMLDivElement,
  3: HTMLDivElement,
  4: HTMLDivElement,
  context: HTMLDocument,
  length: 5,
  __proto__: Object[0]
 }

jQuery 对象的原型特别有趣,因为它是 Object 而不是 jQuery.fn.init,正如预期的那样,[0] 也表示一些东西,因为这是你得到的。

console.dir([])
// outputs Array[0] as the object name or Array[x] x being the internal length of the
// Array

我不知道 jQuery 是如何将它的原型设置为 Object[0] 的,但我的猜测是答案就在那里。有人有什么想法吗?

【问题讨论】:

  • 我不确定这一点,但你不能创建你的对象然后将它的原型设置为 Array.prototype 吗?那么它将是一个类似数组的对象吗?还是没有?
  • 据我所知,这将使它成为一个正常的数组。但我也想避免这种情况,因为我不想将所有 Array 方法添加到我的对象中,以避免混淆。由于某些数组方法实际上会返回一个新数组,因此当用户使用其中一种方法时,附加到我的数组之类的对象的所有其他方法都将丢失。

标签: javascript jquery arrays javascript-objects


【解决方案1】:

对象必须有lengthsplice

> var x = {length:2, '0':'foo', '1':'bar', splice:function(){}}
> console.log(x);
['foo', 'bar']

和仅供参考,Object[0] 作为原型是出于完全相同的原因。浏览器将原型本身视为一个数组,因为:

$.prototype.length == 0;
$.prototype.splice == [].splice;

【讨论】:

  • 如果您不需要将对象打印为带有 console.log() 的数组,则无需拼接。长度和 0,1 之类的属性足以使用数组方法。
  • @zyklus 你是否知道这是 ECMA 规范(类数组对象)的一部分,还是浏览器的优点?
  • @Usagi - AFAIK 这与 ECMA 脚本无关,只是一个随机的开发工具。 JS 中有很多“类似数组”的对象,无论是语言还是用户创建的,所以如果它们实现了Array 的某个最小子集,那么将它们显示为数组是很有用的,这正是开发人员选择的。
【解决方案2】:

像这样?

function foo() {
  this.push('hello');
}
foo.prototype = [];

var bar = new foo();
console.log(bar.length); // 1
console.log(bar); // ["hello"]

【讨论】:

  • 这与我给@JohnSrickler 的回复具有相同的效果。我不想将所有 Array 方法添加到我的 Object 以避免混淆,因为某些数组方法实际上返回一个新 Array。因此,我附加到对象的任何其他方法在使用时都会丢失。
  • jQuery 对象使用 Array 作为其原型。我认为您可以重新定义这些方法,以便它们返回新的 foo 对象而不是常规数组。
  • @Andrey M. - 请不要说你不确定的东西。 jQuery not 使用 Array 作为它的原型。它使用来自Arraypushsortsplice,仅此而已。
  • 我又查看了 jQuery 对象的原型链,在其中的任何地方都找不到定义的数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 2019-07-28
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多