当我调用.length时,为什么这个数组是不确定的?

时间:2014-10-24 14:13:45

标签: javascript arrays recursion

我正在从 Eloquent JavaScript see 'a list' at bottom of linked page)这本书开始练习。基本上,我想创建一个带有数组的对象,并将其转换为具有以下结构的列表:

var list = {
  value: 1,
  rest: {
    value: 2,
    rest: {
      value: 3,
      rest: null
    }
  }
};

当我在控制台中运行以下代码时,我得到TypeError: Cannot read property 'length' of undefined (line 3 in function 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问题 List data structures in JavaScript 是关于同一问题的非常相似的帖子。我不是在这里寻找解决方案,而是在递归调用中解释干扰的原因。

4 个答案:

答案 0 :(得分:12)

list.rest = arrayToList();

由于您未将任何参数传递给arrayToList,因此array将具有默认值undefined。这就是它失败的原因

  

TypeError:无法读取 未定义

的属性“长度”

因此,在递归调用期间,您应该再次将数组传递给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 } } }

答案 1 :(得分:2)

在这一行:

    list.rest = arrayToList();

...您递归调用该函数但未指定参数,因此array变为undefined

看起来您应该再次传递array(已修改)。

    list.rest = arrayToList(array);

live demo

答案 2 :(得分:2)

在递归arrayToList调用中,您没有将任何内容作为参数传递(!)。

答案 3 :(得分: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;
}