Получить название типа объекта

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

outputStream.close();
inputStream.close();
Client.close();

. К концу строки списка. если это кому-то помогло.

1139
задан Alexander Abakumov 29 August 2018 в 20:02
поделиться

5 ответов

Есть ли JavaScript, эквивалентный из Java class.getName()?

Нет.

Обновление ES2015: название class Foo {} Foo.name. Название thingкласс, независимо от thingвведите, thing.constructor.name. У встроенных конструкторов в среде ES2015 есть корректное name свойство; например, (2).constructor.name "Number".


Но вот различные взломы, что все падают так или иначе:

Вот взлом, который сделает то, в чем Вы нуждаетесь - знать, что он изменяет прототип Объекта, что-то, что люди осуждают (обычно на серьезном основании)

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

Теперь, все Ваши объекты будут иметь функцию, getName(), это возвратит имя конструктора как строка. Я протестировал это в FF3 и IE7, Я не могу говорить за другие реализации.

Если Вы не хотите делать это, вот обсуждение различных способов определить типы в JavaScript...


Я недавно обновил это, чтобы быть немного более исчерпывающим, хотя это - едва это. Приветствующиеся исправления...

Используя constructor свойство...

Каждый object имеет значение для constructor свойство, но в зависимости от как это object был создан, а также что Вы хотите сделать с тем значением, оно может или не может быть полезно.

Вообще говоря, можно использовать constructor свойство для тестирования типа объекта как так:

var myArray = [1,2,3];
(myArray.constructor == Array); // true

Так, это работает достаточно хорошо на большинство потребностей. Это сказало...

Протесты

Не будет работать ВООБЩЕ во многих случаях

Этот шаблон, хотя повреждено, довольно распространен:

function Thingy() {
}
Thingy.prototype = {
    method1: function() {
    },
    method2: function() {
    }
};

Objects созданный через new Thingy будет иметь a constructor свойство, которое указывает на Object, нет Thingy. Таким образом, мы падаем прямо на начало; Вы просто не можете доверять constructor в кодовой базе, которой Вы не управляете.

Множественное наследование

Пример, где это не столь очевидно, использует множественное наследование:

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

Вещи теперь не работают, поскольку Вы могли бы ожидать их к:

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

Так, Вы могли бы получить неожиданные результаты если object Ваше тестирование имеет другое object набор как prototype. Существуют пути вокруг этой внешней стороны объем этого обсуждения.

Существует другое использование для constructor свойство, некоторые из них интересный, другие не так; на данный момент мы не будем копаться в том использовании, так как это не относится к этому обсуждению.

Не будет работать перекрестный кадр и перекрестное окно

Используя .constructor для типа повредится проверка, когда Вы захотите проверить тип объектов, прибывающих из различного window объекты, говорит iframe или всплывающего окна. Это вызвано тем, что существует другая версия каждого базового типа constructor в каждом 'окне', т.е.

iframe.contentWindow.Array === Array // false

Используя instanceof оператор...

instanceof оператор является очевидным способом тестирования object введите также, но имеет его собственные потенциальные проблемы, точно так же, как constructor свойство.

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

Но instanceof сбои для работы на литеральные значения (потому что литералы не Objects)

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

Литералы должны быть перенесены в Object для instanceof работать, например

new Number(3) instanceof Number // true

.constructor проверка хорошо работает для литералов потому что . вызов метода неявно переносит литералы в их тип соответствующего объекта

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

Почему две точки для 3? Поскольку JavaScript интерпретирует первую точку как десятичную точку ;)

Не будет работать перекрестный кадр и перекрестное окно

instanceof также не будет работать через различные окна, по той же причине как constructor проверка свойства.


Используя name свойство constructor свойство...

Не работает ВООБЩЕ во многих случаях

Снова, посмотрите выше; это довольно характерно для constructor быть крайне и абсолютно неправильный и бесполезен.

Не работает в <IE9

Используя myObjectInstance.constructor.name даст Вам строку, содержащую название constructor используемая функция, но подвергается протестам о constructor свойство, которые были упомянуты ранее.

Для IE9 и выше, Вы можете патч обезьяны в поддержке:

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

Обновленная версия от рассматриваемой статьи. Это было добавлено спустя 3 месяца после того, как статья была опубликована, это - рекомендуемая версия для использования автором статьи Matthew Scharley. Это изменение было вдохновлено комментариями, указывающими на потенциальные ловушки в предыдущем коде.

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
}

Использование Object.prototype.toString

Это складывается, поскольку это сообщение детализирует, можно использовать Object.prototype.toString - низкий уровень и универсальная реализация toString - получить тип для всех встроенных типов

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

Можно было записать короткую функцию помощника такой как

function type(obj){
    return Object.prototype.toString.call(obj).slice(8, -1);
}

удалить хлам и достигнуть просто имя типа

type('abc') // String

Однако это возвратится Object для всех пользовательских типов.


Протесты для всех...

Все они подвергаются одной потенциальной проблеме, и это - вопрос того, как рассматриваемый объект был создан. Вот различные способы создать объекты и значения, которые возвратят различные методы проверки типа:

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

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

Примечание:

Обсуждение typeof оператор, может казаться, явный пропуск, но это действительно не полезно в помощи определить ли object данный тип, так как это очень упрощенно. Понимание, где typeof полезно, важно, но я в настоящее время не чувствую, что это ужасно относится к этому обсуждению. Мое отношение является непредвзятым для изменения все же.:)

1514
ответ дан 23 revs, 14 users 49% 29 August 2018 в 20:02
поделиться

Самое близкое, которое можно получить, typeof , но это только возвращает "объект" для любого вида пользовательского типа. Для тех см. Jason Bunting .

Редактирование, Jason удалил свое сообщение по некоторым причинам, поэтому просто используйте Объект constructor свойство.

2
ответ дан Community 29 August 2018 в 20:02
поделиться

Можно использовать "instanceof" оператор, чтобы определить, является ли объект экземпляром определенного класса или нет. Если Вы не знаете название типа объекта, можно использовать его свойство конструктора. Свойство конструктора объектов, ссылка на функцию, которая используется для инициализации их. Пример:

function Circle (x,y,radius) {
    this._x = x;
    this._y = y;
    this._radius = raduius;
}
var c1 = new Circle(10,20,5);

Теперь c1.constructor является ссылкой на эти Circle() функция. Вы можете alsow использовать typeof оператор, но typeof шоу оператора ограниченная информация. Одно решение состоит в том, чтобы использовать toString() метод Объектного глобального объекта. Например, если у Вас есть объект скажем myObject, можно использовать toString() метод глобального объекта для определения типа класса myObject. Используйте это:

Object.prototype.toString.apply(myObject);
3
ответ дан Peter Mortensen 29 August 2018 в 20:02
поделиться

Можно использовать instanceof оператор, чтобы видеть, является ли объект экземпляром другого, но так как нет никаких классов, Вы не можете получить имя класса.

5
ответ дан Greg 29 August 2018 в 20:02
поделиться

Ответ Jason Bunting дал мне действительно ключ к разгадке для нахождения то, в чем я нуждался:

<<Object instance>>.constructor.name

Так, например, в следующей части кода:

function MyObject() {}
var myInstance = new MyObject();

myInstance.constructor.name возвратился бы "MyObject".

113
ответ дан Ewen Cartwright 29 August 2018 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: