new object in constructor from class undefined

2019-07-27 08:59发布

问题:

I'm creating a new object from a class in a constructor, and whenever it runs I get an error that operate is undefined in the method, though it is defined in the constructor. Operate itself is thoroughly tested and works great in a separate context so that's not the problem. I'm building it with Babel, not running it directly in Node 7.0.0

import Operate from "./operate"

export default class {

  constructor(Schema) {
    this.schema = Schema
    this.operate = new Operate(this.schema)
    console.log(this.operate.run) // <- Logs just fine
  }

  update(req, res) {
    console.log(this.operate.run) // <- Nada
    this.operate.run(req.body)
      .then(value => {
        res.status(200).json(value)
      })
  }

This feels like I'm missing something fundamental. I've heard this isn't a great pattern anyway, so please feel free to suggest a better way. Thanks so much in advance.

UPDATE: This is how update is being used. I don't suspect there's any problem here, as it has worked just fine when I had been importing controller as a function from another module, instead of a class

import {Router, } from "express"
import Controller from "../controller"
import User from "./user.model"

let controller = new Controller(User)
let router = new Router()

router.post("/", controller.update)

module.exports = router

回答1:

Change from this:

router.post("/", controller.update)

to this:

router.post("/", controller.update.bind(controller))

When you pass controller.update it only passed a pointer to the method and any association with the controller object is lost. Then, when that update method is called later, there is no association with the appropriate object and thus the this handler in the method is wrong and you get the error you were seeing.

You either force the binding of the update method within the object or when you pass the method elsewhere that might not be called correctly, you can use the above structure to pass a bound version of the method.

You could also modify your definition of the update method to permanently bind it to your object in the constructor by adding this to the constructor:

this.update = this.update.bind(this);