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

Ответы:

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) {
   ...
}
redisko
источник
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.
}
Kurkula
источник
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/

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

ingredient_15939
источник
2
Это легко обмануть любым старым объектом, у которого есть эти методы.
Алекс
8
Это называется типизацией утки - например, если она ходит как строка и говорит как строка, она также может быть строкой. Вы немного сумасшедший, если думаете, что это лучший способ проверить строку, но Javascript - это Thunderdome, вы делаете это.
Jon Z