javascript中类数组对象的内部存储结构怎样的

js中一般认为类数组满足下面几个条件
1一个对象的属性名是正整数
2有length属性,属性值为正整数
3不是数组
在jq中还有DOM中大量应用类数组,那为什么类数组也能像数组一样进行遍历,其可以调用Array.prototype.方法()?原理是什么,类数组中数据的存储结构又是怎样的,与一般对象有什么不同,与真正的数组又有什么不同?

阅读 5.2k
3 个回答

1.遍历通过的是length,以及i++,这么个东东,那个对象let s = {0:'a',1:'b'}中s[0]就是'a'呀。所以可以像数组一样遍历咯。

2.第二个问题,调用Array.prototype中的方法,你不妨打印出来看一下

Array.prototype

而所谓的类数组是Object,所以你再答应一下Object.prototype

Object.prototype

所以说,类数组是没有所谓的push,pop之类的方法,当然了,你也可以自己写这些方法

3.存储结构嘛,就是Object,只不过规定好了你问题中前两个条件。与一般对象不同,我没明白一般对象是什么,难道类数组不是一般对象?

4.与数组的不同嘛,这个别人也写的很全,你可以参考一下

ps:都是个人理解,有不正确的或者补充请指教,互相学习~

我回复一下第一个问题,

function ArraySlice(start, end) {
  var len = ToUint32(this.length);
  var start_i = TO_INTEGER(start);
  var end_i = len;
  
  if (end !== void 0) end_i = TO_INTEGER(end);
  
  if (start_i < 0) {
    start_i += len;
    if (start_i < 0) start_i = 0;
  } else {
    if (start_i > len) start_i = len;
  }
  
  if (end_i < 0) {
    end_i += len;
    if (end_i < 0) end_i = 0;
  } else {
    if (end_i > len) end_i = len;
  }
  
  var result = [];
  
  if (end_i < start_i)
    return result;
  
  if (IS_ARRAY(this))
    SmartSlice(this, start_i, end_i - start_i, len, result);
  else 
    SimpleSlice(this, start_i, end_i - start_i, len, result);
  
  result.length = end_i - start_i;
  
  return result;
};

然后再看一个SimpleSlice函数实现,

function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
  for (var i = 0; i < del_count; i++) {
    var index = start_i + i;
    // The spec could also be interpreted such that %HasLocalProperty
    // would be the appropriate test.  We follow KJS in consulting the
    // prototype.
    var current = array[index];
    if (!IS_UNDEFINED(current) || index in array)
      deleted_elements[i] = current;
  }
};

大概的意思就是楼上的意思,因为slice内部就是用length以及整数下标实现的,所以可以实现,
~

推荐问题
宣传栏