JavaScript изменить имя конструктора в консоли - PullRequest
0 голосов
/ 10 июня 2018

Используя фабрику конструкторов, я хотел бы, чтобы эти конструкторы имели разные имена в консоли, в том числе при регистрации их экземпляров.

Вот упрощенный пример моей проблемы:

// 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 голосов
/ 10 июня 2018

Вы бы подумали: объект с вычисленным обходным свойством свойства ответ на этот вопрос будет работать, но он не работает для описанного вами сценария конструктора (по крайней мере,на данный момент, в Chrome или Firefox , теперь, по крайней мере, в Firefox v66 , в Edge и, что удивительно для меня, в Node.js, несмотря на тот факт, что Node.js и Chrome используют V8 [см. этот комментарий ]):

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 - это то, что создает внешнюю функцию, которую мы немедленно выполняем.

Live Example (посмотрите в реальной консоли для вывода):

// 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 из ненадежного источника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...