为什么调用 .length 时这个数组会变成未定义的?

10

我正在从书籍《JavaScript高级程序设计》中进行一项练习(请参见链接页面底部的“列表”)。基本上,我想要创建一个对象,它可以将一个数组转换成以下结构的列表:

var list = {
  value: 1,
  rest: {
    value: 2,
    rest: {
      value: 3,
      rest: null
    }
  }
};
当我在控制台运行以下代码时,我会得到TypeError: Cannot read property 'length' of undefined (线3中的函数arrayToList)。为什么我调用.length的数组没有定义?
function arrayToList(array){
    var list = {};
    if(!array.length){
        list.value = null;
    }
    else{
        list.value = array.shift();
        list.rest = arrayToList();
    }
    return list;
}

console.log(arrayToList([10, 20]));

注意: Stack Overflow的问题“JavaScript中的列表数据结构”是关于同一问题的非常类似的帖子。我在这里不是特别在寻找一个解决方案,而更多地是关于递归调用出了什么问题的解释。


2
一个想法:函数arrayToList()需要一个数组作为参数。在递归调用中,它没有得到该参数... - Goodword
尝试在调试器中跟踪该函数。 - 1983
5
注意,该错误并未指出.length未定义。 - ThisSuitIsBlackNot
4个回答

12
list.rest = arrayToList();

由于您没有向arrayToList传递任何参数,因此array将具有默认值undefined。这就是为什么会出现以下错误的原因:

TypeError: Cannot read property 'length' of undefined

因此,在递归调用期间,您应该再次向arrayToList传递一个数组。

function arrayToList(array) {
    var list = {};
    if (!array.length) {
        list.value = null;
    } else {
        list.value = array.shift();
        list.rest = arrayToList(array);   // Pass the `array` after shifting
    }
    return list;
}

console.log(arrayToList([10, 20]));
# { value: 10, rest: { value: 20, rest: { value: null } } }

2

在这一行:

    list.rest = arrayToList();

你递归调用函数时没有指定参数,所以array变成了undefined

看起来你应该再次传递已经修改的array参数。

    list.rest = arrayToList(array);

live demo


2
在递归的arrayToList调用中,你没有传递任何参数!

0
function arrayToList(array) {
    var list = {};
    if (!(array instanceof Array) || array.length == 0) {
       list.value = null;
    } else {
        list.value = array.shift();
        list.rest = arrayToList();
    }
    return list;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接