Respuestas:
Puedes usar el typeof
operador:
var booleanValue = true;
var numericalValue = 354;
var stringValue = "This is a String";
var stringObject = new String( "This is a String Object" );
alert(typeof booleanValue) // displays "boolean"
alert(typeof numericalValue) // displays "number"
alert(typeof stringValue) // displays "string"
alert(typeof stringObject) // displays "object"
Ejemplo de esta página web . (Sin embargo, el ejemplo fue ligeramente modificado).
Esto no funcionará como se espera en el caso de las cadenas creadas con new String()
, pero esto rara vez se usa y se recomienda contra [1] [2] . Vea las otras respuestas sobre cómo manejarlas, si así lo desea.
new String('foo')
, pero eso no importa porque las cadenas envueltas en objetos son una característica inútil que no debería usar. La guía de estilo de Google los prohíbe , Douglas Crockford quiere que sean desaprobados , y ninguna biblioteca los usa. Finge que no existen y úsalo typeof
sin miedo.
Esto es lo que funciona para mí:
if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
instanceof
comprobación aquí es ruido sin sentido a menos que esté siguiendo algunas prácticas de codificación muy inusuales , y esta respuesta no hace nada para explicar lo que hace o por qué podría usarlo. La única razón por la que lo necesitaría es si usa cadenas envueltas en objetos, pero las cadenas envueltas en objetos son una característica inútil que nadie usa y Google y Crockford condenan como una mala práctica ( google-styleguide.googlecode.com/svn/ trunk / ... , crockford.com/javascript/recommend.html ).
typeof
y instanceof
parece un buen consejo si su código puede ser llamado por otros '. El postmessage
caso marginal de @ MarkAmery importa si preguntas "¿qué era lo que acabo de decir postmessage
?" - pero esperaría que se maneje en la interfaz y no se permita su propagación. En otros lugares, parece correcto manejar métodos de codificación no obsoletos, incluso si algunos estéticos de JS los desaprueban. ¡NUNCA comente su código como aceptando String, a menos que realmente lo haga!
Dado que más de 580 personas votaron por una respuesta incorrecta, y más de 800 votaron por una respuesta funcional pero de estilo escopeta, pensé que valdría la pena rehacer mi respuesta en una forma más simple que todos puedan entender.
function isString(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
O en línea (tengo una configuración de UltiSnip para esto):
Object.prototype.toString.call(myVar) === "[object String]"
Para su información, la respuesta de Pablo Santa Cruz es incorrecta, porque typeof new String("string")
esobject
La respuesta de DRAX es precisa y funcional, y debería ser la respuesta correcta (ya que Pablo Santa Cruz es definitivamente incorrecto, y no discutiré en contra del voto popular).
Sin embargo, esta respuesta también es definitivamente correcta, y en realidad es la mejor respuesta (excepto, tal vez, por la sugerencia de usar lodash / subrayado ).descargo de responsabilidad: contribuí a la base de código lodash 4.
Mi respuesta original (que obviamente voló sobre muchas cabezas) es la siguiente:
Transcodifiqué esto de underscore.js:
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach(
function(name) {
window['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
};
});
Eso definirá isString, isNumber, etc.
En Node.js, esto se puede implementar como un módulo:
module.exports = [
'Arguments',
'Function',
'String',
'Number',
'Date',
'RegExp'
].reduce( (obj, name) => {
obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
return obj;
}, {});
[editar]: Object.prototype.toString.call(x)
funciona para delinear entre funciones y funciones asíncronas también:
const fn1 = () => new Promise((resolve, reject) => setTimeout(() => resolve({}), 1000))
const fn2 = async () => ({})
console.log('fn1', Object.prototype.toString.call(fn1))
console.log('fn2', Object.prototype.toString.call(fn2))
global || window
lugar de, window
pero sería un mal enfoque para resolver un problema que no debería tener en primer lugar).
myObject+"" === myObject
para verificar si un objeto es una cadena (o mejor aún, no escribiría check en un sistema de tipo basado en el comportamiento en primer lugar).
toString
en el Object.prototype
. Entonces, argumentaría que confiar en toString
verificar el tipo de un objeto es, en el mejor de los casos, una mala práctica.
Recomiendo usar las funciones integradas de jQuery o lodash / Underscore . Son más simples de usar y más fáciles de leer.
Cualquiera de las funciones manejará el caso mencionado por DRAX ... es decir, ambos verifican si (A) la variable es un literal de cadena o (B) es una instancia del objeto String. En cualquier caso, estas funciones identifican correctamente el valor como una cadena.
lodash / Underscore.js
if(_.isString(myVar))
//it's a string
else
//it's something else
jQuery
if($.type(myVar) === "string")
//it's a string
else
//it's something else
Consulte la documentación de lodash para _.isString () para obtener más detalles.
Ver documentación de jQuery para $ .type () para obtener más detalles.
_.every()
es un poco confuso de usar al principio, y algo tan simple como _.isBoolean()
ha confundido a los desarrolladores de mi empresa. Un desarrollador erróneamente pensó que sería falso si el valor era booleano y era falso. El inglés es más fácil de leer que el alemán para mí, porque no sé alemán. Aprenda JavaScript y todo tendrá sentido.
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
Vi eso aquí:
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Object.prototype.toString.call(obj) === '[object String]'
?
(x === y)
tiene mejor legibilidad que x === y
?
Mejor manera:
var s = 'String';
var a = [1,2,3];
var o = {key: 'val'};
(s.constructor === String) && console.log('its a string');
(a.constructor === Array) && console.log('its an array');
(o.constructor === Object) && console.log('its an object');
(o.constructor === Number || s.constructor === Boolean) && console.log('this won\'t run');
Cada uno de estos ha sido construido por su función de clase apropiada, como "new Object ()", etc.
Además, Duck-Typing: "Si parece un pato, camina como un pato y huele a pato, debe ser una matriz", lo que significa que compruebe sus propiedades.
Espero que esto ayude.
Recuerde, siempre puede usar combinaciones de enfoques también. Aquí hay un ejemplo del uso de un mapa en línea de acciones con typeof :
var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];
Aquí hay un ejemplo más 'real' del uso de mapas en línea:
function is(datum) {
var isnt = !{ null: true, undefined: true, '': true, false: false, 0: false }[ datum ];
return !isnt;
}
console.log( is(0), is(false), is(undefined), ... ); // >> true true false
Esta función usaría "conversión de tipo" [personalizada] - en lugar de "tipo - / - mapeo de valores" - para determinar si una variable realmente "existe". ¡Ahora puedes dividir ese cabello desagradable entre null
& 0
!
Muchas veces ni siquiera te importa su tipo . Otra forma de evitar el tipeo es combinar conjuntos de tipo pato:
this.id = "998"; // use a number or a string-equivalent
function get(id) {
if (!id || !id.toString) return;
if (id.toString() === this.id.toString()) http( id || +this.id );
// if (+id === +this.id) ...;
}
Ambos Number.prototype
y String.prototype
tienen un .toString() method
. Simplemente se aseguró de que el equivalente de cadena del número fuera el mismo, y luego se aseguró de pasarlo a la http
función como a Number
. En otras palabras, ni siquiera nos importaba cuál era su tipo.
Espero que te dé más para trabajar :)
(o.constructor === Number || s.constructor === Boolean)
). Anecdóticamente,parseInt
y NaN
son herramientas frágiles pero poderosas. Solo recuerde que Not-a-Number NO es Not-a-Number y se puede definir indefinido.
if(thing.call) { 'its a function'; }
o if(thing.defineProperties) { 'its an object'; }
. Gracias por el aporte, axkibe!
Honestamente, no puedo ver por qué uno no usaría simplemente typeof
en este caso:
if (typeof str === 'string') {
return 42;
}
Sí, fallará contra las cadenas envueltas en objetos (por ejemplo new String('foo')
), pero estas son ampliamente consideradas como una mala práctica y es probable que la mayoría de las herramientas de desarrollo modernas desalienten su uso. (Si ves uno, ¡solo arréglalo!)
los Object.prototype.toString
truco es algo que todos los desarrolladores front-end han sido declarados culpables de hacer un día en sus carreras, pero no dejes que te engañe por su pulido de inteligencia: se romperá tan pronto como algo parchee el prototipo de Object:
const isString = thing => Object.prototype.toString.call(thing) === '[object String]';
console.log(isString('foo'));
Object.prototype.toString = () => 42;
console.log(isString('foo'));
Me gusta usar esta solución simple:
var myString = "test";
if(myString.constructor === String)
{
//It's a string
}
undefined
y null
, y aún así obtener la respuesta correcta para cadenas vacías (ambos ''
y new String('')
).
(mystring || false) && mystring.constructor === String
. Usé falso en caso de que se use en una función que debe devolver un valor booleano.
Este es un gran ejemplo de por qué el rendimiento es importante:
Hacer algo tan simple como una prueba para una cadena puede ser costoso si no se hace correctamente.
Por ejemplo, si quisiera escribir una función para probar si algo es una cadena, podría hacerlo de dos maneras:
1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');
2) const isString = str => ((typeof str === 'string') || (str instanceof String));
Ambos son bastante sencillos, entonces, ¿qué podría afectar el rendimiento? En términos generales, las llamadas a funciones pueden ser costosas, especialmente si no sabe lo que sucede dentro. En el primer ejemplo, hay una llamada de función al método toString de Object. En el segundo ejemplo, no hay llamadas a funciones, ya que typeof e instanceof son operadores. Los operadores son significativamente más rápidos que las llamadas a funciones.
Cuando se prueba el rendimiento, el ejemplo 1 es un 79% más lento que el ejemplo 2.
Ver las pruebas: https://jsperf.com/isstringtype
typeof str === 'string' || str instanceof String
(puede quitar el paréntesis que prefiero en los if (..)
casos); de todos modos, verificar tanto los tipos primitivos como los de objeto en el n. ° 2 es claro y suficiente. Estas comprobaciones deberían ser "raras" de todos modos.
if (s && typeof s.valueOf() === "string") {
// s is a string
}
Funciona tanto para literales de cadena let s = 'blah'
como para cadenas de objetolet s = new String('blah')
Tomado de lodash:
function isString(val) {
return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]');
}
console.log(isString('hello world!')); // true
console.log(isString(new String('hello world'))); // true
Creo que la solución @customcommander debería ser suficiente en el 90% de sus casos:
typeof str === 'string'
Debería servirle bien (simplemente porque normalmente no hay razón para tener new String('something')
en su código).
Si estás interesado en manejar el String
objeto (por ejemplo, espera algunas variaciones de un tercero), usar lodash como sugiere @ ClearCloud8 parece una solución clara, simple y elegante.
Sin embargo, sugeriría ser cauteloso con las bibliotecas como lodash debido a su tamaño. En lugar de hacer
import _ from 'lodash'
...
_.isString(myVar)
Lo que trae todo el enorme objeto lodash, sugeriría algo como:
import { isString as _isString } from 'lodash'
...
_isString(myVar)
Y con un paquete simple debería estar bien (me refiero aquí al código del cliente).
Si trabaja en el entorno node.js, simplemente puede usar la función integrada isString en utils.
const util = require('util');
if (util.isString(myVar)) {}
Editar: como mencionó @Jehy, esto está en desuso desde v4.
typeof value === 'string'
lugar".
x = new String('x'); x.isString(x);
devuelve falso . Hay util.types.isStringObject()
pero eso devuelve falso para el x = 'x'
tipo cadena. Dos funciones de utilidad que no proporcionan absolutamente ninguna utilidad ...
El siguiente método verificará si alguna variable es una cadena ( incluidas las variables que no existen ).
const is_string = value => {
try {
return typeof value() === 'string';
} catch (error) {
return false;
}
};
let example = 'Hello, world!';
console.log(is_string(() => example)); // true
console.log(is_string(() => variable_doesnt_exist)); // false
También descubrí que esto también funciona bien, y es mucho más corto que los otros ejemplos.
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
Al concatenar entre comillas vacías, convierte el valor en una cadena. Si myVar
ya es una cadena, la instrucción if es exitosa.
typeof
.
typeof
pero aún bastante más rápido que toString
. De cualquier manera, supongo que me gusta la sintaxis para coaccionar.
var s = new String('abc'); > s === s + '' > false
new String
cus que crea un tipo de object
. w3schools.com/js/tryit.asp?filename=tryjs_string_object2
var a = new String('')
var b = ''
var c = []
function isString(x) {
return x !== null && x !== undefined && x.constructor === String
}
console.log(isString(a))
console.log(isString(b))
console.log(isString(c))
false
.
Me parece útil esta técnica simple para verificar el tipo de String -
String(x) === x // true, if x is a string
// false in every other case
const test = x =>
console.assert
( String(x) === x
, `not a string: ${x}`
)
test("some string")
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
La misma técnica también funciona para Number :
Number(x) === x // true, if x is a number
// false in every other case
const test = x =>
console.assert
( Number(x) === x
, `not a number: ${x}`
)
test("some string") // assertion failed
test(123)
test(0)
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Y para RegExp -
RegExp(x) === x // true, if x is a regexp
// false in every other case
const test = x =>
console.assert
( RegExp(x) === x
, `not a regexp: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Lo mismo para objetos -
Object(x) === x // true, if x is an object
// false in every other case
NB, regexps, matrices y funciones también se consideran objetos.
const test = x =>
console.assert
( Object(x) === x
, `not an object: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ])
test({ a: 1 })
test(x => x + 1)
Pero, verificar Array es un poco diferente:
Array.isArray(x) === x // true, if x is an array
// false in every other case
const test = x =>
console.assert
( Array.isArray(x)
, `not an array: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ])
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Sin embargo, esta técnica no funciona para las funciones :
Function(x) === x // always false
var x = new String(x); String(x)===x
devuelve falso sin embargo, ({}).toString.call(x).search(/String/)>0
siempre regresa por cosas
function isClass(x,re){return ({}).toString.call(x).search(re)>0;};
isClass("hello",/String/)
o isClass(3,/Number/)
oisClass(null,/Null/)
Una solución simple sería:
var x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
toString()
función
.toString
ningún valor; pruebe si la x que se va a verificar es nula o indefinida, su excepción de lanzamiento de código
toString()
método puede ser anulado y puede generar una excepción (debido a alguna implementación específica), y su verificación no funcionará con seguridad. La idea principal es que no debe llamar a métodos que no están relacionados con lo que desea obtener. Ni siquiera estoy hablando de gastos generales innecesarios relacionados con el toString
método. Votación a favor.
Un ayudante de Typechecker:
function isFromType(variable, type){
if (typeof type == 'string') res = (typeof variable == type.toLowerCase())
else res = (variable.constructor == type)
return res
}
uso:
isFromType('cs', 'string') //true
isFromType('cs', String) //true
isFromType(['cs'], Array) //true
isFromType(['cs'], 'object') //false
Además, si desea que sea recursivo (como Array que es un Objeto), puede usar instanceof
.
( ['cs'] instanceof Object //true
)
Voy a tomar una ruta diferente al resto aquí, que intentará saber si una variable es un tipo específico o un miembro de un conjunto específico de tipos.
JS se basa en ducktyping; si algo grazna como una cadena, podemos y debemos usarlo como una cadena.
Es 7
una cuerda? Entonces, ¿por qué /\d/.test(7)
funciona?
Es {toString:()=>('hello there')}
una cuerda? Entonces, ¿por qué ({toString:()=>('hello there')}) + '\ngeneral kenobi!'
funciona?
Estas no son preguntas sobre si el trabajo anterior funciona, el punto es que lo hacen.
Así que hice una duckyString()
función
A continuación, pruebo muchos casos no atendidos por otras respuestas. Para cada uno el código:
duckyString()
debe normalizar las entradas para el código que espera cadenas realestext = 'hello there';
out(text.replace(/e/g, 'E') + ' ' + 'hello there'.replace(/e/g, 'E'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = new String('oh my');
out(text.toUpperCase() + ' ' + 'oh my'.toUpperCase());
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = 368;
out((text + ' is a big number') + ' ' + ('368' + ' is a big number'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = ['\uD83D', '\uDE07'];
out(text[1].charCodeAt(0) + ' ' + '😇'[1].charCodeAt(0));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
function Text() { this.math = 7; }; Text.prototype = {toString:function() { return this.math + 3 + ''; }}
text = new Text();
out(String.prototype.match.call(text, '0') + ' ' + text.toString().match('0'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
Esto está en la misma línea en !!x
lugar de x===true
probar algo si es como una matriz en lugar de necesitar una matriz real.
jQuery objetos; son matrices? No. ¿Son lo suficientemente buenos? Sí, puedes ejecutarlos a través de Array.prototype
funciones bien.
Es esta flexibilidad la que le da a JS su poder y las pruebas para cadenas específicamente hace que su código sea menos interoperables.
La salida de lo anterior es:
hEllo thErE hEllo thErE
Is string? true "hello there"
OH MY OH MY
Is string? true "oh my"
368 is a big number 368 is a big number
Is string? true "368"
56839 56839
Is string? true "😇"
0 0
Is string? true "10"
Entonces, se trata de por qué quieres saber si algo es una cadena.
Si, como yo, llegaste aquí desde google y quisiste ver si algo era como una cadena , aquí hay una respuesta.
Ni siquiera es costoso a menos que esté trabajando con matrices de caracteres muy largas o profundamente anidadas.
Esto se debe a que es todo si las declaraciones, ninguna función llama como .toString()
.
Excepto si está tratando de ver si una matriz de caracteres con objetos que solo tienen toString()
caracteres de varios bytes, en cuyo caso no hay otra forma de verificar, excepto hacer la cadena y contar los caracteres que componen los bytes, respectivamente
function duckyString(string, normalise, unacceptable) {
var type = null;
if (!unacceptable)
unacceptable = {};
if (string && !unacceptable.chars && unacceptable.to == null)
unacceptable.to = string.toString == Array.prototype.toString;
if (string == null)
;
//tests if `string` just is a string
else if (
!unacceptable.is &&
(typeof string == 'string' || string instanceof String)
)
type = 'is';
//tests if `string + ''` or `/./.test(string)` is valid
else if (
!unacceptable.to &&
string.toString && typeof string.toString == 'function' && string.toString != Object.prototype.toString
)
type = 'to';
//tests if `[...string]` is valid
else if (
!unacceptable.chars &&
(string.length > 0 || string.length == 0)
) {
type = 'chars';
//for each char
for (var index = 0; type && index < string.length; ++index) {
var char = string[index];
//efficiently get its length
var length = ((duckyString(char, false, {to:true})) ?
char :
duckyString(char, true) || {}
).length;
if (length == 1)
continue;
//unicode surrogate-pair support
char = duckyString(char, true);
length = String.prototype[Symbol && Symbol.iterator];
if (!(length = length && length.call(char)) || length.next().done || !length.next().done)
type = null;
}
}
//return true or false if they dont want to auto-convert to real string
if (!(type && normalise))
//return truthy or falsy with <type>/null if they want why it's true
return (normalise == null) ? type != null : type;
//perform conversion
switch (type) {
case 'is':
return string;
case 'to':
return string.toString();
case 'chars':
return Array.from(string).join('');
}
}
Se incluyen opciones para
.toString()
)Aquí hay más pruebas porque soy un finalista:
out('Edge-case testing')
function test(text, options) {
var result = duckyString(text, false, options);
text = duckyString(text, true, options);
out(result + ' ' + ((result) ? '"' + text + '"' : text));
}
test('');
test(null);
test(undefined);
test(0);
test({length:0});
test({'0':'!', length:'1'});
test({});
test(window);
test(false);
test(['hi']);
test(['\uD83D\uDE07']);
test([['1'], 2, new String(3)]);
test([['1'], 2, new String(3)], {chars:true});
Salida:
Edge-case testing
is ""
null null
null null
to "0"
chars ""
chars "!"
null null
chars ""
to "false"
null null
chars "😇"
chars "123"
to "1,2,3"
Solo para ampliar la respuesta de @ DRAX , haría esto:
function isWhitespaceEmptyString(str)
{
//RETURN:
// = 'true' if 'str' is empty string, null, undefined, or consists of white-spaces only
return str ? !(/\S/.test(str)) : (str === "" || str === null || str === undefined);
}
También tendrá en cuenta null
sy undefined
tipos, y se encargará de los tipos que no son de cadena, como 0
.
Esto es lo suficientemente bueno para mí.
ADVERTENCIA: Esta no es una solución perfecta. Ver el final de mi publicación.
Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };
var isString = function(a) {
return (a !== null) && (a !== undefined) && a.isString();
};
Y puedes usar esto como a continuación.
//return false
isString(null);
isString(void 0);
isString(-123);
isString(0);
isString(true);
isString(false);
isString([]);
isString({});
isString(function() {});
isString(0/0);
//return true
isString("");
isString(new String("ABC"));
ADVERTENCIA: esto funciona incorrectamente en el caso:
//this is not a string
var obj = {
//but returns true lol
isString: function(){ return true; }
}
isString(obj) //should be false, but true
Puede usar esta función para determinar el tipo de cualquier cosa:
var type = function(obj) {
return Object.prototype.toString.apply(obj).replace(/\[object (.+)\]/i, '$1').toLowerCase();
};
Para verificar si una variable es una cadena:
type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false
No estoy seguro de si te refieres a saber si es un tipo string
independientemente de su contenido, o si su contenido es un número o una cadena, independientemente de su tipo.
Entonces, para saber si su tipo es una cadena, eso ya ha sido respondido.
Pero para saber en función de su contenido si es una cadena o un número, usaría esto:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
Y para algunos ejemplos:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
para evitar las complejidades de los posibles problemas de análisis)