Как определить, является ли переменная строкой или чем-то еще в JavaScript?
Вы можете использовать оператор typeof
:
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"
Пример с этой веб-страницы. (Пример был слегка изменен, хотя).
Это не будет работать должным образом в случае строк, созданных с помощью new String()
, но это редко используется и рекомендуется в отношении [1] [2]. Посмотрите другие ответы о том, как справиться с этим, если вы этого хотите.
Это то, что работает для меня:
if (typeof myVar === 'string' || myVar instanceof String)
// it a string
else
// it something else
Поскольку 580+ люди голосовали за неправильный ответ, а 800+ голосовали за рабочий, но в стиле дробовика, я подумал, что, возможно, стоит повторить мой ответ в более простой форме, понятной каждому.
function isString(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
Или, встроенный (у меня есть настройка UltiSnip для этого):
Object.prototype.toString.call(myVar) === "[object String]"
К вашему сведению, Пабло Санта-Крус ответ неверен, потому что typeof new String("string")
является object
Ответ DRAX точный и функциональный, и должен быть правильным (поскольку Пабло Санта-Крус, безусловно, неверен, и я не буду спорить с голосами избирателей).
Тем не менее, этот ответ также определенно правильный, и на самом деле лучший ответ (за исключением, возможно, предложения использовать lodash/underscore). Отказ от ответственности: я внес вклад в кодовую базу lodash 4.
Мой оригинальный ответ (который явно пролетел над многими головами) следующий:
Я перекодировал это из underscore.js:
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach(
function(name) {
window['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
};
});
Это определит isString, isNumber и т.д.
В Node.js это может быть реализовано как модуль:
module.exports = [
'Arguments',
'Function',
'String',
'Number',
'Date',
'RegExp'
].reduce( (obj, name) => {
obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
return obj;
}, {});
global || window
вместо window
но это был бы плохой подход для решения проблемы, которую вы не должны иметь в первую очередь).
Я рекомендую использовать встроенные функции из jQuery или lodash/Underscore. Они проще в использовании и легче читать.
Любая функция будет обрабатывать упомянутый случай DRAX... то есть они оба проверяют, является ли (A) переменная строковым литералом, или (B) это экземпляр объекта String. В любом случае эти функции правильно идентифицируют значение как строку.
lodash/Underscore.js
if(_.isString(myVar))
//it a string
else
//it something else
JQuery
if($.type(myVar) === "string")
//it a string
else
//it something else
Подробнее см. lodash Documentation для _.isString().
Подробнее см. jQuery Documentation для $.type().
_.every()
немного сбивает с толку, и что-то такое простое, как _.isBoolean()
с толку разработчиков в моей компании. Разработчик ошибочно полагал, что будет ложным, если значение будет логическим и будет ложным. Английский для меня легче читать, чем немецкий, потому что я не знаю немецкий. Изучайте JavaScript, и все это будет иметь смысл.
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
Я видел это здесь:
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Вы можете использовать этот ресурс с открытым исходным кодом is-string component, чтобы проверить, является ли var строкой, избегая копирования в нее.
Примеры:
isString(3) // => false
isString('') // => true
Кроме того, вот как isString
был реализован в AngularJS:
function isString(value) {return typeof value === 'string';}
Лучший способ:
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');
Каждая из них была построена с помощью соответствующей функции класса, например "new Object()" и т.д.
Кроме того, Duck-Typing: "Если это похоже на утку, ходит как утка и пахнет уткой - это должен быть массив", Значение, проверьте его свойства.
Надеюсь, что это поможет.
Помните, вы всегда можете использовать комбинации подходов. Здесь приведен пример использования встроенной карты действий с типомof:
var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];
Здесь приведен пример "реального мира" использования встроенных карт:
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
Эта функция будет использовать [custom] "type-casting" - скорее, "type -/- value-mapping" - выяснить, действительно ли переменная "существует". Теперь вы можете разделить эти неприятные волосы между null
и 0
!
Много раз вы даже не заботитесь о его типе. Другой способ обхода печати - объединение наборов Duck-Type:
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) ...;
}
Оба Number.prototype
и String.prototype
имеют .toString() method
. Вы только что удостоверились, что строка-эквивалент номера была одинаковой, а затем вы убедились, что вы передали ее в функцию http
как Number
. Другими словами, нам даже не важно, что это за тип.
Надеюсь, что вам будет больше работать с:)
Мне нравится использовать это простое решение:
var myString = "test";
if(myString.constructor === String)
{
//It a string
}
Взято из 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
Это отличный пример того, почему производительность имеет значение:
Выполнение чего-либо столь же простого, как тест на строку, может быть дорогостоящим, если не выполнено правильно.
Например, если бы я хотел написать функцию для проверки, является ли что-то строкой, я мог бы сделать это одним из двух способов:
1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');
2) const isString = str => ((typeof str === 'string') || (str instanceof String));
Оба они довольно просты, так что может повлиять на производительность? Вообще говоря, вызовы функций могут быть дорогими, особенно если вы не знаете, что происходит внутри. В первом примере есть вызов функции для метода Object toString. Во втором примере вызовы функций отсутствуют, так как typeof и instanceof являются операторами. Операторы значительно быстрее, чем вызовы функций.
Когда тестируется производительность, пример 1 на 79% медленнее, чем пример 2!
Смотрите тесты: https://jsperf.com/isstringtype
typeof str === 'string' || str instanceof String
(можно опустить скобки, которые я предпочитаю в случаях if (..)
); независимо от того, проверка как примитивных, так и типов объектов в # 2 ясна и достаточна. Эти проверки должны быть «редкими» в любом случае.
Если вы работаете в среде node.js, вы можете просто использовать встроенную функцию isString в utils.
const util = require('util');
if (util.isString(myVar)) {}
Изменить: как упоминалось @Jehy, это устарело, поскольку v4.
Я также обнаружил, что это тоже отлично работает, и это намного короче, чем другие примеры.
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
Объединяясь в пустые кавычки, он превращает значение в строку. Если myVar
уже является строкой, то оператор if будет успешным.
typeof
.
typeof
но все же немного быстрее, чем toString
. В любом случае, я думаю, мне просто нравится синтаксис для принуждения.
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
.
Простое решение:
var x = "hello"
if(x === x.toString(){
// it a string
}else{
// it isn't
}
toString()
Следующий метод проверяет, является ли какая-либо переменная строкой (включая переменные, которые не существуют).
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
Это простой трюк. "using charAt"
var string1 = "hello world";
var string2 = String("hello world");
var string3 = new String("hello world");
(string1.charAt && string2.charAt && string3.charAt) && true == true //true
((1).charAt || ({}).charAt || ([]).charAt ) || false == true // false
вы можете использовать charAt для каждого строкового формата, а другие - false. Но null вызывает ошибки.
Вот полное решение, которое не только дает вам базовую функцию использования, чтобы узнать, является ли значение объектом String или чем-то еще. Плюс некоторые другие хорошие функции.
этот необработанный файл используется в моем этом простом проекте реакции редукции на github Simple React Redux
var Sys = {
/** This Returns Object Type */
getType: function(val){
return Object.prototype.toString.call(val);
},
/** This Checks and Return if Object is Defined */
isDefined: function(val){
return val !== void 0 || typeof val !== 'undefined';
}
/** Run a Map on an Array **/
map: function(arr,fn){
var res = [], i=0;
for( ; i<arr.length; ++i){
res.push(fn(arr[i], i));
}
arr = null;
return res;
},
/** Checks and Return if the prop is Objects own Property */
hasOwnProp: function(obj, val){
return Object.prototype.hasOwnProperty.call(obj, val);
},
/** Extend properties from extending Object to initial Object */
extend: function(newObj, oldObj){
for(var prop in oldObj){
if(hasOwnProp(oldObj, prop)){
newObj[prop] = oldObj[prop];
}
}
return newObj;
} }
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Object', 'Array'].forEach(
function(name) {
Sys['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
}; });
Вышеприведенный код создаст объект Sys = {} этот метод имеет все функции, такие как getType, isDefined Чтобы использовать их, просто попробуйте вызвать этот метод следующим образом.
if(Sys.isDefined(myVar)){ console.log('myVar is defined'); }else { console.log('no myVar is not defined.');}
//Similar to this
var myStr = 'You are awesome.. !!';
if(Sys.isString(myStr)){console.log(myStr);}
Просто чтобы расширить на @DRAX ответ, я бы сделал это:
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);
}
Он будет также учитывать типы null
и undefined
, и он позаботится о нестроковых типах, таких как 0
.
Я не могу честно понять, почему нельзя просто использовать typeof
в этом случае:
if (typeof str === 'string') {
return 42;
}
Да, он не будет работать с объектно-упакованными строками (например, new String('foo')
), но это широко считается плохой практикой, и большинство современных инструментов разработки, скорее всего, будут препятствовать их использованию. (Если вы видите, просто исправьте это!)
Уловка Object.prototype.toString
- это то, что все разработчики фронт-энда признали виновными в том, что они однажды сделали в своей карьере, но не дайте ему обмануть вас своим умным умом: он сломается, как только что-то изменится. Объект-прототип:
const isString = thing => Object.prototype.toString.call(thing) === '[object String]';
console.log(isString('foo'));
Object.prototype.toString = () => 42;
console.log(isString('foo'));
Это достаточно хорошо для меня.
ВНИМАНИЕ: Это не идеальное решение. Смотрите внизу моего поста.
Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };
var isString = function(a) {
return (a !== null) && (a !== undefined) && a.isString();
};
И вы можете использовать это, как показано ниже.
//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"));
ВНИМАНИЕ: Это работает неправильно в случае:
//this is not a string
var obj = {
//but returns true lol
isString: function(){ return true; }
}
isString(obj) //should be false, but true
Я не уверен, если вы имеете в виду знать, является ли это типом string
независимо от его содержимого, или же оно является числом или строкой, независимо от ее типа.
Поэтому, чтобы узнать, является ли его тип строкой, на который уже был дан ответ.
Но чтобы знать, основываясь на его содержании, если это строка или число, я бы использовал это:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
И для некоторых примеров:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
чтобы избежать сложностей потенциальных проблем с /^\d+$/.test('123')
)
new String('foo')
, но это не имеет значения, потому что строки, обернутые объектами, являются бесполезной функцией, которую вы не должны использовать. Руководство по стилю Google запрещает их , Дуглас Крокфорд хочет, чтобы они устарели , и никакие библиотеки их не используют. Притворись, что они не существуют, и используйtypeof
без страха.