JavaScript在控制台中更改构造函数名称

时间:2018-06-10 11:45:47

标签: javascript debugging constructor

使用构造函数的工厂,我希望这些构造函数在控制台中具有不同的名称,也可以在记录它们的实例时使用。

以下是我的问题的简化示例:

// Constructor factory //
function type(name, prototype) {
    function Constructor() {}
    Constructor.name ; // "Constructor"
    // Constructor.name = name  won't work properly.
    Object.defineProperty(Constructor, 'name', { value:name }) ;
    Constructor.prototype = prototype ;

    window[name] = Constructor ;
    return Constructor ;
}

// Creating constructor and instance //
type('Cat', { name:"", paws:4 }) ;
var chat = new Cat ;

// Tests //
Cat.name ; // "Cat"    -> Correct name
Cat ; // Constructor() { ... }     -> Incorrect name
chat ; // Constructor {name:"", paws:4}     -> Incorrect name

在这种情况下,有没有办法显示正确的名字?

使用最新版本的Chrome(67)进行测试。在这种情况下,我不想使用class功能。

1 个答案:

答案 0 :(得分:1)

你很想the object with computed property workaroundthis question的回答是可行的,但它对你描述的构造函数场景不起作用(至少目前在Chrome或 Firefox 它现在,至少在Firefox v66 ;它确实在Edge中,对我来说,在Node.js中令人惊讶,尽管Node.js和Chrome都使用V8 [见this comment]):

const dynamicName = "foo" + Math.floor(Math.random() * 1000);
const obj = {
  [dynamicName]: function() {
  }
};
const f = obj[dynamicName];
const inst = new f();
console.log(f.name);	// works
console.log(f);				// nope (on Chrome)
console.log(inst);		// nope (on Chrome)
Look in the real console.

不幸的是,即使Function#name现在是函数的指定功能,正如您所发现的那样,name并不总是JavaScript引擎内部在堆栈跟踪等中使用的(然而;希望这变化为name成熟;它只在ES2015中添加。)

如果您确实需要这样做,那么它就是您为生成和执行动态代码而努力的极少数地方之一,例如new Function

var Constructor = new Function("return function " + name + "() { };")();

执行以下操作,但动态使用name代替nameGoesHere

var Constructor = (function() {
    return function nameGoesHere() { };
})();

new Function是创建我们立即执行的外部函数的原因。

实例(在实际控制台中查看输出):

// Constructor factory //
function type(name, prototype) {
    var Constructor = new Function("return function " + name + "() { };")();

    window[name] = Constructor ;
    return Constructor ;
}

// Creating constructor and instance //
type('Cat', { name:"", paws:4 }) ;
var chat = new Cat ;

// Tests //
console.log(Cat.name) ;
console.log(Cat) ;
console.log(chat) ;

显然,这假设您没有从不受信任的来源获取name