【问题标题】:ES6: "TyperError: X is not a function"ES6:“TypeError:X 不是函数”
【发布时间】:2019-04-08 03:08:35
【问题描述】:

我正在尝试向我的 Express/Node 服务器中的类添加一个函数,但我不断收到TypeError: req.session.user.bills[0].getFormattedDueDate is not a function。我有其他类的成员函数可以工作,包括在引发此错误的同一方法中。我检查了req.session.user.bills 中的对象类型,它是object。该项目是使用 Webpack 和 Babel 构建的。

如果我将req.session.user.bills[0] 中的所有属性放入一个新对象中,那么这些函数就可以工作。这个对象的数据流是这样工作的。主文件名为server2.js

  1. 用户通过点击server2.js端点登录。
  2. 对象名称userDao 从数据库中获取用户并返回一个User 对象,其中包含Bills 数组。 UserDaoUser 都是 required 在 server2.js 的顶部。
  3. 点击另一个端点来显示账单。这会将 User 对象传递给 EJS 文件。正是在这里,我尝试使用该功能,但它不起作用。

server.js:

const User = require('babel-loader!./src/model/user.js');
const UserDao = require('babel-loader!./src/model/userDao.js');
const Bill = require('babel-loader!./src/model/bill.js');

const userDao = new UserDao(pool);
...
app.all('/bills', function(req, res) {
    const temp1 = req.session.user.bills[0].getFormattedDueDate();
    res.render('bills.ejs', {
        URL: config.URL,
        user: req.session.user
    })
});

但如果我实例化一个新对象,它就可以工作:

app.all('/bills', function(req, res) {
    const temp = new Bill(
        req.session.user.bills[0].id, 
        req.session.user.bills[0].userId, 
        req.session.user.bills[0].periodId, 
        req.session.user.bills[0].accountId, 
        null, 
        req.session.user.bills[0].name, 
        req.session.user.bills[0].amount, 
        req.session.user.bills[0].autoPay, 
        req.session.user.bills[0].weekDay, 
        req.session.user.bills[0].dueDate, 
        req.session.user.bills[0].dueDate2, 
        req.session.user.bills[0].paid
    );
    const temp1 = temp.getFormattedDueDate();
    res.render('bills.ejs', {
        URL: config.URL,
        user: req.session.user
    })
});

userDao.js:

//Lots of other data is put in user...
//Bills
for (let i = 0; i < rows[BILLS_INDEX].length; i++) {
    user.bills.push(new Bill(
        rows[BILLS_INDEX][i].id,
        rows[BILLS_INDEX][i].userId,
        rows[BILLS_INDEX][i].periodId,
        rows[BILLS_INDEX][i].accountId,
        new Tag(rows[BILLS_INDEX][i].tagId, rows[BILLS_INDEX][i].userId, rows[BILLS_INDEX][i].name),
        rows[BILLS_INDEX][i].name,
        rows[BILLS_INDEX][i].amount,
        rows[BILLS_INDEX][i].autoPay === 1,
        rows[BILLS_INDEX][i].weekDay === 1,
        rows[BILLS_INDEX][i].startDate,
        rows[BILLS_INDEX][i].startDate2,
        rows[BILLS_INDEX][i].paid === 1
    ));
}

resolve(user);

user.js:

module.exports = class User {
    constructor(id, firstName, lastName, imageUrl, email, tags, items, budgetItems, piggyBanks, bills) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.imageUrl = imageUrl;
        this.email = email;
        this.tags = tags || new Array();
        this.items = items || new Array();
        this.budgetItems = budgetItems || new Array();
        this.piggyBanks = piggyBanks || new Array();
        this.bills = bills || new Array();
    }
}

bill.js:

const moment = require('moment');

module.exports = class Bill {
    constructor(pId, pUserId, pPeriodId, pAccountId, pTag, pName, pAmount, pAutoPay, pWeekDay, pdueDate, pdueDate2, pPaid) {
        this.id = pId;
        this.userId = pUserId,
        this.periodId = pPeriodId,
        this.accountId = pAccountId,
        this.tag = pTag,
        this.name = pName,
        this.amount = pAmount,
        this.autoPay = pAutoPay,
        this.weekDay = pWeekDay,
        this.dueDate = pdueDate,
        this.dueDate2 = pdueDate2,
        this.paid = pPaid
    }

    getFormattedDueDate() {
        return moment(this.dueDate).format('MMM DD, YYYY');
    }

    getFormattedDueDate2() {
        return moment(this.dueDate2).format('MMM DD, YYYY');
    }
}

我希望该方法可以工作,因为userDao.js 中的方法可以工作,但是我得到了未定义的方法错误。

编辑:我检查了req.session.user.bills[0] instanceof Bill,它返回错误。

【问题讨论】:

  • 你永远不会打电话给getFormattedDate
  • 您如何将req.session.user.bills 放入会话中?它似乎不是 Bill 对象。你在使用JSON.stringify -> JSON.parse吗?
  • 当我实例化变量temp1时,我在server2.js中做。
  • 当用户登录时,我在检索到他们的所有信息后设置req.session.user = user
  • 你打电话给getFormattedDueDate而不是getFormattedDate

标签: javascript node.js webpack babeljs es6-class


【解决方案1】:

当您将对象存储在session 中时,它会被序列化为 JSON。当你检索它时,它会被再次解析,作为一个普通的对象。所以任何原始原型信息都会在这个过程中丢失。如express-session module的文档所述:

要存储或访问会话数据,只需使用请求属性req.session,它(通常)由存储序列化为 JSON [...]

要恢复原型信息,您可以这样做:

req.session.user.bills.forEach(bill => Object.setPrototypeOf(bill, Bill.prototype));

然后这应该可以工作:

const temp1 = req.session.user.bills[0].getFormattedDueDate();

或者,如果你只想调用一次方法,你可以使用.call

const temp1 = Bill.prototype.getFormattedDueDate.call(req.session.user.bills[0]);

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 1970-01-01
    • 2021-01-10
    • 2016-08-11
    • 2017-10-05
    • 2018-01-09
    • 1970-01-01
    • 2019-08-25
    • 2016-07-03
    相关资源
    最近更新 更多