首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JavaScript中创建类似数组的对象

问在JavaScript中创建类似数组的对象
EN

Stack Overflow用户
提问于 2012-08-09 23:17:27
回答 6查看 13.2K关注 0票数 23

在JavaScript中,有一些对象伪装成数组(或“类似数组”)。这些对象包括arguments、NodeList(从getElementsByClassName等返回)和jQuery对象。

当console.log合并时,它们显示为数组,但它们不是。我知道为了成为类似数组的对象,对象必须有一个length属性。

所以我做了一个这样的“对象”:

代码语言:javascript
复制
function foo(){
    this.length = 1;
    this[0] = "bar";
}

var test = new foo;

当我执行console log(test)时,我得到了一个foo对象(不出所料)。我可以使用以下命令将其“转换”为数组

代码语言:javascript
复制
Array.prototype.slice.call(test)

但是,我不想转换它,我想让它像数组一样。我如何制作一个类似数组的对象,这样当它被console.log的时候,它看起来就像一个数组?

我尝试设置foo.prototype = Array.prototype,但console.log(new foo)仍然显示foo对象,而不是数组。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-08-09 23:19:59

具体取决于控制台。对于Chrome开发人员控制台中的自定义对象和Firebug,您需要同时使用length和splice属性。splice也必须是一个函数。

代码语言:javascript
复制
a = {
    length: 0,
    splice: function () {}
}
console.log(a); //[]

然而,重要的是要注意,没有官方标准。

以下代码由jQuery (v1.11.1)在内部使用,用于确定对象应该使用for循环还是for..in循环:

代码语言:javascript
复制
function isArraylike( obj ) {
    var length = obj.length,
        type = jQuery.type( obj );

    if ( type === "function" || jQuery.isWindow( obj ) ) {
        return false;
    }

    if ( obj.nodeType === 1 && length ) {
        return true;
    }

    return type === "array" || length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}

请注意,可以有一个在控制台中显示为数组([])但在jQuery中使用for..in循环进行迭代的对象,或者一个在控制台中显示为对象({})但在jQuery中使用for循环进行迭代的对象。

票数 32
EN

Stack Overflow用户

发布于 2019-02-17 18:45:47

当我们可以使用类似arguments参数的数组时,同样的问题也出现在我的脑海中:

​

代码语言:javascript
复制
function arrayLike() {
  console.log(typeof arguments)
  console.log(arguments)
  console.log(Array.from(arguments))
}
arrayLike(1,2,3)

​

因此,让我们尝试创建我们自己的类似数组的对象:

​

代码语言:javascript
复制
let arrayLikeObject = {
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))

​

显然,没有定义长度属性,所以我们的arrayLikeObject将只返回一个空数组。现在,让我们尝试定义一个长度属性:

​

代码语言:javascript
复制
let arrayLikeObject = {
  length: 2,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))

​

如果长度设置不同怎么办?

​

代码语言:javascript
复制
let arrayLikeObject = {
  length: 1,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))
 // it will only return the value from first `0: 1`

​

​

代码语言:javascript
复制
let arrayLikeObject = {
  length: 5,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))
 // other 3 values will be printed as undefined

​

但是,我不想转换它..。

您实际上想创建一个数组,而不是一个类似数组的对象。类数组对象必须按照您所说的那样进行转换:

代码语言:javascript
复制
Array.prototype.slice.call(arrayLikeObject)
// Or,
[].slice.call(arrayLikeObject)

如果您确实尝试在类似数组对象上使用数组方法,那么您将得到类型错误:

​

代码语言:javascript
复制
let arrayLikeObject = {
  length: 5,
  0: 1,
  1: 2
 }

 console.log(arrayLikeObject.sort())

​

因此,要在arrayLikeObject上使用数组方法,我们需要将其转换为数组,就像我们在前面使用Array.from的示例中所做的那样。

否则,您只需创建一个数组:

代码语言:javascript
复制
let arr = [1,2] // I don't mean, you don't know

其他注意事项:

您不能将其用作构造函数:

​

代码语言:javascript
复制
let arrayLikeObject = {
    length: 1,
    slice: function () {
      return 1
    }
}

console.log(new arrayLikeObject) // Type error

​

在下面的代码片段中,由于length属性设置为1,但没有0索引属性,因此结果将为[undefined]:

​

代码语言:javascript
复制
let arrayLikeObject = {
  length: 1,
  slice: function () {
    return 1
  }
}
console.log(Array.from(arrayLikeObject))

​

但是如果您将长度设置为0,那么结果将是一个空数组[],因为我们告诉您在这个类似数组的对象中没有任何值。

票数 4
EN

Stack Overflow用户

发布于 2012-08-09 23:21:38

这有什么用处吗:extended array prototype,他似乎在做你做的事情,并将原型创建为一个数组,但包含了一个额外的方法(可能会工作,也可能不会工作,我还没有测试过这个):

代码语言:javascript
复制
var MyArray = function() {
};

MyArray.prototype = new Array;

MyArray.prototype.forEach = function(action) {
    for (var i = 0, l=this.length; i < l, ++i) {
        action(this[i]);
    }
};

希望它能在某种程度上有所帮助。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11886578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档