TypeError: Cannot set property 'key' of undefined

TypeError: Cannot set property 'key' of undefined

class Discount {
    discount;
    constructor() {
        this.key = '';
        this.code = '';
        this.discountValue = 0;
    }
    checkData(searchCode) {
        fetch('discount.json').then ((response) =>{
            return response.json()
        }).then ((obj)=>{
           Object.keys(obj).forEach(function(key) {
                obj[key].forEach((data)=> {
                  // console.log(data.code);
                   // console.log(obj[key]);
                    if (data.code === searchCode) {
                        console.log(key);
                        console.log(data.code);
                        console.log(data.discount);
                       this.key = key;
                       this.code = data.code;
                       this.discountValue = data.discount;
                    }
                });
           });

            console.log(this.key);
            console.log(this.code);
            console.log(this.discountValue);


        }).catch((error)=>{
            console.error('Wrong');
            console.error(error);
        });
    }


}


document.addEventListener("DOMContentLoaded", () =>{
    document.getElementById('calcDiscount').addEventListener('click', ()=>{
        const codeInput = document.getElementById('codeInput').value.toUpperCase();
        const myName = new Discount();

        myName.checkData(codeInput);
    });
});

    at main.js:20
    at Array.forEach (<anonymous>)
    at main.js:13
    at Array.forEach (<anonymous>)
    at main.js:12
(anonymous) @ main.js:34
Promise.catch (async)
checkData @ main.js:32
(anonymous) @ main.js:47

为什么这段代码不起作用?请帮助我,我无法理解。如果您知道如何解决,请向我解释这个问题的解决方案。这是一个折扣,从 json 中获取数据,它应该 return 键、代码和值,但不起作用。

尝试使用 ES6 箭头函数。

class Discount {
    discount;
    constructor() {
        this.key = '';
        this.code = '';
        this.discountValue = 0;
    }

    checkData = (searchCode) => {
        fetch('discount.json').then (res=>res.json()).then ((obj)=>{
           Object.keys(obj).forEach((key) => {
                obj[key].forEach((data)=> {
                  // console.log(data.code);
                   // console.log(obj[key]);
                    if (data.code === searchCode) {
                        console.log(key);
                        console.log(data.code);
                        console.log(data.discount);
                       this.key = key;
                       this.code = data.code;
                       this.discountValue = data.discount;
                    })
                });
           });

            console.log(this.key);
            console.log(this.code);
            console.log(this.discountValue);


        }).catch((error)=>{
            console.error('Wrong');
            console.error(error);
        });
    }


}

试试下面这个:

您需要使用异步等待,因为调用是异步的,执行不会等待您的响应,这就是为什么您在 Object.keys(obj)

中变得未定义
async checkData(searchCode) {
        await fetch('discount.json').then ((response) =>{
            return await response.json()
        }).then ((obj)=>{
           Object.keys(obj).forEach(function(key) {
                obj[key].forEach((data)=> {
                  // console.log(data.code);
                   // console.log(obj[key]);
                    if (data.code === searchCode) {
                        console.log(key);
                        console.log(data.code);
                        console.log(data.discount);
                       this.key = key;
                       this.code = data.code;
                       this.discountValue = data.discount;
                    }
                });
           });

            console.log(this.key);
            console.log(this.code);
            console.log(this.discountValue);


        }).catch((error)=>{
            console.error('Wrong');
            console.error(error);
        });
    }

thisforEach 循环 i:e this.key = key 中,没有指向 Discount class 实例。

作为回调的正常函数将创建它自己的 this i:e Object.keys(obj).forEach(function(key) {

而是使用基于箭头的函数,它没有自己的 this 并且会从指向 class 实例的外部直接范围引用 this

Object.keys(obj).forEach(() => (key) {.

checkData(searchCode) {
    // here `this` points to the class instance
    fetch('discount.json').then ((response) =>{
        // this is retrieved from the outer scope, which is class instance
        return response.json()
    }).then ((obj)=>{
       // this is retrieved from the outer scope, which is class instance
       Object.keys(obj).forEach(function(key) {
           // The normal callback function, will create it's own this, so `this` won't point to the class instance.
            obj[key].forEach((data)=> {
                // Here, this refer to newly created `this` from the immediate enclosed function.
                if (data.code === searchCode) {
                    console.log(key);
                    console.log(data.code);
                    console.log(data.discount);
                   this.key = key;
                   this.code = data.code;
                   this.discountValue = data.discount;
                }
            });
       });