美文网首页
引用类型 Array 的实践探索

引用类型 Array 的实践探索

作者: 爆发吧小宇宙 | 来源:发表于2019-02-12 18:59 被阅读0次
《飞驰人生》之去热带岛屿游泳

开工第一天,后面的老王同志就抛出了一个让我很懵逼的问题。正好没啥子事,我就扒了一扒,学习一下基础知识。于是有了一些收获,感谢老王同志。

题目:

  • 模拟代码
var a = [];
a.length = 2;
console.log(a.indexOf(undefined)); // 此处打印出 -1
  • 问题:
    已知,a[0] === undefined,
    为什么 a.indexOf(undefined) = -1 ?

indexOf() 方法源码

题目一看,有点懵,第一反应也是去查源码,搜了一会子,找到如下片段:

// For .indexOf, we don't need to pass in the number of arguments
// at the callsite since ToInteger(undefined) == 0; however, for
// .lastIndexOf, we need to pass it, since the behavior for passing
// undefined is 0 but for not including the argument is length-1.
function InnerArrayIndexOf(array, element, index, length) {
  if (length == 0) return -1;
  if (IS_UNDEFINED(index)) {
    index = 0;
  } else {
    index = TO_INTEGER(index);
    // If index is negative, index from the end of the array.
    if (index < 0) {
      index = length + index;
      // If index is still negative, search the entire array.
      if (index < 0) index = 0;
    }
  }
  var min = index;
  var max = length;
  if (UseSparseVariant(array, length, IS_ARRAY(array), max - min)) {
    %NormalizeElements(array);
    var indices = %GetArrayKeys(array, length);
    if (IS_NUMBER(indices)) {
      // It's an interval.
      max = indices;  // Capped by length already.
      // Fall through to loop below.
    } else {
      if (indices.length == 0) return -1;
      // Get all the keys in sorted order.
      var sortedKeys = GetSortedArrayKeys(array, indices);
      var n = sortedKeys.length;
      var i = 0;
      while (i < n && sortedKeys[i] < index) I++;
      while (i < n) {
        var key = sortedKeys[I];
        if (!IS_UNDEFINED(key) && array[key] === element) return key;
        I++;
      }
      return -1;
    }
  }
  // Lookup through the array.
  if (!IS_UNDEFINED(element)) {
    for (var i = min; i < max; i++) {
      if (array[i] === element) return I;
    }
    return -1;
  }
  // Lookup through the array.
  for (var i = min; i < max; i++) {
    if (IS_UNDEFINED(array[i]) && i in array) {
      return I;
    }
  }
  return -1;
}

看来看去,这里面看不出答案,比较关键的一句就是var indices = %GetArrayKeys(array, length);IS_UNDEFINED(array[i]) && i in array。我自己理解这两句体现的要点如下:

  • 查询的范围和key值获取结果有关;
  • 判断数组中的元素是否为undefined,判断索引是否合法或索引对应的元素是否在数组中。

关于 in 算法,我找到如下解释,可以帮助理解:

  1. 如果右边是数组左边是数字,会把左边的数字 (字符串形式的也可以如 "2" in arr 等于 2 in arr)当成一个索引去检查,如果索引是合法的就返回true。
  2. 如果右边是数组左边是字符串 比如"id",会把左边的值当成一个属性去检查,如果找到该属性就返回true。
  3. 如果右边是对象这个时候不管左边字符串还是数字,会把左边的值当成一个属性去检查,如果找到该属性就返回true。

经验证,在数组未赋值的时候拿不到key值。

查询 key 值

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。

  • 语法

Object.keys(obj)

  • 参数
    obj
    要返回其枚举自身属性的对象。

  • 返回值
    一个表示给定对象的所有可枚举属性的字符串数组。

  • 相关描述
    Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的 object 上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。

如果想获取一个对象的所有属性,甚至包括不可枚举的,可使用 Object.getOwnPropertyNames

从上述关于获取 key 的内容来看,可以推测,我们的数组中是找不到未赋值的索引属性的,所以才会找不到。

我看了在《JavaScript高级程序设计》一书中找到了关于array的篇章,对array也有了更深的理解。贴图如下,供大家参考:


JavaScript高级程序设计-引用类型-arra�y
JavaScript高级程序设计-引用类型-array-1
JavaScript高级程序设计-引用类型-array-2
JavaScript高级程序设计-引用类型-array-3
JavaScript高级程序设计-引用类型-array-4

我自己理解如下:
在js语言中,数组实际上是一个对象,有一些固定的属性如:length 等,当给数组增加元素的时候,比如执行 a[0] = 222 这个操作,会在数组的属性中增加键值对(用json表示) {'0': 222},这样数组就会多了一个由索引生成的属性 ‘0’。对于未赋值的数组的元素,值为 undefined,通过 indexOf 方法查找是否包含 undefined 这个值时,未赋值的元素没有索引属性,无法查到值。

欢迎补充和指正

相关文章

  • 引用类型 Array 的实践探索

    开工第一天,后面的老王同志就抛出了一个让我很懵逼的问题。正好没啥子事,我就扒了一扒,学习一下基础知识。于是有了一些...

  • 系统学习 JavaScript 的笔记【7】

    引用类型 引用类型分为 object 类型 Array 类型,我个人觉得 Array 的重点能多一些,因此我主要总...

  • 引用类型 - Array 类型

    Array构造函数 当Array被当做一个函数调用时,也会创建并初始化一个新的Array对象。因此,当参数相同时,...

  • 引用类型-Array类型

    EAMAScript数组的每一项可以保存任何类型的数据 1.创建数组 使用Array构造函数 数组字面量方法 2....

  • 引用类型—Array类型

    ECMAScript数组与其它语言数组一样,都是数据的有序列表。但是ECMAScript数组的每一项可以保存任何类...

  • 引用类型与对象拷贝

    1.引用类型有哪些?非引用类型有哪些引用类型:Object / Array / Function / Date /...

  • 引用类型与对象拷贝

    引用类型有哪些?非引用类型有哪些 引用类型:Object、Array、Date、RegExp、Function、M...

  • 基本包装类型和引用类型

    引用类型包括:Object、Array、Date、RegExp、Function。特殊的引用类型():Boolea...

  • javascript 引用对象(绪论与Object)

    Object类型Array类型Date类型RegExp类型Function类型均为引用对象,有着共同的继承于引用对...

  • 引用类型与对象拷贝

    1、引用类型有哪些?非引用类型有哪些 引用类型:Object、Array、Function、正则,将这些对象保存在...

网友评论

      本文标题:引用类型 Array 的实践探索

      本文链接:https://www.haomeiwen.com/subject/bvuqeqtx.html