简体   繁体   中英

Get name of constructor in javascript

Is there a way to get the name of the variable made with a constructor?

var TestFunction = function () {
  this.name = ???(); // should return '$testName'
}
var $testName = new TestFunction();

$testName.name should return $testName THX

should return '$testName'

That means you're asking how a function can know the name of a variable its result (or rather, the result of new calling it) is about to be assigned to. It can't, there is no mechanism for that, not least because of these possibilities:

a = b = c = d = new TestFunction();
// or
new TestFunction();
// or
foo(new TestFunction());

...but really because fundamentally, the function has no business knowing anything about the context in which it's called other than what the programmer has chosen to tell it by passing as arguments.

Consequently, if you want the function to have that information, you'll need to pass it in, even though that's repetitive:

var $testName = new TestFunction("$testName");

There's a special case (variables at global scope) where you could avoid repeating the name and only pass it as an argument to the function (leaving off the var $testname = part) and then have the function create the "variable," but it would tie the function to global scope, which would fall deep, deep into Bad Idea™ territory. :-)

This is what the special case looks like. Strongly recommend not doing this. (Instead: squint had an excellent suggestion in a comment .)

// STRONGLY RECOMMEND NOT DOING THIS
function TestFunction(name) {
    window[name] = this; // Creates a global
    this.name =name;
}

new TestFunction("$testname");
console.log($testname); // {name: "$testname"}

That works because when you create a property on the global object (which you can access via window on browsers), it creates a global variable.

Please don't do that. :-)


Regarding squint's Proxy idea , it would look something like this:

 // Requires ES2016 ("ES6") support in the browser // Proxy cannot be shimmed, so transpiling won't help const cookieStore = new Map(); // Our fake storage; you'd use the browser's actual cookie store function cmAccessor(name, ...args) { if (args.length == 0) { // Getter; you'd actually use the browser store const entry = cookieStore.get(name); return entry && entry.value; } // Setter const [value, duration] = args; console.log(`Setting '${name}' to '${value}' for ${duration}`); // You'd use the real browser store here cookieStore.set(name, {value, duration}); } const CM = new Proxy(Object.create(null), { get(target, name) { let result = target[name]; if (!result) { result = cmAccessor.bind(null, name); target[name] = result; } return result; } }); CM.cookie1("cookie1 value", 42); CM.cookie2("cookie2 value", 42); console.log(CM.cookie1()); console.log(CM.cookie2()); 

But you'd probably be better off just using a function, a'la jQuery:

 // This version is ES5 compatible const cookieStore = new Map(); // Our fake storage; you'd use the browser's actual cookie store function CM(name, value, duration) { switch (arguments.length) { case 0: throw new Error("'name' is required"); case 1: // Getter // You'd use the browser's real cookie store here const entry = cookieStore.get(name); return entry && entry.value; default: // Setter console.log("Setting '" + name + "' to '" + value + "' for " + duration); // You'd use the real cookie store here cookieStore.set(name, {name: name, value: value}); } } // Usage: CM("cookie1", "cookie1 value", 42); CM("cookie2", "cookie2 value", 42); console.log(CM("cookie1")); console.log(CM("cookie2")); 

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