Javascript数组成员变量未使用Prototype方法定义

Cha*_*ins 5 javascript arrays oop prototype

在下面的代码中,pushElement方法在处理"words"变量时工作正常,但是一旦我运行popElement方法,它就会在"this.words.length"上失败并出现以下错误:"Uncaught TypeError" :无法读取未定义的属性"长度".

有任何想法吗?

function AnimationStack() {
    this.words = [];
}

AnimationStack.prototype.pushElement = function(element) {
    this.words.push(element);
}

AnimationStack.prototype.popElement = function() {
    if (this.words.length>0) {
        var element = this.words.shift();
        return element;
    } else {
        return null;
    }
}

var AS = new AnimationStack();

var element = $("<div></div>");
AS.pushElement(element); // works perfect
AS.pushElement(element); // works perfect
AS.pushElement(element); // works perfect

var pop = AS.popElement(); // always fails
Run Code Online (Sandbox Code Playgroud)

编辑:上面的代码是完美的.在我实际执行的方式中,我使用上面的代码.我正在使用setInterval调用popElement()来改变"this"的范围.阅读完整的答案:

http://forrst.com/posts/Javascript_Array_Member_Variable_is_Undefined_wi-g6V

小智 1

@Chad 已经找到了答案,但这是解释。

如果您像这样调用该函数:

AS.popElement();
Run Code Online (Sandbox Code Playgroud)

popElement 函数在 AS 对象的上下文中运行(意味着“this”指的是 AS)。但是如果你像这样使用 setInterval (或任何回调风格的函数):

setInterval(AS.popElement, 1000);
Run Code Online (Sandbox Code Playgroud)

您仅传递对 popElement 函数的引用。因此,当 1000 毫秒后执行 popElement 时,它是在全局上下文中执行的(意思是“this”指的是 window)。如果您调用以下命令,您会得到相同的错误:

window.popElement();
Run Code Online (Sandbox Code Playgroud)

避免这种情况的一种可能的替代方法是执行以下操作:

setInterval(function() { return AS.popElement() }, 1000);
Run Code Online (Sandbox Code Playgroud)

另一种选择可能是使用 apply 或 call 方法显式设置上下文:

setInterval(AS.popElement.apply(AS), 1000);
Run Code Online (Sandbox Code Playgroud)