Can a JavaScript Object Know The Identifier Name of its Instance?
To begin with, let me assure you that this is one classic case of “I was too busy thinking whether I could, that I forgot whether I should.”
This started when I stumbled upon this question on SO: How to include or detect the name of a new Object when it’s created from a Constructor
I understand that in most cases your code shouldn’t need to know the identifier name. However, this might have some application in debugging (maybe?) Nevertheless, given the flexibility of JavaScript
I was almost certain that this is possible.
So here is my solution for the same. Here I am using anError
object to get the current line number and then reading the source file to find the identifier name.
let fs = require('fs');class Foo {
constructor(bar) {
this.bar = bar;
readIdentifierFromFile(getLineAndFile()).then(identifier => {
this.identifier = identifier;
})
}
toString() {
return `bar: ${this.bar}, identifier:${this.identifier}`;
}
}
let foo = new Foo(5);setTimeout(() => {
console.log(foo.toString()); // bar: 5 identifier:foo
}, 2000); // Some delay to allow the source code to be read #bad_codefunction getErrorObject(){
try { throw Error('') } catch(err) { return err; }
}function getLineAndFile() {
let err = getErrorObject();
let callerLine = err.stack.split("\n")[5];
let index = callerLine.indexOf("(");
return callerLine.slice(index+1, callerLine.length-1);
}function readIdentifierFromFile(lineAndFile) {
let file = lineAndFile.split(':')[0];
let line = lineAndFile.split(':')[1];
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) {
reject(err);
}
resolve(data.split('\n')[parseInt(line)-1].split('=')[0].trim().split(' ')[1]);
});
})
}
PS: The code breaks if you assign a new identifier to a reference: let foo2 = foo
Can you think of a valid use-case for such code? Is there any other approach you can think of?