JavaScript "This" 断章取义,而是指 window

JavaScript "This" is out of context, refers to window instead

我遇到这样一种情况,一个函数正在调用另一个函数,改变了正在使用的 "this" 的上下文。在 "check" 函数中,我在变量 'self' 中添加了尝试对此进行补偿,以及 "alert" 以确保 "self" 正在显示 [object Object ] (它是),但是当我将 "self" 传递给 "recurse" 函数时,使用警报我可以看到键变为 [object Window] 并且 val 变为未定义。我一辈子都想不出如何解决这个问题...

$.each(data, check);

function check(key, val){
    var self = this;
    if (self.group == "whatever"){
        alert(self);
        recurse(self);
    }
}

function recurse(key, val) {
    if (val instanceof Object) {
        if (this.hasOwnProperty('subNav')) {
            items.push("<li class='" + this.n_class + "'><a target='" + this.target + "' href='" + this.link + "'>" + this.name + "</a>");
            items.push("<ul>");
            $.each(this.subNav, recurse);
            items.push("</ul></li>");
        }
        else {
            items.push("<li class='" + this.n_class + "'><a target='" + this.target + "' href='" + this.link + "'>" + this.name + "</a></li>");
        }
    }
};

您可以使用 javascript 函数 callapply。有关详细信息,请参阅此答案

recurse.call(this); 

Your using the this keyword。 在你的函数中 this 默认会引用全局对象;在浏览器中这是 window.

我已经稍微修改了您的代码以解决您的问题,但尚未经过测试。

$.each(data, parse);

function parse(key, val) {
    if (val instanceof Object) {
    items.push("<li class='" + val.n_class + "'><a target='" + val.target + "' href='" + val.link + "'>" + val.name + "</a>");
        if (val.hasOwnProperty('subNav')) {
            items.push("<ul>");
            $.each(val.subNav, parse);
            items.push("</ul>");
        }
    items.push("</li>");
    }
};

我明白了。我只需要 "this" 来引用同一个对象,所以我从 recurse() 中删除了 "key" 和 "val" 参数,并将内部的 val 更改为 "this",也称为使用 "recurse.call(this)" (*见下文)

在 check() 中递归
$.each(data, check);
function check(key, val){
    if (this.group == "whatever"){
        recurse.call(this); //*****first change
    }
}

function recurse() { //****removed parameters
    if (this instanceof Object) { //**** changed "val" to "this"
        if (this.hasOwnProperty('subNav')) {
            items.push("<li class='" + this.n_class + "'><a target='" + this.target + "' href='" + this.link + "'>" + this.name + "</a>");
            items.push("<ul>");
            $.each(this.subNav, recurse);
            items.push("</ul></li>");
        }
        else {
            items.push("<li class='" + this.n_class + "'><a target='" + this.target + "' href='" + this.link + "'>" + this.name + "</a></li>");
        }
    }
};