如何从 JavaScript 构造函数中的 forEach 循环内部调用嵌套函数?

How to invoke a nested function from inside a forEach loop in a JavaScript constructor function?

代码 1 - forEach 中的 this.kitchenStatus() 无法访问

我无法从 forEach 内部访问函数 (this.kitchenStatus()) 的值,当我尝试下面的操作时,我得到“未捕获的类型错误:this.kitchenStatus 不是函数” :

const KitchenUtensil = function () {
    // Pay attention to this.kitchenStatus(), this is the function 
    // I want to get the values from inside the loops
    this.kitchenStatus = function () {
        let kStatus = "Kitchen open.";
        return kStatus;
    };
    let utensilsArray = ["spoon", "fork", "kettle"];

    // 1. WITH FOREACH FUNCTION
    utensilsArray.forEach(function (utensil) {
        let utensilLine = "In a forEach loop function:" + "\n";
        utensilLine += "It's a " + utensil 
        + ". " 
        // If you want to see it breaking uncomment the code below:
        // + this.kitchenStatus() 
        ;
        console.log(utensilLine);
    });

};

let teapot = new KitchenUtensil ();

代码 2 - for 循环中的 this.kitchenStatus() 可访问

所以,我尝试使用一个简单的 for 循环并且它起作用了:

const KitchenUtensil = function () {
    // Pay attention to this.kitchenStatus(), this is the function 
    // I want to get the values from inside the loops
    this.kitchenStatus = function () {
        let kStatus = "Kitchen open.";
        return kStatus;
    };
    let utensilsArray = ["spoon", "fork", "kettle"];

    // 2. WITH FOR LOOP
    for (let i = 0; i < utensilsArray.length; i++) {
        let utensilLine2 = "In a simple for loop:" + "\n";
        utensilLine2 += "It's a " + utensilsArray[i] 
        + ". " 
        // Unlike the forEach, the for loop can access the function:
        + this.kitchenStatus() 
        ;
        console.log(utensilLine2);
    };
};

let teapot = new KitchenUtensil ();

代码 3 - this.kitchenStatus() 将值分配给新变量并从 forEach 内部调用新变量 - 它有效,但嘿,它看起来像一个蹩脚的解决方案

我没有放弃 forEach 并做了一个变通方法。我没有尝试从 forEach 函数内部访问 this.kitchenStatus,而是在循环外部创建了一个新变量“letMeIn”,并将 this.kitchenStatus() 的值赋给它,然后从循环内部我调用了 letMeIn。它有效,但感觉根本不对,我刚刚创建了一段新代码,它的唯一功能是作为转到下面几行代码的另一段代码:

const KitchenUtensil = function () {
    // Pay attention to this.kitchenStatus(), this is the function 
    // I want to get the values from inside the loops
    this.kitchenStatus = function () {
        let kStatus = "Kitchen open.";
        return kStatus;
    };
    let utensilsArray = ["spoon", "fork", "kettle"];

    // 3. THE ONLY WAY TO GET FOREACH TO ACCESS THE FUNCTION
    // Before the loop function is declared create a variable 
    // (e.g. letMeIn) and assign the value of this.kitchenStatus to it
    // This looks like a really crappy and unprofessional workaround:
    let letMeIn = "From a variable: " + this.kitchenStatus();
    utensilsArray.forEach(function (utensil) {
        let utensilLine = "In a forEach loop function:" + "\n";
        utensilLine += "It's a " + utensil 
        + ". " 
        // Once inside the loop invoke the variable:  
        + letMeIn 
        ;
        console.log(utensilLine);
    });

};

let teapot = new KitchenUtensil ();

代码 4 - 如果主构造函数作为简单函数调用而不是使用 new

,则 forEach 会找到 this.kitchenStatus() 值

最后我尝试的最后一件事是通过使用“new KitchenUtensil ()”而不是“let teapot = new KitchenUtensil ()”将构造函数 (?) 函数 KitchenUtensil 作为一个简单函数调用:

const KitchenUtensil = function () {
    // Pay attention to this.kitchenStatus(), this is the function 
    // I want to get the values from inside the loops
    this.kitchenStatus = function () {
        let kStatus = "Kitchen open.";
        return kStatus;
    };
    let utensilsArray = ["spoon", "fork", "kettle"];
    
    utensilsArray.forEach(function (utensil) {
        let utensilLine = "In a forEach loop function:" + "\n";
        utensilLine += "It's a " + utensil 
        + ". " 
        // Now it will work, why???:
        + this.kitchenStatus() 
        ;
        console.log(utensilLine);
    });

};

// 4. INVOKE FUNCTION WITHOUT NEW
// Just comment the next line, and instead of invoking as a constructor:
// let teapot = new KitchenUtensil ();
// Invoke the then constructor directly as a simple function:
KitchenUtensil ();

这是怎么回事?在其他方面我需要做什么才能让 forEach 找到并访问 this.kitchenStatus() 函数?

一个function创建了一个新的上下文,所以this引用了这个函数。为了使其按预期工作,您需要在 forEach:

中将 function 更改为 () => {} (箭头)函数
utensilsArray.forEach((utensil) => {
    let utensilLine = "In a forEach loop function:" + "\n";
    utensilLine += "It's a " + utensil 
    + ". " 
    // Now it will work
    + this.kitchenStatus() 
    ;
    console.log(utensilLine);
});

另一种解决方案是将this保存到forEach()之前的变量:

const self = this;
utensilsArray.forEach(function (utensil) {
    let utensilLine = "In a forEach loop function:" + "\n";
    utensilLine += "It's a " + utensil 
    + ". " 
    // Now it will work too
    + self.kitchenStatus() 
    ;
    console.log(utensilLine);
});

有关 this 工作原理的更多信息,请参阅 this great answer