为什么即使构造函数在其原型链中,类的instanceof仍返回false?

时间:2018-11-28 15:12:59

标签: javascript node.js instanceof

在NodeJS应用中,我正在尝试检查传递给函数的值是否是特定类的实例,但是在模块之间使用import SomeClass from 'utils/class'; import SomeModel from 'models/model'; const model = SomeModel.findOne({id: 'abc'}); const values = {a: 'b'}; const classInstance = new SomeClass({id: 'def'}); classInstance instanceof SomeClass //returns true Object.getPrototypeOf(classInstance) //returns SomeClass {} model.update(values, { a: classInstance, b: SomeClass }); 并检查类。

endpoint.js

Object.getPrototypeOf(a)

当classInstance传递给更新函数时,我看到了意外的行为。

a.constructor.name一样,调用a instanceof SomeClass返回SomeClass。但是,require.resolve('utils/class') 返回false。

此外,仅检查导入的类和传递给函数的类之间的相等性将返回false。

import SomeClass from 'utils/class'; class Model { async update(values, injections) { const { a, b } = injections; // checking instance a.constructor.name //returns SomeClass Object.getPrototypeOf(a) //returns SomeClass {} a instanceof SomeClass; //returns false // checking class b === SomeClass; //returns false } } 为两个导入返回相同的路径。

models / model.js

b === SomeClass

我希望a instanceof SomeClass将返回true,就像export default class SomeClass { constructor(foo) { this.bar = foo; } } 也应返回true一样,除非我丢失了某些内容。感谢您的帮助。

utils / class.js

NODE_PATH=./src/ nodemon -r @std/esm src/server.js

编辑:正在使用@ std / esm编译代码。 @Bean public DataSource storageDataSource() { HikariConfig config = new HikariConfig(); LOGGER.info("Database username: " + jdbcProperties.getStorage().getUser()); LOGGER.info("Database password in use: " + (!StringUtils.isEmpty(jdbcProperties.getStorage().getPass()) ? "Yes" : "No")); LOGGER.info("Database URL: " + jdbcProperties.getStorage().getUrl()); config.setDriverClassName(jdbcProperties.getDriverClassName()); config.setJdbcUrl(jdbcProperties.getStorage().getUrl()); config.setUsername(jdbcProperties.getStorage().getUser()); config.setPassword(jdbcProperties.getStorage().getPass()); config.setAutoCommit(false); config.setPoolName("storage-connection-pool"); config.setMaximumPoolSize(5); config.addDataSourceProperty("dataSource.cachePrepStmts", "true"); config.addDataSourceProperty("dataSource.prepStmtCacheSize", "250"); config.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048"); config.addDataSourceProperty("dataSource.useServerPrepStmts", "true"); return new HikariDataSource(config); }

2 个答案:

答案 0 :(得分:1)

是由于SomeClass实例被多次定义(由于编译器等)引起的吗?考虑以下代码,该代码将返回false:

(function() {

    class Foo {};

    class Bar {
        check(a) {
            console.log(a instanceof Foo);
        }
    };

    window.bar = new Bar();

})();

(function() {
    class Foo {};
    const foo = new Foo();
    window.bar.check(foo);
})();

vs Foo,Bar等仅在全局范围内定义1次(require()应该缓存这些依赖项,因此您不应该遇到这种行为):

class Foo {};

class Bar {
    check(a) {
        console.log(a instanceof Foo);
    }
};

const foo = new Foo();
Bar.prototype.check(foo);

std / esm项目上有一个issue,某人正在经历同样的事情。我不使用该库,所以没有任何细节上的想法。

不然我可能会离开。

答案 1 :(得分:1)

查理的评论为我们指明了正确的方向。

https://github.com/DaveStein/esm-bug正在重现此问题,我在查理(Charlie)报告的https://github.com/standard-things/esm/issues/633问题中已经指出了这一点。