【问题标题】:Having trouble implementing my stack class in Javascript在 Javascript 中实现我的堆栈类时遇到问题
【发布时间】:2017-01-06 02:28:46
【问题描述】:

我正在创建我的堆栈类。我遵循了一本 javascript 数据结构书,但我更改了一些函数,但我不断收到一条错误消息,上面写着“s.length 不是函数”。我有一个长度函数,但我想知道既然 javascript 中有一个关键字“长度”,那么与函数同名可能会导致问题。:

// LIFO

function Stack() 
{
    this.dataStore = [];
    // top of the stack
    this.top = 0;
    this.push = push;
    this.pop = pop;
    this.peek = peek;
 }

function push(element)
{
    // when new element is pushed, it needs to be stored
    // in the top position and top var needs to be incremented
    // so the new top is the next empty pos in the array 
    //this.dataStore(this.top++) = element;
    // the increment op after the call ensures that the 
    // current value of top is used to place the new element
    // at the top of the stack before top is incremented 
    this.dataStore.push(element);
 }

function pop()
{
    // returns element in top pos of stack and then decrements
    // the top variable
    //return this.dataStore[--this.top];
    return this.dataStore.pop(element);
}

function peek()
{
    // returns the top element of the stack by accessing 
    // the element at the top-1 position of the array
    //return this.dataStore[this.top-1];
    return this.dataStore[items.length-1];
}

function length()
{
    //return this.top;
    return this.dataStore.length;
}

function clear()
{
    //return this.top = 0;
    return this.dataStore = [];
}

var s = new Stack();
s.push("David");
s.push("Raymond");
s.push("Bryan"); 
console.log("length: " + s.length());

【问题讨论】:

    标签: javascript algorithm data-structures stack


    【解决方案1】:

    首先,我认为使用这种模式不是一个好主意:

    function MyClass () {
      this.method = method;
    }
    function method () {
      // ...
    }
    

    它污染了命名空间,而length 作为一个公共属性很快就会变得混乱。我更喜欢在定义构造函数后使用原型对象的显式覆盖,这样就不需要全局函数作为方法。

    也许这样的东西会更好? (为简洁起见,省略了 cmets)

    function Stack() 
    {
        this.dataStore = [];
        // top of the stack
        this.top = 0;
        // this.push = push;
        // this.pop = pop;
        // this.peek = peek;
        // this.length = length;
     }
    
    Stack.prototype.push = function(element)
    {
        this.dataStore.push(element);
     }
    
    Stack.prototype.pop = function()
    {
        return this.dataStore.pop( /*element*/ );
    }
    
    Stack.prototype.peek = function()
    {
        return this.dataStore[ /*items*/ this.dataStore.length-1];
    }
    
    Stack.prototype.length = function()
    {
        return this.dataStore.length;
    }
    
    Stack.prototype.clear = function()
    {
        return this.dataStore = [];
    }
    

    那么你的例子就可以了。

    length视为用户自定义属性

    快速测试一下,javascript 对length 以这种方式覆盖没有问题。这是因为length 不是对象的属性(不过是数组),因此您可以在自己的类中随意将其用作属性或方法名称。

    【讨论】:

      【解决方案2】:

      “不是函数”这样的错误通常意味着您试图将非函数对象属性作为函数调用。这通常通过在属性后面加上括号来完成。

      你在这里做了这个:console.log("length: " + s.length());

      去掉括号:

      console.log("length: " + s.length);.

      但是你的堆栈对象没有长度属性,所以你会用一个错误换另一个错误。我不确定您要检查对象长度的目的是什么,但请查看有关如何get an object’s length in JavaScript 的问题。

      这超出了所提出的问题,但是您遇到了麻烦,因为您试图将 push 推到您的对象上,而您可能希望将 dataStore 推到您的对象 inside 数组上,像这样:

      s.dataStore.push("David");
      

      【讨论】:

      • 哦,太好了,谢谢!我得到了长度:未定义,所以我的推送功能一定不正确。
      • @user6840964,我更仔细地查看了您的代码并提供了更多指导。
      【解决方案3】:

      无论您遵循什么数据结构书籍,它都做错了;至少在 JS 中。

      在 JS 中,您应该在实例化对象的原型中加入实用方法,这样它们就不会为每个实例化的 Stack 对象占用多余的内存空间。

      到目前为止,我符合@Xeren Narcy's answer,但是这个堆栈是使用数组子类的完美候选,因此您不需要重新实现标准数组方法,如.pop() 和@987654323 @ 在Stack() 构造函数的原型下。相反,您可以将Array.prototype 设为Stack.prototype 的超类(此处为子类)。最重要的是,由于我们的 Stack 对象将从适当的 Array 对象继承,它们神奇的长度属性将像任何数组一样工作。 (即使您通过索引分配项目。)

      让我们看看实现...

      function Stack(...a){
        var stack = new Array(...a);
        Object.setPrototypeOf(stack, Stack.prototype);
        return stack;
      }
      Stack.prototype = Object.create(Array.prototype); // now stack has full access to array methods.
      Stack.prototype.constructor = Stack;              // now Stack is a proper constructor
      Stack.prototype.peak = function(){return this[this.length-1]}; // add Stack "only" methods to the Stack.prototype.
      
      var s = new Stack(1,2,3,4,1);
      console.log(s.peak());
      s[s.length] = 7;
      console.log(s.length);
      s.push(42);
      console.log(s);
      console.log(s.length);

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2021-06-01
        • 2020-01-24
        • 2018-01-05
        • 1970-01-01
        • 1970-01-01
        • 2020-06-28
        • 2020-07-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多