0

我只是在玩一些 JavaScript 并有以下代码:

function Stack() {
    // Wrapper class for Array. This class only exposes the push
    // and pop methods from the Array and the length property
    // to mimic the a LIFO Stack.

    // Instantiate new Array object.
    this.stack = new Array();

    // Pushes a new value on to the stack.
    // @param arg to be pushed.
    this.push = function(arg) {
        return this.stack.push(arg);
    }

    // Pops a value from the stack and returns it.
    this.pop = function() {
        return this.stack.pop();
    }

    // Get size of the Stack.
    this.size = function() {
        return this.stack.length;
    }
}

var stack = new Stack();

// Push 10 items on to the stack
for (var i = 0; i < 10; i++) {
    stack.push(i);
}

for (var i = 0; i < stack.size(); i++) {
    console.log(stack.pop());
}

第一部分定义了一个 Stack 对象,它实际上只是原生 Array 对象的包装器,但只公开了一些方法和属性以使其类似于 LIFO 堆栈。为了测试它,我在底部编写了代码。但是,当我尝试stack.size()在 for 循环中使用返回堆栈的当前大小时,循环仅迭代 5 次。然而,如果我将该方法调用的返回值分配给一个变量并将该变量传递给 for 循环,它会迭代正确的次数(10)。为什么是这样?我应该不能在 for 循环中使用 stack.size() 吗?

4

5 回答 5

1

当你stack.size()在循环中使用时,循环迭代5次后,stack.size()等于5,因为你已经出栈5次,i也等于5。在下一次迭代中,i大于堆栈的大小,循环最终结束。

于 2013-09-16T11:13:12.097 回答
1

因为stack.size()在每次执行后都会测试 for 循环,所以每次从堆栈中弹出一个元素时,大小都会变小。而如果您使用该变量,则将堆栈大小保存在该变量中,即使您从堆栈中弹出该变量也不会改变。

于 2013-09-16T11:13:13.987 回答
1

另一种写法是:

for (var i = 0, l = stack.size(); i < l; i++) {
  console.log(stack.pop());
}

for...loops以及编写IMO的最佳方式。

于 2013-09-16T11:15:56.410 回答
0

另外,为什么不这样做:

this.pop = this.stack.pop;

而不是

this.pop = function() {
    return this.stack.pop();
}

对我来说似乎是不必要的关闭?

于 2013-09-16T11:35:39.623 回答
0

对于每次迭代,您将删除其中一个对象并使数组的大小减小 1。

于 2013-09-16T11:13:23.913 回答