在像对象这样的数组上使用slice()方法

Using slice() method on Array like Object

本文关键字:slice 方法 数组 对象      更新时间:2023-09-26

我对输出感到困惑。

var arrLike = {0:'Martin', 1:78, 2:67, 3:['L', 'M', 'P'], length: 4};

如果我在arrLike上使用slice()

var newArr = Array.prototype.slice.call(arrLike, 0);

输出:

console.log(newArr);
["Martin", 78, 67, Array[3]]

这是怎么发生的?我无法用输出来包装我的头。

前言:请注意,控制台输出中的Array[3]只是控制台向您显示它的方式。您的newArr是:

["Martin", 78, 67, ['L', 'M', 'P']]

发生这种情况是因为这就是slice的定义方式。粗略地说:

  1. 创建一个新的空数组
  2. 读取您为其提供的内容的length属性
  3. 从起始索引(默认0)循环到结束索引(默认length - 1);调用循环变量k
    1. 在请求对象输入属性k时,将对象中找到的任何属性放入索引 k - start 处的数组中。
  4. 将返回数组的length设置为 k - start
  5. 返回数组

或者(再次非常松散):

function slice(start, end) {
    var n, k, result;
    start = arguments.length < 1 ? 0 : +start;
    end = arguments.length < 2 ? +this.length : +end;
    result = [];
    for (var k = start, n = 0; k < end; ++k, ++n) {
        if (n in this) {
            result[n] = this[k];
        }
    }
    result.length = n;
    return result;
}

所有血腥的细节。

由于您的arrLike对象具有length属性,并且具有名称为 0123 的属性,因此您可以得到所显示的结果。

查看slice()的规范。slice() 函数会将您未指定的 end 参数默认为 this.length ,并且...

  1. 如果 end 未定义,则让 relativeEnd 为 len;否则让 relativeEnd 为 到整数(结束)。

因此,您只是将arrLike对象的前 4 个非元素属性推送到新数组中。

尝试使用...

var arrLike = {0:'Martin', 1:78, 2:67, 3:['L', 'M', 'P'], length: 6, 4: 'test'};