Esiste un JavaScript equivalente di Java s' class.getName()?
Esiste un JavaScript equivalente di Java s' class.getName()?
Risposte:
Esiste un equivalente JavaScript di Java
class.getName()?
No .
Aggiornamento ES2015 : il nome di class Foo {}èFoo.name . Il nome della thingclasse, indipendentemente dal thingtipo, è thing.constructor.name. I costruttori incorporati in un ambiente ES2015 hanno la nameproprietà corretta ; per esempio (2).constructor.nameè "Number".
Ma qui ci sono vari hack che cadono tutti in un modo o nell'altro:
Ecco un hack che farà ciò di cui hai bisogno: tieni presente che modifica il prototipo dell'Oggetto, qualcosa che la gente non vede bene (di solito per una buona ragione)
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Ora, tutti i tuoi oggetti avranno la funzione getName(), che restituirà il nome del costruttore come una stringa. Ho provato questo FF3e IE7, non posso parlare per altre implementazioni.
Se non vuoi farlo, ecco una discussione sui vari modi di determinare i tipi in JavaScript ...
Recentemente ho aggiornato questo per essere un po 'più esaustivo, anche se non è così. Correzioni benvenute ...
constructorproprietà ...Ognuno objectha un valore per la sua constructorproprietà, ma a seconda di come è objectstato costruito e di ciò che vuoi fare con quel valore, potrebbe essere utile o meno.
In generale, è possibile utilizzare la constructorproprietà per testare il tipo di oggetto in questo modo:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
Quindi, funziona abbastanza bene per la maggior parte delle esigenze. Detto ciò...
Non funziona AFFATTO in molti casi
Questo modello, sebbene rotto, è abbastanza comune:
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objectscostruito via new Thingyavrà una constructorproprietà che punta a Objectno Thingy. Quindi cadiamo proprio all'inizio; semplicemente non puoi fidarti constructordi una base di codice che non controlli.
Ereditarietà multipla
Un esempio in cui non è così ovvio è l'utilizzo dell'ereditarietà multipla:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Le cose ora non funzionano come ci si potrebbe aspettare che:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
Quindi, potresti ottenere risultati imprevisti se il objecttuo test ha un objectset diverso come suo prototype. Ci sono modi per aggirare questo al di fuori dell'ambito di questa discussione.
Ci sono altri usi per la constructorproprietà, alcuni interessanti, altri meno; per ora non approfondiremo questi usi poiché non è rilevante per questa discussione.
Non funzionerà cross-frame e cross-window
L'uso .constructorper il controllo del tipo si interromperà quando si desidera controllare il tipo di oggetti provenienti da windowoggetti diversi , ad esempio quello di un iframe o di una finestra popup. Questo perché esiste una versione diversa di ciascun tipo di core constructorin ciascuna `finestra ', cioè
iframe.contentWindow.Array === Array // false
instanceofdell'operatore ...L' instanceofoperatore è anche un modo pulito di testare il objecttipo, ma ha i suoi potenziali problemi, proprio come la constructorproprietà.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
Ma instanceofnon funziona per valori letterali (perché i letterali non lo sono Objects)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
I letterali devono essere racchiusi in un Objectper instanceofpoter funzionare, ad esempio
new Number(3) instanceof Number // true
Il .constructorcontrollo funziona bene per i letterali perché l' .invocazione del metodo avvolge implicitamente i letterali nel rispettivo tipo di oggetto
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Perché due punti per il 3? Perché Javascript interpreta il primo punto come un punto decimale;)
instanceofinoltre non funzionerà su finestre diverse, per lo stesso motivo del constructorcontrollo delle proprietà.
nameproprietà della constructorproprietà ...Ancora una volta, vedi sopra; è abbastanza comune constructoressere completamente, completamente sbagliato e inutile.
L'uso di myObjectInstance.constructor.namefornisce una stringa contenente il nome della constructorfunzione utilizzata, ma è soggetto alle avvertenze sulla constructorproprietà menzionate in precedenza.
Per IE9 e versioni successive, è possibile applicare la patch scimmia nel supporto :
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) {}
});
}
Versione aggiornata dall'articolo in questione. Questo è stato aggiunto 3 mesi dopo la pubblicazione dell'articolo, questa è la versione consigliata da usare dall'autore dell'articolo Matthew Scharley. Questa modifica è stata ispirata da commenti che evidenziano potenziali insidie nel codice precedente.
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) {}
});
}
Si scopre che, come indicato in questo post , è possibile utilizzare Object.prototype.toString- l'implementazione generica e di basso livello toString- per ottenere il tipo per tutti i tipi predefiniti
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Si potrebbe scrivere una funzione di supporto breve come
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
per rimuovere la cruft e ottenere solo il nome del tipo
type('abc') // String
Tuttavia, verrà restituito Objectper tutti i tipi definiti dall'utente.
Tutti questi sono soggetti a un potenziale problema, e questa è la domanda su come è stato costruito l'oggetto in questione. Ecco vari modi di costruire oggetti e i valori restituiti dai diversi metodi di verifica del tipo:
// 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
Sebbene non tutte le permutazioni siano presenti in questo set di esempi, speriamo che ce ne siano abbastanza per darti un'idea di come le cose disordinate potrebbero arrivare a seconda delle tue esigenze. Non dare per scontato nulla, se non capisci esattamente cosa stai cercando, potresti finire con la rottura del codice dove non ti aspetti a causa della mancanza di grokking delle sottigliezze.
La discussione typeofsull'operatore può sembrare un'omissione lampante, ma in realtà non è utile per aiutare a identificare se si objecttratta di un determinato tipo, poiché è molto semplicistico. Capire dove typeofè utile è importante, ma al momento non ritengo che sia estremamente rilevante per questa discussione. La mia mente è aperta al cambiamento però. :)
constructormetodo dell'oggetto (con .toString()o .name) non funzionerà se il tuo Javascript è stato minimizzato con uno strumento come uglify o la pipeline delle risorse di Rails. La minificazione rinomina il costruttore, quindi finirai con nomi di classe errati come n. Se ti trovi in questo scenario, potresti voler definire manualmente una classNameproprietà sui tuoi oggetti e usarla invece.
La risposta di Jason Bunting mi ha dato abbastanza indizio per trovare ciò di cui avevo bisogno:
<<Object instance>>.constructor.name
Quindi, ad esempio, nel seguente codice:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.namesarebbe tornato "MyObject".
function getType(o) { return o && o.constructor && o.constructor.name }
Un piccolo trucco che uso:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
class Square, il nome è Square.name/ MySquare.constructor.namepiuttosto che Square.prototype.name; attivando namela funzione di costruzione non inquina il prototipo o alcuna istanza, ma è accessibile da entrambi.
Per essere precisi, penso che OP abbia richiesto una funzione che recupera il nome del costruttore per un particolare oggetto. In termini di Javascript, objectnon ha un tipo ma è un tipo e in sé . Tuttavia, oggetti diversi possono avere costruttori diversi .
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"
Nota: l'esempio seguente è obsoleto.
Un post sul blog collegato da Christian Sciberras contiene un buon esempio su come farlo. Vale a dire, estendendo il prototipo Object:
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
test.getClassName()vs getClassName.apply(test).
Utilizzo di Object.prototype.toString
Si scopre che, come indicato in questo post, è possibile utilizzare Object.prototype.toString - l'implementazione generica di basso livello di toString - per ottenere il tipo per tutti i tipi predefiniti
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Si potrebbe scrivere una funzione di supporto breve come
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
.slice():Object.prototype.toString.call(obj).slice( 8, -1 );
Ecco una soluzione che ho trovato che risolve i difetti di esempio di. Può controllare i tipi di un oggetto da finestre incrociate e cornici incrociate e non ha problemi con i tipi primitivi.
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 richiede due parametri: un oggetto e un tipo. Il vero trucco di come funziona è che controlla se l'oggetto proviene dalla stessa finestra e se non ottiene la finestra dell'oggetto.
Esempi:
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
L'argomento type può anche essere una funzione di callback che restituisce un costruttore. La funzione di callback riceverà un parametro che è la finestra dell'oggetto fornito.
Esempi:
//"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
Una cosa da tenere a mente è che IE <9 non fornisce il costruttore su tutti gli oggetti, quindi il test sopra riportato per NodeList restituisce false e anche un isInstance (alert, "Function") restituisce false.
In realtà stavo cercando una cosa simile e mi sono imbattuto in questa domanda. Ecco come ottengo i tipi: 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);
}
Dovresti usare somevar.constructor.namecome un:
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'
La funzione kind () di Agave.JS restituirà:
Funziona su tutti gli oggetti e le primitive JS, indipendentemente da come sono stati creati e non ha sorprese. Esempi:
kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'
kind(NaN) === 'NaN'
kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'
kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'
kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'
kind({a:1}) === 'Object'
kind(new Object()) === 'Object'
kind(new Date()) === 'Date'
kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'
kind(undefined) === 'undefined'
kind(null) === 'null'
Puoi usare l' instanceofoperatore per vedere se un oggetto è un'istanza di un'altra, ma poiché non ci sono classi, non puoi ottenere un nome di classe.
instanceofcontrolla solo se un oggetto eredita da un altro oggetto. Ad esempio, un semplice []eredita da Array, ma Array eredita anche da Object. Poiché la maggior parte degli oggetti ha più livelli di ereditarietà, trovare il prototipo più vicino è una tecnica migliore. Vedi la mia risposta per come.
Ecco un'implementazione basata sulla risposta accettata :
/**
* 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));
Usiamo la proprietà del costruttore solo quando non abbiamo altra scelta.
È possibile utilizzare l'operatore "instanceof" per determinare se un oggetto è un'istanza di una determinata classe o meno. Se non si conosce il nome del tipo di un oggetto, è possibile utilizzare la sua proprietà di costruzione. La proprietà costruttore degli oggetti è un riferimento alla funzione utilizzata per inizializzarli. Esempio:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Ora c1.constructor è un riferimento alla Circle()funzione. Puoi anche usare l' typeofoperatore, ma l' typeofoperatore mostra informazioni limitate. Una soluzione è utilizzare il toString()metodo dell'oggetto globale Object. Ad esempio, se si dispone di un oggetto, ad esempio myObject, è possibile utilizzare il toString()metodo dell'oggetto globale per determinare il tipo della classe di myObject. Usa questo:
Object.prototype.toString.apply(myObject);
Di 'che hai var obj;
Se vuoi solo il nome del tipo di obj, come "Object", "Array" o "String", puoi usare questo:
Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');
Il più vicino che puoi ottenere è typeof, ma restituisce solo "oggetto" per qualsiasi tipo di tipo personalizzato. Per quelli, vedi Jason Bunting .
Modifica, Jason ha cancellato il suo post per qualche motivo, quindi usa la constructorproprietà di Object .
Se qualcuno stava cercando una soluzione che funzioni con jQuery, ecco il codice wiki modificato (l'originale interrompe 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] : "";
}
});
getNamee cade.
Lodash ha molti isMethods, quindi se stai usando Lodash forse un mixin come questo può essere utile:
// 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;
}
});
Aggiunge un metodo a lodash chiamato "identifica" che funziona come segue:
console.log(_.identify('hello friend')); // isString
Ok, gente, sto lentamente costruendo un metodo tutto per questo da qualche anno lol! Il trucco è:
Per un esempio (o per vedere come ho affrontato il problema) guarda il seguente codice su github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js e cerca:
classOf =,
classOfIs =e o
defineSubClass =(senza i backtick (`)).
Come puoi vedere, ho alcuni meccanismi per forzarmi classOfa darmi sempre il nome del tipo di classe / costruttore, indipendentemente dal fatto che sia una classe primitiva, una definita dall'utente, un valore creato usando un costruttore nativo, Null, NaN, ecc. Per ogni singolo valore JavaScript otterrò il nome univoco dalla classOffunzione. Inoltre, posso passare a costruttori reali sjl.classOfIsper controllare il tipo di un valore oltre a poter passare anche il nome del suo tipo! Quindi per esempio:
`` // Per favore, perdona gli spazi dei nomi lunghi! Non avevo idea dell'impatto fino a dopo averli usati per un po '(fanno schifo ahah)
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`!
`` `
Se sei interessato a leggere di più su come utilizzo la configurazione di cui sopra dai un'occhiata al repository: https://github.com/elycruz/sjljs
Libri anche con contenuti sull'argomento: - "JavaScript Patterns" di Stoyan Stefanov. - "Javascript - La guida definitiva". di David Flanagan. - e molti altri .. (cerca nel web).
Inoltre puoi testare rapidamente le funzionalità di cui sto parlando qui: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (anche il percorso 0.5.18 nell'URL ha le fonti da github lì meno il nodo_moduli e simili).
Buona programmazione!
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
function checkType(entity, type){
return getType(entity) === type
}
Usa class.name. Questo funziona anche con function.name.
class TestA {}
console.log(TestA.name); // "TestA"
function TestB() {}
console.log(TestB.name); // "TestB"
classe non istanza.