I have a (very) complicated JS class, which has potentially endless nested versions of the same class (and others) under a properties
key. It has functions on it which can change features of the properties
, eg re-case them, omit or pick some, etc. All of these functions are designed to be non-mutative, returning a new class with new properties.
At any rate, I've run into a SUPER weird issue with an instance of this class. Essentially, the properties
accessed from "the outside" are different from those on the inside. (This is after calling snakeCase()
to snake case the keys of the properties, but that shouldn't really be relevant to this question, because the problem seems more fundamental/weird than anything specific to this class.
Here's what's going on. I added a testFunc
function to debug this issue:
testFunc = self => {
const keys = Object.keys(this.properties);
console.log("KEYS", keys);
debugger;
const keys2 = Object.keys(self.properties);
console.log("KEYS2", keys2);
};
Here's what I'm calling:
// SomeSchema is an instance of this class, as is snaked, because snakeCase returns a new instance.
const snaked = SomeSchema.snakeCase();
// I'm simplifying, but obj is also an instance, because SomeSchema has, under properties, more instances of the same class.
// At any rate, it's just relevant that `obj` is an instance of the class
const obj = snaked.properties.nested?.value;
console.log("OUTSIDE KEYS", Object.keys(obj.properties));
obj.testFunc(obj);
console.log("ABOUT TO RUN AGAIN");
obj.testFunc(obj);
And here's the output
console.log
OUTSIDE KEYS [ 'snake_name', 'camel_name_nested' ]
at Object.<anonymous> (common/utils/__tests__/object.test.ts:70:19)
console.log
KEYS [ 'snake_name', 'camelNameNested' ]
at Object.testFunc (common/utils/object.ts:220:13)
console.log
KEYS2 [ 'snake_name', 'camel_name_nested' ]
at Object.testFunc (common/utils/object.ts:223:13)
console.log
ABOUT TO RUN AGAIN
at Object.<anonymous> (common/utils/__tests__/object.test.ts:72:19)
console.log
KEYS [ 'snake_name', 'camelNameNested' ]
at Object.testFunc (common/utils/object.ts:220:13)
console.log
KEYS2 [ 'snake_name', 'camel_name_nested' ]
at Object.testFunc (common/utils/object.ts:223:13)
The question: How the hell is this happening? How is obj
as this
different from obj
as self
? Or, in other words, why is this
not referring to the same properties from within the testFunc
function as from "without" when properties is called directly on
obj`?
I'm happy to provide other code (let me know what), but I suspect it's a distraction, since the problem is so narrow.
What are the possible cases where the this
binding gets broken like this? (It specifically seems to be the pre-snake-case value, but it seems to me that the functionality that "brought us here" is irrelevant, because the issue is obj.properties
is just two different things in two different contexts