Как установить имя объекта JavaScript, которое будет возвращено в console.log? - PullRequest
6 голосов
/ 28 января 2011

Итак, первый вопрос здесь - пожалуйста, будьте нежны.

Я работаю над довольно тяжелым JavaScript-проектом с несколькими другими разработчиками из разных областей, не связанных с веб-программированием, и мы решили попробовать использовать публичные и частные методы и свойства в наших псевдо-классах JavaScript исключительно в качестве хорошего практика кодирования (т. е. мы знаем, что в этом нет реального преимущества или безопасности)

Мы поиграли с несколькими различными способами сделать общедоступными и приватными (то есть, используя локальные переменные и функции с привилегированными методами для общественного потребления), и в настоящее время мы решили, что наши конструкторы классов JavaScript действительно возвращают объект, который представляет только их общедоступный интерфейс, эффективно скрывая все остальное.

Вот пример:

function MyObject()
 {
  var _this = this;

  this._privateProperty = 'somevalue';

  this._privateMethod = function()
  {
   // Do Something
  }

  this.public = 
  {
   publicProperty : _this._privateProperty,
   publicMethod : function(){ return _this.privateMethod() }
  }

  return this.public;
 }

Который при создании и входе в Chrome:

 var obj = new MyObject();
 console.log(obj);

Выходы:

> Object
    > publicMethod: function (){ return _this.privateMethod() }
    > publicProperty: "somevalue"
    >__proto__: Object

Теперь на мой вопрос: Потому что возвращали открытый интерфейс из конструктора как новый объект, когда вы будете console.log, вы заметите, что он идентифицирует себя как > Object, тогда как если мы не возвращаем этот открытый интерфейс, он идентифицируется как > MyObject.

В идеале, мы хотели бы, чтобы последний отображался для целей отладки, и я знаю, как получить доступ к имени MyObject contstructor с помощью _this.constructor.name, но не знаю, как его настроить, чтобы он распознавался таким образом.

Кто-нибудь знает, как установить это вручную?

Примечание
Я знаю, что это в некотором роде подмена соглашения JavaScript и попытка поместить квадратный колышек в круглое отверстие, но мы обнаружили, что это очень очевидный и читаемый способ выполнить то, что мы пытались сделать. Я открыт для предложений о том, как сделать это с помощью другого дизайна, но в конечном итоге я ищу ответ, который соответствует нашему текущему дизайну.

Ответы [ 3 ]

3 голосов
/ 28 января 2011

Вы должны быть в состоянии установить функцию 'toString' объекта obj.Например,

obj.constructor.prototype.toString = function() { return "MyObject"; }

Это заставит console.log отображать 'MyObject' вместо Object.

3 голосов
/ 29 января 2011

Несмотря на доблестные усилия членов моей команды и очень услужливых пользователей этого сайта, которые предлагали решения, мы решили, что этот дизайн в конечном счете не поддерживается, и вместо этого выбрали дизайн, который немного менее очевиден, но достигает того жерезультат.

function MyObject()
{
    var _privateProperty = 'somevalue';

    function _privateMethod()
    {
        // Do Something
    }

    // Public Interface
    this.publicProperty = _privateProperty;
    this.publicMethod = _privateMethod; 

}

При таком подходе мы по умолчанию делаем КАЖДЫЕ свойство и метод закрытыми по умолчанию, а в нижней части наших «классов» мы выставляем те, которые нам нужны, для общего доступа.Я думаю, что большинство согласится с тем, что это следует обычному соглашению JavaScript лучше, чем наш первоначальный дизайн, что, надеюсь, означает, что его будет легче читать и поддерживать другим.

Еще раз спасибо тем, кто нашел время попробоватьс решением.

1 голос
/ 28 января 2011

Это немного странно (но, возможно, вы уже привыкли к этому :-), но вы можете переопределить конструктор MyObject локальным:

function MyObject() {
  function MyObject(p) {
    for (var k in p) if (p.hasOwnProperty(k)) this[k] = p[k];
  }

  this.public = new MyObject({
    publicMethod: function() { /* whatever */ },
    publicProperty: "something"
  });
  return this.public;
}

Ясно, что вы могли бы выделить код для большей части этого, чтобы у вас могла быть функция, которая, учитывая функцию, выполняющую инициализацию для определенного класса, установила бы все это для вас. (Необходимость поддерживать систему, подобную той, которую вы предлагаете без , некоторая поддержка библиотеки для обработки деталей кажется настоящей рутинной работой, а в долгосрочной перспективе очень трудной задачей для продолжения работы и еще более сложной для изменения.)

...