有没有办法获取使用构造函数创建的变量的名称?
var TestFunction = function () {
this.name = ???(); // should return '$testName'
}
var $testName = new TestFunction();
$testName.name
应该返回$testName
THX
答案 0 :(得分:6)
应该返回'$ testName'
这意味着您正在询问函数如何知道变量的名称,其结果(或者更确切地说,new
调用它的结果)将被分配给。它不能,没有机制,尤其是因为这些可能性:
a = b = c = d = new TestFunction();
// or
new TestFunction();
// or
foo(new TestFunction());
...但实际上,因为从根本上说,除了程序员选择通过作为参数传递的方式之外,该函数没有任何关于被调用的上下文的知识。
因此,如果您希望函数具有该信息,则需要将其传入,即使这是重复的:
var $testName = new TestFunction("$testName");
有一个特殊情况(全局范围内的变量),你可以避免重复这个名称,只有 将它作为参数传递给函数(不用var $testname =
部分),然后让函数创建“变量”,但它会将函数与全局范围联系起来,这将深入到Bad Idea™领域。 : - )
这是特殊情况的样子。 强烈建议不要这样做。(相反:squint有一个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"}
这是有效的,因为当您在全局对象上创建属性(可以通过浏览器上的window
访问)时,它会创建一个全局变量。
请不要那样做。 : - )
关于squint's Proxy
idea,它看起来像这样:
// 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());
但是你最好只使用一个函数,一个'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"));