TypeError:无法设置未定义的属性“键”

时间:2020-04-12 10:14:26

标签: javascript 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中获取数据,它应该返回键,代码和值,但不起作用。

3 个答案:

答案 0 :(得分:0)

尝试使用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);
        });
    }


}

答案 1 :(得分:0)

在下面尝试一下:

您需要使用async等待,因为调用是异步的,执行不会等待您的响应,这就是为什么您在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);
        });
    }

答案 2 :(得分:0)

thisforEach循环this.key = key内,没有指向Discount类实例。

正常的回调函数将创建自己的this,即Object.keys(obj).forEach(function(key) {

请改为使用基于箭头的函数,该函数没有自己的this,而是从指向类实例的外部直接作用域中引用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;
                }
            });
       });