【问题标题】:Object Type Error in Prepend Function前置函数中的对象类型错误
【发布时间】:2026-01-03 09:20:03
【问题描述】:

我目前正在学习 Eloquent JS 书中的 Javascript 和 DataStructures。我目前的任务是“编写辅助函数 prepend,它接受一个元素和一个列表并创建一个新列表,将元素添加到输入列表的前面”。我想改进,所以我不一定要为我做我的工作,但请赐教。我有 3 个问题,但我的主要问题是第一个:

1:在下面的代码中,我的类型错误在哪里?控制台日志显示“TypeError:oldObj 未定义”,但我在函数内部对其进行了初始化。

lsPre = function(obj)
{   
    var iter = 0;
    var maxIT = 0; //use to capture final     object iteration
    var oldObj = obj; //initialize old object

    //create new object to prepend to old object
    var newObj = {iteration: iter,
    value: 'Overwrite this Value',
              next: oldObj.next
             };

    while (oldObj.iteration + 1 > maxIT)
    {
        maxIT++;
        newObj.next = oldObj.next;
        oldObj = oldObj.next;
    }
    return newObj;
}

2:是否有比我预期的前置功能更优化的解决方案(范式)?我正在尝试学习更多面向 js 的范例,并且目前正在避免递归解决方案。

3:下面是与上述相同问题集中的较早问题的链接列表递归解决方案。是否有原因将对象返回为:

Object {iteration: 1, value: 2, next: Object}

而不是:

Object {iteration: 1, value: x, next: Object { iteration: 2, value: x, next: (and so on) }}

代码如下:

//Link List
rayREC = function(ray,iter=0)
{   //Default param 'inc' allows arbitrary implementation of this function
    var rLen = ray.length;
    if (iter > rLen) return;
    return  {//recurively increment objects
             iteration: iter,
             value: ray[iter],
             next: rayREC(ray,iter + 1), //recursion
           };
}

我还想要 3 的最佳范例或解决方案。

【问题讨论】:

    标签: javascript list data-structures prepend


    【解决方案1】:

    答案 1:

    您得到"TypeError: oldObj is undefined" 可能是因为您使用undefined 参数调用了该函数。

    例如:

    lsPre(); // "TypeError: oldObj is undefined"
    
    lsPre({iteration: 1, value: 2, next: Object}) // Works... well, kind of...
    

    答案 2:

    这取决于您要实现的链表类型。

    例如,一个非常简单的链表,包含valuenext

    var simpleListedList = {"value": "Value One", "next": null};
    

    可以看到,这个所谓的“链表”本身就是一个节点。

    要“前置”,即在前面添加一些东西,我们可以简单地:

    var oldNode = simpleListedList;
    simpleListedList = {"value": "Value Zero (New)", "next": oldNode};
    

    我们也可以像这样无脑地迭代它:

    var currentNode = simpleListedList;
    while (currentNode != null){
        console.log(currentNode.value);
        currentNode = currentNode.next;
    }
    

    使用“基于下一个”的链表,实际上更难追加(即在后面添加):

    // First iterate to the last node
    var lastNode = simpleListedList;
    while (lastNode.next != null) {
        lastNode = lastNode.next;
    }
    
    // We then add something at the end
    lastNode.next = {"value": "Value N plus One (New last guy)", "next": null}
    
    // Note that simpleListedList is still the first node, unchanged.
    

    答案 3:

    我不太明白这个问题。

    Object {iteration: 1, value: 2, next: Object}
    

    只有一个节点,next 的值是一个常量 Object(不能迭代)

    Object {iteration: 1, value: x, next: Object { iteration: 2, value: x, next: (and so on) }}
    

    这似乎是一个正确的链表,如果你用 JSON 表示它,它应该是这样的:

    {
        iteration: 1,
        value: "val of 1",
        next: {
            iteration: 2,
            value: "val of 2",
            next: {
                iteration: 3,
                value: "val of 3",
                next: {
                    iteration: 4,
                    value: "val of 4",
                    next: {
                        // ... Not sure how you would terminate the linked list
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 对于答案 1,我仍然收到类型错误。考虑使用问题 3 中的函数创建的新列表。编辑:抱歉,移动浏览器不会让我换行,所以这里有一些糟糕的格式:z = rayRec([1,2,3,4]); lsPre(z); //"TypeError oldObj is undefined"
    • 您可能应该得到TypeError: Cannot read property 'iteration' of undefined。这是由于 oldObj = oldObj.next;lsPre 的 while 循环内。最后一个对象的下一个是null
    • 就是这样!非常感谢!