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

时间:2016-11-20 12:49:56

标签: javascript

有没有办法获取使用构造函数创建的变量的名称?

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

$testName.name应该返回$testName THX

1 个答案:

答案 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"));