property - metodos javascript
¿Cómo verificar eficientemente si la variable es Matriz u Objeto(en NodeJS & V8)? (14)
Acabo de encontrar una solución rápida y simple para descubrir el tipo de variable.
ES6
export const isType = (type, val) => val.constructor.name.toLowerCase() === type.toLowerCase();
ES5
function isType(type, val) {
return val.constructor.name.toLowerCase() === type.toLowerCase();
}
Ejemplos:
isType(''array'', [])
true
isType(''array'', {})
false
isType(''string'', '''')
true
isType(''string'', 1)
false
isType(''number'', '''')
false
isType(''number'', 1)
true
isType(''boolean'', 1)
false
isType(''boolean'', true)
true
EDITAR
Mejora para evitar valores "indefinidos" y "nulos":
ES6
export const isType = (type, val) => !!(val.constructor && val.constructor.name.toLowerCase() === type.toLowerCase());
ES5
function isType(type, val) {
return !!(val.constructor && val.constructor.name.toLowerCase() === type.toLowerCase());
}
¿Hay alguna forma de comprobar de manera eficiente si la variable es Object o Array, en NodeJS & V8?
Estoy escribiendo un modelo para MongoDB y NodeJS, y para recorrer el árbol de objetos necesito saber si el objeto es simple (Number, String, ...) o composite (Hash, Array).
Parece que V8 tiene Array.isArray
, pero ¿cómo verificar si object es un Object? Quiero decir objeto complejo como hash {}
o instancia de clase, no algo así como new String()
?
Por lo general, se puede hacer así:
Object.prototype.toString.call(object) == "[object Object]"
o esto:
object === Object(object)
Pero parece que estas operaciones no son baratas, ¿tal vez hay algunas más eficientes? Está bien si no es universal y no funciona en todos los motores, solo lo necesito para trabajar en V8.
He usado esta función para resolver:
function isArray(myArray) {
return myArray.constructor.toString().indexOf("Array") > -1;
}
Hola, sé que este tema es antiguo, pero hay una manera mucho mejor de diferenciar una matriz en Node.js de cualquier otro objeto, eche un vistazo a los docs .
var util = require(''util'');
util.isArray([]); // true
util.isArray({}); // false
var obj = {};
typeof obj === "Object" // true
La mejor manera en que puedo usar mi proyecto. ¡Use hasOwnProperty
en Tricky Way !.
var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();
arr.constructor.prototype.hasOwnProperty(''push'') //true (This is an Array)
obj.constructor.prototype.hasOwnProperty(''push'') // false (This is an Object)
Para simplemente verificar contra Object o Array sin función adicional, llame (velocidad).
isArray ()
isArray = function(a) {
return (!!a) && (a.constructor === Array);
};
console.log(isArray( )); // false
console.log(isArray( null)); // false
console.log(isArray( true)); // false
console.log(isArray( 1)); // false
console.log(isArray( ''str'')); // false
console.log(isArray( {})); // false
console.log(isArray(new Date)); // false
console.log(isArray( [])); // true
isObject ()
isObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isObject( )); // false
console.log(isObject( null)); // false
console.log(isObject( true)); // false
console.log(isObject( 1)); // false
console.log(isObject( ''str'')); // false
console.log(isObject( [])); // false
console.log(isObject(new Date)); // false
console.log(isObject( {})); // true
Sé que ha pasado un tiempo, pero pensé que actualizaría la respuesta ya que hay formas nuevas (más rápidas y simples) de resolver este problema. Desde ECMAscript 5.1 yo puedo usar el método isArray()
disponible en la clase Array
.
Puede ver su documentación en MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Creo que no deberías tener un problema de compatibilidad hoy en día, pero por si acaso, si agregas esto a tu código, siempre debes estar seguro de que Array.isArray()
está cubierto:
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === ''[object Array]'';
};
}
Si sabe que un parámetro definitivamente será una matriz o un objeto, puede ser más fácil buscar una matriz en comparación con buscar un objeto con algo como esto.
function myIsArray (arr) {
return (arr.constructor === Array);
}
Si solo se trata de detectar si se trata o no de un Object
, podría pensar en
Object.getPrototypeOf( obj ) === Object.prototype
Sin embargo, esto probablemente fallaría para valores primitivos no objeto. En realidad, no hay nada de malo en invocar .toString()
para recuperar la propiedad [[claseclass]]. Incluso puedes crear una sintaxis agradable como
var type = Function.prototype.call.bind( Object.prototype.toString );
y luego usarlo como
if( type( obj ) === ''[object Object]'' ) { }
Puede que no sea la operación más rápida, pero no creo que la pérdida de rendimiento sea demasiado grande.
Solo para el registro, lodash
también tiene isObject(value)
Todos los objetos son instancias de al menos una clase - Object
- en ECMAScript. Solo puede diferenciar entre instancias de clases incorporadas y objetos normales utilizando Object#toString
. Todos tienen el mismo nivel de complejidad, por ejemplo, si se crean usando {}
o el new
operador.
Object.prototype.toString.call(object)
es la mejor Object.prototype.toString.call(object)
para diferenciar entre objetos normales e instancias de otras clases incorporadas, ya que object === Object(object)
no funciona aquí. Sin embargo, no veo una razón por la cual deba hacer lo que está haciendo, así que quizás si comparte el caso de uso, puedo ofrecerle un poco más de ayuda.
Uso typeof
para determinar si la variable que estoy viendo es un objeto. Si es así, uso instanceof
para determinar de qué tipo es
var type = typeof elem;
if (type == "number") {
// do stuff
}
else if (type == "string") {
// do stuff
}
else if (type == "object") { // either array or object
if (elem instanceof Buffer) {
// other stuff
encontré una función simple como esta.
function getClass(object) {
return Object.prototype.toString.call(object).slice(8, -1);
}
y uso:
if ( getClass( obj ) === ''String'' ) {
console.log( ''This is string'' );
}
if ( getClass( obj ) === ''Array'' ) {
console.log( ''This is array'' );
}
if ( getClass( obj ) === ''Object'' ) {
console.log( ''This is Object'' );
}
mirando jQuery allí jQuery.isArray(...)
lo hacen:
isArray = Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
}
esto nos lleva a: jQuery.type
:
type = function( obj ) {
return obj == null ?
String( obj ) :
class2type[ toString.call(obj) ] || "object";
}
y nuevamente tenemos que mirar adentro: class2type
class2type = {};
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
y en JS nativo:
var a, t = "Boolean Number String Function Array Date RegExp Object".split(" ");
for( a in t ) {
class2type[ "[object " + t[a] + "]" ] = t[a].toLowerCase();
}
esto termina con:
var isArray = Array.isArray || function( obj ) {
return toString.call(obj) === "[object Array]";
}
underscore.js está usando lo siguiente
toString = Object.prototype.toString;
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == ''[object Array]'';
};
_.isObject = function(obj) {
return obj === Object(obj);
};
_.isFunction = function(obj) {
return toString.call(obj) == ''[object Function]'';
};