Reputation: 101
In a NodeJS app, I am trying to check that a value passed into a function is an instance of a specific Class, however I am getting unexpected behavior using instanceof
between modules, and when checking the equality of the Class.
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 });
When the classInstance is passed through to the update function, I see unexpected behavior.
Calling Object.getPrototypeOf(a)
returns SomeClass, as does a.constructor.name
. However, a instanceof SomeClass
returns false.
Furthermore, just checking equality between the class imported and the class passed into the function returns false.
require.resolve('utils/class')
returns the same path for both imports.
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
}
}
I would expect that b === SomeClass
would return true, just like a instanceof SomeClass
should also return true, unless I am missing something. Thanks for any help.
export default class SomeClass {
constructor(foo) {
this.bar = foo;
}
}
Edit: The code is being transpiled with @std/esm.
NODE_PATH=./src/ nodemon -r @std/esm src/server.js
Upvotes: 10
Views: 1718
Reputation: 9326
Charlie in the comments pointed us the right way.
https://github.com/DaveStein/esm-bug is reproducing this and I've noted it as such in the issue Charlie reported https://github.com/standard-things/esm/issues/633.
Upvotes: 2
Reputation: 8246
Is it due to the SomeClass
instances being defined multiple times (due to transpiler, etc)? Consider this code which will return 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, etc., being defined in a global scope only 1 time (require()
should cache these dependencies and thus you shouldn't run into this behavior):
class Foo {};
class Bar {
check(a) {
console.log(a instanceof Foo);
}
};
const foo = new Foo();
Bar.prototype.check(foo);
There's an issue on the std/esm project where someone's experiencing this same thing. I don't use that library, so no ideas on the specifics.
Or I could be way off.
Upvotes: 2