Reputation: 359
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
Upvotes: 1
Views: 75
Reputation: 1074335
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"));
Upvotes: 6