在像Object这样的Array上使用slice()方法

时间:2016-01-14 18:22:37

标签: javascript

我对输出感到困惑。

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

如果我在slice()上使用arrLike

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

输出:

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

这是怎么发生的?我无法用输出结束我的头脑。

2 个答案:

答案 0 :(得分:7)

前言:请注意,控制台输出中的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. 返回数组
  6. 或(再次非常松散):

    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;
    }
    

    All the gory details

    由于您的arrLike对象具有length属性,并且其属性的名称为0123,你得到了你已经展示的结果。

答案 1 :(得分:1)

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

  
      
  1. 如果end未定义,则让relativeEnd为len;否则让relativeEnd成为   ToInteger(结束)。
  2.   

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

尝试使用...

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