简体   繁体   中英

Javascript ES6 - get name of instance from within class

I'd like to be able to get the name of the instance that instantiated a class, from within the class.

Example:

class MyClass {
    getInstanceName() {
        // code that figures out the name given to the instance 
        // instantiating this class
    }
}

var inst = new MyClass();
console.log(inst.getInstanceName()); // should log "inst"

I'd like to get this to emit an event from within the class with the instance name. I'm doing this in node.js

I'd like to be able to get the name of the variable the instance was assigned to, from within the class.

This is not something that is possible in Javascript.

An object can be assigned to hundreds of variables. Only the internals of the language implementation (such info used by the garbage collector) knows what variables contain a reference to a given object. That is not information that is made available to users of the language.

If, in your circumstance, you wanted an object to store info like this, you'd have to pass in the name to the constructor yourself. And, then the object's constructor could save that string to be provided later when the getInstanceName() method was called. There is no way to do this automatically.

Here's a simple implementation of the constructor storing the name.

var inst = new MyClass("inst");

class MyClass {
    constructor(name) {
        this._name = name;
    }
    getInstanceName() {
        return this._name;
    }
}

Or, a non-settable, non-enumerable property:

class MyClass {
    constructor(name) {
        Object.defineProperty(this, "_name", {
            configurable: false,
            enumerable: false,
            value: name,
            writable: false
        });
    }
    getInstanceName() {
        return this._name;
    }
}

Which could be shortened to this:

class MyClass {
    constructor(name) {
        Object.defineProperty(this, "_name", {value: name});
    }
    getInstanceName() {
        return this._name;
    }
}

because configurable , enumerable and writable all default to false when you use Object.defineProperty() .


Or, if you wanted to not use an accessible property on the object, you could make it private by doing this:

const MyClass = (function() {
    // keep track of names in a private space
    const names = new WeakMap();


    class MyClass {
        constructor(name) {
            names.set(this, name);
        }
        getInstanceName() {
            return names.get(this);
        }
    }
    return MyClass;
})();

var inst = new MyClass("inst");

As an example of multiple variables containing the same reference, look at this:

var x, y, z;
x = y = z = new MyClass();

Now, you have three separate variables, all with a reference to the same object. So, even if the language wanted to do what you asked (which it doesn't), there is no canonical variable that contains a reference to a given object.

Or, this:

function doSomething(obj) {
   var t = obj;
   // at this point, there are 5 separate variables with a reference to your object
}

var x, y, z;
x = y = z = new MyClass();

doSomething(x);

Which has 5 separate references to the same object. There is no canonical variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM