Pobranie nazwy typu obiektu
Czy istnieje JavaScriptodpowiednik Java'S class.getName()
?
21 answers
Czy istnieje odpowiednik JavaScript
class.getName()
Javy?
Nie..
Aktualizacja ES2015: nazwa class Foo {}
to Foo.name
. Nazwa klasy thing
, niezależnie od typu thing
, to thing.constructor.name
. Konstruktory wbudowane w środowisku ES2015 mają poprawną właściwość name
; na przykład (2).constructor.name
to "Number"
.
Ale tutaj są różne hacki, które wszystkie padają w taki czy inny sposób: {]}
Oto hack, który będzie róbcie to, czego potrzebujecie-bądźcie świadomi, że modyfikuje on prototyp obiektu, na co ludzie marszczą brwi (zazwyczaj nie bez powodu) [72]}
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Teraz wszystkie twoje obiekty będą miały funkcję getName()
, która zwróci nazwę konstruktora jako łańcuch znaków. Testowałem to w FF3
i IE7
, nie mogę mówić o innych implementacjach.
Jeśli nie chcesz tego robić, oto dyskusja na temat różnych sposobów określania typów w JavaScript...
Ostatnio zaktualizowałem to ma być nieco bardziej wyczerpujące, choć nie jest tak. Poprawki mile widziane...
Przy użyciu właściwości constructor
...
Każda object
ma wartość dla swojej właściwości constructor
, ale w zależności od tego, w jaki sposób object
została skonstruowana, jak również co chcesz zrobić z tą wartością, może być użyteczna lub nie.
Ogólnie rzecz biorąc, możesz użyć właściwości constructor
, aby przetestować typ obiektu w następujący sposób:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
Więc, to działa wystarczająco dobrze dla większości potrzeb. Że said...
Caveats
Nie będzie działać W OGÓLE w wielu przypadkach
Ten wzór, choć złamany, jest dość powszechny:]}function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects
skonstruowany przez new Thingy
będzie miał właściwość constructor
, która wskazuje na Object
, a nie Thingy
. Więc spadamy na samym początku; po prostu nie można ufać {28]} w bazie kodu, której nie kontrolujesz.
Dziedziczenie Wielokrotne
Przykładem, w którym nie jest to tak oczywiste, jest użycie wielu dziedziczenie:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Rzeczy teraz nie działają tak, jak można się ich spodziewać:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
Więc możesz uzyskać nieoczekiwane wyniki, jeśli object
twój test ma inny object
ustawiony jako jego prototype
. Istnieją sposoby obejścia tego problemu poza zakresem tej dyskusji.
Istnieją inne zastosowania właściwości constructor
, niektóre z nich są interesujące, inne nie tak bardzo; na razie nie będziemy się zagłębiać w te zastosowania, ponieważ nie jest to istotne w tej dyskusji.
Nie zadziała rama poprzeczna i okno poprzeczne
Użycie .constructor
do sprawdzania typu spowoduje przerwanie, gdy chcesz sprawdzić typ obiektów pochodzących z różnych obiektów window
, powiedzmy, że z ramki iframe lub wyskakującego okna. Jest to spowodowane tym, że w każdym `oknie' istnieje inna wersja każdego typu rdzenia constructor
, tj.
iframe.contentWindow.Array === Array // false
Używając operatora instanceof
...
Operator instanceof
jest również czystym sposobem testowania typu object
, ale ma swoje własne potencjalne problemy, podobnie jak {28]} własność.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
Ale instanceof
nie działa dla wartości literalnych (ponieważ literały nie są Objects
)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
W 1999 roku w ramach programu "Horyzont 2020" w ramach programu Horyzont 2020 w ramach programu Horyzont 2020 w ramach programu Horyzont 2020 w ramach programu Horyzont 2020 "Horyzont 2020" - program ramowy w zakresie badań naukowych i innowacji (2014-2020)]}
new Number(3) instanceof Number // true
Sprawdzanie .constructor
działa dobrze dla literałów, ponieważ metoda .
wywołanie niejawnie zawija literały w ich odpowiedni typ obiektu
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Dlaczego dwie kropki za trzy? Ponieważ Javascript interpretuje pierwszą kropkę jako punkt dziesiętny;)
Nie będzie rama robocza i okno krzyżowe
instanceof
również nie będzie działać w różnych oknach, z tego samego powodu, co sprawdzanie właściwości constructor
.
Korzystanie z właściwości name
właściwości constructor
...
Nie działa W OGÓLE w wielu przypadkach
Ponownie, patrz wyżej; jest to dość powszechne dla constructor
być całkowicie i całkowicie błędne i bezużyteczne.
Nie działa w Użycie myObjectInstance.constructor.name
da ci łańcuch zawierający nazwę constructor
funkcja używana, ale podlega zastrzeżeniom dotyczącym właściwości constructor
, które zostały wymienione wcześniej.
Dla IE9 i wyższych, możesz monkey-patch w obsłudze :
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) {}
});
}
Zaktualizowana wersja z danego artykułu. Dodano 3 miesiące po opublikowaniu artykułu, jest to zalecana wersja do wykorzystania przez autora artykułu Matthew Scharley. Ta zmiana została zainspirowana uwagami wskazującymi potencjalne pułapki w poprzednim kod.
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) {}
});
}
Używanie Obiektu.prototyp.toString
Okazuje się, że ponieważ ten post szczegóły , możesz użyć Object.prototype.toString
- niski poziom i ogólna implementacja toString
- aby uzyskać typ dla wszystkich wbudowanych typów
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Można napisać krótką funkcję pomocniczą, taką jak
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
Aby usunąć cruft i uzyskać tylko nazwę typu
type('abc') // String
Zwróci jednak Object
dla wszystkich typów zdefiniowanych przez użytkownika.
Zastrzeżenia Dla wszystkie...
[71]] wszystkie z nich podlegają jednemu potencjalnemu problemowi, a mianowicie pytaniu o to, w jaki sposób dany obiekt został zbudowany. Oto różne sposoby budowania obiektów i wartości, które będą zwracane przez różne metody sprawdzania typu:
// 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
Chociaż nie wszystkie permutacje są obecne w tym zestawie przykładów, mam nadzieję, że jest wystarczająco dużo, aby zapewnić Ci wyobrażenie o tym, jak bałagan może się stać w zależności od twoich potrzeb. Nie zakładaj niczego, jeśli nie rozumiesz dokładnie to, czego szukasz, może skończyć się łamaniem kodu tam, gdzie się tego nie spodziewasz, z powodu braku grokking subtelności.
Uwaga:
Dyskusja o operatorze typeof
może wydawać się rażącym pominięciem, ale tak naprawdę nie jest to przydatne w identyfikacji, czy object
jest danym typem, ponieważ jest bardzo uproszczone. Zrozumienie, gdzie typeof
jest użyteczne jest ważne, ale obecnie nie uważam, że jest to strasznie istotne w tej dyskusji. My mind is open ale żeby się zmienić. :)
Użycie myObjectInstance.constructor.name
da ci łańcuch zawierający nazwę constructor
funkcja używana, ale podlega zastrzeżeniom dotyczącym właściwości constructor
, które zostały wymienione wcześniej.
Dla IE9 i wyższych, możesz monkey-patch w obsłudze :
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) {}
});
}
Zaktualizowana wersja z danego artykułu. Dodano 3 miesiące po opublikowaniu artykułu, jest to zalecana wersja do wykorzystania przez autora artykułu Matthew Scharley. Ta zmiana została zainspirowana uwagami wskazującymi potencjalne pułapki w poprzednim kod.
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) {}
});
}
Używanie Obiektu.prototyp.toString
Okazuje się, że ponieważ ten post szczegóły , możesz użyć Object.prototype.toString
- niski poziom i ogólna implementacja toString
- aby uzyskać typ dla wszystkich wbudowanych typów
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Można napisać krótką funkcję pomocniczą, taką jak
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
Aby usunąć cruft i uzyskać tylko nazwę typu
type('abc') // String
Zwróci jednak Object
dla wszystkich typów zdefiniowanych przez użytkownika.
Zastrzeżenia Dla wszystkie...
[71]] wszystkie z nich podlegają jednemu potencjalnemu problemowi, a mianowicie pytaniu o to, w jaki sposób dany obiekt został zbudowany. Oto różne sposoby budowania obiektów i wartości, które będą zwracane przez różne metody sprawdzania typu:// 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
Chociaż nie wszystkie permutacje są obecne w tym zestawie przykładów, mam nadzieję, że jest wystarczająco dużo, aby zapewnić Ci wyobrażenie o tym, jak bałagan może się stać w zależności od twoich potrzeb. Nie zakładaj niczego, jeśli nie rozumiesz dokładnie to, czego szukasz, może skończyć się łamaniem kodu tam, gdzie się tego nie spodziewasz, z powodu braku grokking subtelności.
Uwaga:
Dyskusja o operatorze typeof
może wydawać się rażącym pominięciem, ale tak naprawdę nie jest to przydatne w identyfikacji, czy object
jest danym typem, ponieważ jest bardzo uproszczone. Zrozumienie, gdzie typeof
jest użyteczne jest ważne, ale obecnie nie uważam, że jest to strasznie istotne w tej dyskusji. My mind is open ale żeby się zmienić. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Odpowiedź Jasona Buntinga dała mi wystarczająco dużo wskazówek, aby znaleźć to, czego potrzebowałem:
<<Object instance>>.constructor.name
Więc, na przykład, w następującym fragmencie kodu:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.name
zwróci "MyObject"
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-01 22:35:50
Mała sztuczka, której używam:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-13 00:11:24
Update
Aby być precyzyjnym, myślę, że OP poprosił o funkcję, która pobiera nazwę konstruktora dla określonego obiektu. W języku Javascript, object
nie ma typu, ale jest typem I samym w sobie . Jednak różne obiekty mogą mieć różne konstruktory .
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function\s(\w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
Uwaga: poniższy przykład jest przestarzały.
A blog post linked by Christian Sciberras Zawiera dobry przykład, jak to zrobić. Mianowicie, poprzez rozszerzenie prototypu obiektu:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Korzystanie Z Obiektu.prototyp.toString
Okazuje się, że w tym poście można użyć obiektu.prototyp.toString - niskopoziomowa i ogólna implementacja toString - aby uzyskać typ dla wszystkich wbudowanych typów
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Można napisać krótką funkcję pomocniczą, np.
function type(obj){
return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-24 12:26:57
Oto rozwiązanie, które wymyśliłem, które rozwiązuje braki instanceof. Może sprawdzać typy obiektów z krzyżowych okien i ramek i nie ma problemów z typami prymitywnymi.
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
IsInstance wymaga dwóch parametrów: obiektu i typu. Prawdziwa sztuczka polega na tym, że sprawdza, czy obiekt jest z tego samego okna, a jeśli nie, pobiera okno obiektu.
Przykłady:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
Argument type może być również funkcją wywołania zwrotnego który zwraca konstruktor. Funkcja callback otrzyma jeden parametr, który jest oknem podanego obiektu.
Przykłady:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
Należy pamiętać, że IE
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-05 14:42:01
Szukałam czegoś podobnego i natknęłam się na to pytanie. Oto jak dostaję typy: jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( 'object' === typeOfThing ) {
typeOfThing = Object.prototype.toString.call( thing );
if ( '[object Object]' === typeOfThing ) {
if ( thing.constructor.name ) {
return thing.constructor.name;
}
else if ( '[' === thing.constructor.toString().charAt(0) ) {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
else {
typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );
if ( typeOfThing ) {
return typeOfThing[1];
}
else {
return 'Function';
}
}
}
else {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
}
return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-04 09:34:19
Powinieneś użyć somevar.constructor.name
Jak:
const getVariableType = a => a.constructor.name.toLowerCase();
const d = new Date();
const res1 = getVariableType(d); // 'date'
const num = 5;
const res2 = getVariableType(num); // 'number'
const fn = () => {};
const res3 = getVariableType(fn); // 'function'
console.log(res1); // 'date'
console.log(res2); // 'number'
console.log(res3); // 'function'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-28 22:47:45
Użyj constructor.name
Kiedy możesz, a funkcja regex kiedy nie mogę.
Function.prototype.getName = function(){
if (typeof this.name != 'undefined')
return this.name;
else
return /function (.+)\(/.exec(this.toString())[1];
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-12 19:38:06
Możesz użyć instanceof
operator, aby sprawdzić, czy obiekt jest instancją innej instancji, ale ponieważ nie ma klas, nie można uzyskać nazwy klasy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-01 22:13:00
Funkcja kind () z Agave.Js zwróci:
- najbliższy prototyp w drzewie dziedziczenia
- Dla zawsze prymitywnych typów, takich jak 'null' i 'undefined', prymitywna nazwa.
Działa na wszystkich obiektach i prymitywach JS, niezależnie od tego, jak zostały stworzone i nie ma żadnych niespodzianek. Przykłady:
Liczby
kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'
NaN
kind(NaN) === 'NaN'
Struny
kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'
Booleans
kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'
Tablice
kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'
Obiekty
kind({a:1}) === 'Object'
kind(new Object()) === 'Object'
Daty
kind(new Date()) === 'Date'
Funkcje
kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'
Undefined
kind(undefined) === 'undefined'
Null
kind(null) === 'null'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 15:04:46
Oto implementacja oparta na zaakceptowanej odpowiedzi :
/**
* Returns the name of an object's type.
*
* If the input is undefined, returns "Undefined".
* If the input is null, returns "Null".
* If the input is a boolean, returns "Boolean".
* If the input is a number, returns "Number".
* If the input is a string, returns "String".
* If the input is a named function or a class constructor, returns "Function".
* If the input is an anonymous function, returns "AnonymousFunction".
* If the input is an arrow function, returns "ArrowFunction".
* If the input is a class instance, returns "Object".
*
* @param {Object} object an object
* @return {String} the name of the object's class
* @see <a href="https://stackoverflow.com/a/332429/14731">https://stackoverflow.com/a/332429/14731</a>
* @see getFunctionName
* @see getObjectClass
*/
function getTypeName(object)
{
const objectToString = Object.prototype.toString.call(object).slice(8, -1);
if (objectToString === "Function")
{
const instanceToString = object.toString();
if (instanceToString.indexOf(" => ") != -1)
return "ArrowFunction";
const getFunctionName = /^function ([^(]+)\(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
return "AnonymousFunction";
return "Function";
}
// Built-in types (e.g. String) or class instances
return objectToString;
};
/**
* Returns the name of a function.
*
* If the input is an anonymous function, returns "".
* If the input is an arrow function, returns "=>".
*
* @param {Function} fn a function
* @return {String} the name of the function
* @throws {TypeError} if {@code fn} is not a function
* @see getTypeName
*/
function getFunctionName(fn)
{
try
{
const instanceToString = fn.toString();
if (instanceToString.indexOf(" => ") != -1)
return "=>";
const getFunctionName = /^function ([^(]+)\(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
{
const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
if (objectToString === "Function")
return "";
throw TypeError("object must be a Function.\n" +
"Actual: " + getTypeName(fn));
}
return match[1];
}
catch (e)
{
throw TypeError("object must be a Function.\n" +
"Actual: " + getTypeName(fn));
}
};
/**
* @param {Object} object an object
* @return {String} the name of the object's class
* @throws {TypeError} if {@code object} is not an Object
* @see getTypeName
*/
function getObjectClass(object)
{
const getFunctionName = /^function ([^(]+)\(/;
const result = object.constructor.toString().match(getFunctionName)[1];
if (result === "Function")
{
throw TypeError("object must be an Object.\n" +
"Actual: " + getTypeName(object));
}
return result;
};
function UserFunction()
{
}
function UserClass()
{
}
let anonymousFunction = function()
{
};
let arrowFunction = i => i + 1;
console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(\"text\"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));
Używamy właściwości konstruktora tylko wtedy, gdy nie mamy innego wyboru.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:33
Możesz użyć operatora "instanceof", aby określić, czy obiekt jest instancją określonej klasy, czy nie. Jeśli nie znasz nazwy typu obiektu, możesz użyć jego właściwości konstruktora. Właściwość konstruktora obiektów jest odniesieniem do funkcji, która jest używana do ich inicjalizacji. Przykład:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Teraz c1.konstruktor jest odniesieniem do funkcji Circle()
.
Można również użyć operatora typeof
, ale operator typeof
pokazuje ograniczone informacje. Jednym z rozwiązań jest użycie metoda toString()
obiektu global object. Na przykład, jeśli masz obiekt, powiedzmy myObject, możesz użyć metody toString()
obiektu globalnego do określenia typu klasy myObject. Użyj tego:
Object.prototype.toString.apply(myObject);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-04 10:58:38
Powiedz, że masz var obj;
Jeśli chcesz tylko nazwę typu obj, np. "Object", "Array" lub " String", możesz użyć tego:
Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 19:35:28
Najbliżej można dostać to typeof
, ale zwraca tylko "object" dla dowolnego typu niestandardowego. Zobacz: Jason Bunting.
Edit, Jason usunął swój post z jakiegoś powodu, więc po prostu użyj właściwości obiektu constructor
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:26
Dość Proste!
- Moja ulubiona metoda na uzyskanie typu czegokolwiek w JS
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
- moja ulubiona metoda sprawdzania typu czegokolwiek w JS
function checkType(entity, type){
return getType(entity) === type
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-06 12:10:51
Jeśli ktoś szukał rozwiązania, które działa z jQuery, oto poprawiony kod wiki(oryginalny łamie jQuery).
Object.defineProperty(Object.prototype, "getClassName", {
value: function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-29 11:49:15
Lodash lodash ma wiele izmetodów, więc jeśli używasz Lodash może Mixin taki jak ten może być przydatny:
// Mixin for identifying a Javascript Object
_.mixin({
'identify' : function(object) {
var output;
var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments',
'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber',
'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
Dodaje do lodash metodę o nazwie "identify", która działa następująco:
console.log(_.identify('hello friend')); // isString
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 17:00:42
[7]}ok, ludzie, powoli buduję metodę catch all na to przez kilka lat lol! Sztuczka polega na:
- mają mechanizm tworzenia klas.
- mają mechanizm sprawdzania wszystkich klas utworzonych przez użytkownika, pierwiastków i wartości utworzonych/wygenerowanych przez natywne konstruktory.
- mają mechanizm rozszerzania klas utworzonych przez użytkownika na nowe, tak aby powyższa funkcjonalność przenika przez Twój kod / aplikację/bibliotekę / itp..
Dla przykład (lub aby zobaczyć, jak poradziłem sobie z tym problemem) spójrz na następujący kod na GitHubie: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js i Szukaj:
classOf =
,
classOfIs =
, oraz lub
defineSubClass =
(bez backtików (')).
Jak widzisz, mam pewne mechanizmy zmuszające classOf
do podawania mi zawsze nazwy typu klas/konstruktorów, niezależnie od tego, czy jest to prymitywna, zdefiniowana przez użytkownika Klasa, wartość utworzona przy użyciu natywnego konstruktora, Null, NaN, itp.. Dla każdej pojedynczej wartości javascript uzyskam unikalną nazwę typu z funkcji classOf
. Ponadto mogę przekazać w rzeczywistych konstruktorach do sjl.classOfIs
, aby sprawdzić typ wartości, a także być w stanie przekazać w jego nazwie typu! Tak na przykład:
``` // Proszę wybaczyć długie przestrzenie nazw! Nie miałem pojęcia o wpływie, dopóki nie użyłem ich przez jakiś czas (są do bani haha)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = 'helloworld';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === 'NaN'; // true
sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!
```
Jeśli jesteś zainteresowany przeczytaniem więcej o tym, jak używam konfiguracji wymienionych powyżej spójrz na repo: https://github.com/elycruz/sjljs
Również książki z treściami na ten temat: - "JavaScript Patterns" stojana Stefanowa. - "Javascript-The Definitive Guide."autorstwa Davida Flanagana. - i wiele innych.. (search le ' web).
Możesz również szybko przetestować funkcje, o których tutaj mówię: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (również ścieżka 0.5.18 w adresie url ma tam źródła z Githuba minus node_modules i takie).
Szczęśliwego Kodowania!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-19 07:27:17
Użyj class.name
. Działa to również z function.name
.
class TestA {}
console.log(TestA.name); // "TestA"
function TestB() {}
console.log(TestB.name); // "TestB"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-28 16:34:36
Dla tych z Was, którzy to czytają i chcą prostego rozwiązania, które działa dość dobrze i zostało przetestowane:
const getTypeName = (thing) => {
const name = typeof thing
if (name !== 'object') return name
if (thing instanceof Error) return 'error'
if (!thing) return 'null'
return ({}).toString.call(thing).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
Aby uzyskać wgląd w to, dlaczego to działa, sprawdź dokumentację polyfill dla Array.isArray (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#polyfill
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-10 07:04:14