Phra
Phra

Reputation: 21

How to include or detect the name of a new Object when it's created from a Constructor

I have a constructor that include a debug/log code and also a self destruct method

I tried to find info on internet about how to detect the new objects names in the process of creation, but the only recommendation that I found was pass the name as a property.

for example

var counter = {}
counter.a =new TimerFlex({debug: true, timerId:'counter.a'});

I found unnecessary to pass counter.a as a timerId:'counter.a' there should be a native way to detect the name from the Constructor or from the new object instance.

I am looking for something like ObjectProperties('name') that returns counter.a so I don't need to include it manually as a property.

Adding more info

@CertainPerformance What I need is to differentiate different objects running in parallel or nested, so I can see in the console.

counter.a data...
counter.b data...
counter.a data...
counter.c data... etc

also these objects have only a unique name, no reference as counter.a = counter.c

Another feature or TimerFlex is a method to self desruct

 this.purgeCount = function(manualId) {

    if (!this.timerId && manualId) { 
      this.timerId = manualId;
      this.txtId =  manualId;
    } 

    if (this.timerId) {
      clearTimeout(this.t);
      this.timer_is_on = 0;
      setTimeout (  ()=> { console.log(this.txtId + " Destructed" ) },500);
      setTimeout ( this.timerId +".__proto__ = null", 1000);
      setTimeout ( this.timerId +" = null",1100);
      setTimeout ( "delete " + this.timerId, 1200);

    } else {
      if (this.debug) console.log("timerId is undefined, unable to purge automatically");
    }
  }

While I don't have a demo yet of this Constructor this is related to my previous question How to have the same Javascript Self Invoking Function Pattern running more that one time in paralel without overwriting values?

Upvotes: 1

Views: 101

Answers (3)

Charlie
Charlie

Reputation: 23858

Objects don't have names - but constructors!

Javascript objects are memory references when accessed via a variables. The object is created in the memory and any number of variables can point to that address.

Look at the following example

var anObjectReference = new Object();
anObjectReference.name = 'My Object'

var anotherReference = anObjectReference;
console.log(anotherReference.name);   //Expected output "My Object"

In this above scenario, it is illogical for the object to return anObjectReference or anotherReference when called the hypothetical method which would return the variable name.

Which one.... really?


In this context, if you want to condition the method execution based on the variable which accesses the object, have an argument passed to indicate the variable (or the scenario) to a method you call.

Upvotes: 1

Abhas Tandon
Abhas Tandon

Reputation: 1889

This is definitely possible but is a bit ugly for obvious reasons. Needless to say, you must try to avoid such code.

However, I think this can have some application in debugging. My solution makes use of the ability to get the line number for a code using Error object and then reading the source file to get the identifier.

let fs = require('fs');
class Foo {
    constructor(bar, lineAndFile) {
        this.bar = bar;
        this.lineAndFile = lineAndFile;
    }
    toString() {
        return `${this.bar} ${this.lineAndFile}`
    }
}
let foo = new Foo(5, getLineAndFile());

console.log(foo.toString()); // 5 /Users/XXX/XXX/temp.js:11:22
readIdentifierFromFile(foo.lineAndFile); // let foo

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

function getLineAndFile() {
    let err = getErrorObject();
    let callerLine = err.stack.split("\n")[4];
    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];
    fs.readFile(file, 'utf-8', (err, data) => { 
        if (err) throw err; 
        console.log(data.split('\n')[parseInt(line)-1].split('=')[0].trim());
    }) 
}

If you want to store the variable name with the Object reference, you can read the file synchronously once and then parse it to get the identifier from the required line number whenever required.

Upvotes: 0

Daniel L.
Daniel L.

Reputation: 447

In JavaScript, you can access an object instance's properties through the same notation as a dictionary. For example: counter['a'].

If your intent is to use counter.a within your new TimerFlex instance, why not just pass counter?

counter.a = new TimerFlex({debug: true, timerId: counter});
// Somewhere within the logic of TimerFlex...
// var a = counter.a;

Upvotes: 0

Related Questions