我应该如何在JS类中声明属性?

我目前正在使用API​​,我想创建类,一个类Object从表中检索数据,而一个类与表相关联。我正在尝试在Object类中创建一个属性,该属性是在从与表关联的类中调用静态方法get()时设置的。我应该如何使用属性?

我的API正在Express上运行,我在Ubuntu 19.04上,我使用ObjectionJS作为我的ORM,我也使用了Knex。我有一个loader.js文件,该文件需要我所有的模型文件。

Object.js:

'use strict';

const dbTables = require('../../src/database/Models/loader');

module.exports = class Object {


    constructor () {
        console.log('Test');
    }

    //Get queries

    static get() {
        console.log(`ModelName = ${this.modelName}`);
        const req = 'dbTables.' + this.modelName + '.query()';
        return eval(req);
    }
}

UserClass.js:

'use strict';

const Object = require('./Object');

module.exports = class UserClass extends Object {

    constructor() {
        super('Employee');
        this.modelName = 'Employee';
    }
};

这是我遇到的错误:

ModelName = undefined
TypeError: Cannot read property 'query' of undefined
    at eval (eval at get (/home/usersio/SafiAPI/src/Classes/Object.js:17:16),<anonymous>:1:20)
    at Function.get (/home/usersio/SafiAPI/src/Classes/Object.js:17:16)
    at app.get (/home/usersio/SafiAPI/index.js:54:28)
    at Layer.handle [as handle_request] (/home/usersio/SafiAPI/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/usersio/SafiAPI/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/usersio/SafiAPI/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/usersio/SafiAPI/node_modules/express/lib/router/layer.js:95:5)
    at /home/usersio/SafiAPI/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/usersio/SafiAPI/node_modules/express/lib/router/index.js:335:12)
    at next (/home/usersio/SafiAPI/node_modules/express/lib/router/index.js:275:10)
    at methodOverride (/home/usersio/SafiAPI/node_modules/method-override/index.js:65:14)
    at Layer.handle [as handle_request] (/home/usersio/SafiAPI/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/usersio/SafiAPI/node_modules/express/lib/router/index.js:317:13)
    at /home/usersio/SafiAPI/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/usersio/SafiAPI/node_modules/express/lib/router/index.js:335:12)
    at next (/home/usersio/SafiAPI/node_modules/express/lib/router/index.js:275:10)
yk8278 回答:我应该如何在JS类中声明属性?

您的问题是因为您的函数get()是静态的,并且您试图在其上获取this.modelName。 但是静态函数不会引用它的特定实例。

让我们看一些示例:

const dbTables = {
  Employee: {query : () => ['1','2','3']},Car: {query : () => ['A','B','C']},}

class AbstractTable {
    //Get queries
    static get() {
        console.log(`get():`,{this:this,model: this.modelName});
        return dbTables[this.modelName] 
            && dbTables[this.modelName].query() 
            || null;
    }
    
    // Same but non static
    getNonStatic() {
        console.log(`getNonStatic():`,model: this.modelName});
        return dbTables[this.modelName] 
            && dbTables[this.modelName].query() 
            || null;
    }
    
    // Static with args
    static getWithArg(table) {
    
        console.log(`getWithArg(table):`,model: table.modelName,table:table});
        return dbTables[table.modelName] 
            && dbTables[table.modelName].query() 
            || null;
    }
}
class UserTable extends AbstractTable {

    constructor() {
        super('Employee');
        this.modelName = 'Employee';
    }
};

console.log("--- Test 1 ---");
console.log(UserTable.get()); // get() is static so NO instance (this is undefined)


console.log("--- Test 2 ---");
// Create an instance of UserTable: 
const userTable = new UserTable();
console.log("Function:",userTable.get); // This is not defined because get() is static  


console.log("--- Test 3 ---");
console.log("Function:",userTable.getNonStatic); 
console.log("Result:",userTable.getNonStatic()); // This is not defined because get() is static  


console.log("--- Test 4 ---");
// you can also use static and inject the UserTable
console.log("Function:",AbstractTable.getWithArg(userTable));

您还可以重新定义抽象静态函数,并使用super()

使用它

const dbTables = {
  Employee: {query : () => ['1',}

class AbstractTable {
    //Get queries
    static get(modelName) {
        return dbTables[modelName] 
            && dbTables[modelName].query() 
            || null;
    }
}

class UserTable extends AbstractTable {
  static get() {
    return super.get("Employee");
  }
}

console.log(UserTable.get());

,

在创建类的实例时会调用构造函数。

class Test {
  constructor() {
    console.log('ctor called');
  }
}

const instance = new Test();
// will log 'ctor called'

调用静态方法时,不会创建实例,也不会调用构造函数。这就是为什么get()函数中的this.modelName未定义的第一个原因,因此您试图在不存在的对象上调用query()

在您的get()函数中尝试console.log(req)

第二个原因是,构造函数中的this引用了实例,而静态方法中的this则引用了类。

一种选择是向扩展类添加静态属性,然后在其中设置模型名称。

const dbTables = {
  Employee: {query : () => ['1',}

/*module.exports =*/ class Object {
    //Get queries
    static get() {
        return dbTables[this.modelName].query();
    }
}

/*module.exports =*/ class UserClass extends Object {
    static modelName = 'Employee';
};

const queryResult = UserClass.get();
console.log("Users: ",queryResult);

本文链接:https://www.f2er.com/3136819.html

大家都在问