1

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?

Phra
  • 21
  • 4
  • You can pass objects around and store the same object in many variables. What should the name be once you've written `counter.c = counter.a` and both `a` and `c` point to the same object? – Mark Apr 19 '19 at 04:53
  • 2
    When your code depends on the name of a variable staying constant (eg, if your code cannot be minified), that's a sign that the code should be refactored. Best to change `TimerFlex` so that it does not need to be passed `counter.a` in `timerId`. – CertainPerformance Apr 19 '19 at 04:54
  • @CertainPerformance that make sense, 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 ... counter.c ... etc – Phra Apr 19 '19 at 05:03
  • It's not really clear from the code what exactly the issue is you're trying to solve is - if you post a fuller [MCVE], there may well be a more elegant solution that can be posted – CertainPerformance Apr 19 '19 at 05:04
  • OK, it sounds like you just need to differentiate counters. Then you shouldn't care what the property is called, just give them any name. This is exactly what `console.time()` does - you just start a named counter and `console.timeEnd()` stops a counter by name, giving you the result. In your case, you just need to report which counter has what value, so you don't even need a `console.timeEnd` equivalent simply going `MyCounter("some name")` can give it an identifier and then `myCounter.print()` will use it. – VLAZ Apr 19 '19 at 05:16
  • Possible duplicate of [Getting the object variable name in JavaScript](https://stackoverflow.com/questions/42870307/getting-the-object-variable-name-in-javascript) – Charlie Apr 19 '19 at 05:19
  • @VLAZ thanks for this, while is not only track counters this will be useful – Phra Apr 19 '19 at 05:25
  • @CharlieH Actually what I am currently doing is recommended in the accepted answer. So there is not solution to this. – Phra Apr 19 '19 at 05:30
  • @Phra Given the fact that objects don't have names, there is no question how to get the name. – Charlie Apr 19 '19 at 05:34
  • @CertainPerformance I updated my question and added the purgeCount method to self destruct the counter, I choose to add this methods as if a new instance is called with the same name, the oldest instance behave like an anonymous function and it's hard to debug and to know what properties are shared or not – Phra Apr 19 '19 at 05:37

3 Answers3

1

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.

Charlie
  • 22,886
  • 11
  • 59
  • 90
0

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;
Daniel L.
  • 437
  • 3
  • 15
  • Because I can have many of these objects running as event listeners, probably hundred of these so I don't want to pollute the global scope and as each of these are doing very different things, really there is no need to share a dictionary. – Phra Apr 19 '19 at 05:41
0

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.

Abhas Tandon
  • 1,859
  • 16
  • 26