Как я могу проверить, является ли var строкой в ​​JavaScript?


182

Как я могу проверить, является ли var строкой в ​​JavaScript?

Я пробовал это, и это не работает ...

var a_string = "Hello, I'm a string.";

if (a_string typeof 'string') {
    // this is a string
}

Ответы:


381

Вы были близки

if (typeof a_string === 'string') {
    // this is a string
}

В связи с этим: вышеуказанная проверка не сработает, если будет создана строка с new String('hello')типом Object. Есть сложные решения, чтобы обойти это, но лучше просто избегать создания строк таким образом.


1
Ребята, я действительно дал бы принятый ответ обоим вам, но я не могу, все, что я могу сделать, это +1 к обоим, чем дать принятый ответ, кто ближе к моей конкретной проблеме, что я не полностью объяснил.
Витто

это сработало для меняif(typeof(str) === typeof(String()))
Скотт Мерфи

78

typeofОператор не инфиксный (так LHS вашего примера не имеет смысла).

Вы должны использовать это так ...

if (typeof a_string == 'string') {
    // This is a string.
}

Помните, typeofэто оператор, а не функция. Несмотря на это, вы увидите, typeof(var)что вас часто используют в дикой природе. Это имеет такой же смысл, как var a = 4 + (1).

Кроме того, вы также можете использовать ==(оператор сравнения на равенство), поскольку оба операнда являются Strings ( typeof всегда возвращает a String), JavaScript определен для выполнения тех же шагов, которые я использовал ===(оператор строгого сравнения).

Как упоминает Box9 , это не обнаружит экземпляр Stringобъекта.

Вы можете обнаружить это с ....

var isString = str instanceof String;

jsFiddle .

...или...

var isString = str.constructor == String;

jsFiddle .

Но это не будет работать в мульти- windowсреде (думаю, iframeс).

Вы можете обойти это с ...

var isString = Object.prototype.toString.call(str) == '[object String]';

jsFiddle .

Но опять же (как упоминает Box9 ), вам лучше использовать буквальный Stringформат, например var str = 'I am a string';.

Дальнейшее чтение .


1
@ Box9 Не беспокойся, я все равно повторюсь: P
alex

@alex Я сейчас тоже: o (еще 10 минут!)
Дэвид Тан

3
@RobG Количество повторений ограничено, когда вы набрали максимальное количество повторений за один 24-часовой период. После этого, положительные отзывы не засчитываются в вашу репутацию.
Алекс

Разве нельзя проверить, является ли переменная строкой, просто проверив наличие члена, который есть только в строках? Например: if(myVar.toUpperCase) alert('I am a string');? См: jsfiddle.net/tb3t4nsx
ingredient_15939

1
@ ingredient_15939 это не очень хороший способ ... из{ toUpperCase: '' }
Алекса

14

Объединение предыдущих ответов дает следующие решения:

if (typeof str == 'string' || str instanceof String)

или

Object.prototype.toString.call(str) == '[object String]'

4

Следующее выражение возвращает true :

'qwe'.constructor === String

Следующее выражение возвращает true :

typeof 'qwe' === 'string'

Следующее выражение возвращает false (sic!):

typeof new String('qwe') === 'string'

Следующее выражение возвращает true :

typeof new String('qwe').valueOf() === 'string'

Лучший и правильный путь ( имхо ):

if (someVariable.constructor === String) {
   ...
}

1

Сейчас я считаю, что предпочтительнее использовать функциональную форму typeof (), так что ...

if(filename === undefined || typeof(filename) !== "string" || filename === "") {
   console.log("no filename aborted.");
   return;
}

нет никакой формы функции typeof, вы просто контролируете порядок операций с этими скобками. Некоторые люди могут найти его более читабельным при определенных обстоятельствах.
Джон

@Jonz Что вы имели в виду под «контролем порядка операций»? Спасибо.
20

Думаю, позже я понял, что вы можете проверить конструктор и предпочесть его, поскольку теоретически я думал, что это будет быстрее, но не быстрее? Пример № 4 здесь показывает использование скобок developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… это определенно более читабельно и меньше для разбора компилятором. Мое предположение о 'порядке', возможно, связано со скоростью или связано с тем, как компилятор загружает стек аргументов, я не уверен.
Мастер Джеймс

1
@ a20 порядок операций описывает порядок, в котором операции выполняются для операторов, которые содержат несколько операций. См. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - круглые скобки (операционная группировка) имеют наивысший приоритет оператора и поэтому оцениваются первыми. В этом случае круглые скобки вокруг filenameтолько группируют одно утверждение, и поэтому являются бесполезными и посторонними. Хорошо, что этот ответ имеет оценку 0, потому что он неправильный, вводящий в заблуждение и бесполезный; было бы лучше, если бы у него был отрицательный счет.
Джон

Очень информативное спасибо за ссылку. Итак, скобки проверяются и запускаются первыми? так что должен запускаться сразу, не проверяя следующий для других способов вызова ака без скобок, что будет шаги позже и медленнее? нет? что я не понимаю о компиляторе времени выполнения там.
Мастер Джеймс

0

проверка на ноль или неопределенность во всех случаях a_string

if (a_string && typeof a_string === 'string') {
    // this is a string and it is not null or undefined.
}

typeof nullи typeof undefinedникогда не вернется 'string', так typeof a_stringчто достаточно. Извините за некропостинг
Иван Фролов

-3

Мой личный подход, который, кажется, работает во всех случаях, - это тестирование на присутствие членов, которые будут присутствовать только для строк.

function isString(x) {
    return (typeof x == 'string' || typeof x == 'object' && x.toUpperCase && x.substr && x.charAt && x.trim && x.replace ? true : false);
}

Смотрите: http://jsfiddle.net/x75uy0o6/

Я хотел бы знать, есть ли у этого метода недостатки, но он годился для меня хорошо.


2
Это легко обмануть любым старым объектом, у которого есть эти методы.
Алекс

8
Это называется типизацией утки - например, если она ходит как строка и говорит как строка, она также может быть строкой. Вы немного сумасшедший, если думаете, что это лучший способ проверить строку, но Javascript - это Thunderdome, вы делаете это.
Jon Z
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.