简体   繁体   English

在JavaScript中获取构造函数的名称

[英]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 $testName.name应该返回$testName THX

should return '$testName' 应该返回'$ 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. 这意味着您要问一个函数如何知道将要分配给其结果(或更确切地说是new调用它的结果)的变量的名称。 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. 有一种特殊情况(全局范围内的变量),在这种情况下,您可以避免重复名称,而将其作为参数传递给函数(不使用var $testname = part),然后让函数创建“变量”,但是会将功能与全球范围相关联,而全球范围将深入到Bad Idea™领域。 :-) :-)

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. 之所以可行,是因为在全局对象上创建一个属性(可以通过浏览器上的window访问该属性)时,它会创建一个全局变量。

Please don't do that. 请不要那样做。 :-) :-)


Regarding squint's Proxy idea , it would look something like this: 关于squint的Proxy想法 ,它看起来像这样:

 // 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: 但是,最好只使用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")); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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